Dear,
I’ve tried to create a virtual attribute and validate it, but it only worked with client validation while the server validation didn’t work.
My environment version is:
My code as below:
Project.php (model)
<?php
namespace app\models;
use Yii;
use yii\bootstrap\Html;
use yii\helpers\ArrayHelper;
class Project extends \yii\db\ActiveRecord
{
private $assignArray = [];
/**
* @inheritdoc
*/
public function rules()
{
return [
[['name', 'description', 'assignments'], 'required'],
[['assignments', 'created', 'modified'], 'safe'],
[['name'], 'string', 'max' => 160],
[['description'], 'string', 'max' => 1000]
];
}
/**
* @inheritdoc
*/
public function afterSave($inserted)
{
if (!$inserted) {
ProjectUser::deleteAll('project_id = :id', array('id'=>$this->id));
}
// insert it.
return array_walk($this->assignArray, function ($val, $key) {
$assignment = new ProjectUser();
$assignment->project_id = $this->id;
$assignment->user_id = $val;
$assignment->save();
});
}
/**
* @return \yii\db\ActiveQuery
*/
public function getProjectUsers()
{
return $this->hasMany(ProjectUser::className(), ['project_id' => 'id']);
}
/**
* Set value for user assignment
*
* @param array $members
*/
public function setAssignments($value)
{
$this->assignArray = (array) $value;
}
/**
* @return ProjectUser[]
*/
public function getAssignments()
{
if ($this->isNewRecord) {
return $this->assignArray;
}
return ArrayHelper::getColumn($this->projectUsers, 'user_id');
}
}
ProjecUser.php (model)
<?php
namespace app\models;
use Yii;
class ProjectUser extends \yii\db\ActiveRecord
{
/**
* @inheritdoc
*/
public static function tableName()
{
return 'project_user';
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['project_id', 'user_id'], 'required'],
[['project_id', 'user_id'], 'integer'],
[['created', 'modified'], 'safe']
];
}
/**
* @return \yii\db\ActiveQuery
*/
public function getProject()
{
return $this->hasOne(Project::className(), ['id' => 'project_id']);
}
/**
* @return \yii\db\ActiveQuery
*/
public function getUser()
{
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
}
_form.php(view)
<?php
use app\models\User;
use kartik\widgets\Select2;
use kartik\widgets\ActiveForm;
use yii\helpers\Html;
/* @var $this yii\web\View */
/* @var $model app\models\Project */
/* @var $form kartik\widgets\ActiveForm */
?>
<div class="project-form">
<?php $form = ActiveForm::begin(); ?>
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>
<?= $form->field($model, 'description')->textarea(['maxlength' => true, 'rows' => '10']) ?>
<?= $form->field($model, 'assignments')->widget(Select2::className(), [
'data' => User::findListAsArrayMap('id', 'username'),
'options' => [
'multiple' => true,
'placeholder' => 'Please select ...',
'allowClear' => true,
]
]) ?>
<div class="form-group">
<?= Html::submitButton(
$model->isNewRecord ? Yii::t('app', 'Create') : Yii::t('app', 'Update'),
['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']
) ?>
</div>
<?php ActiveForm::end(); ?>
</div>
I use with kartik activeform and select2, but it doesn’t matter, because it work very well with normal attribute, or an public class property. I mean only when I use set and get function to make a virtual attribute, it just work with client validation, not server validation (focus on assignments required).
Doesn’t Yii2 support it ?