I have a page with multiple forms on, where each form is processed with PHP in the backend that sends data to a MySQL database, but on the front end it uses Javascript's fetchAPI to prevent the page refreshing when an instance of the form is completed and data is sent to the database.
I have some PHP server side validations that take place that still work in terms of not sending the data to the database, although on submission the instance of the form completed does disappear from the page (due to javascript shown below), but re-appears when refreshed if it failed the validations.
The main code example below includes this code block that would normally output the error message:
<?php
// echo form validation error messages
if(isset($error)) {
foreach($error as $msg) {
echo "<p>** {$msg}</p>";
}
}
?>
In terms of outputting these error messages is it possible to still use this PHP code (currently not working), or now I'm using the javascript fetchAPI in conjunction with PHP, will I have to also write validations in JavaScript to output the errors on the front end, in addition to the PHP ones which securely prevent the form failing the validations?
<?php
// note $imageTitle is a variable given to the title of a post submitted via an HTML form
if(!preg_match('/^[a-zA-Z0-9\s] $/', $imageTitle)) {
$error[] = "Post Title can be letters and numbers only";
}
if(empty(trim($imageTitle))){
$error[] = "Image Title cannot be blank";
}
// if no errors process submission
if (!isset($error)) {
try {
// PDO prepared statements that update the database
} catch (PDOException $e) {
echo "There is an error: " . $e->getMessage();
}
}
?>
Also here is the javascript fetchAPI code that works on the page.
var forms = document.querySelectorAll('.image-upload-details-form'),
forms.forEach(item => {
item.querySelectorAll('[type="submit"], button').forEach(button => {
button.addEventListener("click", e => item._button = button); //store this button in the form element
})
item.addEventListener("submit", function(evt, btn) {
evt.preventDefault();
const formData = new FormData(this);
if (this._button) //submitted by a button?
{
formData.set(this._button.name, this._button.value);
}
fetch("upload-details.php", {
method: 'post',
body: formData
}).then(function(response){
return response.text();
}).then(function(text){
console.log(text);
}).catch(function (error){
console.error(error);
})
// removes form when submitted
item.remove();
})
})
Many thanks in advance for any help / advice.
CodePudding user response:
My understanding is after making the fetch request you want to show the error message.
Your php code is incomplete. On pdo execption, you are outputting a string. On your validation, you are storing in an array.
Not clear about the output, if the validation fails.
(Recommended is output a string with html tags, so you can overcome the complexity of running a loop and creating dom nodes at js end)
While communicating with backend, best way is to use JSON format, to identify whether the response success or error
<?php
// echo form validation error messages // from php
if(isset($error)) {
foreach($error as $msg) {
echo "<p>** {$msg}</p>";
}
}
<div class="error-messages"></div> // for fetch error messages. leave it blank
?>
const errorElement = document.querySelector(".error-messages"); // capture error element
errorElement.innerHTML =''; // clean previous errors
fetch("upload-details.php", {
method: 'post',
body: formData
}).then(function(response){
const echoed = response.text(); // assuming you are captuing the text
if(echoed.includes("There is an error: ")){ // it is an error
errorElement.innerHTML = echoed; // insert the error message into the div
return;
}
return response.text();
}).then(function(text){
console.log(text);
}).catch(function (error){
errorElement.innerHTML = "Error communicating with server.Contact administrator"
console.error(error);
})
CodePudding user response:
When you catch PDOException you make echo (but not throw new Exeption). So in JS it goes to then(function(response), not to catch(function (error).
You should check response in then(function(response). Example:
.then(function(response){ if (response.includes('Error:') { // do something }