16
Joomla select multiple insert in to db automatically
Программирование
Делая кое-что в joomla 1.7, столкнулся с тем, что не записывается само по себе добавленное мною поле select multiple в неком компоненте (component) joomla. Казалось бы, если на сервер поступает число или строка, то скрипт который наследует класс JTable знает что с этим полем делать, а вот когда поступает массив, то не знает. Хотя по умолчанию могли бы сделать и обычный implode через запятую. Ну да ладно. Решение нашел в википедии, правда на англицком языке.
Поэтому и решил написать этот пост, так как на русском языке в поиске выпадет ноль.
Короче говоря нужно в классе который наследует JTable дописать такую вот функцию
function bind( $array, $ignore = '' ) { if (key_exists( 'field-name', $array ) && is_array( $array['field-name'] )) { $array['field-name'] = implode( ',', $array['field-name'] ); } return parent::bind( $array, $ignore ); } |
Ясное дело, что “field-name” необходимо поменять на название поля в базе данных, в которое и будет записана строка, в которой через запятую будут записаны значения выбранных опций в select multiple.
В комментариях поступил вопрос “еще бы как выделение сохранять multiple списка…)”. Отвечаю на своем примере :
<!--?php $fieldName=array(); if(strlen($this--->conf->fieldName)>0){ $fieldName = explode(',', $this->conf->fieldName); } $query = "SELECT id, title FROM #__usergroups"; $db=JFactory::getDbo(); $db->setQuery($query); $usergroups = $db->loadObjectList(); ?> <select name="field-name[]" multiple="multiple"> <!--?php foreach ($usergroups AS $k =--> $v): ?> <option value="<?php echo $v->id; ?>">id, $fieldName)) { echo "selected"; } ?>><!--?php echo $v--->title; ?></option> <!--?php endforeach; ?--> </select> |
В данном случае я делаю мульти выбор юзерских групп, их можно выбрать несколько. Выделяются только те, которые есть в строке, которую мы достали из базы данных и превратили в массив с помощью функции explode . Переменную fieldName я сам придумал, вы можете использовать любое название.
Благодаря пользователю Brr нашлось решение для joomla 2.5, которое несколько отличается от предыдущих версий.
Далее идет цитата
В модели JModelAdmin, которая используется для создание формы в админке, есть определенный пустой метод prepareTable(), он вызывается перед занесением данных в бд, переопределяем его в своей модели:
protected function prepareTable(&$table) { if(isset($table->field_name) && is_array($table->field_name)) $table->field_name=implode(‘,’, $table->field_name); }этот метод возьмет массив выбранных элементов поля сохранит в виде строки через “,”.
Также, для обратного преобразования строки в массив при выводе в форме есть еще один предопределенный метод loadFormData(), унаследованный классом JModelAdmin от JModelForm, сам по себе он ничего не делает, его нужно переопределить в своем классе. Он выполняет загрузку данных по-умолчанию в поля формы, и тут же мы преобразуем строку в массив:
protected function loadFormData() { $data=JFactory::getApplication()->getUserState('com_fteach.edit.workplan.data', array()); if(empty($data)) { $data=$this->getItem(); } if(isset($data->field_name) && !is_array($data->field_name)) $data->field_name=explode(',', $data->field_name); return $data; }Вуаля, все работает:)
Спасибо за внимание.
Будут вопросы, отвечу в комментариях…
An answer from an eepxrt! Thanks for contributing.
Thanks!
Как раз этим же вопросом озадачился, думал – куда бы implode впихнуть -а тут готовое решение)
еще бы как выделение сохранять multiple списка…)
Eliarh, я в статье добавил ответ на ваш вопрос
Тоже с этим сегодня столкнулся, но что-то не понял, как применить изложенное в этой статье. Есть стандартное поле list (JFormFieldList) указываю в хмл файле формы, что селект список должен быть multiple, в форме появляется список с мультивыбором, но никаких изменений в базу он не вносит, даже если выбрано одно значение. Как с этим бороться?
Какую версию joomla вы используете??
В статье я описал случай для 1.7, но не знаю будет ли то же самое работать и на 2.5.
Может вы не поняли фразу “нужно в классе который наследует JTable дописать такую вот функцию” ??? Мне не понятно, что именно вам нужно разъяснить ??
Использую 2.5.3. Я понимаю значение этой фразы, но у меня нет классов, унаследованных от JTable. Я работаю с полями, там они унаследуются от JFormField. Или я что-то неправильно понимаю? И самое интересное, что в J2.5 есть поле list (JFormFieldList), в нем можно задавать параметр multiple, поле отображается с возможностью множественного выбора, но при сохранении в базу изменения не вносятся. Вот с этим у меня проблемка
Да, для 2.5 данный пример не подходит, в 2.5 кардинально многие вещи изменили. Админ, если у тебя будет время разобраться с 2.5, отпиши пожалуйста решение данной проблемы для версии 2.5
Мне этот вопрос нужно решить чем побыстрее, некоторые варианты выйти из положения есть, вот например: моя модель формы редактирования унаследована от JModelAdmin, там есть метод save(). Данные моего multiple-поля должны сохраняться в бд в виде строки идов через запятую, поэтому в своем производном классе модели нужно дописать метод сейва:
function save($data) {
if(isset($data['field_name']) && is_array($data['field_name'])) $data['field_name']=implode(‘,’, $data['field_name']);
return parent::save($data);
}
Также, с другой стороны, нужно перед показом в форме полученную с бд строку разобрать обратно в массив, для этого я предлагаю создать свой тип поля, унаследованный от JFormFieldList и реализовать в нем преобразование строки в массив с последующим выводом списка.
Может кто-то нашел другие способы, поделитесь пожалуйста.
Стоить добавить, что предлагаемое в статье решение(функция bind() ) и мое ( save() ) эквивалентны, и каждый уже сам может выбирать способ. Но если учитывать логику MVC-модели, то, думаю, будет правильнее все-таки поместить код преобразования данных поля в модели.
Главное, чтобы после обновления joomla не затерла все ваши изменения. Вот если не затрет, значит это правильно …
Нашел более правильное решение. В модели JModelAdmin, которая используется для создание формы в админке, есть определенный пустой метод prepareTable(), он вызывается перед занесением данных в бд, переопределяем его в своей модели:
protected function prepareTable(&$table) {
if(isset($table->field_name) && is_array($table->field_name)) $table->field_name=implode(‘,’, $table->field_name);
}
этот метод возьмет массив выбранных элементов поля сохранит в виде строки через “,”.
Также, для обратного преобразования строки в массив при выводе в форме есть еще один предопределенный метод loadFormData(), унаследованный классом JModelAdmin от JModelForm, сам по себе он ничего не делает, его нужно переопределить в своем классе. Он выполняет загрузку данных по-умолчанию в поля формы, и тут же мы преобразуем строку в массив:
protected function loadFormData() {
$data=JFactory::getApplication()->getUserState(‘com_fteach.edit.workplan.data’, array());
if(empty($data)) {
$data=$this->getItem();
}
if(isset($data->field_name) && !is_array($data->field_name)) $data->field_name=explode(‘,’, $data->field_name);
return $data;
}
Вуаля, все работает:)
Спасибо вам большое. Я еще не разбирался с joomla 2.5 . Можно ли ваше решение добавить в конец статьи, как решение данной проблемы для joomla 2.5 ???
Faradey:
“Главное, чтобы после обновления joomla не затерла все ваши изменения. Вот если не затрет, значит это правильно …”
Joomla ничего не затрет, потому что код самой системы никто не трогает.
Admin, конечно, буду рад если добавите, рад был помочь:)
Добавил в запись решение Brr, как решение для joomla 2.5. Спасибо большое Brr за помощь