Validate dynamic form

Hi,

I’m currently using code that lets users create new form fields, then set them as either as required or not required. The problem I’m having is that as this is a component, and not in the model, I can’t add it to the rules if validation is equal to 1 in the db.

How do I go about dynamically adding values to the rules? or at least adding errors to these fields. Ie. Adding a validator to all attr with the value of required field 1

This dynamic form data doesgo into the user type variable model as the name, but that model seems to be purely working for the form to input the data rather than handling the dynamic data. This data also needs passed through with the user model when the user form is created


class DynamicForm extends CWidget {




    public $attributes = array();

    public $id = null;

    public $enctype = null;

    public $target = null;

    public $action = null;

    public $model_name = '';

    public $method = 'post';


    public function init() {

        parent::init();

    }


 public function run() {

 foreach ($this->attributes as $attr) {

  $attr['formname'] = $this->model_name . '_' . $attr['name'];

            $attr['htmlOptions'] = array('class' => 'span5', 'placeholder' => $attr['name']);

            $attr['htmlOptions']['class'] .= ' form-control';


            if ($attr['required'] === 1){

                $attr['requiredfields'] = array('required' => true);

            }else{

                $attr['requiredfields'] = '';

            }

  if ($attr['type'] == 'text') {

                echo '<div class="form-group">';

                echo CHtml::label($attr['name'], $attr['formname'],$attr['requiredfields']);

                echo CHtml::textField($attr['formname'], $attr['value'], $attr['htmlOptions']);

                echo '</div>';

            } 

            elseif ($attr['type'] == 'radio') {

                echo '<div class="form-group">';

                echo CHtml::label($attr['name'], $attr['formname'],$attr['requiredfields']);

                echo CHtml::radioButton($attr['formname'],$attr['requiredfields']);

                echo '</div>';

            } 

            elseif ($attr['type'] == 'textarea') {

                echo '<div class="form-group">';

                echo CHtml::label($attr['name'], $attr['formname'],$attr['requiredfields']);

                echo CHtml::textArea($attr['formname'], $attr['value'], $attr['htmlOptions']);

                echo '</div>';

            } 

            elseif ($attr['type'] == 'select') {

                $items = explode(',', $attr['options']);

 echo CHtml::label($attr['name'], $attr['formname'],$attr['requiredfields']);

                //echo CHtml::dropDownList($attr['formname'], $attr['value'], array($items));

                echo CHtml::dropDownList($attr['formname'], $attr['value'], $items, array('class'=>'form-control','prompt'=>'Please Choose'));

                echo '</div>';

 } 

            elseif ($attr['type'] == 'boolean') {

                echo '<div class="form-group">';

                echo CHtml::label($attr['name'], $attr['formname'],$attr['requiredfields']);

                echo CHtml::radioButtonList($attr['formname'], $attr['value'], array('No' => 0, 'Yes' => 1));

                echo '</div>';

            }

        }

 }


}



The user form


<div class="clearfix"></div>

<?php

$varform = new DynamicForm();

$varform->attributes = $user->getDynamicFormConfig();

$varform->model_name = 'user';

echo $varform->run();

?>

CActiveForm widget is made considering the basic requirements. You may check this file to find out how it is coded so that you may get the idea for your widget class.

\framework\web\widgets\CActiveForm.php

Hi,

A couple of things look right from this, I guess I’m just not sure how to (or where) to detail that when the required field in db is 1, to add it to the list of cvalidators that run when the user form is submitted.

Where do I declare the required attribute, and add it to the list of cvalidators when the user form is submitted? (which is passed through the user model)

You can create a form using CActiveForm and check how the javascript code generated to populate errors.

Also, you can check Yii2 ActiveForm. There it is made much more simpler than CActiveForm. Check how these codes work and you will find out a solution.

Unfortunatly this is a large project built by another developer that was meant to be entirely dynamic for users to create their own forms, so moving to Yii2 is not viable. Also, nothing is actually dynamic at the minute

I can suggest you one logic, but you have to figure out if it works. It is wild thinking assuming by what you mentioned above.

  1. You create a class Dynaform extending CFormModel.

  2. If you know the limits at which your users can add fields to their form, create the maximum variables.

  3. Create a logic by which based on the number and type of the fields selected by the user, array returned by rules() will change.

  4. Create a logic by which based on the label which users want for their fields, the array returned by attributeLabels() change.

  5. Use CActiveForm widget to create the form with the same logic.

Literally all of this works already. It’s simply the validation rules that I’m setting that aren’t being taken, as the user gets an option to set the required to yes or no (1 or 0) but the rules aren’t being taken into consideration in the user model (as this dynamic form is being used in the user-form, which links with the model)

if that is the case then it will be some small error,

may be if ($attr[‘required’] == 1) may do the work if you save 1 as a string.

I forgot t omention that it does in fact add the class required to the fields but it does not run the javascript validation form.

I changed how the config works, but it’s still not passing through to the user model validation.

this config is being declared in the user model.


    public function getDynamicFormConfig() {

        // For each attribute in

        $varibles = array();


        //echo sizeof($this->type->userTypeVariables);


        if (sizeof($this->type->userTypeVariables) > 0) {


            foreach ($this->type->userTypeVariables as $var) {


                //$varibles[] = $var;

                $varibles[] = array(

                    'id' => $var->id,

                    'name' => $var->name,

                    'type' => $var->type,

                    'value' => $this->getDynamicVaribleValue($var->name),

                    'required' => $var->required,

                    'options' => $var->htmlOptions,

                );

               if ($var->required) {

                   $var->validatorList->add(

                           CValidator::createValidator('required',$this->getDynamicVaribleValue($var->name),'')

                   );

               }

            }

        }

        return $varibles;

    }

The line that isn’tw orking is




if ($var->required) {

                   $var->validatorList->add(

                           CValidator::createValidator('required',$this->getDynamicVaribleValue($var->name),'')

                   );

               }