问题
I have a html/php code as shown below. The below html/php code is working in a way that on adding rows, we can select date from every row and can save it as well.
html/php code:
<?php
$output = array();
$output['house_sitting_date']=$_POST['house_sitting_date'];
$output['row_delete']=$_POST['row_delete'];
$fp = fopen('../feeds/ptp-ess_landing_house.json', 'w');
fwrite($fp, json_encode($output));
fclose($fp);
if(file_exists('../feeds/ptp-ess_landing_house.json')){
$data = json_decode(file_get_contents('../feeds/ptp-ess_landing_house.json'));
}
?>
<?php if($data) { ?>
<form method="post">
<div id="rows" style="display:flex; justify-content: center;"><!-- Big div START -->
<!-- Remove Button START -->
<div class="rows-delete">
<h4 style="text-align:center;">Delete Rows</h4>
<?php if (empty($data->row_delete)) { ?>
<div class="row-delete" style="margin-right:30px; margin-top:22.5px;">
<button type="button" id="delete" onclick="rowDelete()">Remove</button>
<input type="hidden" name="row_delete[]" value="1" />
</div>
<?php } else { ?>
<?php foreach ($data->row_delete as $row_delete){ ?>
<div class="row-delete" style="margin-right:30px; margin-top:22.5px;">
<button id="delete" type="button" onclick="rowDelete()">Remove</button>
<input type="hidden" name="row_delete[]" value="<?php echo $row_delete;?>" />
</div>
<?php }} ?>
</div>
<!-- Remove Button END -->
<!-- Sitting Date START -->
<div class="sitting-days">
<h4 style="text-align:center;">Select Date</h4>
<?php if (empty($data->house_sitting_date)) { ?>
<!-- Select Date START -->
<div class="select-date" style="margin-right:30px; margin-top:20px;">
<input type="date" class="house-sitting-date" name="house_sitting_date[]" value="">
</div>
<?php } else { ?>
<?php foreach ($data->house_sitting_date as $date){ ?>
<!-- Select Date START -->
<div class="select-date" style="margin-right:30px; margin-top:20px;">
<input type="date" class="house-sitting-date" name="house_sitting_date[]" value="<?php if($date) {echo $date;}?>">
</div>
<!-- Select Date END -->
<?php }} ?>
</div>
<!-- Sitting Date END -->
</div><!-- Big div END -->
</form>
<?php } else {
echo 'Cannot read JSON settings file';
}
?>
The above html/php code corresponds to the following screenshot:
The JSON (../feeds/ptp-ess_landing_house.json) belonging to the above screenshot is:
{"row_delete":["1","2","3","4"],"house_sitting_date":["2020-01-28","2020-01-29","2020-01-30","2020-01-31"]}
Problem Statement:
I am wondering what Javascript code I need to add on clicking a Delete button, it deletes a complete row and remove the values from the JSON array as well.
The values which are displayed in the screenshot above are pulled from the JSON array above.
This is what I have tried but more need to be done.
<script>
function rowDelete() {
document.getElementsByClassName("row-delete").remove();
document.getElementsByClassName("select-date").remove();
}
</script>
Two things need to be done.
On clicking Delete button, it should remove the value from the JSON array because everything is pulled from the JSON after saving the form.
Also, on clicking Delete button it should delete the complete row from the DOM.
回答1:
you should give each added row an id corresponding to its rank:
row.id=i.toString();
then use the following code to remove the row:
var row = document.getElementById(rowrankid);
row.parentNode.removeChild(row);
回答2:
I have prepared a code sample for you using your example that does exactly what you say.
It is using a javascript fetch post request to post to the script you have provided to remove the dom elements and update the json file.
I have changed some of your paths slightly so you will need to change those back (add in the ../feeds/ parent directory)
Once the user has pressed the button the page will reload, showing the updated interface that is loaded from the json file.
There are some improvements that could be made, for example the javascript is not checking to make sure the request was successful before reloading, but as the input is date select it should be ok.
<?php
if(file_exists('./ptp-ess_landing_house.json')){
$data = json_decode(file_get_contents('./ptp-ess_landing_house.json'));
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$_POST = json_decode(file_get_contents('php://input'), true);
if(isset($_POST['requestType']) && in_array($_POST['requestType'], ['remove'])) {
switch ($_POST['requestType']) {
case 'remove' :
//Unset the values
unset($data->row_delete[$_POST['data'] -1]);
unset($data->house_sitting_date[$_POST['data'] -1]);
//We are reindexing the arrays as we have deleted some rows, note that we are using +1 array indexes
$data->row_delete = array_values($data->row_delete);
$data->house_sitting_date = array_values($data->house_sitting_date);
foreach($data->row_delete as $key=>$value) {
$data->row_delete[$key] = strval($key+1);
}
//Write the file back
$fp = fopen('./ptp-ess_landing_house.json', 'w');
fwrite($fp, json_encode($data));
fclose($fp);
header("HTTP/1.1 200 OK");
echo 'ok';
die;
break;
default:
}
}
}
?>
<script>
function rowDelete(row) {
//Make a request to your entry file (index.php here) to do the removal
fetch('/index.php', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({requestType: 'remove', data: row})
}).then(function(response) {
location.reload();
return response;
});
}
</script>
<?php if($data) { ?>
<form method="post">
<div id="rows" style="display:flex; justify-content: center;"><!-- Big div START -->
<!-- Remove Button START -->
<div class="rows-delete">
<h4 style="text-align:center;">Delete Rows</h4>
<?php if (empty($data->row_delete)) { ?>
<div class="row-delete" style="margin-right:30px; margin-top:22.5px;">
<button type="button" id="delete" onclick="rowDelete()">Remove</button>
<input type="hidden" name="row_delete[]" value="1" />
</div>
<?php } else { ?>
<?php foreach ($data->row_delete as $row_delete){ ?>
<div class="row-delete" style="margin-right:30px; margin-top:22.5px;">
<button id="delete" type="button" onclick="rowDelete(<?php echo $row_delete;?>)">Remove</button>
<input type="hidden" name="row_delete[]" value="<?php echo $row_delete;?>" />
</div>
<?php }} ?>
</div>
<!-- Remove Button END -->
<!-- Sitting Date START -->
<div class="sitting-days">
<h4 style="text-align:center;">Select Date</h4>
<?php if (empty($data->house_sitting_date)) { ?>
<!-- Select Date START -->
<div class="select-date" style="margin-right:30px; margin-top:20px;">
<input type="date" class="house-sitting-date" name="house_sitting_date[]" value="">
</div>
<?php } else { ?>
<?php foreach ($data->house_sitting_date as $date){ ?>
<!-- Select Date START -->
<div class="select-date" style="margin-right:30px; margin-top:20px;">
<input type="date" class="house-sitting-date" name="house_sitting_date[]" value="<?php if($date) {echo $date;}?>">
</div>
<!-- Select Date END -->
<?php }} ?>
</div>
<!-- Sitting Date END -->
</div><!-- Big div END -->
</form>
<?php } else {
echo 'Cannot read JSON settings file';
}
?>
回答3:
If your json is known at the front-end (which I think you are implying, since your rowDelete is a JS-function), you can pass this with the call to rowDelete. Then you can traverse the DOM to get to value the corresponding sibling input-field (perhaps something like this.parentNode.childNodes[1]).
Once you have that value, you can easily remove it from the corrsponding array in your json:
let d = '2020-01-30'
let idx = arr.indexOf(d)
let newdates = ([...arr.slice(0,idx), ...arr.slice(idx+1)])
data.house_sitting_date = newdates
(with some additional index bounds checking, of course).
After that, you can perform a similar DOM traversal to remove the corresponding element from the DOM.
回答4:
Flash, unfortunately, the desing of the code itself is not much professional... there are separate loops for rows (in php), which instead should be only 1 loop, like (with example simple Javascript binding on click):
<?php
for ($i=0; $i<count($data["house_sitting_date"]); $i++)
{
echo '<div class="remove"><a id="'.$data["row_delete"][$i].'" onclick="deleteRow(this);">Remove</a></div>';
echo '<div class="date">....</div>';
...
}
?>
<script> function deleteRow(el) { el.remove(); } </script>
also, lots of embedded style="".. codes, instead you might use 1 style file.
回答5:
This is how I did in past, and it works perfectly
Prerequisite for this answer to work is each button and input field should be in DIV with unique id and there should be container for all these div in my case its
.
On Add button(if you have one) you need clone node, and paste it under or above the element where it was clicked,
// Create a clone of element with id ddl_1:
let clone = document.querySelector('#row'+rownumber).cloneNode( true );
// Append the newly created element on element p
document.querySelector('p').appendChild( clone );
Then every time you add a new row or delete a row you need to append ids on these row, to do this you would a common class for all these rows in my case I used, rows
function changeids()
{
let rows =document.getElementsByClassName('rows');
for(let i=0; i<rows.length; i++)
{
let thisid="row"+i;
rows[i].setAttribute("id", thisid);
let thisAddButton = rows[i].getElementsByClassName("add")[0];
let thisDeleteButton = rows[i].getElementsByClassName("delete")[0];
let onclickaddfunction = "addrow("+i+")";
thisAddButton.setAttribute("onclick", onclickaddfunction);
let onclickDeletefunction = "removerow("+i+")";
thisDeleteButton.setAttribute("onclick", onclickDeletefunction);
}
}
Then when you remove you need to remove node and call changeids again
function removerow(rownumber){
document.getElementById('row'+rownumber).remove();
changeids();
}
This would give you whole working idea of add and delete rows, whole code below please ignore my messy code, just did it to give you and idea
<p>
<div id="row1" class="rows">
<button class="add" onclick="addrow(1)">add</button>
<button class="delete" onclick="removerow(1)"> remove </button>
<input type="text">
</div>
</p>
<script>
function addrow(rownumber)
{
// Create a clone of element with id ddl_1:
let clone = document.querySelector('#row'+rownumber).cloneNode( true );
// Append the newly created element on element p
document.querySelector('p').appendChild( clone );
changeids();
}
function removerow(rownumber)
{
document.getElementById('row'+rownumber).remove();
changeids();
}
function changeids()
{
let rows =document.getElementsByClassName('rows')
for(let i=0; i<rows.length; i++)
{
let thisid="row"+i;
rows[i].setAttribute("id", thisid);
let thisAddButton = rows[i].getElementsByClassName("add")[0];
let thisDeleteButton = rows[i].getElementsByClassName("delete")[0];
let onclickaddfunction = "addrow("+i+")";
thisAddButton.setAttribute("onclick", onclickaddfunction);
let onclickDeletefunction = "removerow("+i+")";
thisDeleteButton.setAttribute("onclick", onclickDeletefunction);
}
}
</script>
回答6:
To delete row from dom, you have to specify unique id for main element of row and you can use [ElementObject].remove() method to delete, So everything inside that will be removed. Also You should simplify and change JSON data, so that it will delete from json also using ajax with using single id(key) as parameter.
Here is the working code:
<?php
if (!empty($_GET)) {
if (!empty($_GET['action']) && $_GET['action'] == 'delete') {
if(file_exists('ptp-ess_landing_house.json')) {
$data = json_decode(file_get_contents('ptp-ess_landing_house.json'), true);
if (!empty($_GET['row_number'])) {
unset($data[$_GET['row_number']]);
$fp = fopen('ptp-ess_landing_house.json', 'w');
fwrite($fp, json_encode($data));
fclose($fp);
echo 1;
exit;
}
}
echo 0;
exit;
}
}
if (!empty($_POST)) {
$output = array();
if (!empty($_POST['row_item'])) {
$output = $_POST['row_item'];
}
$fp = fopen('ptp-ess_landing_house.json', 'w');
fwrite($fp, json_encode($output));
fclose($fp);
}
$data = array();
if(file_exists('ptp-ess_landing_house.json')) {
$data = json_decode(file_get_contents('ptp-ess_landing_house.json'), true);
}
?><form method="post">
<!-- Add New Row Button START -->
<div class="plus-minus-button" style="text-align:center;">
<button type="button" id="addRow" onclick="rowAdd()">+</button>
</div>
<!-- Add New Row Button END -->
<div id="maindiv">
<div style="display:flex; justify-content: center;">
<div class="rows-delete" style="text-align:center;">
<div class="row-delete" style="margin-right:30px;">
<h4 style="text-align:center;">Delete Rows</h4>
</div>
</div>
<div class="sitting-days" style="text-align:center;">
<div class="select-date" style="margin-right:30px;">
<h4 style="text-align:center;">Select Date</h4>
</div>
</div>
<div class="choose-options" style="text-align:center;">
<div class="yes-no-option" style="display:inline-grid;">
<h4 style="text-align:center;">Yes/No</h4>
</div>
</div>
</div>
<!-- Big div START --><?php
$totalrow = 0;
foreach ($data AS $key => $row) {
?><div id="row-<?php echo $key; ?>" style="display:flex; justify-content: center; margin-top:20px;"><?php
?><div class="rows-delete" style="text-align:center;">
<div class="row-delete" style="margin-right:30px;">
<button type="button" class="delete" onClick="delete_row(this.value)" value="<?php echo $key; ?>">Remove</button>
<input type="hidden" name="row_item[<?php echo $key; ?>][row_delete]" value="<?php echo $row['row_delete'];?>" />
</div>
</div>
<!-- Remove Button END -->
<!-- This is what I have tried to add a button (END) -->
<!-- Sitting Date START -->
<div class="sitting-days" style="text-align:center;">
<div class="select-date" style="margin-right:30px;">
<input type="date" class="house-sitting-date" name="row_item[<?php echo $key; ?>][house_sitting_date]" value="<?php echo $row['house_sitting_date']; ?>">
</div>
</div>
<!-- Sitting Date END -->
<!-- YES/NO START --><?php
?><div class="choose-options">
<div class="yes-no-option" style="display:inline-grid;">
<select name="row_item[<?php echo $key; ?>][house_sitting_date_yes_no]" class="house-yes-no" style="height:24px; ">
<option value="<?php echo $row['house_sitting_date_yes_no']; ?>" <?php if($row['house_sitting_date_yes_no'] == "nada" ) echo "selected";?>>Please choose an option</option>
<option value="<?php echo $row['house_sitting_date_yes_no']; ?>" <?php if($row['house_sitting_date_yes_no'] == "yes" ) echo "selected";?>>Yes</option>
<option value="<?php echo $row['house_sitting_date_yes_no']; ?>" <?php if($row['house_sitting_date_yes_no'] == "no" ) echo "selected";?>>No</option>
</select>
</div>
</div>
<!-- YES/NO END -->
</div><?php
if ($key > $totalrow) $totalrow = $key;
else $totalrow++;
}
?>
<input type="hidden" name="totalrow" id="totalrow" value="<?php echo $totalrow; ?>">
</div>
<!-- Big div END -->
<hr />
<div style="text-align:center;">
<input type="submit" value="submit" />
</div>
</form>
<script>
function delete_row(row_number) {
var data = '<?php echo json_encode($data) ?>';
data = JSON.parse(data);
if (typeof(data[row_number]) != undefined) {
var request = new XMLHttpRequest();
request.open("GET", "index.php?action=delete&row_number=" + row_number);
request.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
var row = document.getElementById('row-'+row_number);
row.remove();
}
}
request.send();
}
else {
var row = document.getElementById('row-'+row_number);
row.remove();
}
}
function rowAdd(event) {
var totalrow = document.getElementById("totalrow").value;
totalrow = parseInt(totalrow) + 1;
document.getElementById("maindiv").insertAdjacentHTML('beforeend', newRow(totalrow));
document.getElementById("totalrow").value = totalrow;
}
function newRow(row_number) {
return `<div id="row-` + row_number + `" class="sitting-days" style="display:flex; justify-content:center; margin-top:20px;">
<div class="rows-delete" style="text-align:center;">
<div class="row-delete" style="margin-right:30px;">
<button type="button" class="delete" onClick="delete_row(this.value)" value="` + row_number + `">Remove</button>
<input type="hidden" name="row_item[` + row_number + `][row_delete]" value="` + row_number + `" />
</div>
</div>
<div class="sitting-days" style="text-align:center;">
<div class="select-date" style="margin-right:30px;">
<input type="date" class="house-sitting-date" name="row_item[` + row_number + `][house_sitting_date]" value="">
</div>
</div>
<div class="choose-options">
<div class="yes-no-option" style="display:inline-grid;">
<select name="row_item[` + row_number + `][house_sitting_date_yes_no]" class="house-yes-no" style="height:24px; ">
<option value="nada">Please choose an option</option>
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
</div>
</div>
</div>`;
}
</script>
来源:https://stackoverflow.com/questions/59866216/how-to-delete-a-complete-row-on-button-click-in-javascript