Inside a Model how to set required a field based on another field selection and works properly?


#1

Inside a Model how to set required a field based on another field selection?

I mean I have a dropdown field that the selection of this field must validate the required status of others fields…

For instance of selection is 1 where 1 = hotel, then hotels fields are required
For instance of selection is 2 where 2 = flight, then flight fields are required

and so on,

I tried to validate this in the Model like this, the problem if the type_id selected is 1 and I click save there validation says I need flight_title and this is correct but then if I change the type_id selected to 2 and click save again then the flight_title and hotel_title shows as required both of them and not hotel_title only…

I think that after click save the required fields validated are cached …

is there a way to fix this behaviour ? thanks


    public function validate($intent = null)
        {
            $errors = parent::validate($intent);

            if ($this['type_id'] == 1) {

        
                if (strlen($this['flight_title']) < 1) {
                    $errors['flight_title'] = 'A Sample Flight title is required.';
                }


            }


            if ($this['type_id'] == 2) {

        
                if (strlen($this['hotel_title']) < 1) {
                    $errors['hotel_title'] = 'A Sample Hotel title is required.';
                }

         
            }

         

            return $errors;
    }


#2

We actually have implemented it using custom controller and conditional rules.

  1. Add more properties to the field
  2. Have external object read those properties when called by hooks (e.g. validate)

This way you can make it easy to define. Here is what we have:

        $this->addField('switch_style', [
            'caption'   => 'Switch: Style',
            'default'    => 'default',
            'enum'      => ['default', 'slider', 'toggle'],
            'validate_if'=>['type' => 'switch'],
            'validate'  => ['required'],
        ]);

validate_if defines a pre-condition. If it’s matching then validator is used. This can probably be combined with some display rules too. I haven’t thought yet about introducing it globally into ATK, but probably we need a ticket for that.


#3

Yup, I like this and it seems useful.