【问题标题】:Client side scripting for DataTables Server Side ScriptingDataTables 服务器端脚本的客户端脚本
【发布时间】:2012-05-15 12:25:52
【问题描述】:

我正在为 DataTables 的服务器端处理编写代码。我有一个 UI 页面,在其中收集所有用户输入,例如开始/结束日期、令牌 ID、批处理 ID 等。现在我必须将这些值传递给后端脚本并运行查询并将输出呈现到 UI 页面中的数据表。

所以我有 JS 代码来获取和验证用户输入,但我不确定如何调用/设置数据表的参数以声明服务器端脚本。以下是我的脚本:

function runreport(datastring)
{
       var oTable = $('#example').dataTable( {
                "bProcessing": true,
                "bServerSide": true,
                "sAjaxSource": "runsearch.py",
                "bDestroy" : true,
                "fnServerData": function ( sSource, aoData, fnCallback ) {
                        $.ajax( {
                                        "dataType": 'json',
                                        "type": "POST",
                                        "url": sSource,
                                        "data": aoData,
                                        "success": function(json) {
                                                $("div#report_result").show();
                                                $('html, body').animate({scrollTop:$(document).height()}, 'slow');
                                                fnCallback(json);
                                        }
                                } );
                 }
        } );
}

我在验证所有输入参数后调用“runreport”方法。我像查询字符串一样构造数据字符串: token_id=xxxx&email_id=asdsad@jj.com&start_date=1212121212&end_date=98989898 但这些值没有通过?我收到以下错误:

k is undefined
[Break On This Error]  

...Sorting=="undefined"&&typeof e.saved_aaSorting=="undefined")e.aaSorting[a][1]=k....

jquery....min.js (line 150)

我们应该怎么做才能让后端脚本生成 DataTables 结果?

我没有得到想要的结果输出?这是为服务器端进程调用 DataTables 功能的正确方法吗?

下面是我转储静态结果集的 Python 代码:

#!/usr/local/bin/python

import cgi
import MySQLdb
import json

print "Content-Type: application/json"
print

displaylength =5
result = {'iDisplayLength':str(displaylength), 'sPaginationType':'full_numbers', 'bProcessing':1, 'bDestroy': 1, 'bRetrieve':1, 'aaData':[{'First Field':'First Field Value', 'Second Field':'Second Field Value', 'Third Field':'Third Field Value', 'Fourth Field':'Fourth Field Value', 'Fifth Field':'Fifth Field Value', 'Sixth Field':'Sixth Field Value', 'Seventh Field':'Seventh Field Value', 'Eight Field':'Eight Field Value', 'Nineth Field':'Nineth Field Value'}, {'First Field':'First Field Value', 'Second Field':'Second Field Value', 'Third Field':'Third Field Value', 'Fourth Field':'Fourth Field Value', 'Fifth Field':'Fifth Field Value', 'Sixth Field':'Sixth Field Value', 'Seventh Field':'Seventh Field Value', 'Eight Field':'Eight Field Value', 'Nineth Field':'Nineth Field Value'}], 'aoColumns':[{'sTitle':'First Field', 'mDataProp': 'First Field'},{ 'sTitle':'Second Field', 'mDataProp': 'Second Field'}, {'sTitle':'Third Field', 'mDataProp': 'Third Field' }, { 'sTitle':'Fourth Field', 'mDataProp': 'Fourth Field' }, { 'sTitle':'Fifth Field' , 'mDataProp': 'Fifth Field' }, { 'sTitle':'Sixth Field', 'mDataProp': 'Sixth Field' }, { 'sTitle':'Seventh Field', 'mDataProp': 'Seventh Field' }, { 'sTitle':'Eight Field', 'mDataProp': 'Eight Field' }, { 'sTitle':'Nineth Field', 'mDataProp': 'Nineth Field' }]}

json_string = json.dumps(result)
print json_string

