Updating table with Ajax - javascript

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()

Related

Ajax call won't navigate to a new view

I've created an application using codeigniter 3 that gets quizzes stored in the SQL database using a model and populate in the view using ajax and jquery.
Below is the code for populating data inside a div.
$(document).ready(function() {
$.ajax({
url: "/CW2/ASSWDCW2/cw2app/index.php/Leaderboard/quiz",
method: "GET",
dataType: "json"
}).done(function(data) {
$('#modtable tr').remove(); // clear table for new result
var quizzes = data.allQuizzes;
alert(quizzes.length);
var i;
for (i = 0; i < quizzes.length; i++) {
quiz = quizzes[i];
var block = ' <div id="quizMainBox"><h1>' + quiz.quizName + '</h1><br/><h3>' + quiz.creatorName + '<button onclick="myFunction(\''+quiz.quizId+'\')">Try it</button>'+'</h3></div>'
$('#allQuizBox').append(block);
}
});
return false;
// });
});
Below are 3 quizzes populated in the view.
What I want to do is when the user clicks on the "try it " button, I want the user to be directed to the "single_quiz_view" using the quiz id. So I wrote this ajax function (myFunction) below the above code.
function myFunction(quizId) {
// console.log("heyyyy");
// document.getElementById("demo").innerHTML = "Welcome"+quizId ;
$.ajax({
url: "/CW2/ASSWDCW2/cw2app/index.php/Quiz/loadQuiz/",
method: "POST",
}).done(function(data) {
alert("heyyy")
});
return false;
}
where Quiz is the controller name and loadQuiz is the function calling the "single_quiz_view"
//Quiz Controller
public function loadQuiz()
{
// $quizId = $this->uri->segment(3);
$this->load->view('quiz/single_quiz_view');
}
My problem is,
When I click on the "try it button", I get the alertBox inside the done function. I get the status code as 200 but still wont navigate to "single_quiz_view".Console wont give any errors.Please help

jtable single column/field in a table refresh

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);
}

Set form data without creating DOM inputs

I have an empty form tag, and a function which generates 4000 hidden inputs which contains the data to be send by the form.
Generating the 4000 hidden inputs is pretty fast (takes about 4ms). However, the browser freezes for about 1 second when i am appending the hidden inputs in the form tag.
I have also wrapped the hidden inputs in a <div/> tag, but doesn't helps too much.
Is there any way to set the form data programmatically, without using the input DOM elements?
Something like:
$form[0].setData([{ id: 1, value: "A" }, { id: 2, value: "B" }]);
$form.submit();
Here is the function which generates the hidden inputs
function saveUIPositions() {
var $form = $("#saveUIPositionsForm");
$form.empty();
console.time("ui");
var array = [];
array.push("<div>");
var items = dataTable.dataView.getItems();
for (var i = 0, len = items.length; i < len; i++) {
var item = items[i];
var index = dataTable.dataView.getRowById(item.Id) + 1;
array.push("<input type='hidden' name='[");
array.push(i);
array.push("].Item_Id' value='");
array.push(item.Id);
array.push("' />");
array.push("<input type='hidden' name='[");
array.push(i);
array.push("].Index' value='");
array.push(index);
array.push("' />");
}
array.push("</div>");
console.timeEnd("ui");
// here it gets very costly (and not because of array.join())
$form.append(array.join(""));
$form.submit();
};
Maybe you can send this data using ajax ? If so you will not have to generate and append your 4K hidden inputs to the DOM.
If ajax is not an option, can you give us the code generating and appending your inputs ? Maybe it can be optmized.
I wrote a small jsFiddle (open your debug console to see time informations)
to illustrate the difference between a generate then append all solution:
for(var i=0; i<4000; i++)
inputs += '<input type="hidden" value="' + i + '"/>'
$('form').append(inputs);
and generate and append each:
for(var i=0; i<4000; i++)
$form.append('<input type="hidden" value="' + i + '"/>');
You don't even really need a form element when working in just Javascript, data can be sent to your server with an ajax request.
$.ajax({
url: "myScript.php", //The script on your server that deals with the data
data: {
dataA: "a",
dataB: "b",
dataC: "c" //Your form input name and value key pairs
},
success: function(data){
alert("Form Submitted, Server Responded:"+data); //The server response
},
error: function(data){
alert("Error contacting server:"+data); //Error handler
}
});
You don't even need to reload the page when the form is submitted. Unless you want to, then just add:
location.href="http://link.com";
to the success callback.
You don't need to add the inputs to the DOM, you could create an array of the data an post the form via ajax e.g.
inputNames = 'YourInputNameHere'; // Could be an array of names
generatedData = arrrayOfData //presumably generated elsewhere
for (i=0;i<400;i++) {
formData[inputName][i] = generatedData[i]
// if you are using an array of names you want to change the above line to
// formData[inputName[i]] = generatedData[i]
}
$('body').on('submit', '#myForm', function(e) {
e.preventDefault();
postUrl = 'url/to/send/data';
// get any other use inputs that might have been taken from user ignore
// this line if there are no inputs
formData[] = $(this).serialize();
$.ajax(
{
url: postUrl,
type: 'POST',
data: formData,
dataType: 'html',
success: function( data )
{
// redirect, post message whatever
}
}
)
});
Hope this helps and makes sense.

Sending PHP Array to jQuery with $.post() and then looping through those values

