[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><input type="time" name="hours[monday][from]" id="monday" value="<?php if ($this->input->post('hours')['monday']['from']) { echo $this->input->post('hours', TRUE)['monday']['from']; } ?>" placeholder="9:00"> to <input type="time" name="hours[monday][to]" value="<?php if ($this->input->post('hours')['monday']['to']) { echo $this->input->post('hours', TRUE)['monday']['to']; } ?>" placeholder="19:00"></p>
<p><label for="tuesday">Tuesday</label><input type="time" name="hours[tuesday][from]" id="tuesday" value="<?php if ($this->input->post('hours')['tuesday']['from']) { echo $this->input->post('hours', TRUE)['tuesday']['from']; } ?>" placeholder="9:00"> to <input type="time" name="hours[tuesday][to]" value="<?php if ($this->input->post('hours')['tuesday']['to']) { echo $this->input->post('hours', TRUE)['tuesday']['to']; } ?>" placeholder="19:00"></p>
<p><label for="wednesday">Wednesday</label><input type="time" name="hours[wednesday][from]" id="wednesday" value="<?php if ($this->input->post('hours')['wednesday']['from']) { echo $this->input->post('hours', TRUE)['wednesday']['from']; } ?>" placeholder="9:00"> to <input type="time" name="hours[wednesday][to]" value="<?php if ($this->input->post('hours')['wednesday']['to']) { echo $this->input->post('hours', TRUE)['wednesday']['to']; } ?>" placeholder="19:00"></p>
<p><label for="thursday">Thursday</label><input type="time" name="hours[thursday][from]" id="thursday" value="<?php if ($this->input->post('hours')['thursday']['from']) { echo $this->input->post('hours', TRUE)['thursday']['from']; } ?>" placeholder="9:00"> to <input type="time" name="hours[thursday][to]" value="<?php if ($this->input->post('hours')['thursday']['to']) { echo $this->input->post('hours', TRUE)['thursday']['to']; } ?>" placeholder="19:00"></p>
<p><label for="friday">Friday</label><input type="time" name="hours[friday][from]" id="friday" value="<?php if ($this->input->post('hours')['friday']['from']) { echo $this->input->post('hours', TRUE)['friday']['from']; } ?>" placeholder="9:00"> to <input type="time" name="hours[friday][to]" value="<?php if ($this->input->post('hours')['friday']['to']) { echo $this->input->post('hours', TRUE)['friday']['to']; } ?>" placeholder="19:00"></p>
<p><label for="saturday">Saturday</label><input type="time" name="hours[saturday][from]" id="saturday" value="<?php if ($this->input->post('hours')['saturday']['from']) { echo $this->input->post('hours', TRUE)['saturday']['from']; } ?>" placeholder="9:00"> to <input type="time" name="hours[saturday][to]" value="<?php if ($this->input->post('hours')['saturday']['to']) { echo $this->input->post('hours', TRUE)['saturday']['to']; } ?>" placeholder="19:00"></p>
<p><label for="sunday">Sunday</label><input type="time" name="hours[sunday][from]" id="sunday" value="<?php if ($this->input->post('hours')['sunday']['from']) { echo $this->input->post('hours', TRUE)['sunday']['from']; } ?>" placeholder="9:00"> to <input type="time" name="hours[sunday][to]" value="<?php if ($this->input->post('hours')['sunday']['to']) { echo $this->input->post('hours', TRUE)['sunday']['to']; } ?>" placeholder="19:00"></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