【问题讨论】:

    标签: javascript python datatables


    【解决方案1】:

    有多种方法可以做到这一点。 DataTables 支持AJAX source,因此您可以编写一个脚本来输出一个 json 数组并将其传递给 DataTables 插件。您也可以只从 PHP 渲染表格。

    我会查看其中的一些 examples 以了解可以将数据传递到 DataTables 的其他方式。

    【讨论】:

    • datatables.net/usage/#data_sources 是的,我想使用服务器端处理,想知道我的脚本有什么问题?
    • 您用什么语言编写服务器端脚本?请也分享该代码。如果我看不到代码,我不会知道问题出在哪里。
    【解决方案2】:

    aoData.push 是您正在寻找的。将此用于您的 fnServerData 回调,将 aoData.push 中的名称和值替换为您要传递的值。名称将是键,值将是值,作为 $_REQUEST 变量传递:

    "fnServerData": function ( sSource, aoData, fnCallback ) {
            aoData.push({ "name": "var1name", "value": $('#var1').val() },
                        { "var2name": "company_name", "value": $('#var2').val() });
    
            $.ajax({
                "dataType": 'json',
                "type": "POST",
                "url": sSource,
                "data": aoData,
                "success": fnCallback
             });
    }
    

    要测试它是否正常工作,请让获取 ajax 请求的页面简单地向您发送 $_REQUEST。您应该将这些变量视为其中的一部分。

    回调的一个常见伴侣是添加一个按钮来刷新表格。只需将以下内容绑定到刷新按钮上的单击处理程序即可完成:

    oTable.fnDraw(false);
    

    祝你好运。

    【讨论】:

      【解决方案3】:

      这是我的一些数据表和服务器端/客户端的 C# 代码

      如果你愿意,你可以用它把它翻译成 python,我是从 Alans PHP 例子翻译的

      客户端:

      /* Instantiate the Datatables on the ASP.NET GridView */
      var dt = $('#gvJobs').dataTable({
          "sDom": 'C<"clear">Rlfrtip', /* ColReOrder, ColVis */
          "bFilter": true, /* Use custom filters, i have to revise this as I am doing the drop down filter manually now */
          "bSort": true,
          "bAutoWidth": false,
          "bProcessing": true, /* Needed, Read Datatables documentation */
          "bServerSide": true, /* Needed, Read Datatables documentation */
          "aaSorting": [[0, "desc"]], /* Initial Default Sorting on the First Column */
          "sPaginationType": "full_numbers",
          "fnServerData": function (sSource, aoData, fnCallback) {
              /* Adding Custom Drop Down Filter property to aoData which will be used server side */
              aoData.push({ name: "ddlStatus", value: $("#ddlStatus option:selected").text() });
      
              /*  Here I do the PageMethods call (ASP.NETs Ajax Replacement) PageMethods.getData
              "getData" is a Server Side C# Method which looks like this:
      
              [WebMethod]
              public static string getData(List<oaData> aoData)
              {
              //Method Code
              }
      
              With page methods you pass in all your parameters matching the server side method,
              And right at the end, add your two callback functions for onsuccess and onerror
              */
              PageMethods.getData(aoData, function (obj) {
                  /* On Success, datatables fnCallback with JSON object */
                  fnCallback(JSON.parse(obj));
              }, function (XMLHttpRequest, textStatus, errorThrown) {
                  /* On Error, show error alert */
                  alert(XMLHttpRequest.status + ': ' + XMLHttpRequest.responseText);
              });
          },
          "aoColumns": [
          /*  This (JobNo) my first column which is Custom with 3 Images and a HyperLink to another page,
          The last 5 Columns is hidden from the User because those fields are only used to 
          Render the correct images in this first column, Only used as Eval fields basically
      
          Note that mDataProp is the GridView column's "DataField" and not the "HeaderText"
          */
              { "mDataProp": "JobNo",
                "fnRender": function (oObj) {
                   return "<img src='" + (oObj.aData.HasAttachments ? "css/paperclip-icon.png" : "css/empty-icon.png") + "' height='16px' />"
                          + "<a href='#' onclick=\"gotoJobDetail('" + oObj.aData.JobId + "');\">" + oObj.aData.JobNo + "</a>"
                          + "<img src='" + (oObj.aData.Visited ? "css/yes.png" : "css/no.png") + "' height='16px' />"
                          + "<img src='" + (oObj.aData.Completed ? "css/completed.png" : "css/notcompleted.png") + "' height='16px' />";
                  },
                  "bUseRendered": true /* This renders the Column in HTML first, else you'd see the actual HTML text in the column */
              },
              {    "mDataProp": "JobStatusName" },
              {    "mDataProp": "StatusDateTime" },
              /* Only used as Eval Field for one of the images in the JobNo Column */
              {    "mDataProp": "HasAttachments",
                  "bSearchable": false,
                  "bVisible": false
              },
              /* Only used as Eval Field for one of the images in the JobNo Column */
              {"mDataProp": "Visited",
              "bSearchable": false,
              "bVisible": false
              },
              /* Only used as Eval Field for one of the images in the JobNo Column */
              {"mDataProp": "Completed",
              "bSearchable": false,
              "bVisible": false
              },
              /* Just Hidden, not used at the moment neither by the user nor the application */
              {"mDataProp": "JobStatusId",
              "bSearchable": false,
              "bVisible": false
              },
              /* Only used as Eval Field for one of the images in the JobNo Column */
              {"mDataProp": "JobId",
              "bSearchable": false,
              "bVisible": false
              }
          ]
      });
      

      服务器端对象

      //INCOMING OBJECT FROM CLIENTSIDE
      public class oaData
      {
          public string name { get; set; }
          public string value { get; set; }
      }
      
      //RETURNING OBJECT TO CLIENTSIDE
      public class oaData<T>
      {
          public int sEcho { get; set; }
          public int iTotalRecords { get; set; }
          public int iTotalDisplayRecords { get; set; }
          public T aaData { get; set; }
          public string sColumns { get; set; }
      }
      //THIS IS 'T' IN oaData<T>
      public class JobOverviewDynamic
      {
          public int JobNo { get; set; }
          public string JobStatusName { get; set; }
          public string StatusDateTime { get; set; }
          public bool HasAttachments { get; set; }
          public bool Visited { get; set; }
          public bool Completed { get; set; }
          public int JobStatusId { get; set; }
          public int JobId { get; set; }
      }
      

      填充对象,然后使用 Newtonsoft 库对其进行 JSON 字符串化并返回 这是我的服务器端方法

      [WebMethod]
      public static string getData(List<oaData> aoData)
      {
          /* The Columns array
           * If the array from Parameters is not empty, then use that
           */
          string[] aColumns = { "JobNo", "JobStatusName", "StatusDateTime", "HasAttachments", "Visited", "Completed", "JobStatusId", "JobId" };
          var newCols = aoData.Where(n => n.name == "sColumns").Select(n => n.value).FirstOrDefault().Split(',');
          aColumns = (newCols.Length == 1 && newCols[0] == "") ? aColumns : newCols;
      
          /* Paging */
          var iDisplayStart = aoData.Where(n => n.name == "iDisplayStart").Select(n => n.value).FirstOrDefault();
          var iDisplayLength = aoData.Where(n => n.name == "iDisplayLength").Select(n => n.value).FirstOrDefault();
      
          /* Ordering */
          var sOrder = "";
          var iSortCol_0 = aoData.Where(n => n.name == "iSortCol_0").Select(n => n.value).FirstOrDefault();
          if (iSortCol_0 != null && aColumns.Length > 0)
          {
              sOrder = "ORDER BY  ";
              var iSortingCols = aoData.Where(n => n.name == "iSortingCols").Select(n => int.Parse(n.value)).FirstOrDefault();
              for (int i = 0; i < iSortingCols; i++)
              {
                  var iSortCol = aoData.Where(n => n.name == "iSortCol_" + i).Select(n => int.Parse(n.value)).FirstOrDefault();
                  var bSortable = aoData.Where(n => n.name == "bSortable_" + iSortCol).Select(n => bool.Parse(n.value)).FirstOrDefault();
      
                  if (bSortable)
                  {
                      var sSortDir = aoData.Where(n => n.name == "sSortDir_" + i).Select(n => n.value).FirstOrDefault();
                      sOrder += aColumns[iSortCol] + " " + sSortDir + ", ";
                  }
              }
              sOrder = sOrder.Trim();
              sOrder = sOrder.Substring(sOrder.Length - 1) == "," ? sOrder.Substring(0, sOrder.Length - 1) : sOrder;
              sOrder = (sOrder == "ORDER BY") ? "" : sOrder;
          }
      
          /* Filtering
           */
          var sWhere = "";
          var sSearch = aoData.Where(n => n.name == "sSearch").Select(n => n.value).FirstOrDefault();
          var status = aoData.Where(n => n.name == "ddlStatus").Select(n => n.value).FirstOrDefault();
          if (sSearch != "" && aColumns.Length > 0)
          {
              sWhere = "WHERE (";
              for (int i = 0; i < aColumns.Count(); i++)
              {
                  sWhere += aColumns[i] + " LIKE '%" + sSearch + "%'" + (i < aColumns.Count() - 1 ? " OR " : " ");
              }
              sWhere = sWhere.Trim() + ")";
          }
      
          /* Individual column filtering */
          for (int i = 0; i < aColumns.Count(); i++)
          {
              var bSearchableCol = aoData.Where(n => n.name == "bSearchable_" + i).Select(n => bool.Parse(n.value)).FirstOrDefault();
              var sSearchCol = aoData.Where(n => n.name == "sSearch_" + i).Select(n => n.value).FirstOrDefault();
      
              if (bSearchableCol && sSearchCol != "")
              {
                  sWhere = (sWhere == "") ? "WHERE " : sWhere + " AND ";
                  sWhere += aColumns[i] + " LIKE '%" + sSearchCol + "%' ";
              }
      
              /* Added this second if statement for my custom drop down filter on a specific column
               * The fnFilter setting with a column number does not work, and this way, ColReorder will still work
               */
              if (status != "" && aColumns[i] == "JobStatusName")
              {
                  sWhere = (sWhere == "") ? "WHERE " : sWhere + " AND ";
                  sWhere += aColumns[i] + " = '" + status + "' ";
              }
          }
      
          /* SQL queries
           * Get data to display
           */
          List<LTS.JobOverviewDynamicResult> data;
          using (var m = new Methods())
          {
              //Im not giving my SQL query
              data = m.getJobOverviewDynamicData(sWhere, sOrder, iDisplayStart, iDisplayLength);
          }
      
          int iFilteredTotal = 0;
          int iTotal = 0;
          if (data.Count() > 0)
          {
              /* Filtered dataset and Total dataset length */
              iFilteredTotal = (int)data.FirstOrDefault().ITotalFiltered;
              iTotal = (int)data.FirstOrDefault().ITotal;
          }
      
          /* Output */
          var sEcho = aoData.Where(n => n.name == "sEcho").Select(n => int.Parse(n.value)).FirstOrDefault();
          var output = new oaData<List<JobOverviewDynamic>>()
          {
              sEcho = sEcho,
              iTotalRecords = iTotal,
              iTotalDisplayRecords = iFilteredTotal,
              aaData = data.Select(n => new JobOverviewDynamic()
              {
                  JobNo = (int)n.JobNo,
                  JobStatusName = n.JobStatusName,
                  StatusDateTime = ((DateTime)n.StatusDateTime).ToString("yyyy-MM-dd hh:mm"),
                  HasAttachments = (bool)n.HasAttachments,
                  Visited = (bool)n.Visited,
                  Completed = (bool)n.Completed,
                  JobStatusId = (int)n.JobStatusId,
                  JobId = (int)n.JobId
              }).ToList(),
              sColumns = string.Join(",", aColumns)
          };
      
          return JsonConvert.SerializeObject(output);
      }
      

      我希望这有点道理,如果不是 - 问,我会提供帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-11-02
        • 2018-04-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-11-01
        • 2018-06-19
        相关资源
        最近更新 更多