JavaScript Fetch() 不区分表单的更新和删除功能
JavaScript Fetch() Not Differentiating Between The Update And Delete Functionality Of A Form
我有一个当前在服务器上处理的表单 PHP/MySQL 在前端使用 JavaScript fetch() API 以便在将详细信息提交到数据库时页面不会在提交表单时重新加载。
表单本身位于一个循环中,该循环将表单的多个实例输出到页面上。
要使JavaScript工作,它依赖于以下PHP(我将在问题末尾显示更详细的代码)
if($_SERVER['REQUEST_METHOD'] == 'POST') {
// PHP to process form details
}
javascript是:
var forms = document.querySelectorAll('form');
forms.forEach(item => {
item.addEventListener("submit", function (evt) {
evt.preventDefault();
const formData = new FormData(this);
fetch("upload-details.php", {
method: 'post',
body: formData
}).then(function(response){
return response.text();
}).catch(function (error){
console.error(error);
})
// remove item after form details submitted
item.remove();
})
})
我现在想添加一个删除按钮,它也适用于 JS 提取 API。我遇到的问题是,我无法让 JS Fetch 区分何时更新表单详细信息以及何时删除记录?
我试过改变这个:
if($_SERVER['REQUEST_METHOD'] == 'POST') {
// PHP to process form details (both update and delete)
}
至此(无果):
if(isset($_POST['update'])) {
// PHP to process form details
}
if(isset($_POST['delete'])) {
// PHP to process form details
}
当我关闭 JS fetch() API 代码时,从 PHP / MySQL 的角度来看,下面的代码的行为完全符合预期(即更新和删除相应的记录)。
更详细的代码:
<?php
isset($_REQUEST['username']) ? $username = $_REQUEST['username'] : header("Location: login.php");
// the following variable is already fetched with PHP from the database
// it is added as a value to a hidden input element in the HTML form shown below
$db_image_id = htmlspecialchars($row['image_id']);
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$image_title = $_POST['image-title'];
$image_tags = $_POST['image-tags'];
$image_id = $_POST['image-id']; // value attribute from hidden form element
if(empty(trim($image_title))){
$error[] = "Image Title cannot be blank";
}
if (!isset($error)) {
try {
$sql = "UPDATE imageposts SET
image_title = :image_title,
image_tags = :image_tags
WHERE image_id = :image_id";
$stmt = $connection->prepare($sql);
$stmt->execute([
':image_title' => $image_title,
':image_tags' => $image_tags,
':image_id' => $image_id
]);
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
} else {
// give values an empty string to avoid an error being thrown before form submission if empty
$image_title = $image_tags = "";
}
}
//---- DELETE DETAILS
if(isset($_POST['upload-details-delete'])) {
$image_id = $_POST['image-id']; // 'value' attribute from hidden form element
try {
$sql = "DELETE FROM `lj_imageposts` WHERE image_id = :id";
$stmt = $connection->prepare($sql);
$stmt->execute([
':id' => $image_id
]);
} catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
}
// data is fetched with PHP to add to the form
//(I haven't included this code because there is a lot of values outputted onto the form, and when the JavaScript fetch() is turned off it all works OK)
while ($row = $stmt->fetch()) {
?>
<!-- form that holds the update and delete elements -->
<div class="upload-details-component">
<form method="post" enctype="multipart/form-data">
<button name="delete">Delete</button>
<div class="upload-details-image-wrapper">
<!-- ** image is outputted here from database ** -->
</div>
<div class="edit-zone">
<div class="form-row">
<label>Image Title</label>
<input type="text" name="image-title" placeholder="Image Title" >
</div>
<div class="form-row">
<label>Image Tags</label>
<textarea type="text" name="image-tags"></textarea>
</div>
<div class="form-row">
<input type="submit" name="upload" value="COMPLETE UPLOAD">
</div>
</div>
<input type="hidden" name="image-id" value="<?php echo $db_image_id?>">
</form>
</div>
<?php } ?>
仅当用户单击时才提交添加到 POST 数据的按钮。由于您在 javascript 中收集表单数据,因此没有单击任何按钮,因此它们不包括在内。
您需要做的是找出点击了哪个提交按钮,并在收集表单数据之前手动添加包含此类信息的隐藏输入字段,或者注入到表单数据本身:
var forms = document.querySelectorAll('form');
forms.forEach(item => {
item.addEventListener("submit", function(evt) {
evt.preventDefault();
const formData = new FormData(this);
formData.set(evt.submitter.name, evt.submitter.value);
console.log([...formData].join("|"));
})
})
<form>
<input name="test" value="blah">
<input type="hidden" name="hid" value="hidblah">
<button type="submit" name="update" value="upd">update</button>
<button type="submit" name="delete" value="del">delete</button>
</form>
由于并非所有浏览器都支持 event.submitter
您需要通过 onclick 事件跟踪哪个按钮被点击:
var forms = document.querySelectorAll('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);
delete this._button; //this only needed if form can be submitted without submit button (aka submitted by javascript)
}
console.log([...formData].join("|"));
});
})
<form>
<input name="test" value="blah">
<input type="hidden" name="hid" value="hidblah">
<button type="submit" name="update" value="upd">update</button>
<button type="submit" name="delete" value="del">delete</button>
<button name="submit" value="sub">submit</button>
</form>
<form>
<input name="test2" value="blah2">
<input type="hidden" name="hid2" value="hidblah2">
<button type="submit" name="update2" value="upd2">update2</button>
<button type="submit" name="delete2" value="del2">delete2</button>
<button name="submit2" value="sub2">submit2</button>
</form>
我有一个当前在服务器上处理的表单 PHP/MySQL 在前端使用 JavaScript fetch() API 以便在将详细信息提交到数据库时页面不会在提交表单时重新加载。
表单本身位于一个循环中,该循环将表单的多个实例输出到页面上。
要使JavaScript工作,它依赖于以下PHP(我将在问题末尾显示更详细的代码)
if($_SERVER['REQUEST_METHOD'] == 'POST') {
// PHP to process form details
}
javascript是:
var forms = document.querySelectorAll('form');
forms.forEach(item => {
item.addEventListener("submit", function (evt) {
evt.preventDefault();
const formData = new FormData(this);
fetch("upload-details.php", {
method: 'post',
body: formData
}).then(function(response){
return response.text();
}).catch(function (error){
console.error(error);
})
// remove item after form details submitted
item.remove();
})
})
我现在想添加一个删除按钮,它也适用于 JS 提取 API。我遇到的问题是,我无法让 JS Fetch 区分何时更新表单详细信息以及何时删除记录?
我试过改变这个:
if($_SERVER['REQUEST_METHOD'] == 'POST') {
// PHP to process form details (both update and delete)
}
至此(无果):
if(isset($_POST['update'])) {
// PHP to process form details
}
if(isset($_POST['delete'])) {
// PHP to process form details
}
当我关闭 JS fetch() API 代码时,从 PHP / MySQL 的角度来看,下面的代码的行为完全符合预期(即更新和删除相应的记录)。
更详细的代码:
<?php
isset($_REQUEST['username']) ? $username = $_REQUEST['username'] : header("Location: login.php");
// the following variable is already fetched with PHP from the database
// it is added as a value to a hidden input element in the HTML form shown below
$db_image_id = htmlspecialchars($row['image_id']);
if($_SERVER['REQUEST_METHOD'] == 'POST') {
$image_title = $_POST['image-title'];
$image_tags = $_POST['image-tags'];
$image_id = $_POST['image-id']; // value attribute from hidden form element
if(empty(trim($image_title))){
$error[] = "Image Title cannot be blank";
}
if (!isset($error)) {
try {
$sql = "UPDATE imageposts SET
image_title = :image_title,
image_tags = :image_tags
WHERE image_id = :image_id";
$stmt = $connection->prepare($sql);
$stmt->execute([
':image_title' => $image_title,
':image_tags' => $image_tags,
':image_id' => $image_id
]);
} catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
} else {
// give values an empty string to avoid an error being thrown before form submission if empty
$image_title = $image_tags = "";
}
}
//---- DELETE DETAILS
if(isset($_POST['upload-details-delete'])) {
$image_id = $_POST['image-id']; // 'value' attribute from hidden form element
try {
$sql = "DELETE FROM `lj_imageposts` WHERE image_id = :id";
$stmt = $connection->prepare($sql);
$stmt->execute([
':id' => $image_id
]);
} catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
}
// data is fetched with PHP to add to the form
//(I haven't included this code because there is a lot of values outputted onto the form, and when the JavaScript fetch() is turned off it all works OK)
while ($row = $stmt->fetch()) {
?>
<!-- form that holds the update and delete elements -->
<div class="upload-details-component">
<form method="post" enctype="multipart/form-data">
<button name="delete">Delete</button>
<div class="upload-details-image-wrapper">
<!-- ** image is outputted here from database ** -->
</div>
<div class="edit-zone">
<div class="form-row">
<label>Image Title</label>
<input type="text" name="image-title" placeholder="Image Title" >
</div>
<div class="form-row">
<label>Image Tags</label>
<textarea type="text" name="image-tags"></textarea>
</div>
<div class="form-row">
<input type="submit" name="upload" value="COMPLETE UPLOAD">
</div>
</div>
<input type="hidden" name="image-id" value="<?php echo $db_image_id?>">
</form>
</div>
<?php } ?>
仅当用户单击时才提交添加到 POST 数据的按钮。由于您在 javascript 中收集表单数据,因此没有单击任何按钮,因此它们不包括在内。
您需要做的是找出点击了哪个提交按钮,并在收集表单数据之前手动添加包含此类信息的隐藏输入字段,或者注入到表单数据本身:
var forms = document.querySelectorAll('form');
forms.forEach(item => {
item.addEventListener("submit", function(evt) {
evt.preventDefault();
const formData = new FormData(this);
formData.set(evt.submitter.name, evt.submitter.value);
console.log([...formData].join("|"));
})
})
<form>
<input name="test" value="blah">
<input type="hidden" name="hid" value="hidblah">
<button type="submit" name="update" value="upd">update</button>
<button type="submit" name="delete" value="del">delete</button>
</form>
由于并非所有浏览器都支持 event.submitter
您需要通过 onclick 事件跟踪哪个按钮被点击:
var forms = document.querySelectorAll('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);
delete this._button; //this only needed if form can be submitted without submit button (aka submitted by javascript)
}
console.log([...formData].join("|"));
});
})
<form>
<input name="test" value="blah">
<input type="hidden" name="hid" value="hidblah">
<button type="submit" name="update" value="upd">update</button>
<button type="submit" name="delete" value="del">delete</button>
<button name="submit" value="sub">submit</button>
</form>
<form>
<input name="test2" value="blah2">
<input type="hidden" name="hid2" value="hidblah2">
<button type="submit" name="update2" value="upd2">update2</button>
<button type="submit" name="delete2" value="del2">delete2</button>
<button name="submit2" value="sub2">submit2</button>
</form>