RSS-подписка

RSS-лента

Новые статьи

Последние комментарии


Получать обновления на эл. почту

Ваш e-mail:

Рассылка новостей от Loco

Yii: Настраиваем список listBox на выбор нескольких значений и сохранение их в одном поле MySQL (select multiple listbox)

Yii: Настраиваем список listBox на выбор нескольких значений и сохранение их в одном поле MySQL (select multiple listbox) activeListBox поддерживает выделение нескольких значений в списке. Добавляем смело htmlOption 'multiple' в activeListBox. Это сделает возможным множественное выделение в форме. Но дальше нужно кое-что сделать, чтобы в MySQL сохранять всё как надо - ведь у нас получается уже массив из выбранных значений (когда выбираем одно значение, то всё работает само). Вот этой проблемке и посвящена эта статья.

1. Сохранение значений в MySQL будем делать в одно поле типа varchar в виде строки где все значения разделены запятыми ('6,87,16') ну или ('selection','multiple','yii','listbox'), не важно.

2. Добавляем public virtual attribute в нашу модель (этот атрибут и будет использоваться нашим listbox). Виртуальный – потому, что такого поля в таблице БД на самом деле не существует.

public $selection;

3. Далее мы используем специальный метод afterFind(), встроенный в Yii, который позволяет преобразовать значение атрибута после выборки из базы данных. В нашем случае мы не просто преобразуем значение из БД, но присвоим результат преобразования – нашей переменной $selection. Итак, разобьём значение, хранимое в БД, на массив элементов (разделителем у нас будет служить запятая) и поместим в нашу виртуальную переменную $selection:

protected function afterFind()
{
    parent::afterFind();
    $this->_oldTags=$this->tags;
    $this->_oldSections=$this->sections;

    $this->selection=explode(', ',$this->sections);
    return true;
}

4. Похожим образом организуем обратный процесс – сохранение выбранных в listBox значений в поле таблицы базы данных. Для этого задействуем метод beforeSave(): объединим выбранные в форме значения (удерживая ctrl выбираем несколько их) в строку:

public function beforeSave() {
    if(parent::beforeSave())
    {
        $this->sections=implode(', ',$this->selection);
        return true;
    }
    else
        return false;
}
В этих функциях должен быть 'return true;'

В Модели атрибут "selection" надо добавить в список safe атрибутов, в Виде уже используем его, а не 'sections'. То есть получилось промежуточное звено перед обращением к базе MySQL.

almix
Разработчик Loco, автор статей по веб-разработке на Yii, CodeIgniter, MODx и прочих инструментах. Создатель Team Sense.

Вы можете почитать все статьи от almix'а.



Другие статьи по этой теме:

Комментарии (2)     Подпишитесь на RSS комментариев к этой статье.

2 комментариев

#716
Виталий говорит:
November 28, 2012 at 03:28 pm

Здравствуйте, после выполнения всех пунктов получаю ошибку "Не определено свойство "Aircraft.dbcolumn"."

Я смотрел тему на форуме за 2009 год с таким же решением, но там у человека после проделанных операций все работало. Возможно что то поменялось, подскажите как сделать правильно.

Заранее весьма благодарен за помощь.

#1336
almix говорит:
March 4, 2015 at 09:21 pm
Виталий, что у вас за поле 'dbcolumn'? В статье я использовал поле 'sections' (реально существует в таблице БД), и псевдо-атрибут 'selection' (это массив элементов для строки из 'sections', его на самом деле нет в таблице БД, оно только обьявляется в модели, чтобы использовать потом его, а не sections). Скорее всего ваш 'dbcolumn' не создан в таблице БД, а в вашей модели вы его указали.