Bruce Gust
asked on
How can I preserve my form data if it fails to validate?
I've got a form that was built by another developer and they did a bang up job!
To facilitate form validation, they've got this in place...
Controller:
The "Util::valid" method looks like this:
So, it looks like you're ferrying the fields to a method that's looping through them to ensure that there's a value attached to each field.
What's great about this is that in the aftermath of a failed validation, you have something that looks like this:
Notice how the fields that have to be populated are in red and the values that were correctly inputted are still in tact.
Now, here comes Bruce...
I added some additional fields at the bottom of the form. They're hidden until the user clicks on a button indicating their desire to input some additional information. It looks like this:
That looks like this:
Notice how in the "ending value" field I've got a string?
So, now when this form hits the Controller, that field is going to be evaluated and it will be found to be wanting. Here's the validation code I just referenced with the additional code that I added which is checking for the validity of the values coming from the fields I just added. I've got that in bold:
// validate fields
foreach(['campName', 'campPointConv', 'campHierarchy', 'campParticUnits', 'campStartDate', 'campEndDate'] as $requiredField){
if(!Util::valid($requiredF ield, $data)){
$this->addNotice('You are missing required fields', 'error');
return $this->redirectToRoute('ad min_gamifi cation_cha llenges_ed it', ['id'=>$id]);
}
}
if(!empty($data['campAutoS ync'])){
foreach(['campAutoSyncHrId ', 'campAutoSyncPoints', 'campAutoSyncUnits'] as $requiredField){
if(!Util::valid($requiredF ield, $data)){
$this->addNotice('You are missing required auto sync fields', 'error');
return $this->redirectToRoute('ad min_gamifi cation_cha llenges_ed it', ['id'=>$id]);
}
}
if(!is_numeric($data['camp AutoSyncPo ints']) || !is_numeric($data['campAut oSyncUnits '])){
$this->addNotice('Auto sync points and units must be numbers', 'error');
return $this->redirectToRoute('ad min_gamifi cation_cha llenges_ed it', ['id'=>$id]);
}
}
/*
here you're looking to make sure that if the "BETWEEN" clause was used for any of the rules, that the values inputted are, in fact, integers
*/
if(isset($_POST['criteria' ])) {
foreach ($_POST['criteria'] as $key=>$value )
{
if($key=='operator' && $value='between') {
foreach($_POST['criteria'] ['between_ value_star t'] as $thing) {
if(!is_numeric($thing)) {
$this->addNotice('Be sure that your "between" values are integers.', 'error');
return $this->redirectToRoute('ad min_gamifi cation_cha llenges_ed it', ['id'=>$id]);
}
}
foreach($_POST['criteria'] ['between_ value_end' ] as $boom) {
if(!is_numeric($boom)) {
$this->addNotice('Be sure that your "between" values are integers.', 'error');
return $this->redirectToRoute('ad min_gamifi cation_cha llenges_ed it', ['id'=>$id]);
}
}
}
}
}
I included the initial "validation" code because when my user submits this form having filled in all of the fields, yet made the mistake of inserting some text into the "ending value" field, they get this:
The original validation piece works great in the way it redirects the user back to the form and allows to pick up where they left off.
My addition routes the user back to the form, but all the data that was originally inputted is gone.
What am I missing? How do I preserve the user's correctly inputted information so, should they miss the piece pertaining to the "starting value" and "ending value" fields, they're not having to start all over again?
To facilitate form validation, they've got this in place...
Controller:
// validate fields
foreach(['campName', 'campPointConv', 'campHierarchy', 'campParticUnits', 'campStartDate', 'campEndDate'] as $requiredField){
if(!Util::valid($requiredField, $data)){
$this->addNotice('You are missing required fields', 'error');
return $this->redirectToRoute('admin_gamification_challenges_edit', ['id'=>$id]);
}
}
if(!empty($data['campAutoSync'])){
foreach(['campAutoSyncHrId', 'campAutoSyncPoints', 'campAutoSyncUnits'] as $requiredField){
if(!Util::valid($requiredField, $data)){
$this->addNotice('You are missing required auto sync fields', 'error');
return $this->redirectToRoute('admin_gamification_challenges_edit', ['id'=>$id]);
}
}
if(!is_numeric($data['campAutoSyncPoints']) || !is_numeric($data['campAutoSyncUnits'])){
$this->addNotice('Auto sync points and units must be numbers', 'error');
return $this->redirectToRoute('admin_gamification_challenges_edit', ['id'=>$id]);
}
}
The "Util::valid" method looks like this:
public static function valid($key, $vars=[]) {
// check the variable set
if (!is_array($vars) || empty($vars) || empty($key)) {
return false;
}
// standardize the key into an array of keys
if (is_string($key)) {
$key = [$key];
}
// check each key
foreach ($key as $k) {
// fail if the key is an object or array
if (is_array($k) || is_object($k)) {
return false;
}
// check if the key exists
if (!isset($vars[$k])) {
return false;
}
// we can't use empty here because '0' will give a false positive
if (is_string($vars[$k]) && strlen($vars[$k]) == 0) {
return false;
}
}
// if we made it this far, we're good to go
return true;
}
So, it looks like you're ferrying the fields to a method that's looping through them to ensure that there's a value attached to each field.
What's great about this is that in the aftermath of a failed validation, you have something that looks like this:
Notice how the fields that have to be populated are in red and the values that were correctly inputted are still in tact.
Now, here comes Bruce...
I added some additional fields at the bottom of the form. They're hidden until the user clicks on a button indicating their desire to input some additional information. It looks like this:
That looks like this:
Notice how in the "ending value" field I've got a string?
So, now when this form hits the Controller, that field is going to be evaluated and it will be found to be wanting. Here's the validation code I just referenced with the additional code that I added which is checking for the validity of the values coming from the fields I just added. I've got that in bold:
// validate fields
foreach(['campName', 'campPointConv', 'campHierarchy', 'campParticUnits', 'campStartDate', 'campEndDate'] as $requiredField){
if(!Util::valid($requiredF
$this->addNotice('You are missing required fields', 'error');
return $this->redirectToRoute('ad
}
}
if(!empty($data['campAutoS
foreach(['campAutoSyncHrId
if(!Util::valid($requiredF
$this->addNotice('You are missing required auto sync fields', 'error');
return $this->redirectToRoute('ad
}
}
if(!is_numeric($data['camp
$this->addNotice('Auto sync points and units must be numbers', 'error');
return $this->redirectToRoute('ad
}
}
/*
here you're looking to make sure that if the "BETWEEN" clause was used for any of the rules, that the values inputted are, in fact, integers
*/
if(isset($_POST['criteria'
foreach ($_POST['criteria'] as $key=>$value )
{
if($key=='operator' && $value='between') {
foreach($_POST['criteria']
if(!is_numeric($thing)) {
$this->addNotice('Be sure that your "between" values are integers.', 'error');
return $this->redirectToRoute('ad
}
}
foreach($_POST['criteria']
if(!is_numeric($boom)) {
$this->addNotice('Be sure that your "between" values are integers.', 'error');
return $this->redirectToRoute('ad
}
}
}
}
}
I included the initial "validation" code because when my user submits this form having filled in all of the fields, yet made the mistake of inserting some text into the "ending value" field, they get this:
The original validation piece works great in the way it redirects the user back to the form and allows to pick up where they left off.
My addition routes the user back to the form, but all the data that was originally inputted is gone.
What am I missing? How do I preserve the user's correctly inputted information so, should they miss the piece pertaining to the "starting value" and "ending value" fields, they're not having to start all over again?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.