How to reload a datable after adding a data through ajax? - javascript

I've a UI which adds data to the database via ajax. That data should reflect in my datatable without reloading the whole page or by just reloading the datatable. I've tried using t.api().ajax.reload() & t.ajax.reload() but it throws error in console like "Cannot read property 'reload' of undefined" or "t.api is not a function" i Don't know what am doing wrong here. Below are some reference
UI - Adding datas through add role btn which brings a pop up
Add Role Pop Up
HTML
<div id="roles" style="display: block" >
<ul class="tab-onebtn">
<li class="logouttab"> <a style="float: left;" id="myBtn"> Add Role </a> </li>
</ul>
<div class="table roles_table" >
<table class="example display" id="mytable" cellspacing="0" width="100%">
<thead>
<tr>
<th>Roles</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<?php foreach($resultRoles as $r) { ?>
<tr>
<td><?php echo $r->cptv_role; ?></td>
<td></td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<h1> Roles coming soon</h1>
</div>
<div id="myModal" class="modal" >
<!-- Modal content -->
<div class="modal-content">
<span class="close">×</span>
<!-- <div class="modal-header">
<h2 style="text-align:center";>Add Role</h2>
</div>-->
<div class="modal-body">
<form action="" method="post" class="addRoleForm">
<?php if(!empty($this->session->flashdata('error')) ) { ?><div class='error' style="margin-top: -20px;"><h2><?php echo $this->session->flashdata('error'); ?> </h2></div><?php } ?>
<?php if(validation_errors() != false) { ?><div class='error'><?php echo validation_errors(); ?></div><?php } ?>
<div class="field-wrap">
<label>
Role <span class="req">*</span>
</label>
<input name="role" class="roleInput" type="text"required autocomplete="off"/>
</div>
<div id="result" class="msg" style="display:none;"></div>
<button class="button button-block submitbtn"/><span class="addRole" >Add Role </span> <span class="Added" style="display:none;"><b>Successfully Added </b></span></button>
</form>
</div>
<!-- <div class="modal-footer">
<h3>Modal Footer</h3>
</div>-->
</div>
</div>
Javascript
// Ajax post
$(document).ready(function() {
var t = $('#mytable').DataTable();
$(".addRoleForm").submit(function(){
event.preventDefault();
var str = $(this).serialize();
console.log();
jQuery.ajax({
type: "POST",
url: base_url+ "admin/roles/addRole",
dataType: 'json',
data: str,
success: function(result) {
if (result)
{
console.log(result);
// Show Entered Value
jQuery("div#result").show();
if(result.success){
// $('#mytable tbody').append('<tr><td>'+$('input[name="role"]').val().trim()+'</td><td></td></tr>');
// $('#mytable').DataTable();
t.api().ajax.reload();
jQuery("div.msg").html("<div class='success'><h2>"+result.success+"</div>");
setTimeout(function(){
span.click();
}, 2000);
}else{
jQuery("div.msg").html("<div class='error'><h2>"+result.error+"</h2></div>");
}
//var ref = $('#mytable').DataTable();
//setInterval( function () {
// ref.ajax.reload(); // user paging is not reset on reload
//}, 1000 );
setTimeout(function(){
jQuery("div#result").hide();
$(".roleInput").val('');
}, 2000);
}
}
});
});
});
Controller
public function addRole() {
if (empty($this->sessionData)){
// print_r($this->sessionData['id']); exit;
$this->index();
}
$post = $this->input->post();
$this->form_validation->set_rules('role', 'Role', 'trim|required|xss_clean');
if ($this->form_validation->run()) {
$roleDet = $this->roles_model->checkCpRoles(array('cptv_role' => $post['role']));
if ($roleDet->num_rows()) {
$data['error'] = " Role already Exist.";
echo json_encode($data);
} else {
$result = $this->roles_model->addCpRoles(array('cptv_role' => $post['role']));
if ($result){
$data['success'] = " Successfully added the Role ";
echo json_encode($data);
} else {
$data['error'] = " Something went wrong ";
echo json_encode($data);
}
}
}
}
Can somebody help me please!?

Reload the datatable after ajax success like:
You're using old API: $().dataTable() (v1.9 and earlier) which is still available in DataTables v1.10. The old API returns jQuery object, so you should use .api() in order to use DataTable API methods:
oTable.api().ajax.reload();
// where oTable is the reference to datatable.

Since you have written some code in php I dont understand it much, But I can point the issue in your code. You are having a normal HTML table to which you apply the DataTable plugin.
Your code t.api().ajax.reload(); breaks because the DataTable is not fetching data via ajax, meaning your DataTable is not setup for a ajax based data, Its a normal HTML table.
What I suggest you is return the entire row that you need to append into the table (make sure all the columns are returned, right now you have only 2 columns in your table) in your ajax success method. Now all you have to do is add this new column into the dataTable and redraw the table.
Syntax to add a new row into the dataTable and redraw it is as below.
t.row.add(yourArrayGoesHere).draw( false );
So that means your response from the server must be a array. Example : ["Admin",""]
Test: Open your console window in the browser (press F12 to open)
and paste this code and hit enter. You must be able to see a new row with first cell having the value Admin.
t.row.add(["Admin",""]).draw( false );
Let me know if this helps.

This is the best example i have ever seen in which datatable is implemented with the Codeigniter framweork.
http://mbahcoding.com/tutorial/php/codeigniter/codeigniter-ajax-crud-using-bootstrap-modals-and-datatable.html

Related

how can i refresh just the modal with ajax call without losing JavaScript tag

so im working on this library project where students can order books and admin has to confirm those requests from his side.
here is a pic of the project to have a small idea:
those are students requests
when u click on the blue button you can see more details of the student order:order details
as you can see there is the book that the student has ordered.
now what i wanted is to refresh just the modal after the admin click accept and i did achieve that by using the .load() function here is the piece of code that responsible that :code that load the modal
since we have multiple students and they can order multiple books so i had to use 2 loops that why you see those dynamic id on the modal id and button id, $tmp is for the students loop and $tmp2 is for the books loop. so far so good, the problem is when the modal refresh i lose my script tag which is bad why because all my buttons have click events so no script means buttons will not work here is before and after modal refresh before refresh you can see the script tag that responsible for the buttons and the ajax call here is after as you can see the modal refresh successfully but i lost my script so the buttons will not work so i have to reload the whole page so i can retrieve my script then the buttons will work again.
some of the solutions i tried is to put the script outside of the modal because i assumed .load() can only fetch html no script but i can't because i need the script to be inside that loop in the modal for the books button
here is the modal code if you want more details :
<!-- user books details modal -->
<div class="modal fade" id="userBooksDetails<?= $tmp ?>" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg ">
<div id="modalContent<?= $tmp ?>" class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" class="btn-close" data-mdb-dismiss="modal" aria-label="Close"></button>
</div>
<div id="modalBody<?= $tmp ?>" class="modal-body">
<table class="table">
<thead>
<tr>
<th scope="col">Picture</th>
<th scope="col">Name</th>
<th scope="col">Status</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
<?php
//dont mind this its just to fetch information of the book to display it in the modal
$livre = new Livre();
$exemplaire = $livre->myBooks($user->id);
if ($exemplaire) {
//here is the second loop because student can order multiple books and each book request need to have an unique id for it button
foreach ($exemplaire as $exem) {
$tmp2--;
$copy = Exemplaire::find($exem['Num_Exemp']);
$book = Livre::find($copy->ISBN);
?>
<script>
$(document).ready(function() {
//request for accepting the order of the user
$("#acceptBook<?= $tmp2 ?>").click(function() {
let copyId = $(this).attr("data-idCopy");
$.ajax({
url: "<?= PROOT ?>emprunts/acceptOrder/" + copyId,
type: "POST",
success: function(data) {
$("#modalContent<?= $tmp ?>").load(window.location.href + " #modalContent<?= $tmp ?>" );
console.log(data)
}
});
});
//request for rejecting the order of the user
$("#rejectBook<?= $tmp2 ?>").click(function() {
let copyId = $(this).attr("data-idCopy");
$.ajax({
url: "<?= PROOT ?>emprunts/rejectOrder/" + copyId,
type: "POST",
success: function(data) {
//$("#userBooksDetails<?= $tmp ?>").load(" #userBooksDetails<?= $tmp ?>");
console.log(data);
$("#modalBody<?= $tmp ?>").load(window.location.href + " #modalBody<?= $tmp ?>" );
}
});
});
//request for returning the book (is not working after reloading on accept fix it )
$("#return<?= $tmp2 ?>").click(function() {
let copyId = $(this).attr("data-idCopy");
$.ajax({
url: "<?= PROOT ?>emprunts/returnBook/" + copyId,
type: "POST",
success: function(data) {
console.log(data);
$("#modalBody<?= $tmp ?>").load(window.location.href + " #modalBody<?= $tmp ?>" );
}
});
})
})
</script>
<tr>
<th> <img src="<?= PROOT . "/public/img/books/" . $book->img ?>" class="w-50 rounded-t-5 rounded-tr-md-0 rounded-bl-md-5" aria-controls="#picker-editor">
</th>
<td class="display-6 text-align-center">
<div class="my-5">
<?= $book->Titre_livre ?>
</div>
</td>
<td>
<div class="form-group mt-4">
<button id="stat<?= $tmp2 ?>" disabled class="btn mt-5"><?php if($exem['isConfirm']==0)
echo "Not Confirmed";
else echo "Confirmed"; ?></button>
</div>
</td>
<td id="test<?= $tmp2 ?>">
<!-- here im checking if the book is confirmed if yes im showing some specific buttons if not hiding some buttons -->
<div class="form-group mt-5">
<a <?php if($exem['isConfirm']==1)
echo "hidden";
else
echo "" ?>
id="acceptBook<?= $tmp2 ?>" class="btn m-2" data-idCopy="<?= $exem['Num_Exemp'] ?>" role="button">Accept</a>
<a <?php if($exem['isConfirm']==1)
echo "hidden";
else
echo "" ?> id="rejectBook<?= $tmp2 ?>" class="btn btn-dark m-2" data-idCopy="<?= $exem['Num_Exemp'] ?>" role="button">Reject</a>
<a <?php if($exem['isConfirm']==0)
echo "hidden";
else
echo "" ?> id="return<?= $tmp2?>" data-idCopy="<?= $exem['Num_Exemp'] ?>" class="btn btn-secondary mt-4"> Return </a>
</div>
</td>
</tr>
<?php }
}
?>
</tbody>
</table>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-mdb-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>

Making a jQuery change permanent on page refresh

Back Ground:
I have made a script that loads a table of product names, when you click a button on that table row it shows a search box. This search box uses the jquery UI autocomplete function. When an option is selected it pulls that products information from a different database from this main project database and puts them in their corresponding tags within the table. It also then submits this content to another table in another database which is the main database for the project. It is storing the information correctly, and when the foreach loop runs with the database content from the main project it is loading correctly. The button that the user presses to reveal the search box says "Link Product", once they selected it the button changes css and html value to Edit Product.
The problem
The issue I'm having is any table row that has content loaded from the main database needs to have the "Edit Button" still be there and any blank rows must show the Link Product Button. But when you refresh the page they all revert to "Link Button".
Now I'm going to show you the code but I will give you a heads up its very messy as I'm new to both ajax and jquery.
The Code
Html Page
<div class="container">
<div class="row">
<div class="col text-center">
<h3 id="edit_sheet_title" class="mt-3 mb-3"><?php echo $title; ?></h3>
</div>
</div>
<div class="row mb-5">
<div class="col-xl-12 col-md-12 col-sm-12 col-12 text-center">
Bulk Import
Container Import
Add Product
Generate Sheet
Go Back
</div>
</div>
</div>
<div class="table-container">
<div class="row">
<div class="col">
<div class="table-responsive">
<table class="table" id="sheet_list">
<thead>
<tr>
<th class="align-middle th-id">ID</th>
<th class="align-middle th-name">Product Name</th>
<th>Ingredients</th>
<th id="button_th"></th>
</tr>
</thead>
<tbody>
<?php if(!empty($sheet_product_list)) { ?>
<?php foreach($sheet_product_list as $product) { ?>
<tr>
<td><p data-id="entry_id" id="entry_id" class="table-p"><?php echo $product['entry_id']; ?></p></td>
<td class="td-name"><?php echo $product['display_name']; ?></td>
<td>
<div id="search_div">
<input type="text" class="wholesale_product_search mb-5 block" data-info="search_box" data-entry-id="<?php echo $product['entry_id']; ?>" name="product_search" id="product_search" placeholder="Search for product...">
</div>
<p data-info="product_id" id="product_id" class="<?php echo $product['entry_id']; ?>">
<?php if(isset($product['wholesale_product_id'])){ echo "Product ID: " . $product['wholesale_product_id'];} ?>
</p>
<p data-info="wholesale_name" id="wholesale_name" class="<?php echo $product['entry_id']; ?>">
<?php if(isset($product['wholesale_name'])){ echo $product['wholesale_name'];} ?>
</p>
<p data-info="is_manual" class="<?php echo $product['entry_id']; ?>">
</p>
<p data-info="ingredients_section" id="ingredients_section" class="<?php echo $product['entry_id']; ?>">
<?php if(isset($product['wholesale_ingredients'])){echo $product['wholesale_ingredients'];} ?>
</p>
</td>
<td class="pull-right align-middle">
<div class="button_td_div">
<button id="edit_product_button" data-id="<?php echo $product['entry_id']; ?>" class="btn btn-info" role="button">Link Product</button><br>
<a id="column_button" href="<?php echo URLROOT; ?>product/delete/<?php echo $sheet['sheet_id']; ?>/<?php echo $product['entry_id']; ?>" class="btn btn-danger" role="button">Delete Product</a>
</div>
</td>
</tr>
<?php } ?>
<?php } ?>
</tbody>
</table>
</div>
</div>
</div>
</div>
<input type="hidden" id="sheet_id" value="<?php echo $sheet_id; ?>">
Jquery Function
$('button[data-id]').click( function () {
var display_name = $('.td-name').html();
var entry_id = $(this).attr("data-id");
var search_box = $("input[data-info='search_box'][data-entry-id="+entry_id+"]");
var ingredients_section = $("p[data-info='ingredients_section']."+entry_id);
var wholesale_name = $("p[data-info='wholesale_name']."+entry_id);
var wholesale_product_id = $("p[data-info='product_id']."+entry_id);
var edit_button = $('button[data-id='+entry_id+']');
const sheet_id = $('#sheet_id').val();
$(search_box).on( "autocompleteselect", function(e, ui) {
var result_string = ui.item.value; // this is the string returned from the search
var product_id = result_string.match( /\d+/ )[0];
$(search_box).hide();
edit_button.html('Edit Product');
edit_button.removeClass("btn btn-warning").addClass("btn btn-success");
$.ajax({
type: "GET",
url: ajax_url,
data: "product_id="+product_id,
success: function(data){
var obj = JSON.parse(data);
const ingredients = obj[0].ingredients;
const product_name = obj[0].name;
const w_product_id = obj[0].product_id;
$(wholesale_product_id).html('Product ID: '+w_product_id);
$('#confirmed').show();
$(wholesale_name).html('Wholesale Name: '+product_name);
$(ingredients_section).html(ingredients);
$.ajax({
type: "POST",
url: ajax_url,
data: {post_sheet_id: sheet_id,post_wholesale_product_id: w_product_id, post_wholesale_ingredients: ingredients, entry_id: entry_id,wholesale_product_name: product_name},
success: function(data){
var obj = JSON.parse(data);
$.ajax({
type: "GET",
url: ajax_url,
data: "sheet_id="+sheet_id+"&content",
success: function(data){
var obj = JSON.parse(data);
const content = obj[0].wholesale_product_id;
console.log(content);
}
});
}
});
}
});
} );
if($(this).html() == 'Link Product'){
$(search_box).show();
$(search_box).focus();
$(this).html('Cancel');
$(this).removeClass("btn btn-info");
$(this).addClass("btn btn-warning");
} else if($(this).html() == 'Cancel'){
$(search_box).hide();
$(this).removeClass("btn btn-warning");
$(this).addClass("btn btn-info");
$(this).html('Link Product');
}
} );
$(function() {
$(".wholesale_product_search").autocomplete({
source: ajax_url,
minLength: 1
});
});
I have not a single clue how to make the Edit Product html value to stay on the page refresh, every time I refresh that page all the buttons go back to saying Link Product, but I only want blank ingredients boxes to have a "Link Product" button, any with ingredients loaded the button needs to say "Edit Product".
I have been driven mad by this for days and I'm at my whits end.
Any help, literally anything at all would spare me my sanity.
** EDIT **
I know its a horrendous mess, but my deadline is fast approaching I'm miles off and at this point will do whatever it takes to make it work. It's used in house and is not accessible to the outside world.
Just use php if else statmant:
<?= isset($product['wholesale_ingredients']) ? 'Edit product' : 'Link Product' ?>
This will echo 'Edit product' if wholesale_ingredients is set, and 'Link product' wholesale_ingredients is empty
This is how your actual button should look like
<div class="button_td_div">
<button id="edit_product_button" data-id="<?php echo $product['entry_id']; ?>" class="btn btn-info" role="button">
<?= isset($product['wholesale_ingredients']) ? 'Edit product' : 'Link Product' ?>
</button><br>
<a id="column_button" href="<?php echo URLROOT; ?>product/delete/<?php echo $sheet['sheet_id']; ?>/<?php echo $product['entry_id']; ?>" class="btn btn-danger" role="button">Delete Product</a>
</div>

How to delete a complete row on button click in javascript?

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.
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.
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);
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';
}
?>
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.
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.
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>
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>

