Архив рубрики «Новое»

Вызов меню выбора файла из javascript-а

02.12.2010

Столкнулся с очень своеобразной проблемой - нужно было сделать, чтобы по крику на ссылку открывалось окошко выбора файла как в input type="file". Перерыл инет, нашел советы по поводу вызова метода click у input type="file", но у меня так оно и не прокатило. Стал рыться дальше - нашел даже очень большую статью, в которой написано мол "если бы браузеры давали возможность скриптам манипулировать этим типом инпута, то злоумышленники бы могли выкачать любой файл с компа человека". И я понимаю, безопасность все такое, но заказчик хочет.

В итоге на мою злочастную ссылку отдельным слоем сверху (через position: absolute) была наложена прозрачная кнопка из input type="hidden".

Вот так: <div style="width: 100px; height: 20px;" ><input type="file" /></div>

Т.е. это был div фиксированного размера, в нем поле input type="file" с большим шрифтом (чтобы сама кнопка обзор была большая), инпут перекручен так, чтобы видна была только кнопка (тогда cursor: pointer и пользователь не может тыкнуть в поле), т.е. инпут гораздо больше чем div, просто находится внутри него кнопкой попадая в то что из-под дива видно.

И разумеется все это счастье прозрачное. И вуаля! Пользователь думает что кликает на ссылку, а на самом деле кликает на кнопку - и наше менюшка выбора файла тут же появляется на экране.

теплый дом .

Как работает removeChild :)

11.08.2010

Оказалось, что el.removeChild не удаляет сам элемент как мне раньше казалось, а лишь отвязывает элемент от родителя. А потом этот же элемент можно привязать к другому родителю скажем, что позволяет перемещать элементы по DOM-у. Например так:

var el = document.getElementById('element');
el.parentNode.removeChild(el);
document.getElementById('destination').appendChild(el);

PhpDoc для конкретной переменной

10.12.2009

Мне никогда не нравился паттерн Factory в php. Не потому что он плохой или неудобный, нет. Просто IDE никак не понимали то что фабрика собственно возвращает. Это как и вечная проблема, что в phpDoc-ах можно указать какие параметры принимаются методом, какие возвращаются им, но никак нельзя указать класс для конкретной переменной.

Но недавно оказалось что можно. На примере:

$input = Input_Factory::factory('text'); /*@var $input Input_Text*/

И ура, подсказки работают :)

MySQL альтернативный синтаксис INSERT

10.12.2009

Недавно узнал, что оказывается MySQL поддерживает 2-й альтернативный синтаксис оператора INSERT :)

Ну традиционный понятно:

INSERT INTO sometable (`field1`, `field2`,  `field3`)  VALUES ('value1', 'value2', 'value3');

А альтернативный как и UPDATE:

INSERT INTO sometable SET `field1`='value1' , `field2`='value2', `field3`='value3';

PHP_EOL

23.10.2009

Наткнулся на прикольную предопределенную константу PHP_EOL в которой лежит "\n", если сервер линуксовый или "\r\n" если виндошный. Ниче особенного, просто прикольная штука

Многострочные строки в javascript

27.05.2009

Мож кто и в курсе, но я не знал и не сразу вкурил. Оказывается,  в джаваскрипте многострочные строки можно писать не только вот так:
var val = 'Индикатор ядовито'+
' гидролизует сернистый газ,'+
' таким образом за синтез';

А еще и вот так:
var val = 'Индикатор ядовито\
гидролизует сернистый газ,\
таким образом за синтез';

Не сказать, чтобы было гораздо читабельнее, но есть и такой вариант :)

REGEXP и RLIKE

20.04.2009

Наткнулся недавно в коде проекта на вот такую вот конструкцию:

...AND (`struct`.`regions` = "" OR `struct`.`regions` REGEXP "^a:[0-9]+:\{.*(i:[0-9]+;s:[0-9]+:\"'.$current_region_id.'\"\;).*\}$" OR `struct`.`regions` REGEXP "^a:[0-9]+:\{.*(i:[0-9]+;s:[0-9]+:\"'.ALL_REGIONS_ID.'\"\;).*\}$" OR `struct`.`regions` REGEXP "^a:[0-9]+:\{+(i:[0-9]+;s:[0-9]+:\"0\"\;)*\}$" )...

и не сразу вкурил что это за загадочный REGEXP. Оказалось что это синоним старого доброго RLIKE, ну точнее последний синоним первого :) так-то :)

This page contains both secure and nonsecure items

17.04.2009

Недавно наткнулся на хабре на стетейку о «//» в ссылках, т.е. идея писать абсолютные пути без указания протокола типа http://ya.ru заменять на //ya.ru/.

Не буду копипастить - статья лежит тут: http://bolknote.ru/2009/04/04/~2074 советую прочитать всем.

