I'm trying to integrate AJAX into my form submissions. I have a pretty well established method for submitting the forms currently but would like to move away from the whole submit, reload page thing.
I'm completely new to AJAX and JQUERY so am on a steep learning curve. I'm trying to get to a point where my existing PHP can be integrated into the AJAX form submit. What I'm stuck on is the ability to send the validation result to the script.
I currently have this on my form processing php
UPDATED WITH NEW CODE FROM FEEDBACK RECEIVED
$return = array();
if($validation->passed()) {
try {
$getPassageId = Input::get('passageId'); //Get the passage plan id passed via the form
$latitude = convertDMSToDecimal(Input::get('lat'));
$longitude = convertDMSToDecimal(Input::get('long'));
$insertIntoWaypoints = DB::getInstance()->insert('ym_waypoints', array(
'vessel_id' => $vid,
'user_id' => $uid,
'waypoint_num' => Input::get('waypoint'),
'waypoint_name' => Input::get('waypointName'),
'latitude' => $latitude,
'longitude' => $longitude,
'cts' => Input::get('courseToSteer'),
'dtw' => Input::get('DistanceToWaypoint'),
'hw_time' => Input::get('HWTime'),
'hw_height' => Input::get('HWHeight'),
'lw_time' => Input::get('LWTime'),
'lw_height' => Input::get('LWHeight'),
'chart_num' => Input::get('chartNumbers'),
'almanac' => Input::get('almanacPages'),
'radio_signals' => Input::get('radioPages'),
'por' => Input::get('por'),
'por_almanac' => Input::get('porAlmanac'),
'por_vhf' => Input::get('porVHF'),
'vhf' => Input::get('vhf'),
'passage_note' => Input::get('notes')
));
$recordID = $insertIntoWaypoints;
$insertInto = DB::getInstance()->insert('ym_passageplan_route', array(
'passageplan_id' => $getPassageId,
'waypoint_id' => $recordID
));
$return['success'] = True;
$return['message'] = 'successful!';
print json_encode($return);
} catch (Exception $e) {
$return['success'] = False;
$return['message'] = 'fail';
print json_encode($return);
}
} else {
foreach (array_combine($validation->errors(), $validation->fields()) as $error => $field) {
// Append an array of the error data to $return.
$return['success'] = False;
$return['message'] .= $error;
}
print json_encode($return);
}
And this is the script I'm using to send the data
$(routePlan_form).submit(function(e){
e.preventDefault();
$.ajax({
type: "POST",
url: "/pages/voyages/passageplans/createroute.php",
dataType: 'json',
data: $("#routePlan_form").serialize(),
'success': function(data) {
if(data['success']) {
//refresh the table
$("#table").load(location.href + " #table");
//reset the form
$('#routePlan_form').trigger("reset");
//scroll to the top
window.scrollTo({ top: 0, behavior: 'smooth' });
//send the user a success message
resetToastPosition();
$.toast({
heading: 'Success',
text: 'Waypoint added successfully',
textColor: 'white',
showHideTransition: 'slide',
hideAfter : 7000,
icon: 'success',
loaderBg: '#f96868',
position: 'top-center'
})
} else {
// var i;
// for (i = 0; i < data['message'].length; i++) {
// this.error(this.xhr, data['message']);
// }
this.error(this.xhr, data['message']);
}
},
'error': function(jqXHR, textStatus, errorThrown) {
console.log(textStatus);
}
})
})
});
When intentionally submitting the form I am leaving out the required fields which should send the validation errors back. After the fantastic help below i'm now getting the expected errors in the console. However they are listed as "Waypoint number is required.Waypoint name is required.Latitude is required.Longitude is required."
What I need to be able to do is split this list into individual messages....
I'm assuming I need some sort of foreach or $.each statement but new to JQuery that I'm unsure how to progress...
As a stretch goal I'd also like a way of adding the following into the whole thing so I can alert the user to the incorrect fields
$("#<?php echo $field ?>").addClass("form-control-danger");
$('<label id="<?php echo $field ?>-error" class="badge badge-danger" for="<?php echo $field ?>"><?php echo $error ?></label>').insertAfter("#<?php echo $field ?>");
Any pointers would be fantastic!
Regards
Matt
A quick update---
I'm getting closer! I now have the following code in the processing php file
foreach (array_combine($validation->errors(), $validation->fields()) as $error => $field) {
// Append an array of the error data to $return.
$return['success'] = False;
$return['message'] .= [$error];
}
print json_encode($return);
And the following to loop through the messages
else {
var i;
for (i = 0; i < data['message'].length; i++) {
this.error(this.xhr, data['message']);
}
//this.error(this.xhr, data['message']);
}
},
'error': function(jqXHR, textStatus, errorThrown) {
//send the user a success message
resetToastPosition();
$.toast({
heading: 'Error',
text: '' + textStatus,
textColor: 'white',
showHideTransition: 'slide',
hideAfter : 10000,
icon: 'error',
bgColor: '#f96868',
position: 'top-center',
loaderBg: '#405189'
})
}
This gives me 5 pop-up error messages, however the text states ArrayArrayArrayArray so I know it's getting the 4 errors as I expected. I think what is happening is that I am adding the error into the $return['message'] array so we are being output a, b, c, d etc. I think I need to add an array into the 'message' array?? Any pointers where to / how to get the error message or where I'm going wrong?
Getting closer!!!
Thinking about the logic behind what is going on I'm now closer again I think. I now get just four messages (as I'd expect with this form) but all the messages are grouped together in each message box, so I added the variable 'i' as a reference to the 'messages' part in it now displays the messages as I'd expect!! Woop woop!
Just need to work out how to add some classes to the fields and we are all good!
parts I'm editing in the Processing page
$return = array();
$messages = array();
$return['success'] = False;
foreach (array_combine($validation->errors(), $validation->fields()) as $error => $field) {
// Append an array of the error data to $return.
array_push($messages, $error);
//$return['message'] = array($error);
}
$return['message'] = $messages;
echo json_encode($return);
and the ajax call on the form page
$(document).ready(function() {
$(routePlan_form).submit(function(e){
e.preventDefault();
$.ajax({
type: "POST",
url: "/pages/voyages/passageplans/createroute.php",
dataType: 'json',
data: $("#routePlan_form").serialize(),
'success': function(data) {
if(data['success']) {
//refresh the table
$("#table").load(location.href + " #table");
//reset the form
$('#routePlan_form').trigger("reset");
//scroll to the top
window.scrollTo({ top: 0, behavior: 'smooth' });
//send the user a success message
resetToastPosition();
$.toast({
heading: 'Success',
text: 'Waypoint added successfully',
textColor: 'white',
showHideTransition: 'slide',
hideAfter : 7000,
icon: 'success',
loaderBg: '#f96868',
position: 'top-center'
})
} else {
var i;
for (i = 0; i < data['message'].length; i++) {
this.error(this.xhr, data['message'][i]);
}
}
},
'error': function(jqXHR, textStatus, errorThrown) {
//send the user a success message
resetToastPosition();
$.toast({
heading: 'Error',
text: '' + textStatus,
textColor: 'white',
showHideTransition: 'slide',
hideAfter : 10000,
icon: 'error',
bgColor: '#f96868',
position: 'top-center',
loaderBg: '#405189'
})
}
})
})
});