Run PHP insert function from javascript

I have a HTML table with employee name and id that is being retrieved from an SQL select. I want to be able to edit the employee password and update it my DB. The php function is working but I want to run it from an onclick function in javascript. My code is:
function update(id) {
var pass = document.getElementById('pass'+id).value;
var Cpass = document.getElementById('Cpass'+id).value;
if (pass != Cpass){
Notify("Passwords don't match. Please reneter passwords");
}
else{
//run php function $this->ea_user_settings->update_password(id, pass);
Notify("Password saved");
document.getElementById('update'+id).style.display = 'none';
}
}
function edit(id) {
if (document.getElementById('update'+id).style.display == 'inline'){
document.getElementById('update'+id).style.display = 'none';
}
else{
document.getElementById('update'+id).style.display = 'inline';
}
}
function Notify($msg) {
$("#notification").text("");
$("#notification").fadeIn(1000).append($msg);
$("#notification").fadeOut(5000);
}
<div id="notification" style="display : none" value=""></div>
<?php
$invoice = $this->ea_user_settings->get_employee_name_id();
?>
<table class="table table-hover table-bordered table-striped" id = "EmployeeList">
<thead>
<tr>
<th style="background-color:#BA9E5E; position:sticky; top: 0"><p style="color: white;">Name</p></th>
<th style="background-color:#BA9E5E; position:sticky; top: 0"><p style="color: white;">ID</p></th>
<th style="background-color:#BA9E5E; position:sticky; top: 0"><p style="color: white;">Update Password</p></th>
</tr>
</thead>
<tbody>
<?php
foreach ($invoice as $report): ?>
<tr>
<td><?php echo $report->Name ?> </td>
<td><?php echo $report->ID ?> </td>
<td>
<div>
<div id="<?php echo 'update'.$report->ID;?>" style="display:none">
<input type="text" id="<?php echo 'pass'.$report->ID;?>" name="pass" placeholder="Password">
<input type="text" id="<?php echo 'Cpass'.$report->ID;?>" name="Cpass" placeholder="Confirm Password">
<button id='updateBtn' type="button" onClick='update("<?php echo $report->ID;?>")'>Save</button>
</div>
<div id="<?php echo 'edit'.$report->ID;?>" style="display:inline; text-align:right; padding:10px" align="right">
<button id='editBtn' type="button" onClick='edit("<?php echo $report->ID;?>")'>Edit</button>
</div>
</div>
</td>
</tr>
<?php endforeach;?>
</tbody>
</table>
I want to run my php update function ($this->ea_user_settings->update_password(id, pass);) when I click on the save button.
You need to use ajax for the same.
$.ajax({
url: '/change-password.php',
data: {'user_id':user_id, 'pass': pass, 'new_pass': new_pass},
type: 'POST',
success: function (result)
{
//Do something
}
});
You can refer this sample code :)
You cannot directly call the PHP function from your JavaScript function. PHP runs on the server whereas JS runs on the client.
You could, however, send a get or post request to your server from a javascript function and execute your php function based on the received parameters.
[update - adding an example]
Consider your php page to contain the following function:
<?php
function writeMsg($param) {
echo "Hello ".$param;
}
writeMsg($_GET["name"]);
?>
//Here the parameter 'name' is retrieved from the http request and passed to the function.
For eg., if the link is something like //test-php-page?name=stackoverflow, the displayed HTML page will contain Hello stackoverflow
From your client code, you cannot call the function writeMsg. You would have to send a valid http request to the server with the parameter 'name'. It can be achieved just by placing an anchor tag.
<a href="/test-php-page?name=stackoverflow'>link</a>
or, by form action method
<form action="/test-php-page" method="get">
<input type="text" name="name">
<input type="submit" value="Submit">
</form>
or, by ajax calls using JS.
var xhttp = new XMLHttpRequest();
xhttp.open("GET", "/test-php-page?name=stackoverflow", true);
xhttp.send();
You could also use jQuery or any other library for ease of using ajax calls.
Refer the following w3schools link for better understanding: https://www.w3schools.com/php/php_ajax_intro.asp