Раскажу я о том, что это может поправить. Так вот, дело в том, что когда IE подгружает страницу по https, в которой есть ссылки на цсски или джээсники по http - ругается, дескать "This page contains both secure and nonsecure items". Такой баг я поймал когда прикручивал WorldPay - там страница ответа подгружается системой и отображается как своя - т.е. ваша страница ответа будет по урлу http://www.worldpay.com/etc.... Ясное дело, что если ссылки в урлах относительные - то css не загрузится и дизайну кабзда :) поэтому ссылки делаются абсолютными - ну а если они генерятся автоматом - то путь на них будет по http - вот и получаем такой варнинг. Если же пользоваться «Common Internet Scheme Syntax», то все будет окей :) жаль что я не знал этого пару лет назад :(

Тег <colgroup>

17.04.2009

Ширина ячеек таблицы - отдельная песня для создания сайтов. В больших таблицах, где линий много, тегов <td> еще больше. Чтобы указать ширину ячеек один раз - я обычно указывал ее только для первой линии (т.е. для td-шек 1-й tr-ки), а остальные уже подстраивались под первую. Если же таблица генерилась циклом, то width получалось был в каждой ячейке.

(далее...)

Тег <nobr>

17.04.2009

Мне нравится работать в команде опытных ребят, постоянно тибрим друг у друга идеи и учимся чему-нить. На этот раз открытием для меня стал тег <nobr>. Я раньше часто мучался, выискавая место куда можно тыркнуть nowrap, а оказывается все гораздо проще:

Тег <NOBR> (NO BReak line) запрещает перевод строки. Бывают случаи, когда возникает надобность в операции противоположного назначения – запретить перевод строки. Текст, заключенный между тэгами <NOBR> и </NOBR>, будет гарантированно располагаться в одной строке без переноса на другую. Длинная строка не уместится на экране, и для ее просмотра придется использовать горизонтальную полосу прокрутки. Закрывающий тег обязателен

Атрибутов нет, хотя какие-тут могуть быть аттрибуты :)

Избавиться от LIMIT через id последней записи

11.04.2009

Иногда нужно перебрать много записей из базы. Если таблицы большие, то сразу выбрать все - довольно тупое решение, поэтому обычно выбираются записи с лимитом. Вначале первые N, потом от N до 2N и т.д.  Недавно я узнал, что использовать конструкцию с лимитом ( LIMIT n, m ) на больших таблицах - не верно, потому что при выборке скажем:

SELECT * FROM table WHERE true LIMIT 100500, 100;

вначале выберутся 100600 записей, а потом отбросятся 100500, т.е. в двусторонних лимитах вначале выбирается все до последнего предела, а потом уже отбрасывается то что не нужно. Я раньше как-то не задумывался, но на огромных таблицах - это просто фатально для базы :)

Оказалось, что есть решение и для этой проблемы. Вполне логичное, но пока яблоко не упадет бывает так и не догадаешься до очевидных вещей. Суть идеи в том, чтобы помнить не позицию, а последний айдишник записи, его подставлять в WHERE и уже потом делать односторонний быстрый лимит.

Например:

SELECT * FROM table WHERE id>100500 LIMIT 100;

Такое будет гораздо быстрее работать на больших базах (а иногда только оно и будет работать :) ). Конечно, не самый красивый костыль, но какой есть :)

alert anchor-а выдает то что в href :(

10.04.2009

3 часа времени убил недавно на непонятное поведение браузеров. Было у меня примерно следующее:

<div id="aa">

<a href="javascript: ;">Ссылочка</a>

<a href="javascript: ;">и еще ссылочка</a>

<a href="javascript: ;">и еще</a>

</div>

через jQuery дергаю массив ссылок:

var links = $('#aa a');

и когда пробегаюсь по ним циклом - то при алерте элемента (другими словами, alert(a), где a - anchor) - получаю текст "javascript: ;".

2,5 часа я думал что дело в том как я выбираю данные в массив - мне казалось что цикл пробегает по полям <a /> и выводит собственно их, пробовал даже через $('#aa').getElementsByTagName('a'), но потом оказалось, что браузеры почему-то ведут себя неадекватно, если делается alert по <a />.

К примеру:

<a id="diablog" href="http://www.diablog.ru">Диаблогъ</a>
<span id="oneone">АДЫНАДЫН</span>
<script type="text/javascript">
alert(document.getElementById('diablog'));
alert(document.getElementById('oneone'));
</script>

Про спан все честно скажут, что это Object HTMLElement (Opera),  Object HTMLSpanElement (FF) и просто object в IE6, а вот зато про анчор - тупо выведется то, что в параметре href.

this is kind of magic o-o-ou :)

autocomplete=»off»

10.04.2009

На заре моей программистской деятельности был популярен один из тупых багов от тестеров - "Опера подсвечивает оранжевым поля, а это ни разу не по дизайну", который естесственно возникал из-за того, что пользователь "запомнил пароль и логин" - и опера таким макаром говорила о том, что данные под эти поля у нее таки есть. Тестеров есесна отправляли с этим багом нахуй к разработчикам оперы, однако недавно я узнал, что оказывается, можно сделать так, чтобы браузер вообще ничего не запоминал и не предлагал пользователю это сделать. Ежу ясно, что самый интуитивный алгоритм - это просто втупую менять параметры инпутов, чтобы даже если и запомнилось что-то - то уже железно не то, что в очередной раз отобразится на сайте. Но, оказалось, можно и проще...

(далее...)

Fulltext Index в MySQL и встроенный поиск

07.04.2009

С самой первой книжки по пхп, поиск по сайту у меня ассоциировался с конструкцией LIKE в MySQL. На не очень навороченных сайтах и на не очень навороченных поисках - она работала на ура, даже если полей, по которым шел поиск, было много. На маленьких сайтах вообще многое допустимо :) Однако, как только надо было сделать что-нить более или менее серьезное на этом фронте - как сразу LIKE шел в топку из-за своих тормозов. И не важно что это было - Sphinx, Lucene или написанный самим заказчиком типа мегаиндексатор (было однажды и такое) - возможности MySQL отметались  - и задача поиска переносилась на другие приложения. И только недавно я узнал, что оказывается MySQL сама отлично умеет все это делать!

(далее...)

Грабли: json, eval и скобки

06.04.2009

Несмотря на то, что в слове AJAX последняя буква явно показывает на то что пересылаться должны таки xml-ники, на деле это очень не удобно, громоздко и геморойно. Раньше, когда я использовал Prototype.js я просто юзал Ajax.Updater - генерил html-код на серваке - и напрямую вставлял его куда надо.  Потом, поняв, что под прототайп не так уж много чего и есть - перешел на jQuery - и познакомился с json-ом.

И все бы зашибись - jQuery с ним работает как с родным (впрочем для javascript-а) он и есть родной, на обработку приходят уже сгенерированые объектики и т.п. все было классно и супер пока мне не попался проект, написанный с использованием прототайпа. Естесственно, на стороне сервера я по-привычке сделал json_encode - однако на клиент пришла именно что строка json. Что с ней делать я не знал - и полез курить гугл. Оказалось, что надо сделать eval, что вполне логично, потому что запись json - это ничто иное как короткая запись анонимного объекта javascript. Но это не работало. Никак. Ваще никак. json = eval(responseText) никак не хотел работать хоть ты убейся. Полчаса я пытался допереть в чем же все-таки дело, оказалось, что в такой записи json надо обрамлять скобками, т.е.:

json = eval( '(' + responseText + ')' );

вот так. Почему - хз. Перед тем как писать эту статью я честно перерыл все что можно было перерыть, но так и не смог найти, собсна почему это нужно делать именно так. Все что я нашел, это какую-то муть про Invalid Label, почему же она возникает тоже не понятно ни разу. Тем не менее, сути дела это не меняет - грабли с json-ом и евалом так и будут граблями, которые просто нужно запомнить как таблицу умножения и никогда на них не наступать :)

onkeypress vs. onkeydown

23.03.2009

Недавно пришлось прикручивать "умную" валидацию данных на клиенте через JavaScript. Заказчик захотел, чтобы в числовые поля нельзя было вбить нечисловые символы. Обычно (у нормальных людей) это делается так, чтобы при сабмите формы сгенерированный скрипт пробегался по полям - и подсвечивал (алертил, и т.п.) ошибки. Вначале был запрещен ввод пользователем не цифр. Работало это через onkeypress - там по event.charCode проверялся собственно код символа. Но тут за дело взялся тестер - и как всегда в подобных случаях предложил хуйню решение (запретить ctrl+v на поле, т.к. через него вставить не число можно), которое пришлось реализовывать.

И оказалось, что  onkeypress на ctrl+v вообще по-барабану - он его пропускает и ложит на все болт. Погуглив немного - переделал все под onkeydown - return !event.ctrlKey; И тут полетели странные баги - оказалось что фильтр, пропускавший только числа - теперь магическим образом пропускает и символы v,c,#,$ - причем только их.

И только по просшествии 2-х часов и около 5 переделок всего пришло откровение:

onkeypress - ложит болт на ctrl+v, однако коды символов приходят именно такими какими они есть

onkeydown - может отловить ctrl+v, однако коды символов - это коды нажатых клавишь! т.е. на раскладку ему тоже по-барабану

Так что если кому-нить нужно будет реализовать такую-же муть - пристрелите тестера нафиг надо юзать одновременно и то и то.

Магия isset

19.03.2009

Всю жизнь писал вот так:

if(isset($_GET['id']) && isset($_GET['filter']) && isset($_GET['order'])) // do something

Благодаря Говнокоду узнал что функция (ну вообще-то конструкция языка - но нам по-барабану же :) )  isset оказывается:

bool isset ( mixed $var [, mixed $var [, $... ]] )

т.е. принимает не один параметр, а несколько, причем

isset($a, $b) = isset($a) && isset($b)


Информеры с тИЦ и PR: получить код для сайта