Welcome Guest, Not a member yet? Register   Sign In
form_validation with multidimensional arrays incl. check for value pairs in a set of field pairs
#1

[eluser]Unknown[/eluser]
Good evening from Bavaria,

I'm trying to validate a form with field names based on multidimensional arrays. The validation is based on the following rules:

Rule 1

Opening hours can only be submitted as value pairs. Example: Submitting a value for hours[monday][from] requires the submission of a value for hours[monday][to] et vice versa.

This works fine. The validation routine triggers an error with the corresponding field name when only one value is submitted instead of a pair.

Rule 2

It is required to submit at least one value pair. Submitting no value pair at all is not valid.

Is there an elegant way to accomplish the check incl. triggering a generic error message if no value pair is submitted? A validation rule like $this->form_validation->set_rules('hours', 'Opening hours', 'required'); does not work.

HTML markup

Code:
<fieldset>
  <legend>Opening hours</legend>
  <p>For closed days just leave the corresponding opening hour fields blank.</p>
  <p><label for="monday">Monday</label>&lt;input type="time" name="hours[monday][from]" id="monday" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['monday']['from']) { echo $this-&gt;input-&gt;post('hours', TRUE)['monday']['from']; } ?&gt;" placeholder="9:00"&gt; to &lt;input type="time" name="hours[monday][to]" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['monday']['to']) { echo $this-&gt;input-&gt;post('hours', TRUE)['monday']['to']; } ?&gt;" placeholder="19:00"&gt;&lt;/p>
  <p><label for="tuesday">Tuesday</label>&lt;input type="time" name="hours[tuesday][from]" id="tuesday" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['tuesday']['from']) { echo $this-&gt;input-&gt;post('hours', TRUE)['tuesday']['from']; } ?&gt;" placeholder="9:00"&gt; to &lt;input type="time" name="hours[tuesday][to]" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['tuesday']['to']) { echo $this-&gt;input-&gt;post('hours', TRUE)['tuesday']['to']; } ?&gt;" placeholder="19:00"&gt;&lt;/p>
  <p><label for="wednesday">Wednesday</label>&lt;input type="time" name="hours[wednesday][from]" id="wednesday" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['wednesday']['from']) { echo $this-&gt;input-&gt;post('hours', TRUE)['wednesday']['from']; } ?&gt;" placeholder="9:00"&gt; to &lt;input type="time" name="hours[wednesday][to]" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['wednesday']['to']) { echo $this-&gt;input-&gt;post('hours', TRUE)['wednesday']['to']; } ?&gt;" placeholder="19:00"&gt;&lt;/p>
  <p><label for="thursday">Thursday</label>&lt;input type="time" name="hours[thursday][from]" id="thursday" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['thursday']['from']) { echo $this-&gt;input-&gt;post('hours', TRUE)['thursday']['from']; } ?&gt;" placeholder="9:00"&gt; to &lt;input type="time" name="hours[thursday][to]" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['thursday']['to']) { echo $this-&gt;input-&gt;post('hours', TRUE)['thursday']['to']; } ?&gt;" placeholder="19:00"&gt;&lt;/p>
  <p><label for="friday">Friday</label>&lt;input type="time" name="hours[friday][from]" id="friday" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['friday']['from']) { echo $this-&gt;input-&gt;post('hours', TRUE)['friday']['from']; } ?&gt;" placeholder="9:00"&gt; to &lt;input type="time" name="hours[friday][to]" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['friday']['to']) { echo $this-&gt;input-&gt;post('hours', TRUE)['friday']['to']; } ?&gt;" placeholder="19:00"&gt;&lt;/p>
  <p><label for="saturday">Saturday</label>&lt;input type="time" name="hours[saturday][from]" id="saturday" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['saturday']['from']) { echo $this-&gt;input-&gt;post('hours', TRUE)['saturday']['from']; } ?&gt;" placeholder="9:00"&gt; to &lt;input type="time" name="hours[saturday][to]" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['saturday']['to']) { echo $this-&gt;input-&gt;post('hours', TRUE)['saturday']['to']; } ?&gt;" placeholder="19:00"&gt;&lt;/p>
  <p><label for="sunday">Sunday</label>&lt;input type="time" name="hours[sunday][from]" id="sunday" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['sunday']['from']) { echo $this-&gt;input-&gt;post('hours', TRUE)['sunday']['from']; } ?&gt;" placeholder="9:00"&gt; to &lt;input type="time" name="hours[sunday][to]" value="&lt;?php if ($this-&gt;input-&gt;post('hours')['sunday']['to']) { echo $this-&gt;input-&gt;post('hours', TRUE)['sunday']['to']; } ?&gt;" placeholder="19:00"&gt;&lt;/p>
</fieldset>

Validation

Code:
if ($this->input->post('hours')) {
   $i = 0;
   // set search & replace arrays for conversion from weekdays to numbers (sunday = 1, monday = 2, etc.)
   $search  = array('sunday', 'monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday');
   $replace = array('1', '2', '3', '4', '5', '6', '7');
  
   // process input from 'opening hours' fields
   foreach($this->input->post('hours') as $key => $value) {
    // check for 'opening hours' field pairs where only one value is submitted
    if ($this->input->post('hours')[$key]['from'] OR $this->input->post('hours')[$key]['to']) {
     array_push($config,
      array(
       'field'   => 'hours['.$key.'][from]',
       'label'   => 'Opening hours for '.ucfirst($key).' (From)',
       'rules'   => 'required'
      ),
      array(
       'field'   => 'hours['.$key.'][to]',
       'label'   => 'Opening hours for '.ucfirst($key).' (To)',
       'rules'   => 'required'
      )
     );
    
     // check for 'opening hours' field pairs where two values are submitted
     if ($this->input->post('hours')[$key]['from'] AND $this->input->post('hours')[$key]['to']) {
      if (!isset($data['hours'])) { $data['hours'] = ''; }
      $data['hours'] .= str_replace($search, $replace, $key.':'.$value['from'].':'.$value['to'].',');
      $i++;
     }
    }
   }
   // check if at least one 'opening hours' value pair is submitted
   if ($i != 0) {
    // remove trailing colon from 'opening hours' string
    $data['hours'] = str_replace($search, $replace, rtrim($data['hours'], ','));
   } else {
    // no idea how to trigger a validation error for the case when no 'opening hours' pair has been submitted at all
   }
  }

Thanks,
Oliver




Theme © iAndrew 2016 - Forum software by © MyBB