背景 我有一个包含小部件的小型jquery应用程序。这个应用程序有两种类型的小部件,它们是计数器小部件和网格小部件。对于网格小部件,我正在使用dataTables。
我的应用程序基本上连接到服务器并接收各种信息,例如小部件名称和计数器和网格小部件的值。因此,根据收到的信息,我为每个小部件动态创建页面。目前情况正常,但我遇到了一个小问题。
问题 我现在的问题是使用我的网格小部件,它使用dataTables api。从我的服务器,我收到这种格式的网格信息。
**//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>
*/**
然后我解析它并将其插入表中。问题是我每3秒做一次更新,因为网格数据实时更新。因此,当我进行更新时,我的搜索过滤器和排序会重置。
因此,例如下面,如果我按最高分排序
PLAYER POINTS
KING JAMES 45
DERRICK ROSE 30
UPDATE HAPPENS AND MY SORTING WILL GET REST TO THIS
PLAYER POINTS
DERRICK ROSE 30
KING JAMES 45
我的HTML代码
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="generator" content="HTML Tidy for Windows (vers 14 February 2006), see www.w3.org" />
<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" type="text/css" />
<link rel="stylesheet" href="themes/jquery.mobile.icons.min.css" type="text/css" />
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.0/jquery.mobile.structure-1.4.0.min.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="cssfinal/style.css" />
<script src="http://code.jquery.com/jquery-1.10.2.min.js" type="text/javascript"></script>
<script src="http://code.jquery.com/mobile/1.4.0/jquery.mobile-1.4.0.min.js" type="text/javascript"></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" type="text/javascript"></script>
<script src="jquery.ui.touch-punch.min.js" type="text/javascript"></script>
<!-- MAIN JS SCRIPT CONTANS CODE FOR COUTNER WIDGETS, TABLES , AJAX REQUEST FOR GETTING DATA-->
<script src="dynamic.js" type="text/javascript"></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="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><!-- 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</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();
});
$(document).on('pagecreate', '#page1', function () {
$("#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) {
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);
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) {
//Header FOR grid Widget Page
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 {
//Header For Counter Widget Page
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'>";
}
//Footer for all Widget Pages
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) {
//Grid Page widget title
var check = "<div data-role='tbcontent'><ul data-role='listview'data-insert='true'><li data-role='list-divider' data-theme='a'>" + widgetNames[i] + "";
}
//Counter Page widget title
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) {
//Counter Content (actual value of the counter widget)
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) {
//Grid content(actual values for the grid widget)
widgetPart[i] = '<DIV id=widgetContainer_' + widgetId[i] + '></DIV><SCRIPT>' + 'function UpdateWidgetDiv' + widgetId[i] + '() {' + testwidget[i] + '}' + '</SCRIPT>';
} else {
//Miscalenous content(these are counter widgets that will contain text messages for now just putting "i dont know what i am")
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;
}
}
eval(testwidget[idx]);
$("#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) {
//alert(updateLines[i]);
// updateFunctionCode = " try { ";
var updateURL = updateLines[i];
if (updateURL.indexOf("&windowWidth=") > 0) {
updateURL = updateURL.substr(0, updateURL.lastIndexOf("&windowWidth=")) + "';";
//console.log(updateURL);
}
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) {
//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 James</cell>
<cell>Injured</cell>
<cell>25 </cell>
</row>
</rows>
*/
console.log(serverXML);
//PARSE THE ABOVE XML STRING to required FORMAT
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;
}
请告知如何解决这个问题我已经坚持了一个星期现在几乎我很抱歉,如果这个问题很糟糕,因为我只有几个月新的js和html和web开发一般。我也为我可怜的英语道歉。
EZ更新的代码
查看以//EZ
开头的评论:
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;
}
}
eval(testwidget[idx]);
if (counterValue == false) {
//EZ: no need to recreate datatable
return;
} else {
$("#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 createTableStringFromXML(serverXML, thisWidgetID) {
//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 James</cell>
<cell>Injured</cell>
<cell>25 </cell>
</row>
</rows>
*/
console.log(serverXML);
//PARSE THE ABOVE XML STRING to required FORMAT
var xmlLines = serverXML.split("\n");
var returnTable = "";
//EZ: See if table already exists
if ( $("#grid_" + thisWidgetID).length > 0){
//EZ: update table using the datatables API...
//EZ: then return false
return false;
} else {
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;
}
答案 0 :(得分:2)
Datatables有一个丰富的api(http://datatables.net/api),可以在保持排序的同时添加,删除和更新行。在您的情况下,新数据可能需要删除不再存在于XML中的行,更新现有行,以及添加XML中但不在表中的新行。
最简单的方法可能是调用fnClearTable删除所有当前行并使用fnAddData添加XML中的所有行:
var oTable = $('#example').dataTable();
oTable.fnClearTable();
$xml.find("row").each(function(index){
var $cells = $(this).find("cell");
var c1 = $cells.eq(0).text();
var c2 = $cells.eq(1).text();
var c3 = $cells.eq(2).text();
oTable.fnAddData( [c1, c2, c3]);
});
<强> DEMO 强>