Add a row to a HTML table dynamically loaded and refresh it via AJAX and .load

I have an HTML table that loads its values dynamically through a PHP snippet with SQL sentences. There is also a Select and a button to add a row to the table. This button is listened by an ajax procedure to send the data to the php and to insert the new row as a record in the database. I want of course the table (not all the page) refresh the information. For that I use the jquery ($).load function. Everything is working good, the database is updated, but when the HTML table refresh it appears empty. What I am doing wrong?
Here is the HTML table:
<!-- Procedure Table-->
<div id=idProcedimientos class="col-md-12 col-sm-12 col-xs-12">
<div class="x_panel">
<div class="x_title">
<h2>Procedures <small></small></h2>
<div class="clearfix"></div>
</div>
<div class="x_content">
<div class="row">
<div class="col-sm-12">
<div class="card-box table-responsive">
<div class="form-group">
<div class="col-md-2 col-sm-6 col-xs-12">
<? $qProcedure = "SELECT * FROM Procedures";
$resultsProcedure = mysqli_query($db, $qProcedure);
echo "<select id='idSelected_procedure' name='selected_procedure' class='form-control'>";
while ($rowProcedure = mysqli_fetch_assoc($resultsProcedure)) {
echo"<option value ='{$rowProcedure['IdProcedure']}'>{$rowProcedure['Name']}</option>";
};
echo "</select><br />";
?>
</div>
</div>
<div class="form-group">
<div class="col-md-12 col-sm-6 col-xs-12">
<button type="submit" id="idBttnProcedure-add" class="bttnProcedure-add btn btn-round btn-primary">Add Procedure</button><br /><br />
</div>
</div>
<div id="idProcedureTable" class="table-editable">
<table id="datatable-responsive" class="table table-striped table-bordered dt-responsive nowrap" cellspacing="0" width="100%">
<thead>
<tr>
<th>Procedure</th>
<th>Date</th>
<th>Ok</th>
<th>Summary</th>
<th>Remove</th>
</tr>
</thead>
<tbody>
<?
$queryProcedure = "SELECT FoalingsP.IdFoaling, Procedures.Name, JournalProcedures.IdJournalFk, FoalingsP.Date, FoalingsP.Ok,
FoalingsP.Summary FROM FoalingsP, Procedures, JournalProcedures
WHERE
JournalProcedures.IdJournalFk=$row[IdJournal] AND
JournalProcedures.IdJournalProcedure=FoalingsP.IdJournalProcedureFk AND
JournalProcedures.IdProcedureFk=Procedures.IdProcedure
UNION
SELECT UltrasonographiesP.IdUltrasonography, Procedures.Name, JournalProcedures.IdJournalFk, UltrasonographiesP.Date,
UltrasonographiesP.Ok, UltrasonographiesP.Summary FROM UltrasonographiesP, Procedures, JournalProcedures
WHERE
JournalProcedures.IdJournalFk=$row[IdJournal] AND
JournalProcedures.IdJournalProcedure=UltrasonographiesP.IdJournalProcedureFk AND
JournalProcedures.IdProcedureFk=Procedures.IdProcedure";
$resultsProcedure = mysqli_query($db, $queryProcedure);
while ($rowProcedure = mysqli_fetch_assoc($resultsProcedure)){
echo " <tr><td>{$rowProcedure['Name']}</td>
<td>{$rowProcedure['Date']}</td>";
if($rowProcedure["Ok"]=="1") {echo "<td contenteditable='true'><label><input type='checkbox' checked></label></td>";};
if($rowProcedure["Ok"]=="0") {echo " <td contenteditable='true'><label><input type='checkbox'></label></td>";};
echo "<td>{$rowProcedure['Summary']}</td>
<td><span id='tableProcedure-remove' class='tableProcedure-remove table-remove glyphicon glyphicon-remove'></span></td></tr>";
};
?>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- /Procedure Table-->
And here is the script:
<script>
$('.bttnProcedure-add').click(function () {
var idJournal = "<?php echo $row[IdJournal]; ?>";
var idSelected_procedure = document.getElementById("idSelected_procedure").value;
alert(idSelected_procedure);
$.ajax({
type: "POST",
url: "server.php",
data: {mare_idJournal:idJournal,
mare_idSelected_procedure:idSelected_procedure
},
success: function(msg){
alert("Everything saved correctly");
$("#datatable-responsive").load("control_horse_journal.php #datatable-responsive");
}
});
return false;
});
</script>
Thank you very much.
Thanks to #epascarello for the advice. I got the solution. I discarded .load function, and instead I appended a row directly with .after .The final script is like this:
<script type="text/javascript">
$('.bttnProcedure-add').click(function () {
var idJournal = "<?php echo $row[IdJournal]; ?>";
var idSelected_procedure = document.getElementById("idSelected_procedure").value;
var $TABLE_PROCEDURES = $('#idProcedureTable');
var selectedProcedure = document.getElementById("idSelected_procedure");
var name = selectedProcedure.options[selectedProcedure.selectedIndex].text;
var rowP="<tr>"
+"<td>" +name+"</td>"
+"<td>"+"0000-00-00 00:00:00"+"</td>"
+"<td contenteditable='true'><label><input type='checkbox'></label></td>"
+"<td>"+""+"</td>"
+"<td><span id='tableProcedure-remove' class='tableProcedure-remove table-remove glyphicon glyphicon-remove'></span></td>"
+"</tr>";
$('#bodyTbProcedure tr:last').after(rowP);
$.ajax({
type: "POST",
url: "server.php",
data: {mare_idJournal:idJournal,
mare_idSelected_procedure:idSelected_procedure
},
success: function(msg){
alert("Everything saved correctly");
//$("#datatable-responsive").load("control_horse_journal.php #datatable-responsive");
}
});
return false;
});
</script>

Categories

Resources