is there any way to initialize details in jquery datatable? - javascript

I have a problem with jquery datatable details initialization.
I need to get table with opened details after page has loaded.
I have a following code:
function format(d) {
return d;
}
$(document).ready(function () {
$.ajax({
type: "GET",
dataType: "json",
url: "/SHOP/Promotions/GenerateDetailsToJson", //teraz w tym miejscu inicjuję dane do tabel
success: function (result) {
SetDetails(result);
},
error: function () {
alert("Wystąpił nieoczekiwany błąd");
}
})
dt = $('#table').DataTable(
{
"aoColumnDefs": [
{ 'bSortable': false, 'aTargets': [0, 6, 7] }
]
}
);
dt.on('draw', function () {
$.each(detailRows, function (i, id) {
$('#' + id + ' td:first-child').trigger('click');
});
});
$('#table').DataTable();}
var table_length = $('#table tbody tr').length; //HERE iS PROBLEM
var tr = document.getElementsByClassName("details");
for (var i = 0; i < table_length; i++) {
var row = dt.row(tr[i]);
row.child(format(details[i])).show();
}
);
The problem is in last few lines in above code.
These lines need to initialize and open all jquery datatables details but these function do not execute at time and nothing is displayed.
I have have tried to use timeout it better worked but not like as wanted and for couple of refreshing one was with no data
If You know any solution for that, please help.

You must wait for ajax request to complete.
For example:
$(document).ready(function () {
$.ajax({
//...
success: function (result) {
SetDetails(result);
process();
}
});
function process() {
var table_length = $('#table tbody tr').length;
var tr = document.getElementsByClassName("details");
for (var i = 0; i < table_length; i++) {
var row = dt.row(tr[i]);
row.child(format(details[i])).show();
}
}
});

1: try removing the ajax call before the datatable code (maybe there is some error in ajax call which leads to non working of the code below it )
2: in the ajax call , i beleive the url is wrong .
3: is there a setdetails function present , if its not present , then the code will give error
4: try run your code in firefox browser (with firebug on) , try googling about firebug if u do not know about it , but its recommended to use firebug (very helpful)

Try using $.when and .then so that you can wait for your ajax to get complete and then execute the remaining initializations as below:
$.when(
$.ajax({
....
....
})).then(function()
{
dt = $('#table').DataTable(
....
....
});
//Other initializations.
});

Related

Bootstrap popover doesn't appear the first time on hover event using ajax

The appropriate bits of what I tried are here:
$(".popovers").mouseover( function()
{
//var mainTableBody = document.getElementById("subCriteriaTableBody");
var tableRows = document.getElementsByClassName("popoversBlock");
var i = 0, j = 0;
for (i = 0; i < tableRows.length; i++)
{
var labelList = tableRows[i].getElementsByTagName("label");
var tdList = tableRows[i].getElementsByClassName("popovers");
for (j = 0; j < labelList.length; j++)
{
if(labelList[j].parentElement.parentElement.rowIndex == tdList[j].parentElement.rowIndex)
{
attName = $(this).text();
var attributeName = attName.slice(0, -1);
$.ajax({
url:'/diganta/getPopoverValueReassignTaskOfUser.do?attributeName='+attributeName,
type:'post',
dataType: 'json',
success: function(data) {
$('.popovers').attr('data-content', data.PopoverValue);
},
error: function (xhr, ajaxOptions, thrownError) {
alert("Failed! Reason: "+ thrownError);
}
});
break;
}
else
{
continue;
}
}
}
});
When I mouse hover, I see the request get made, but doesn't populate the popover. I don't even see JSP page for the popover first time but second time it's ok get added to the DOM.
Please help me ....
Thanks in advance.
You need to call
$('.popovers').attr('data-content', data.PopoverValue).popover('show');
to show the Popover
Hope it will solve your problem...
Edit
$('#your_lable_id').attr('data-content', data.PopoverValue).popover('show');
If the problem appears at the first time only and it works afterwards, you are probably missing:
$(document).ready(function(){
...
});
Another advice, quoting W3C page:
Popovers are not CSS-only plugins, and must therefore be initialized with jQuery: select the specified element and call the popover() method.

