jtable single column/field in a table refresh - javascript

I am using Jtable for booking events. In combination with PHP, MySQL. My question is, is there a way to just reload every 10 second single column. Precisely I have something like this:
Checkbox ID Event Reservations
+ 4 ev1 22
- 5 ev2 19
I would like to have the reservations column reloaded every 10 seconds, so the user that is logged in can see the changes. Now I got it working with reloading the whole table, but this is not what I really need because every user can book only 9 events and I need to have checkboxes at the left side. After reloading the whole table my checkboxes are not working as expected. So is there a way to reload just one column? My code right now is:
window.setInterval(function(){
$('#Events').jtable('reload');
}, 10000);
Any help or suggestion would be appreciated.

I found a way around how to solve it:
First create a new field in JS like this:
test: {
title: 'test',
display: function (data) {
var $div = $('<div id="test"">'+data.record.id+'</div>');
return $div;
}
},
Than create a function that will be run every 10 seconds and make an AJAX request:
function UpdateRes(){
$.ajax({
url: 'Actions.php?action=update',
type: 'post',
data: '&kiu='+$kiu,
}).success(function(data) {
var jsondata = JSON.parse(data);
$.each(jsondata.Records, function(i, item) {
$('.jtable tr.jtable-data-row').each(function(){
if($(this).attr('data-record-key')==item.id){
$(this).find('div').html( item.reservations );
}
})
});
});
}
window.setInterval(function(){
UpdateRes();
}, 10000);
Let your JSON response look like this:
{"Result":"OK",
"Records":
[
{"0":"111","id":"111","1":"20","reservations":"20"},
{"0":"127","id":"127","1":"20","reservations":"20"},
{"0":"133","id":"133","1":"20","reservations":"20"},
{"0":"134","id":"134","1":"20","reservations":"20"},
{"0":"135","id":"135","1":"20","reservations":"20"},
{"0":"326","id":"326","1":"20","reservations":"20"}
]}
And in the end in Actions.php make your query in try catch:
else if($_GET["action"] == "update")
{
//Get records from database
$result8 = mysqli_query($con,
"SELECT l.id,(l.max-l.reserviert) as reservations
FROM td_res l WHERE
l.kiu='" . mysqli_real_escape_string($con,$_POST["kiu"]) . "';");
//Add all records to an array
$rows8 = array();
while($row8 = mysqli_fetch_array($result8))
{
$rows8[] = $row8;
}
//Return result to jTable
$jTableResult = array();
$jTableResult['Result'] = "OK";
$jTableResult['Records'] = $rows8;
print json_encode($jTableResult);
}

Related

Server-side table deletes row from tables (but not database) using JS, Php, or Ajax

Project Link: https://databasetable-net.000webhostapp.com/
This following code correctly deletes a row in a table:
$('#example').on('click', '.delete_btn', function () {
var row = $(this).closest('tr');
var data = table.row( row ).data().delete;
console.log(data);
alert("delete_btn clicked");
row.remove();
});
However, it is not permately deleting the row. If you refresh the page, the row that got 'deleted' still exists. I believe this is because I am not deleting the row out of the database. Normally in php you safely remove a row in a database with something like this:
id = mysqli_real_escape_string($con, $_GET['del']);
$stmt = $con->prepare("DELETE FROM employees WHERE id = ? LIMIT 1");
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->close();
header('location: index.php');
EDIT: Revised Code Index.php:
(document).ready(function() {
var asc = true;
var table = $('#example').DataTable( {
"processing": true,
"serverSide": true,
"ajax": {
"url": "server.php",
"type": "POST",
},
//http://live.datatables.net/xijecupo/1/edit
columnDefs: [{
targets: -1,
defaultContent: '<button type="button" class="delete_btn">Delete</button>'
}],
rowGroup: {
dataSrc: 1
}
});
$(function(){
$(document).on('click','.delete_btn',function(){
var del_id= $(this).closest('tr');
var ele = $(this).parent().parent(); //removed the "$" from the ele variable. It's a js variable.
console.log(del_id);
$.ajax({
type:'POST',
url:'delete.php',
dataType: 'json', //This says I'm expecting a response that is json encoded.
data: { 'del_id' : del_id},
success: function(data){ //data is an json encoded array.
console.log('Data: ' + data); //Going to display whats in data so you can see whats going on.
if(data['success']){ //You are checking for true/false not yes or no.
console.log('You successfully deleted the row.');
alert("delete btn clicked");
ele.remove();
}else{
console.log('The row was not deleted.');
}
}
});
});
}); //http://jsfiddle.net/zfohLL0a/
}); //end doc ready
delete.php code:
$del_id = $_POST['del_id'];
$stmt = $conn->prepare("DELETE FROM employees WHERE id = ?"); //LIMIT 1
$stmt->bind_param('i', $del_id);
$confirmDelete = $stmt->execute();
$array['success'] = FALSE; //Initialize the success parameter as false.
if($confirmDelete){ //Check to see if there was an affected row.
$array['success'] = TRUE;
}
echo json_encode($array);
?>
Partial Solution: Sample format how to setup the ajax. You have to start off by using the datatables.net "ajax": method for the original server.php. But then after that you use the normal $.ajax methods for the add.php, delete.php, etc. It is confusing because you use two different syntax for ajax. Easiest to just look at the sample link. Youtube video for same code
Another helpful link that discusses sending info to and from the ajax/json are one two three Four
Updated answer using your latest updated code.
JS
$(function(){
$(document).on('click','.delete_btn',function(){
var del_id= $(this).closest('tr');
var ele = $(this).parent().parent(); //removed the "$" from the ele variable. It's a js variable.
console.log(del_id);
$.ajax({
type:'POST',
url:'delete.php',
dataType: 'json', //This says I'm expecting a response that is json encoded.
data: { //Set up your post data as an array of key value pairs.
'del_id' : del_id
},
success: function(data){ //data is an json encoded array.
console.log('Data: ' + data); //Going to display whats in data so you can see whats going on.
if(data['success']){ //You are checking for true/false not yes or no.
console.log('You successfully deleted the row.');
ele.fadeOut().remove();
}else{
console.log('The row was not deleted.');
}
}
});
});
});
delete.php
$del_id = $_POST['del_id'];
$stmt = $con->prepare("DELETE FROM employees WHERE id = ?"); //LIMIT 1
$stmt->bind_param('i', $del_id);
$confirmDelete = $stmt->execute();
$array['success'] = FALSE; //Initialize the success parameter as false.
if($confirmDelete){ //Check to see if there was an affected row.
$array['success'] = TRUE;
}
echo json_encode($array); //Your ajax is setup to expect a json response.
//json_encode the $array and echo it out. You have to do this.
//When you "echo" out a value, that is what the server is going to submit back to the ajax function.
//If you do not do this, the ajax script will not recieve a response from the delete.php page.
This code should work for you.
In addition to Joesph's response who was extremely helpful:
"The console shows "Uncaught RangeError: Maximum call stack size exceeded". It looks as though the Ajax call isn't being issued (nothing is showing on the network tab) - so it must be when creating the request. I suspect I may need to JSON.stringify your del_id."
Someone suggested this:
"The main stack problem is caused by var edit_id = $(this).closest('tr'); . You try to send that whole jQuery object as data in the ajax. Then jQuery can't serialize it internally and throws a fit
You probably want some property like ID or a data attribute from that row to send (not clear what expectations are)."
Please post if you have any recommendations. I will edit in any finalized code solution soon.

Load more return duplicate

I trying to make load more content from database via php and ajax and read some tutorial but what I tried return duplicate entry. (here is just an example of my real code:)
Query:
$sql = "SELECT name FROM table WHERE cat = 2 LIMIT 10";
This load first 10 items.
Query for load more:
$limit = $_GET['limit'];
$current = $_GET['current'];
$sql = "SELECT name FROM table WHERE cat = 2 LIMIT $current OFFSET $limit";
Ajax:
$('.getMore').click(function() {
var adslen = $('.Ads').length; // this return current items
var limit = $(this).attr('data-limit'); // this return current item and items after load more
$.ajax({
type: "GET",
data: {
limit: limit,
current: adslen
},
dataType: 'html',
url: '/api/fetch.php?getBrowse',
success: function(data) {
// do something
}
});
});
For example now we have 10 items, after click on loadMore it load another 10 items, but the problem is it load duplicate itemes too, what I have done wrong?
HTML:
<a class="getMore" id="browse-getMore" data-limit="10">More</a>
After press load more it update data-limit:
<a class="getMore" id="browse-getMore" data-limit="20">More</a>
The problem is that you do not specify order. In your case SELECT statement returns rows with no specific order. When you run it once, it may return one list of records, when you run it twice (the same select query) it may return another set of records. So, do it like so:
$sql = "SELECT name FROM table WHERE cat = 2 ORDER BY id LIMIT $current OFFSET $limit";
And read theory. It says that relation (or table) is an unordered set of records, unless you specify order explicitly. And by the way, if you specify order, it is no longer a relation, if I'm not mistaken.

Using JavaScript to refresh or retrieve current information on button click

I'll preface this with I'm still new to JavaScript. So problem is in a larger application, our controller is passing in a list of information to the view where certain JavaScript functions rely on certain ViewModel properties. I've written a simple application to hopefully illustrate what I'm getting at.
Below is a sample controller that's passing in List to the Index page:
public ActionResult Index() {
List<int> activeIds = new List<int>();
SqlConnection sqlConn = new SqlConnection(connection_String);
sqlConn.Open();
string sqlStr = "SELECT * FROM dbo.[JS-Test] WHERE Active = 1";
SqlCommand sqlCmd = new SqlCommand(sqlStr, sqlConn);
SqlDataReader sqlDR = sqlCmd.ExecuteReader();
if(sqlDR.HasRows) {
while (sqlDR.Read()) {
activeIds.Add((int)sqlDR["ID"]);
}
}
sqlDR.Close();
sqlCmd.Dispose();
sqlConn.Close();
return View(activeIds);
}
This returns the current "active" items in the database. The (rough) view is as follows...
#model List<int>
#{
ViewBag.Title = "Index";
}
<p>Current Recognized Count: #Model.Count() </p>
Print
<script>
$(document).ready(function () {
$('#printBtn').click(function () {
var numberOfActiveIds = #Model.Count();
$.ajax({
type: "POST",
url: "/Home/PostResults",
data: { ids: numberOfActiveIds},
success: function (results) {
if(results == "Success") {
window.location.href = '/Home/Results';
}
}
});
});
});
</script>
The issue is getting the current number of active items from the database when the button is clicked. Let's say that the user remains idle on the page after it loads for a few minutes. When their page originally loaded, the model returned 5 items listed as active... but while they've been waiting 3 additional items were switched to active in the database for a total of 8. However, when the user finally clicks the button it'll submit 5 items instead of the current 8.
I'm unable to run the query to get the current number of active items in the "/Home/PostResults" ActionResult due to the nature of how the larger application is set up. Is there a way I could refresh the page (getting the updated model) before the rest of the function carries out using values of the refreshed model?
If you have any additional questions, please let me know and I will gladly comply. I've looked at other questions and answers on SO but I haven't found one that quite works for my situation. Thanks!
Edit #1
So, I've added this function to the Home controller which just returns the list count as Json.
public ActionResult GetIds(){
List<int> activeIds = new List<int>();
SqlConnection sqlConn = new SqlConnection(connection_String);
sqlConn.Open();
string sqlStr = "SELECT * FROM dbo.[JS-Test] WHERE Active = 1";
SqlCommand sqlCmd = new SqlCommand(sqlStr, sqlConn);
SqlDataReader sqlDR = sqlCmd.ExecuteReader();
if (sqlDR.HasRows) {
while (sqlDR.Read()) {
activeIds.Add((int)sqlDR["ID"]);
}
}
sqlDR.Close();
sqlCmd.Dispose();
sqlConn.Close();
return Json(activeIds.Count());
}
The view script now looks like this...
<script>
$(document).ready(function () {
$('#printBtn').click(function () {
var numberOfActiveIds = #Model.Count();
$.ajax({
type: "GET",
url: "/Home/GetIds",
success: function(response) {
numberOfActiveIds = response;
$.ajax({
type: "POST",
url: "/Home/PostResults",
data: { ids: numberOfActiveIds},
success: function (results) {
if(results == "Success") {
window.location.href = '/Home/Results';
}
}
});
}
});
});
});
</script>
I'm currently getting the following error...
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
Edit #2
I had to set the JsonRequestBehavior to AllowGet for it to work properly. Thanks again, everyone!
gforce301 mentioned to GET the current actives via an ajax call to an additional, separate method making the query to the database and THEN ajax post the returned "actives". Is that possible?
Yes this is possible. That's why I mentioned it. Irregardless of other peoples opinions on how they think you should do this, I understand that you may be limited on why you can't do it their way even if they don't.
The code below is a restructuring of your code. It chains 2 ajax calls together, with the second one depending on the success of the first. Notice the comment block in the success handler of the first ajax call. Since I don't know what the response will be, I can't fill in the part on how to use it. This accomplishes your goal of having the user only make a single button click.
<script>
$(document).ready(function () {
$('#printBtn').click(function () {
var numberOfActiveIds = #Model.Count();
$.ajax({
type: 'GET',
url: '/path/to/get/activeIds',
success: function(response) {
/*
Since I don't know the structure of response
I have to just explain.
use response to populate numberOfActiveIds
now we just make our post ajax request.
*/
$.ajax({
type: "POST",
url: "/Home/PostResults",
data: { ids: numberOfActiveIds},
success: function (results) {
if(results == "Success") {
window.location.href = '/Home/Results';
}
}
});
}
});
});
});
</script>
I can give you an idea, i hope it can help,
run another ajax 1st on btnclick to get the data(or datat count) again, if the record count is greater then current then update the view and don't PostResults and if its same then just PostResults
on ajax success you can reload the data or view
and on failure(when no new record) just do PostResults

Updating table with Ajax

I have a data table that I am trying to append rows to when there is new data to display. I'm relatively inexperienced so I took the easy way out on this and wanted to write a script that checked the database for updates every second instead of listening for server-sent events. I tried to write an Ajax query that would get all the objects in the data table, and if their 6th value is false (which means they have not been loaded), then it would add a row to my data table with that information. My tables are in a Django webapp, and here's the code I have tried to implement:
<script type="text/javascript">
$(document).ready(function(){
var table = $('#example').DataTable();
setInterval(function(){
newrequests = $.ajax({
type: "GET",
url: "/main/newrequests/",
// I tried this and it didn't work
// success: function(data) {
// for(i = 0; i < data.length; i++){
// // check if the request has been loaded
// if(data[i][5] == 0)
// // if not, load and set to loaded
// table.row.add(data[i]).draw;
// data[i][5] == 1;
// }
// }
});
for(i=0; i<newrequests.length; i++){
if (newrequests[i][5] == 0){
table.row.add(newrequests[i]).draw();
newrequests[i][5] = 1;
}
}
}, 1000)
});
</script>
I have a view set up for /main/newrequests which simply all the objects in the database:
def newrequests(request):
return HttpResponse(Request.objects.all())
When I update the database, the data table does not refresh. Does anyone know what I am doing wrong? I feel like it might be how I am trying to use Ajax.
Datatable already has an option for that:
var table = $('#example').DataTable({
"ajax": '/main/newrequests'
});
setInterval(function () {
table.ajax.reload();
}, 30000 );
https://datatables.net/examples/data_sources/ajax.html
https://datatables.net/reference/api/ajax.reload()

Fetch number of rows using javascript

I'm trying to fetch number of rows that were not in another table and show them using javascript.
First, in the main page, it will list the inbox name from inboxtb table. Then I have a script that should pass the value (inboxid) to another file and return the number of result back to the main file, in its corresponding row.
I'll fetch first all the inbox row (main page):
while($stmt->fetch()){
echo '<li>'.$name.' <span id="loadnumber"></span></li>';
}
Then my script:
$(function(){
$('.loadmessage').ready(function(){
var elem = $(this);
var dataString = "inboxid="+elem.attr('data-artid');
var $parent = $(this).closest('loadmessage');
setInterval(function() {
$.ajax({
type: "GET",
url: "noofres.php",
data: dataString,
success: function(data) {
var $span = $parent.find('.loadnumber'); /* FIND THE CORRESPONDING SPAN */
$span.append(data); /* LOAD THE DATA INSIDE THE SPAN */
}
});
});
return false;
});
});
And my noofres.php:
if($stmt = $con->prepare("SELECT a.messageid FROM messagetb a LEFT JOIN readtb b ON a.messageid = b.messageid WHERE a.inboxid = ? AND b.readid IS NULL")){
$stmt->bind_param("i",$_GET["inboxid"]);
$stmt->execute();
$stmt->store_result();
$noofunreadmessages = $stmt->num_rows;
$stmt->close();
} /* END OF SECOND PREPARED STATEMENT */
echo '<span class="badges">'.$noofunreadmessages.'</span>';
But it doesn't return the numbers, where it should. What am I doing wrong? Or a better script to do it?
Very rough example output:
Person1 Message - 3
Person2 Message - 1
Person3 Message - 10
But my current output is:
Person1 Message
Person2 Message
Person3 Message
Number does not return the corresponding number at all. And error are showing up and continuously growing with this message.
Your code is incorrect in terms of logic.
You are executing AJAX once and receiving the value once as well.
Then, you update your element's HTML many times with the same one value.
$.ajax({}, {
success: function(data) {
setInterval(function() {
$('#loadunreadmessages').html(data);
}, 1000);
}
});
In order to get fresh values every time, you need to change it such way that it will execute AJAX many times and every time it will update value once. It sounds logical.
setInterval(function() {
$.ajax({}, {
success: function(data) {
$('#loadunreadmessages').html(data);
}
});
}, 1000);
In your case it is:
setInterval(function() { /* EVERY SECOND, IT EXECUTES NEW REQUEST TO GET FRESH VALUES */
$.ajax({
type: "GET",
url: "../fetch/noofres.php", /* THIS IS WHERE THE NUMBER OF UNREAD MESSAGES SHOULD COME FROM */
data: dataString,
success: function(data) {
$('#loadunreadmessages').html(data); /* LOAD THE NUMBER TO THIS SPAN WITH THE ID OF loadunreadmessages */
}
}) ;
}, 1000);

Categories