javascript - 刷新表后排序和搜索数据表

标签 javascript jquery html datatables

背景: 我有一个包含小部件的小型 jquery 应用程序。此应用程序中有 2 种类型的小部件,它们是计数器小部件和网格小部件。对于网格小部件,我正在使用 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>

我的 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;
}

最佳答案

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

关于javascript - 刷新表后排序和搜索数据表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22938579/

相关文章:

javascript - Bootstrap Datepicker 使用 Ajax 加载最大和最小日期

javascript - 获取复选框值并显示它们

php - JQUERY - PHP - MySQL - 添加结果数组,添加更多信息

html - CSS 可以否决 HTML 输入大小声明

html - 位置固定时过渡不起作用

javascript - 如何从外部范围解析和分配内部 Controller ?

javascript - 多对象 knockout 映射

javascript - 跨域 ajax 请求成功事件不会触发

javascript - 简单的移动 jQuery 切换按钮和 .toggle 最新 jQuery 的替代品

iphone - iPhone 的字体大小问题