jQuery Find and Replace is Hanging up the browser! Data size too big?

With alot of help from #kalley we have found out that If I comment the following two lines out the LAG is gone!
var $tableContents = $table.find('tbody')
var $html = $('<tbody/>').html(data);
But how do I keep the above but cancel out the LAG ?
MORE INFO:
The code below works but the problem is that the $.GET is causing the browser to hang until the ajax request completes. I need (flow control?) or something that will solve this problem without locking/hanging up the browser until ajax completes the GET request.
The biggest LAG/Lockup/Hang is at $.get("updatetable.php", since the others only return 7 or less (number) values and this one ('updatetable.php') returns alot more (200-300kb). I would like to implement some sort of flow control here or make the script wait like 5 secs before firing the update command for tablesort and before showing the toast message so that ajax has time to GET the $.get("updatetable.php"data I just don't understand why does it lockup the browser as it is getting the data? is it trying to fire the other commands and that's whats causing the LAG?
Here are the STEPS
1.
$.get("getlastupdate.php" Will fire every 10 secs or so to check if the date and time are the same the return data looks like this: 20130812092636 the format is: YYYmmddHHmmss.
2.
if the date and time are not the same as the last GET then $.get("getlastupdate2.php" will trigger and this data will be send back and placed into a toast message and dispalyed to the user $().toastmessage('showNoticeToast', Vinfoo);
3.
before or after the above ($.get("getlastupdate2.php") another GET will fire: $.get('updatetable.php' this will GET the updated table info. and replace the old one with the new info. and then update/resort the table
4.
at the end of it all I want to $.get("ajaxcontrol.php" and this will return a 1 or 2 if the user is logged in then it will be a 2 else it's a 1 and it will destroy the session and log the user out.
<script type="text/javascript" src="tablesorter/jquery-1.10.2.min.js"></script>
<script type="text/javascript" src="tablesorter/final/jquery.tablesorter.js"></script>
<script type="text/javascript" src="tablesorter/final/jquery.tablesorter.widgets.js"></script>
<script type="text/javascript" src="tablesorter/final/toastmessage/jquery.toastmessage-min.js"></script>
<script type="text/javascript" src="tablesorter/qtip/jquery.qtip.min.js"></script>
<script type="text/javascript">
var comper;
function checkSession() {
return $.get("ajaxcontrol.php", function (DblIn) {
console.log('checking for session');
if (DblIn == 1) {
window.location = 'loggedout.php';
}
}).then(updateTable);
}
function checkComper() {
var SvInfo;
var onResponse = function (comperNow) {
if (comper === undefined) {
comper = comperNow;
} else if (comper !== comperNow) {
var Vinfoo;
comper = comperNow;
// returning this $.get will make delay done until this is done.
return $.get("getlastupdate2.php", function (primaryAddType) {
Vinfoo = primaryAddType;
$().toastmessage('showNoticeToast', Vinfoo);
}).then(checkSession);
}
};
$.get('getlastupdate.php').then(onResponse).done(function () {
tid = setTimeout(checkComper, 2000);
});
}
function updateTable() {
return $.get('updatetable.php', function (data) {
console.log('update table');
var $table = $("table.tablesorter");
var $tableContents = $table.find('tbody')
var $html = $('<tbody/>').html(data);
$tableContents.replaceWith('<tbody>' + data + '</tbody>')
//$tableContents.replaceWith($html)
$table.trigger("update", [true]);
var currentUrl = document.getElementById("frmcontent").contentWindow.location.href;
var urls = ['indexTOM.php', 'index1.php'],
frame = document.getElementById('frmcontent').contentDocument;
for (var i = 0; i < urls.length; i++) {
var url = urls[i];
if (frame.location.href.indexOf(url) !== -1) {
frame.location.reload()
}
}
$('[title!=""]').qtip({});
});
};
$(function () {
var tid = setTimeout(checkComper, 2000);
$("#append").click(function (e) {
// We will assume this is a user action
e.preventDefault();
updateTable();
});
// call the tablesorter plugin
$("table.tablesorter").tablesorter({
theme: 'blue',
// hidden filter input/selects will resize the columns, so try to minimize the change
widthFixed: true,
// initialize zebra striping and filter widgets
widgets: ["saveSort", "zebra", "filter"],
headers: {
8: {
sorter: false,
filter: false
}
},
widgetOptions: {
filter_childRows: false,
filter_columnFilters: true,
filter_cssFilter: 'tablesorter-filter',
filter_filteredRow: 'filtered',
filter_formatter: null,
filter_functions: null,
filter_hideFilters: false, // true, (see note in the options section above)
filter_ignoreCase: true,
filter_liveSearch: true,
filter_reset: 'button.reset',
filter_searchDelay: 300,
filter_serversideFiltering: false,
filter_startsWith: false,
filter_useParsedData: false
}
});
// External search
$('button.search').click(function () {
var filters = [],
col = $(this).data('filter-column'), // zero-based index
txt = $(this).data('filter-text'); // text to add to filter
filters[col] = txt;
$.tablesorter.setFilters($('table.hasFilters'), filters, true); // new v2.9
return false;
});
});
</script>
Maybe instead of using setInterval, you should consider switching to setTimeout. It will give you more control over when the time repeats:
function checkComper() {
var SvInfo;
var onResponse = function (comperNow) {
if (comper === undefined) {
comper = comperNow;
} else if (comper !== comperNow) {
var Vinfoo;
comper = comperNow;
// returning this $.get will make delay done until this is done.
return $.get("getlastupdate2.php", function (primaryAddType) {
Vinfoo = primaryAddType;
$().toastmessage('showNoticeToast', Vinfoo);
}).then(checkSession);
}
};
$.get('getlastupdate.php').then(onResponse).done(function () {
tid = setTimeout(checkComper, 10000);
});
}
var tid = setTimeout(checkComper, 10000);
Then you can keep it async: true
Here's a fiddle showing it working using echo.jsontest.com and some fudging numbers.
Since the click event callback seems to be where the issue is, try doing this and see if it removes the lag (I removed other comments to make it more brief):
function checkSession() {
return $.get("ajaxcontrol.php", function (DblIn) {
console.log('checking for session');
if (DblIn == 1) {
window.location = 'loggedout.php';
}
}).then(updateTable);
}
function updateTable() {
return $.get('updatetable.php', function (data) {
console.log('update table');
var $tableContents = $table.find('tbody')
//var $html = $('<tbody/>').html(data);
//$tableContents.replaceWith($html);
// replaceWith text seems to be much faster:
// http://jsperf.com/jquery-html-vs-replacewith/4
$tableContents.replaceWith('<tbody'> + data + '</tbody>');
//$table.trigger("update", [true]);
var currentUrl = document.getElementById("frmcontent").contentWindow.location.href;
var urls = ['indexTOM.php', 'index1.php'],
frame = document.getElementById('frmcontent').contentDocument;
for (var i = 0; i < urls.length; i++) {
var url = urls[i];
if (frame.location.href.indexOf(url) !== -1) {
frame.location.reload()
}
}
$('[title!=""]').qtip({});
});
};
$("#append").click(function (e) {
// We will assume this is a user action
e.preventDefault();
updateTable();
});
I commented out $table.trigger("update", [true]) since if you sort the table on the server before you return it, you shouldn't need to run that, which I'm almost certain is where the bottleneck is.
It is really hard untangle the mess you have but if what you want is ajax requests every 10 seconds it make sense to separate this logic from business logic over data from server.
Your code would also really benefit from using promises. Consider this example
$(document).ready(function() {
var myData = { }
, ajaxPromise = null
setInterval(callServer, 1000)
function callServer() {
ajaxPromise = updateCall()
.then(controlCall)
.done(handler)
.error(errorHandler)
}
function updateCall() {
return $.get('updateTable.php', function(data) {
myData.update = data
})
}
function controlCall( ) {
return $.get('ajaxControl.php', function(data) {
myData.control = data
})
}
function handler() {
console.dir(myData)
}
function errorHandler(err) {
console.log(err)
console.dir(myData)
}
})

getJson after getJson not working

I'm trying to make a request when the button is clicked.
If it is the first time clicking it, I make a getJson to get an array with the IDs for the second request.
The problem is, when it makes the first request, it stops right before the second request, so I have to click again to make the second request.
Here is my script code:
<script type="text/javascript">
$(document).ready(function() {
var IDs = new Array();
var iterator = 0;
// When id with Action is clicked
$("#Action").click(function() {
if(IDs.length <= 0){
// Load generator.php as JSON and assign to the data variable
$.getJSON('generator.php', {tags : "lol"}, function(data) {
IDs = data.value;
});
}
//PAGE STOPS HERE
$.getJSON('imagem.php', {ids : IDs[iterator]}, function(data) {
iterator++;
document.title = "IMG2";
$("#Imagem").html(data.value);
if(iterator > IDs.length-1)
iterator = 0;
});
});
});
</script>
The $.getJson() function is asynchronous. This means that when it executes that bit of code, it continues on with execution. The second call depends on the first one so should be nested in the success callback like this:
$.getJSON('generator.php', {tags : "lol"}, function(data) {
IDs = data.value;
$.getJSON('imagem.php', {ids : IDs[iterator]}, function(data) {
iterator++;
document.title = "IMG2";
$("#Imagem").html(data.value);
if(iterator > IDs.length-1)
iterator = 0;
});
});
From your code visiting, we think -
It is a typical case of ajax call ...
to make the 2nd call after 1st call, you should call the 2nd getjson within 1st getjson callback to make this working - i.e. -
<script type="text/javascript">
$(document).ready(function() {
var IDs = new Array();
var iterator = 0;
// When id with Action is clicked
$("#Action").click(function() {
if(IDs.length <= 0){
// Load generator.php as JSON and assign to the data variable
$.getJSON('generator.php', {tags : "lol"}, function(data) {
IDs = data.value;
$.getJSON('imagem.php', {ids : IDs[iterator]}, function(data) {
iterator++;
document.title = "IMG2";
$("#Imagem").html(data.value);
if(iterator > IDs.length-1)
iterator = 0;
});
});
}
});
});
</script>
I have faced same situation before, for ajax calling in different applications. Hope this help you.
This is because $getJSON is an async event, so both your $getJSON function calls are happening at once, and your second requires results from the first. Please use the success event from jquery: http://api.jquery.com/jQuery.getJSON/
example from the above website:
$.getJSON("example.json", function() {
alert("success");
})
.success(function() { alert("second success"); });
New Code:
<script type="text/javascript">
$(document).ready(function() {
var IDs = new Array();
var iterator = 0;
// When id with Action is clicked
$("#Action").click(function() {
if(IDs.length <= 0){
// Load generator.php as JSON and assign to the data variable
$.getJSON('generator.php', {tags : "lol"}, function(data) {
IDs = data.value;
}).success(function() {
$.getJSON('imagem.php', {ids : IDs[iterator]}, function(data) {
iterator++;
document.title = "IMG2";
$("#Imagem").html(data.value);
if(iterator > IDs.length-1)
iterator = 0;
});
});
}
});
});
</script>

JavaScript/jQuery dynamic function binding and ajax

I'm trying to build out a dynamic list of UI elements. I can hard code the UI list now, and everything works fine. I want this to be extensible however, so I'm trying to figure a way of passing id tags and corresponding functions to be called. Essentially, the callback function for my ajax call isn't being executed, though I am posting the correct data, and receiving the correct response. Here's the code:
myModule = function () {
var titleUI = Object.create(ChainUI());
var memcachedId = '<?php echo $memcachedId;?>';
return {
printChain: function(data) {
alert("printchain");
var territories = jQuery.parseJSON(data);
titleUI.makeChainTable();
territories.forEach(function(territory) {
titleUI.territoryDisplay(territory);
});
titleUI.tableDecorator($('#chainTable'));
},
loadChain: function() {
titleUI.destroyChainTable();
var url = 'traffichandler.php';
var instruction = {'instruction': 'titleChain', 'method': 'printChain', 'memcachedId': memcachedId.toString()};
$.post(url, instruction, this.printChain);
},
loadDefault: function() {
titleUI.loadUI(['Title Chain'], [this.loadChain]);
}
};
}();
The corresponding titleUI code follows:
var ChainUI = function() {
return {
loadUI: function(uiList, funcList) {
$('#uiFunctions').empty();
for(var i in uiList) {
var toDom = '<li id="'+uiList[i]+'">';
toDom += uiList[i];
toDom += '</li>';
$('#uiFunctions').html(toDom);
}
for(var i = 0; i < uiList.length; i++) {
var myFunc = funcList[i];
$('#uiFunctions').delegate($('#'+uiList[i]), "click",
function() {myFunc();}
);
}
},
}
In myModule.loadDefault, I can get this.loadChain to fire. I can't get this.printChain inside the $.post to work though. If remove all the dynamic stuff this.printChain works no problem. Don't get too hung up on the syntax, as is, the syntax is fine on my end. How can I get the ajax call back to work? Thanks!

function executes too soon

I'm stuck with the following problem:
I want a function to create DIV tags to hold images and a second function to create the IMG tag and insert them in the DIVs created before. Works well with "alert messages". However without alerts, the second function runs before the first finished loading the DIV tags.
I think I need some kind of callback function worked in, but I have no clue how to do this.
Here is the code:
function imageLoader ()
{
for (i=1;i<=5;i++)
{
checkPath = 'images/pic'i+'.png';
$.ajax({
url: checkPath,
type:'HEAD',
success:
function() {
//create DIVs t hold images
$('.tools').append("<div class='tooling'></div>");
}
});
}
// after creating DIVs, call function to create <img> tags
appendix();
}
Thanks for helping out.
Regards,
frequent
Since, as Kos pointed out, you can't rely on the calls to complete in order, you'll have to get a little tricky to ensure that all your ajax calls have been completed. Try something like this:
function imageLoader() {
var ajaxCounter = 0;
for (i = 1; i <= 5; i++) {
checkPath = 'images/pic'
i + '.png';
$.ajax({
url: checkPath,
type: 'HEAD',
success: function() {
//create DIVs t hold images
$('.tools').append("<div class='tooling'></div>");
ajaxCounter++;
if (ajaxCounter == 5) {
// after creating DIVs, call function to create <img> tags
appendix();
}
}
});
}
}
That should check to make sure you have the required number of ajax successes before executing the appendix() call.
I can't tell exactly what you're asking, but it looks like maybe you need to move your appendix() call into the success callback. Remember that the success callback may not be executed before the appendix call in the code you presented.
function() {
//create DIVs t hold images
$('.tools').append("<div class='tooling'></div>");
appendix();
}
Of course, you might not want this called 5 times inside your for loop. Here's one way to make it call after the last success occurs, perhaps not the cleanest:
for (i=1;i<=5;i++)
{
if(i == 5) {
var succ = function() {
//create DIVs t hold images
$('.tools').append("<div class='tooling'></div>");
appendix();
};
} else {
var succ = function() {
//create DIVs t hold images
$('.tools').append("<div class='tooling'></div>");
};
}
checkPath = 'images/pic'i+'.png';
$.ajax({
url: checkPath,
type:'HEAD',
success: succ
});
}
a) Create a variable to count how many times the success function callback has executed and run appendix only when this count equals the number of your ajax calls,
b) Register the $.ajaxComplete callback.
The elegant way to do this is to use $.when:
function imageLoader(
$.when.apply($, $.map(new Array(5), function (e, i) {
var checkPath = 'images/pic' + (i + 1) +'.png',
d = $.Deferred();
$.ajax({
url: checkPath,
type:'HEAD',
success: function () {
d.resolve($('<div class="tooling">')
.append($('<img>').attr(src, checkPath)));
},
error: function () { d.resolve(null); }
});
return d.promise();
})
.then(function () {
$('.tools').append(Array.prototype.slice(arguments));
});
}
You could set async to false in $.ajax so it blocks execution.
Or, you could check i in the success callback, and if its 5, call appendix().
function imageLoader ()
{
for (i=1;i<=5;i++)
{
checkPath = 'images/pic'i+'.png';
$.ajax({
url: checkPath,
type:'HEAD',
success:
function() {
//create DIVs t hold images
$('.tools').append("<div class='tooling'></div>",
function(){
appendix();
});
}
});
}
}

Categories