О том, что фреймворки позволяют сократить время разработки, знают все. Но иногда при этом появляются самые неожиданные ограничения.
По-идее, так и должно быть. Каким бы универсальным не пытались сделать фреймворк разработчики, всегда чем-то приходится жертвовать. Точнее искать компромисс между количеством кода, который должен написать пользователь и гибкостью.
В этой статье я хочу показать пример такой ситуации, и, естественно, её решение.
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 callmy_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.
Если вы знаете более удачные варианты, буду рад выслушать и обсудить 😉
До встречи!
Интересно почитать
Удобный и недорогой стол для кассы отечественной разработки