I'm sending an array to jQuery and then looping through those values and displaying them, but I can get it to work right. Can someone point me in the right direction -
PHP - the only part that matters on it - echo json_encode($tR);
jQuery -
$(document).on('click', '.chooseStat', function(){
var id = $(this).attr('id');
$.post('chooseStat.php', {id:id}, function(data){
console.log(data);
var open = '';
for(var i = 0; i < data.length; i++) {
if (i % 2 == 0) {
open+="<tr class='alt'>";
open+="<td>"+data[i]+"</td>";
open+="<td>"+data[i]+"</td>";
open+="<td>"+data[i]+"</td>";
open+="</tr>";
}
else {
open+="<tr>";
open+="<td>"+data[i]+"</td>";
open+="<td>"+data[i]+"</td>";
open+="<td>"+data[i]+"</td>";
open+="</tr>";
}
}
$('#statDisplayBody').html(open);
});
});
Heres what the array looks like when it gets sent to the jQuery script -
http://prntscr.com/24wa68
Heres what it looks like when I try to display them with the method in the script I have -
http://prntscr.com/24wadk
My new jquery -
$(document).on('click', '.chooseStat', function(){
var id = $(this).attr('id');
$.post('chooseStat.php', {id:id}, function(data){
console.log(data);
var open = '<th>Rank</th><th>Username</th><th>Stat</th>';
for(var i = 0; i < data.length; i++) {
if (i % 2 == 0) {
open+="<tr class='alt'>";
open+="<td>"+data[i]["rank"]+"</td>";
open+="<td>"+data[i]["username"]+"</td>";
open+="<td>"+data[i]["score"]+"</td>";
open+="</tr>";
}
else {
open+="<tr>";
open+="<td>"+data[i]["rank"]+"</td>";
open+="<td>"+data[i]["username"]+"</td>";
open+="<td>"+data[i]["score"]+"</td>";
open+="</tr>";
}
}
$('#statDisplayBody').html(open);
}, "json");
});
And that returns a proper array now, but the way I'm looping through apparently doesn't seem to be working because now this is happening - http://prntscr.com/24wcuz (its only displaying the last row of the array).
You need to properly parse it in JavaScript. This can either be done via data = JSON.parse(data); or since you are already using $.post like the following (see jQuery API, Example 7)
$.post('chooseStat.php', {id:id}, function(data){
//code
}, "json");

Cyclo for with inside ajax, the callback return a wrong result

I tried to create a jquery plugIn that load multiple feed rss (they are flexible can be 1 or 2 or 3 ect...), for create an html that show the news feed loaded. My target is having the possibility to load multiple rss feed (xml) and display them by html. When I tried seem that the callback is overwrite,I received 2 results but equal.
Example:
(function($){
$.fn.getFeed = function(Obj){
var
arrOpt = Obj.arrayOptions,
arrOptLng = arrOpt.length;
for(var i = 0; i < arrOptLng; i++){
var
index = i,
Opt = arrOpt[i],
feedUrl = Opt.feed,
sucFnc = Opt.callback,
$cnt = this;
console.log(index);
// here:
// 0
// 1
$.ajax({
url:feedUrl,
dataType: "jsonp",
success:function(data){
sucFnc(data,$cnt,Opt,index);
},
error:function(){
$cnt.html('error');
}
});
}
}
})(jQuery);
function feedManipulation(){
console.log(index)
// here:
// 1
// 1
}
/* DOM LOADED */
$(function(){
$('.news').getFeed({ // Activation getFeed
arrayOptions:[{
feed:'http://feed',
callback:feedManipulation,
imgDefault:'http://img',
nArtc:1
},{
feed:'http://feed',
callback:feedManipulation,
imgDefault:'http://img',
nArtc:1
}]
});
});
Ciao, I wrote this question and I created the solution so I would explain.
In this code I removed the cyclo for and I create a function that contain the ajax call.
The first time that I trigger the ajax function I pass an argument to the ajax function with inside an object that I used to set the plugIn (lock on the bottom) whereas my ajax function is itself calls, before sending the same object to the ajax function I change some information like "Opt.index" creating in this way a ajax cyclo. Is it really usefull ;) use it.
(function($){
$.fn.getFeed = function(Obj){
// Options object
Opt = new Object();
Opt.index = 0;
Opt.$cnt = this;
Opt.arrOpts = Obj.arrayOptions;
Opt.arrOptLng = Opt.arrOpts.length;
Opt.arrOpt = Opt.arrOpts[Opt.index];
Opt.feedUrl = Opt.arrOpts[Opt.index].feedUrl;
// ajax call
cycloAjax(Opt);
}
/* ajax cyclo */
function cycloAjax(Obj){
$.ajax({
url: Obj.feedUrl,
dataType: "jsonp",
success:function(data){
feedManipulation(data,Obj.$cnt,Obj);
if(Obj.index < Obj.arrOptLng - 1){
Obj.index++;
Obj.arrOpt = Obj.arrOpts[Obj.index];
Obj.feedUrl = Obj.arrOpts[Obj.index].feedUrl;
cycloAjax(Obj);
}
else{
completeLoadFeeds(Obj.$cnt,Obj);
}
},
error:function(){
Obj.$cnt.html('<p>error</p>');
}
});
}
.
.
.
})(jQuery);
/* DOM LOADED */
$(function(){
$('.news').getFeed({ // Activation getFeed
arrayOptions:[{
feed:'http://feed',
callback:feedManipulation,
imgDefault:'http://img',
nArtc:1
},{
feed:'http://feed',
callback:feedManipulation,
imgDefault:'http://img',
nArtc:1
}]
});
});

Categories