BACKGROUND: I have a small jquery app that contains widgets. There are 2 types of widgets in this app and they are counter widgets and grid widgets. For grid widgets i am utilizing dataTables.
My app basically connects to a server and recieves various information such as widget names etc. So based on the information received i dynamically create pages for each widget. Things are working fine at the moment but i am facing a little problem.
Problem The issue i have right now is to do with my grid widgets which utilize dataTables api.From my server I receive the grid information in this format.
//EXAMPLE INPUT
/*
<?xml version="1.0" encoding="UTF-8"?>
<rows>
<head>
<column width="55" type="ro" align="left" sort="str">Player</column>
<column width="55" type="ro" align="left" sort="str">State</column>
<column width="55" type="ro" align="left" sort="str">Points</column>
</head>
<row id="1">
<cell>Lebron King James</cell>
<cell>Best Mode</cell>
<cell>45</cell>
</row>
</rows>
*/
Then i parse it to the appropriate table format (function createTableStringFromXML) so it works with the datatables.
My table is reloading every 3 seconds. So this is the problem.
Eventhough i want my table to update i think reloading the entire table is bad because not only does it look weird but i think it is not necessary. I was wondering is there way i can write some function that compares the old table with the new updated table and only updates rows that need update? So this way the entire table it self is not loaded?
MY HTML CODE
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>NBA Fanatico</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="themes/tdMobile.min.css" />
<link rel="stylesheet" href="themes/jquery.mobile.icons.min.css" />
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.0/jquery.mobile.structure-1.4.0.min.css" />
<link rel="stylesheet" type="text/css" href="cssfinal/style.css" />
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.js"></script>
<script src="dhtmxSuite/dhtmlxWindows/codebase/dhtmlxcommon.js" type="text/javascript"></script>
<script src="http://code.jquery.com/ui/1.10.3/jquery-ui.min.js"></script>
<script src="jquery.ui.touch-punch.min.js"></script>
<!-- MAIN JS SCRIPT CONTANS CODE FOR COUTNER WIDGETS, TABLES , AJAX REQUEST FOR GETTING DATA-->
<script src="dynamic.js"></script>
<!-- SCRIPTS FOR DATA TABLES -->
<!-- DataTables CSS -->
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/css/jquery.dataTables.css" />
<!-- DataTables -->
<script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.4/jquery.dataTables.min.js"></script>
</head>
<body>
<!-- PAGE 1 -->
<div data-role="page" data-theme="a" id="page1">
<!-- <div data-role="header" data-position="fixed">
<h1></h1>
</div> -->
<div data-role="content" data-theme="a">
<div class="login-box" id="login">
<div id="loginprompt">
<div id="header">
<h3>Basketball Fanatico</h3>
</div>
</div>
<form method="GET">
<div id="username" data-role="fieldcontain">
<input type="text" name="username" placeholder="Username" />
</div>
<div id="password" data-role="fieldcontain">
<input type="password" name="password" id="txtId" placeholder="Password"/>
</div>
<div id ="loginbtn">
<a data-role="button" id="log" data-theme="a" href="#page2" data-transition="slide">LOGIN</a>
</div>
</form>
<br />
</div>
</div>
</div>
</div>
<!-- PAGE 2 -->
<div data-role="page" id="page2">
<div data-role ="header" data-position="fixed" data-theme="a">
<a data-iconpos="notext" href="#panel" data-role="button" data-icon="bars"></a>
<h1 class="ui-title" role="heading">Basketball Fanatico</h1>
<div class="ui-btn-right" data-type="horizontal">
<a data-iconpos="notext" href="#page2" data-role="button" data-icon="home" ></a>
<a data-iconpos="notext" href="#page1" data-role="button" data-icon="delete" ></a>
</div>
</div>
<div data-role="content" id="page2content">
<ul data-role="listview" data-inset="true">
<li data-role="list-divider" data-theme="a">WELCOME!</li>
<li>Use the menu on the left to navigate <br />and configure the various options.</li>
</ul>
</div>
</div>
<div data-role="panel" id="panel" data-position="left" data-theme="a" data-display="push">
<!-- <div> -->
<div id="nav"><h3>Navigation</h3>
<hr>
<label>
<input id="chkSort" type="checkbox" checked="true" />Allow sorting</input>
</label>
<hr>
</div>
<div id="items" data-role="button">
<!-- Insert Parsed Widget Names Here -->
<a href="#page1" data-transition="fade" data-theme="a" data-role="button">LOG OUT</a>
</div>
<!-- </div> -->
</div>
</body>
</html>
MY JS
var widgetNames = new Array();
var widgetId = new Array();
var pageId = ''
$( document ).on( "pagecreate", function() {
$( "body > [data-role='panel']" ).panel().enhanceWithin();
//Format the grid as required
$('#example2').dataTable( {
"bPaginate": false,
"bFilter": true,
"bAutoWidth": false,
"oLanguage": { "sSearch": "" }
} );
$('.dataTables_filter input').attr("placeholder", "Search");
$('.dataTables_filter').css('float','none');
$('.dataTables_filter').css('padding-right','0px');
$("#example_filter").detach().prependTo('#header1');
});
$(document).on('pagecreate', '#page1', function() {
// $( ":mobile-pagecontainer" ).on( "pagecontainershow", function( event, ui ) {
// pageId = $('body').pagecontainer('getActivePage').prop("id");
// alert( "The page id of this page is: " + pageId );
// });
$("#log").on('click', function(){
$.ajax({
url: "script.login",
type: "GET",
data: { 'page':'create_user', 'access':'user','username':$("input[name='username']").val(), 'password':$("input[name='password']").val()},
dataType: "text",
success: function (html) {
//console.log(html);
widgetNames = new Array();
widgetId = new Array();
var res = html.match(/insertNewChild(.*);/g);
//Get each widget name and ID and assign to values in an array
for(var i =0;i<res.length;i++){
//alert(res[i]);
var temp = res[i].split(',');
if(temp.length >= 3){
widgetNames[i] = (temp[2].replace('");','')).replace('"','');
widgetId[i] = temp[1].replace("'","").replace("'","").replace(/ /g,'');
}
}
var AllWidgets = ''
var testwidget = new Array();
//Loop through the html returned and get the data relevant to each widget... save in temp array
var tempWidgetContent = html.match(/w\d+\.isHidden(.*)\(\) == false\)[\s\S]*?catch\(err\)\{ \}/gm);
for(var i =0;i<tempWidgetContent.length;i++){
var widgetContent = tempWidgetContent[i].substring(tempWidgetContent[i].indexOf('{')+1);
//alert(widgetContent);
//This alone handles coutners...
testwidget[i] = widgetContent.replace("site +","");
//replace the code for a grids...
if(testwidget[i].indexOf('grid') > 0){
testwidget[i] = CreateGridUpdateFunction(testwidget[i],i);
}
}
var widgetPart = new Array();
//Assume we have widget names, ids, and loading data in 3 arrays
//Loop through and create the necessary page.
for(var i = 0; i<widgetNames.length; i++){
if(testwidget[i].indexOf('hi') > -1){
// alert('WORKING');
var pageHeaderPart = "<div data-role= 'page' id='"+widgetId[i]+"' data-pageindex='"+i+"' class='dynPageClass'><div data-role='header' id='header1' data-position='fixed' data-theme='a'><a href='#panel' data-icon='bars' data-iconpos='notext' class='ui-btn-left'></a><a href='#' data-icon='search' id='search' data-iconpos='notext' class='ui-btn-left' style='margin-left: 35px'></a><h1>BASKETBALL FANATICO</h1><a href='#page1' data-icon='delete' data-iconpos='notext' class='ui-btn-right'></a><a href='#page2' data-icon='home' data-iconpos='notext' class='ui-btn-right' style='margin-right: 35px;'></a></div><div data-role='content'>";
}
else{
var pageHeaderPart = "<div data-role='page' id='"+widgetId[i]+"' data-pageindex='"+i+"' class='dynPageClass'><div data-role='header'data-position='fixed' data-theme='a'><a data-iconpos='notext' href='#panel' data-role='button'data-icon='bars'></a><h1 class='ui-title'role='heading'>BASKETBALL FANATICO</h1><div class='ui-btn-right' data-type='horizontal'><a data-iconpos='notext' href='#page2' data-role='button'data-icon='home'style=\" margin-right:5px; \"></a><a data-iconpos='notext' href='#page1' data-role='button'data-icon='delete'></a></div></div><div data-role='content'>";
}
var pageFooterPart = "</div><div data-role='footer' data-position='fixed'><span class='ui-title'><div id='navigator'></div></span></div></div>";
if(testwidget[i].indexOf('hi') > -1){
// alert('i am a grid');
var check = "<div data-role='tbcontent'><ul data-role='listview'data-insert='true'><li data-role='list-divider' data-theme='a'>"+widgetNames[i]+"";
}
var check = "<div data-role='content'><ul data-role='listview'data-insert='true'><li data-role='list-divider' data-theme='a'>"+widgetNames[i]+"</div>";
if(testwidget[i].indexOf('counterValue') > 0){
// alert('i am a counter');
widgetPart[i] = '<DIV style=\" text-align: center; background-color:#EDEDED; padding-bottom: auto; font-size: 55pt;\" id=widgetContainer_'+widgetId[i]+'></DIV><SCRIPT>' + 'function UpdateWidgetDiv'+widgetId[i]+'() {' + testwidget[i] + '$(\"#widgetContainer_'+widgetId[i]+'").html(counterValue);' + '}' + '</SCRIPT>';
}
if(testwidget[i].indexOf('hi') > -1){
// alert('i am a grid');
widgetPart[i] = '<DIV id=widgetContainer_'+widgetId[i]+'></DIV><SCRIPT>' + 'function UpdateWidgetDiv'+widgetId[i]+'() {' + testwidget[i] + '}' + '</SCRIPT>';
}
else {
widgetPart[i] = '<DIV style=\" text-align: center; background-color:#EDEDED; padding-bottom: auto; font-size: 55pt;\" id=widgetContainer_'+widgetId[i]+'>I dont know what I am</DIV>';
}
AllWidgets +='<a href="#'+widgetId[i]+'" class="widgetLink" data-theme="b" data-role="button" >'+widgetNames[i]+'</a>';
var makePage = $(pageHeaderPart + check + widgetPart[i] + pageFooterPart);
makePage.appendTo($.mobile.pageContainer);
}
$('#items').prepend(AllWidgets).trigger('create');
//Widget Update Function
function UpdateActivePage(){
//get active page
pageId = $(":mobile-pagecontainer" ).pagecontainer('getActivePage').prop("id");
//figure out index
var idx;
for (var i=0; i<widgetId.length; i++){
if (widgetId[i] == pageId){
idx = i;
break;
}
}
//alert(pageId);
//run your update
//alert("RUNNING:");
eval(testwidget[idx]);
//alert('Updateing active page');
$("#widgetContainer_" + pageId).html(counterValue);
$('#grid_'+idx).dataTable( {
"bPaginate": false,
"bFilter": true,
"bAutoWidth": false,
"oLanguage": { "sSearch": "" }
} );
$('.dataTables_filter input').attr("placeholder", "Search");
$('.dataTables_filter').css('float','none');
$('.dataTables_filter').css('padding-right','0px');
$("#example_filter").detach().prependTo('#header1');
}
function CreateGridUpdateFunction(oldUpdatefunction,thisWidgetID)
{
var updateLines = oldUpdatefunction.split("\n");
var updateFunctionCode = "";
for (var i=0; i<updateLines.length;i++)
{
if(updateLines[i].indexOf(" var url = ") > 0)
{
var updateURL = updateLines[i];
if(updateURL.indexOf("&windowWidth=") > 0){
updateURL = updateURL.substr(0,updateURL.lastIndexOf("&windowWidth=")) + "';";
}
updateFunctionCode += updateURL;
updateFunctionCode += " var loader = dhtmlxAjax.getSync(url);";
updateFunctionCode += " if(loader.xmlDoc.responseText.length > 0){";
updateFunctionCode += " counterValue = createTableStringFromXML(loader.xmlDoc.responseText,"+thisWidgetID+");";
updateFunctionCode += " } ";
}
}
return "var counterValue = \"hi\"; "+updateFunctionCode ;
}
$(":mobile-pagecontainer" ).on( "pagechange", function() { UpdateActivePage(); } )
setInterval(UpdateActivePage, 3000);
}
});
});
});
//Returns a bool indicated if the (space trimmed) string starts with needle.
function startsWith(searchString,searchVal){
var search = searchString.trim();
return search.indexOf(searchVal) >= 0;
}
function createTableStringFromXML(serverXML,thisWidgetID){
console.log(serverXML);
var xmlLines = serverXML.split("\n");
var returnTable = "";
for (var i=0; i<xmlLines.length;i++)
{
if(startsWith(xmlLines[i],"<rows"))
{
returnTable += "<table cellpadding=\"2\" cellspacing=\"2\" border=\"0\" class=\"display\" id=\"grid_"+thisWidgetID+"\" width=\"100%\">";
}
else if(startsWith(xmlLines[i],"</rows>"))
{
returnTable += "</tbody></table>";
}
else if(startsWith(xmlLines[i],"<head>"))
{
returnTable += "<thead><tr>";
}
else if(startsWith(xmlLines[i],"</head>"))
{
returnTable += "</tr></thead><tbody>";
}
else if(startsWith(xmlLines[i],"<column"))
{
returnTable += "<th>"+xmlLines[i].match(/>(.*?)</i)[1]+"</th>";
}
else if(startsWith(xmlLines[i],"<row"))
{
returnTable += "<tr>";
}
else if(startsWith(xmlLines[i],"</row"))
{
returnTable += "</tr>";
}
else if(startsWith(xmlLines[i],"<cell"))
{
returnTable += "<td>"+xmlLines[i].match(/>(.*?)</i)[1]+"</td>";
}
console.log(returnTable);
}
return returnTable ;
}
Please advice on how to achieve this. I am sorry if you have not understood my question so please ask me again. I am only using HTML and JS for couple of months so i am band new to this and that also might be the reason why my question might sound silly to some of you so sorry in advance. I apologize for my poor english please let me know if you dont understand. Thanks.