Welcome Guest, Not a member yet? Register   Sign In
Form Validation "dot array"
#1

Greetings.
Maybe or maybe not, this thread has been submitted. I have done a research and unfortunately I have not found any answer about it.
I'm developing my fist CI-4 project. I use CI since 1.5 version and never regretted. Until very recently I was resisting to let CI-3 go, because I was quite comfortable with this version, but that would be counter productive. Things always move forward. It has not being easy, especially because I have found CI-4 documentation not quite simple and straight forward as it used to be, as also not quite thorough.
Anyways, I'm having some throuble with form validation. I have this html form which has dynamic inputs that are array named, like 'addresses[X][country] ' where 'X' is the index.
I have created the rules for this 'country' input and it is validating just fine. The problem is that I show individual error messages for each input and the message is being shown in those inputs that are filled with data.
To make it clear, I'll post some sample code below:
Code:
    public $customers = [
        'name' => [
            'rules' => 'required',
            'label' => 'Full Name',
            'errors' => [
                'required' => '{field} is required.'
            ]
        ],
        'addresses.country' => [
                'rules' => 'required',
                'label' => 'Country',
                'errors' => [
                    'required' => '{field} is required.'
                ]
        ]
These are the validation rules.

Code:
        $this->form_validation->reset();
        $this->form_validation->setRuleGroup('customers');
        $this->form_validation->run($_POST);


        $data['validation'] = $this->form_validation->getErrors();

Here the rules are applied.
Code:
Array
(
    [name] => Full Name is required.
  [addresses.country] => Country is required.
)

This is what getErrors() returns, which are the messages for the inputs. So far so good. Now it comes the throuble.
Code:
      <div class="col-md-4">
        <div class="d-flex flex-nowrap">
          <label for="name" class="form-label badge bg-light">Full Name</label> <?= (isset($validation['name']) ? display_error($validation['name']) : ''); ?>
        </div> 
        <input type="text" class="form-control" id="name" name="name" placeholder="" value="<?= try_data($_POST, 'name'); ?>" <?= (isset($readonly) ? ' readonly' : ''); ?> />
      </div>

              <div class="col-md-3">
                <label for="country" class="form-label badge bg-light">Country</label> <?= (isset($validation['addresses.country']) ? display_error($validation['addresses.country']) : ''); ?>
                <select name="addresses[<?= $key;?>][country]" class="form-select" data-live-search="true" title="Choose the country" data-node-id="<?= $key;?>" <?= (isset($readonly) ? ' disabled' : ''); ?> onchange="load_states(this);">
                  <option value="" <?= ($address['country'] == '' ? ' selected' : ''); ?>></option>
                  <?php foreach($countries->getResult() as $country): ?>
                    <option value="<?= $country->name; ?>" <?= ($address['country'] == $country->name ? ' selected' : ''); ?>><?= emoji($country->iso2) . ' ' . $country->name; ?></option>
                  <?php endforeach; ?> 
                </select>
              </div>

Country is cloned and inserted in the form dynamically. So, I can have many country inputs and not all will be filled. Those who are not filled, should exhibit the error message, but only the empty ones. The problem is that those that are filled, are also showing the error message.
I hope it is clear enough. If not, just ask me.
So... Any thoughts?
Thanks for listening.
Reply
#2

If you have 'addresses[X][country] ' where 'X' is the index,
it seems the validation rule 'addresses.country' should be 'addresses.*.country'.

https://codeigniter.com/user_guide/libra...are-arrays
Reply
#3

(01-02-2022, 01:48 AM)kenjis Wrote: If you have 'addresses[X][country] ' where 'X' is the index,
it seems the validation rule 'addresses.country' should be 'addresses.*.country'.

https://codeigniter.com/user_guide/libra...are-arrays

I understand what this is about.
PHP Code:
$data = [
    'addresses' => [
        ['country' => ''],
        ['country' => 'USA'],
        ['country' => ''],
    ]
];

$v Services::validation();

$v->setRule('addresses.*.country''Address''required')->run($data);

// error 
// ['addresses.*.country' => "The Address field is required."] 

1. In fact, there are two errors, but one (the last) is displayed. Because the $field parameter is used for the error key.
2. It is impossible to determine which specific field the error applies to.

The error format should be like this
PHP Code:
$erros = [
    'addresses.0.country' => "The Address field is required.",
    'addresses.2.country' => "The Address field is required."
];
//or 
$erros = [
    'addresses' => [
            0 => ['country' => "The Address field is required."],
            2 => ['country' => "The Address field is required."],
    ]
]; 
I wanted to do a PR, but I think it will be tagged as BC.
Reply
#4

> Because the $field parameter is used for the error key.

Do you mean overwriting the error message by the latter error?

Anyway, it seems there is no way to get more than one error messages.
We have to say it is a bug.
Reply
#5

(This post was last modified: 01-02-2022, 11:42 PM by iRedds.)

Yes, the error message is being overwritten because of the same key.
Reply




Theme © iAndrew 2016 - Forum software by © MyBB