<= [[start|Back to Yii2 Overview]] ====== Dynamic Form ====== In this article we are going to create a dynamic form. It is a form that keeps its structure and rules in configuration arrays, not in hard-coded classes. We are going to use the DynamicModel. From the Yii documentation: > DynamicModel is a model class primarily used to support ad hoc data validation. ===== The Dynamic Model Class ===== * Create the Dynamic Model class. Create the file ''app/models/DynamicModel.php'': attributeLabels; } public function setAttributeLabel($attribute, $label) { $this->attributeLabels[$attribute] = $label; } } ===== The Controller Action ===== In a controller file (e.g. ''controllers/SiteController.php''), create an ''action'' method.\ First, we are creating the _field_ definitions, then the _field rules_: [ 'type'=>'text', 'label'=>'Name', 'hint' => 'Bitte geben Sie Ihren Familiennamen ein', ], 'vorname'=>[ 'type'=>'text', 'label'=>'Vorname', ], 'geburtsname'=>[ 'type'=>'text', 'label'=>'Geburtsname', ], 'strasse'=>[ 'type'=>'text', 'label'=>'Strasse', ], 'email'=>[ 'type'=>'text', 'label'=>'E-Mail', ], 'verheiratet' => [ 'type'=>'checkbox', 'label' => 'Verheiratet', ], 'mypassword'=>[ 'type'=>'password', 'label'=>'Password', ], 'sex'=>[ 'type'=>'radioList', 'label'=>'Geschlecht', 'options'=>['m'=>'männlich', 'f'=>'weiblich'], 'inline'=>true, ], 'testDropdown' => [ 'type'=>'dropdownList', // 'label'=>'Geschlecht', 'options'=>[1=>'eins', 2=>'zwei'], ], ]; // }}} $fieldRules = [ // {{{ field rules [['name', 'vorname', 'strasse', 'email'], 'required'], [['name', 'email'], 'string', 'max'=>128], ['email', 'email'], [['verheiratet'], 'boolean'], [['Geburtsname', 'sex'], 'safe'], ['testDropdown', 'number', 'integerOnly'=>true], ]; // }}} } The ''$fields'' array is an array of field attributes, indexed by the field names. As ''type'', we have: * text * textarea * checkbox * password * dropdownList * radioList The ''fieldRules'' array is defined as described in the Guide: [[https://www.yiiframework.com/doc/guide/2.0/en/input-validation#declaring-rules|Getting Data from Users/Validating Input/Declaring Rules]]. We the are going to initialize the model, the checkboxes and the labels: $model = new MyDynamicModel(array_keys($fields)); // Init checkbox attributes $checkboxes = array(); // {{{ Init labels foreach($fields as $field=>$settings) { if(!empty($settings['label'])) $model->setAttributeLabel($field, $settings['label']); else $model->setAttributeLabel($field, \yii\helpers\Inflector::camel2words($field, true)); if($settings['type']=='checkbox') $checkboxes[] = $field; } // }}} We also add the rules we defined earlier, and we initialize some default values for the model attributes: // {{{ Add rules to DynamicModel foreach($fieldRules as $settings) { $attributes = array_shift($settings); $validator = array_shift($settings); $model->addRule($attributes, $validator, $settings); } // }}} // Init default values $model->attributes = array( // {{{ 'name' => 'Werner', 'vorname' => 'Joachim', 'strasse' => 'Am Wingert 10', 'verheiratet' => true, 'sex' => 'm', ); // }}} Finally, we render the form: return $this->render('form', [ 'model' => $model, 'fields' => $fields, ]); ===== The Form View ===== Create the form view file in ''views/site/form.php'':

title) ?>

'my-form', 'layout' => 'horizontal', // 'options' => ['class' => 'form-horizontal'], ]); ?> errorSummary($model) ?> 'Ja', 0=>'Nein']; foreach($model->attributes() as $field) { $input = null; switch($fields[$field]['type']) { case 'text': $input = $form->field($model, $field)->textInput(); break; case 'textarea': $textareaOptions = isset($fields[$field]['options']) ? $fields[$field]['options'] : array(); // $yesNoOptions; $input = $form->field($model, $field)->textarea($textareaOptions); break; case 'checkbox': $input = $form->field($model, $field)->checkbox(); break; case 'password': $input = $form->field($model, $field)->passwordInput(); break; case 'dropdownList': $dropdownOptions = isset($fields[$field]['options']) ? $fields[$field]['options'] : array(); // $yesNoOptions; $input = $form->field($model, $field)->dropdownList($dropdownOptions); break; case 'radioList': $dropdownOptions = isset($fields[$field]['options']) ? $fields[$field]['options'] : $yesNoOptions; $input = $form->field($model, $field); if(!empty($fields[$field]['inline']) and $fields[$field]['inline']==true) $input->inline(true); $input->radioList($dropdownOptions); break; default: $input = $form->field($model, $field)->textInput(); break; } if(!empty($fields[$field]['hint'])) $input->hint($fields[$field]['hint']); echo $input; } ?>
'btn btn-primary']) ?>
This view creates the ''ActiveForm''. In a big ''switch case'' block, the various form input controls are created. ===== Validate the User Input ===== In the controller file, add this code before the ''render'' call: // {{{ Evaluate posted data if ($model->load(Yii::$app->request->post()) && $model->validate()) { Yii::$app->session->setFlash('success', 'The form has been submitted.'); }