@MaikMain
Начинающий backend - developer

Проблема с checkboxList. Yii2?

Добрый день у меня такая проблема.
У меня есть обычный CRUD. И мне нужно добавить запись в БД с размерами товаров. Для этого я создал себе вспоминающий файл (SizeOneHelper):
SizeOneHelper
class SizeOneHelper
{
    public static function typeList(): array
    {
        return [
            'S (55/56)',
            'M (57/58)',
            'L (59/60)',
            'XL (61/62)',
        ];
    }
    public static function typeName($drive): string
    {
        return ArrayHelper::getValue(self::typeList(), $drive);
    }
    public static function typeLabel($drive): string
    {
        return Html::tag('span', ArrayHelper::getValue(self::typeList(), $drive));
    }
}


Во view я вывожу это вот так:
<?= $form->field($model, 'size')->checkboxList(SizeOneHelper::typeList()) ?>

Сохраняю это в БД вот так:
Контроллер

public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            $model->size =  implode(', ',$model->size);
            $model->save();
            return $this->redirect(['view', 'id' => $model->id]);
        }
        return $this->render('update', [
            'model' => $model,
        ]);
    }


Соответственно в БД у меня теперь лежит: "0, 2"
Вопрос в том, как мне сделать так, чтобы checkboxList показывал какие элементы у меня выбраны. И как правильно это вывести в DetailView.
За ранее большое спасибо!
  • Вопрос задан
  • 1363 просмотра
Решения вопроса 1
slo_nik
@slo_nik Куратор тега Yii
У Вас данные размеров хранятся не очень удобно.
Пока можно сделать вот так.
// Ваш статический метод в модели SizeOneHelper
    public static function getSizeList(): array
    {
        return [
            'S (55/56)',
            'M (57/58)',
            'L (59/60)',
            'XL (61/62)',
        ];
    }

// если в $model->size данные хранятся в виде строки, то надо привести к массиву и передать в checkboxList()
$select = explode(',', $model->size);
echo $form->field($model, 'size')->checkboxList(SizeOneHelper::getSizeList(),[
   'item' => function($index, $label, $name, $checked, $value) use ($select){
      if(in_array($index, $select)){
         $checked = 'checked';
      }
      return Html::checkbox($name, $checked);
   }
])

Но я бы не хранил это в виде строки. Скорей всего создал бы отдельную связующую таблицу, где хранил бы размеры и id товара.

p.s. Сделал "на коленке", но если подумать, то можно и это улучшить.

p.s.s. Для того чтобы выводился label checkbox в функцию передаётся нужный параметр в переменной $label. Используйте его и будет выводится название checkbox-a.
return Html::checkbox($name, $checked, ['label' => $label]);


p.s.s.s. В DetailVeiw можно вывести нужные данные таким образом
// метод в модели SizeOneHelper
    public function getSizeName()
    {
        return ArrayHelper::filter(self::getSizeList(), explode(',',$this->size));
    }

// в DetailView получаем строку по названиям размеров
echo DetailView::widget([
  'model' => $model,
  'attributes' => [
     [
       'attribute' => 'size',
       'value' => function($model){
          return implode(',',$model->getSizeName());
       }
     ]  
  ]
]);


p.s.s.s.s. Создайте дополнительный метод в модели SizeOneHelper
public  function getSelectSizeList()
    {
        return explode(',',$this->size);
    }

Метод getSizeName изменится на такой
// метод в модели SizeOneHelper
 public function getSizeName()
    {
        return ArrayHelper::filter(self::getSizeList(), $this->getSelectSizeList());
    }


Тогда вывод размеров может быть таким:
// в checkboxList
echo $form->field($model, 'size')->checkboxList(SizeOneHelper::getSizeList(),[
   'item' => function($index, $label, $name, $checked, $value) use ($model){
      if(in_array($index, $model->getSelectSizeList())){
         $checked = 'checked';
      }
      return Html::checkbox($name, $checked, ['label' => $label, 'value' => $value]);
   }
])
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@dasauser
Пишу на PHP
Ну, вроде как то так:
//controller
public function actionView() {
    $data = [["id" => 1, "checked" => true], ["id" => 2, "checked" => false], ["id" => 3, "checked" => true]];
    return $this->render('view', [ 'data' => $data, 'model' => $this->findModel($id), ]);
}

//View
foreach ($data as $key => $value) {
    $checked = '';
    if ($value['checked'] === true) {
        $checked = 'checked';
    }
    echo "<input type=checkbox id=" . $value['id'] . " $checked>";
}
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы