1

I am trying to use a listbox and using the following syntax for multi-select, which is not working.

<?= $form->field($model, 'weekday')->listBox([
       'monday'=>'Monday',
        'tuesday'=>'Tuesday',
        'wednesday'=>'Wednesday',
        'thursday'=>'Thursday',
        'friday'=>'Friday',
        'saturday'=>'Saturday',
        'sunday'=>'Sunday'],['multiple'=>true,'size'=>7])

            ?>

I am able to multi-select in the list box, but it is returning a null value. If I am taking the part multiple'=>true then It is returning the correct value, but then I am not able to multi-select.

What I am doing wrong here?

Thanks.

relevant code in the appointment model.php

public function rules() {

    return [
        [['appointment_date'], 'safe'],
        [['priority', 'weekday'], 'string', 'max' => 20]
    ];

}

controller code:

public function actionCreate()
    {
        $model = new Appointment();

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

Stack trace for the error I am getting after update of the suggested code in the answer by aragachev

Getting unknown property: app\models\Appointment::weekday 1. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\base\Component.php at line 143 134135136137138139140141142143144145146147148149150151152

 foreach ($this->_behaviors as $behavior) {
            if ($behavior->canGetProperty($name)) {
                return $behavior->$name;
            }
        }
    }
    if (method_exists($this, 'set' . $name)) {
        throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name);
    } else {
        throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name);//line 143
    }
}

/**
 * Sets the value of a component property.
 * This method will check in the following order and act accordingly:
 *
 *  - a property defined by a setter: set the property value
 *  - an event in the format of "on xyz": attach the handler to the event "xyz"

2. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\db\BaseActiveRecord.php – yii\base\Component::__get('weekday') at line 247
3. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\helpers\BaseArrayHelper.php – yii\db\BaseActiveRecord::__get('weekday') at line 190
4. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\widgets\DetailView.php – yii\helpers\BaseArrayHelper::getValue(app\models\Appointment, 'weekday') at line 209
5. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\widgets\DetailView.php – yii\widgets\DetailView::normalizeAttributes() at line 123
6. in E:\wamp\www\HospitalErp\vendor\yiisoft\yii2\base\Object.php – yii\widgets\DetailView::init() 
2
  • Tested it. Everything works fine for me. Is it safe attribute in current scenario? Show the rest of the code related with this attribute (model, controller). Maybe you missed massive assignment? Commented Jan 19, 2015 at 3:16
  • Hi arogachev - included the relevant code for model and controller. Commented Jan 19, 2015 at 9:01

1 Answer 1

2

The reason of this is StringValidator attached to weekday attribute in model rules:

[['priority', 'weekday'], 'string', 'max' => 20],

You are receiving an array, not string (even in case of one selection) because of multiple => true option. It simply did not pass validation.

There is no built-in array validator in Yii 2.

1) Because you want multiple selection I recommend you to rename weekday to weekdays.

2) I recommend to put weekdays list in separate method:

public static function getWeekdaysList()
{
    return [
        'monday' => 'Monday',
        'tuesday' => 'Tuesday',
        'wednesday' => 'Wednesday',
        'thursday' => 'Thursday',
        'friday' => 'Friday',
        'saturday' => 'Saturday',
        'sunday' => 'Sunday',
    ];
}

3) Create inline validator, for example, like this:

public function validateWeekdays ($attribute, $params)
{
    $label = '«' . $this->getAttributeLabel($attribute) . '»';

    // Checking if it's array first
    if (is_array(!$this->$attribute)) {    
        $this->addError($attribute, "$label must be array.");

        return;
    }

    $allowedWeekdays = array_keys(static::getWeekdaysList());

    // Checking if every selection is in list of allowed values
    foreach ($this->$attribute as $weekday) 
    {
        if (!in_array($weekday, $allowedWeekdays)) {
            $this->addError($attribute, "$label - $weekday is not in allowed list");

            return;
        }
    }
}

Read more about inline validators in offical guide.

4) Attach it to weekdays in model rules:

['weekdays', 'validateWeekDays'],

If you don't want to validate weekDays you should explicitly mark it as safe attribute in order to massively assign it with other attributes:

['weekdays', 'safe'],

5) In view you can simplify your code to:

<?= $form->field($model, 'weekdays')->listBox(Appointment::getWeekdaysList(), [
    'multiple' => true,
    'size' => 7,
]) ?> 

And one little remark - weekday it's kind of working day, excluding Saturday and Sunday. The more correct form is days of the week.

Sign up to request clarification or add additional context in comments.

7 Comments

Hi agrogachev - I have modified the code including renaming the weekday to weekdays - I am now getting the error - Getting unknown property: app\models\Appointment::weekday
You should also change it in the database, for example with help of migration. And check attentively again, maybe you missed renaming somewhere.
Yes I have changed it in the database, not with the help of migration but in phpmydmin and even overwritten the model.php and then added your code still the same problem.
Show full stack trace, so we can see the line it's coming from. Or do the global search and replace in your editor, most likely the attribute wilh old name still exists somewhere.
Hi arogachev - I have added the stack trace for the error - I couldn't find any instances of weekday in the model.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.