Ограничения фреймворков (на примере Yii)

Владимир | | Ajax, HTML, JavaScript, PHP, Web разработка, Yii.

yii php framework autocomplete

О том, что фреймворки позволяют сократить время разработки, знают все. Но иногда при этом появляются самые неожиданные ограничения.

По-идее, так и должно быть. Каким бы универсальным не пытались сделать фреймворк разработчики, всегда чем-то приходится жертвовать. Точнее искать компромисс между количеством кода, который должен написать пользователь и гибкостью.

В этой статье я хочу показать пример такой ситуации, и, естественно, её решение.

UPD: Более удачное решение данной проблемы приведено в комментариях.

Не так давно я опубликовал статью Yii PHP фреймворк: создаем поле с автозаполнением, в которой рассказывал об использовании виджета CAutoComplete.

Алгоритм его работы довольно прост.

1) Создать текстовое поле (тег input).
2) Подключить плагин jQuery Autocomplete и файлы CSS стилей.
3) Подключить плагин к текстовому полю.

При этом, все настройки виджета CAutoComplete задаются при его подключении в PHP массиве.

Т.к. основную работу выполняет Autocomplete, то логично было бы предположить, что в настройках виджета можно задать все параметры этого плагина. Для большинства параметров, так оно и есть, но с параметром extraParams возникли проблемы.

В документации сказано.

Extra parameters for the backend. If you were to specify {bar:4}, the autocompleter would call my_autocomplete_backend.php?q=foo&bar=4 (assuming the input box contains «foo»). The param can be a function that is called to calculate the param before each request.

Дополнительный параметр для бэкенда. Если вы указали {bar:4}, плагин отправит запрос my_autocomplete_backend.php?q=foo&bar=4 (предполагается, что текстовое поле содержит текст «foo»). Параметр может быть функцией, которая вызывается чтобы рассчитать значение параметра перед отправкой каждого запроса.

Т.е. вы можете задать настройки для CAutoComplete следующим образом.

$this->widget('CAutoComplete',
     array(
         'extraParams'=>array('mypar'=>'myval'),
         'url'=>array('countries/autocomplete'),
     )
 );

И такой вариант будет работать.

Но если вы захотите использовать в качестве значения функцию, например

'extraParams'=>array('mypar'=>'function() {return $("#myselect").val();}'),

то этот JS код выполняться не будет.

Примечание. Показанная здесь функция возвращает значение из выпадающего списка (myselect).

Дело в том, что функция передается в виде стоки (в кавычках) и JS код при этом, естественно, не выполняется.

Решить проблему можно так.

1) Создаём js файл с таким кодом.

jQuery("#country").setOptions({
'extraParams':{'mypar':function() {return $("#myselect").val();}}}
);

2) Подключаем его к нужной странице.

$cs = Yii::app()->clientScript;
$cs->registerScriptFile(Yii::app()->request->baseUrl.'/js/autocomplete_config.js', CClientScript::POS_END);

Здесь autocomplete_config.js – название вашего скрипта.

Как видите, решение достаточно простое, но не очень красивое. Часть настроек виджета будет задана в PHP файле, часть в JS.

Если вы знаете более удачные варианты, буду рад выслушать и обсудить 😉

До встречи!

Интересно почитать

Удобный и недорогой стол для кассы отечественной разработки