Контроллер может выглядеть так:
public JsonResult NewsJSON(jQueryDataTableParamModel param)
{
var news = _newsRepository.GetNews();
string col = param.sColumns.Split(',')[param.iSortCol_0];
string orderby = col + " " + param.sSortDir_0;
if (param.sSearch != null)
news = news.Search(param.sSearch);
var qry = new PaginatedList<News>(news.OrderBy(orderby), param.iDisplayStart, param.iDisplayLength);
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = qry.TotalCount,
iTotalDisplayRecords = qry.TotalCount,
aaData = (
from n in qry
select new[]
{
n.Headline,
n.DateCreated.ToString()
}).ToArray()
}, JsonRequestBehavior.AllowGet);
}
jQueryDataTableParamModel.cs
public class jQueryDataTableParamModel
{
/// <summary>
/// Request sequence number sent by DataTable,
/// same value must be returned in response
/// </summary>
public string sEcho { get; set; }
/// <summary>
/// Text used for filtering
/// </summary>
public string sSearch { get; set; }
/// <summary>
/// Number of records that should be shown in table
/// </summary>
public int iDisplayLength { get; set; }
/// <summary>
/// First record that should be shown(used for paging)
/// </summary>
public int iDisplayStart { get; set; }
/// <summary>
/// Number of columns in table
/// </summary>
public int iColumns { get; set; }
/// <summary>
/// Number of columns that are used in sorting
/// </summary>
public int iSortingCols { get; set; }
/// <summary>
/// Comma separated list of column names
/// </summary>
public string sColumns { get; set; }
/// <summary>
/// Sort column
/// </summary>
public int iSortCol_0 { get; set; }
/// <summary>
/// Asc or Desc
/// </summary>
public string sSortDir_0 { get; set; }
}
А в виду:
<script type="text/javascript" charset="utf-8">
$(function () {
$('#news').dataTable({
"bSort" : true,
"bServerSide": true,
"sAjaxSource": "/News/NewsJSON",
"bProcessing": true,
"sPaginationType": "full_numbers",
"iDisplayLength": 25,
"aLengthMenu": [[25, 50, 100, 150, 200], [25, 50, 100, 150, 200]],
"aaSorting": [[1,'asc']],
"aoColumns": [
{ "sName": "Headline" }
,{ "sName": "DateCreated" }
]
});
});
</script>
<table id="news" class="default-table" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th>
Headline
</th>
<th style="width: 114px">
Created
</th>
</tr>
</thead>
</table>
или аналогичный :) не уверен, правильно ли я получил JS, но.
/ Lasse
UPDATE:
Немного грязно, но что-то вроде:
public class DataTableOptions
{
public string ID { get; set; }
public string Url { get; set; }
public string Cols { get; set; }
public bool Sort { get; set; }
public string ViewUrlLinkname { get; set; }
public string EditUrlLinkname { get; set; }
public string DeleteLinkname { get; set; }
public string DeleteTitle { get; set; }
public string DeleteYes { get; set; }
public string DeleteNo { get; set; }
public string DeleteMessage { get; set; }
}
public static class DataTableHelpers
{
private static string aLengthMenu = "[[25, 50, 100, 150, 200], [25, 50, 100, 150, 200]]";
public static MvcHtmlString DataTable(this HtmlHelper helper, DataTableOptions options)
{
string[] arrcols = options.Cols.Split(',');
int sortOffset = arrcols.Where(x => x == "Delete" || x == "View" || x == "Edit").Count();
StringBuilder sb = new StringBuilder();
sb.AppendLine("<script type=\"text/javascript\" charset=\"utf-8\">");
sb.AppendLine("$(function () {");
sb.AppendLine("$('#" + options.ID + "').dataTable({");
sb.AppendLine("\"bSort\" : " + options.Sort.ToString().ToLower() + ",");
sb.AppendLine("\"oLanguage\": { \"sUrl\": \"" + oLanguage + "\" },");
sb.AppendLine("\"bServerSide\": true,");
sb.AppendLine("\"sAjaxSource\": \"" + options.Url + "\",");
sb.AppendLine("\"bProcessing\": true,");
sb.AppendLine("\"sPaginationType\": \"full_numbers\",");
sb.AppendLine("\"iDisplayLength\": 25,");
sb.AppendLine("\"aLengthMenu\": " + aLengthMenu + ",");
sb.AppendLine("\"aaSorting\": [[" + sortOffset.ToString() + ",'asc']],");
sb.AppendLine("\"aoColumns\": [");
for (int i = 0; i < arrcols.Length; i++)
{
if (i > 0)
sb.Append(",");
switch (arrcols[i])
{
case "Delete":
sb.AppendLine("{");
sb.AppendLine("\"sName\": \"" + arrcols[i] + "\",");
sb.AppendLine("\"bSearchable\": false,");
sb.AppendLine("\"bSortable\": false,");
sb.AppendLine("\"fnRender\": function (oObj) {");
sb.Append("return '");
sb.Append("<a class=\"deletelink\" href=\"' + oObj.aData["+ i.ToString() + "] + '\">" + options.DeleteLinkname + "</a> ");
sb.Append("';");
sb.AppendLine("}");
sb.AppendLine("}");
break;
case "Edit":
sb.AppendLine("{");
sb.AppendLine("\"sName\": \"" + arrcols[i] + "\",");
sb.AppendLine("\"bSearchable\": false,");
sb.AppendLine("\"bSortable\": false,");
sb.AppendLine("\"fnRender\": function (oObj) {");
sb.Append("return '");
sb.Append("<a class=\"editlink\" href=\"' + oObj.aData["+ i.ToString() + "] +'\">" + options.EditUrlLinkname + "</a> ");
sb.Append("';");
sb.AppendLine("}");
sb.AppendLine("}");
break;
case "View":
sb.AppendLine("{");
sb.AppendLine("\"sName\": \"" + arrcols[i] + "\",");
sb.AppendLine("\"bSearchable\": false,");
sb.AppendLine("\"bSortable\": false,");
sb.AppendLine("\"fnRender\": function (oObj) {");
sb.Append("return '");
sb.Append("<a class=\"viewlink\" href=\"' + oObj.aData["+ i.ToString() + "] + '\">" + options.ViewUrlLinkname + "</a> ");
sb.Append("';");
sb.AppendLine("}");
sb.AppendLine("}");
break;
default:
sb.AppendLine("{ \"sName\": \"" + arrcols[i] + "\" }");
break;
}
}
sb.AppendLine("]");
sb.AppendLine("});");
sb.AppendLine("});");
sb.AppendLine("</script>");
if (options.DeleteLinkname != null)
{
sb.Append(ConfirmHelpers.RenderConfirm(options.DeleteTitle, options.DeleteYes, options.DeleteNo, options.DeleteMessage));
}
return MvcHtmlString.Create(sb.ToString());
}
и в контроллере также передать ссылки:
return Json(new
{
sEcho = param.sEcho,
iTotalRecords = qry.TotalCount,
iTotalDisplayRecords = qry.TotalCount,
aaData = (
from n in qry
select new[]
{
Url.Action("Detail", new { newsID = n.NewsID, headline = n.Headline.ToURLParameter() }),
Url.Action("Edit", new { newsID = n.NewsID, headline = n.Headline.ToURLParameter() }),
Url.Action("Delete", new { newsID = n.NewsID }),
n.Headline,
n.DateCreated.ToString()
}).ToArray()
}, JsonRequestBehavior.AllowGet);
* * Тысяча двадцать-одина затем
@Html.DataTable(Model.DataTableOptions)
<table id="news" class="default-table" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th style="width: 20px">
</th>
<th style="width: 50px">
</th>
<th style="width: 40px"></th>
<th>
Headline
</th>....
Для удаления я использую плагин: http://tutorialzine.com/2010/12/better-confirm-box-jquery-css3/
public static string RenderConfirm(string title, string yes, string no, string deleteMessage)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("<script type=\"text/javascript\" charset=\"utf-8\">");
sb.AppendLine("$(function () {");
sb.AppendLine("$('.deletelink').live('click', function (e) {");
sb.AppendLine("e.preventDefault();");
sb.AppendLine("var elem = $(this);");
sb.AppendLine("$.confirm({");
sb.AppendLine("'title': '" + title + "',");
//sb.AppendLine("'message': $(this).attr('data-delete-message'),");
sb.AppendLine("'message': '" + deleteMessage + "',");
sb.AppendLine("'buttons': {");
sb.AppendLine("'" + yes + "': {");
sb.AppendLine("'class': 'confirm-yes',");
sb.AppendLine("'action': function () {");
sb.AppendLine("$.post($(elem).attr('href'));");
sb.AppendLine("}");
sb.AppendLine("},");
sb.AppendLine("'" + no + "': {");
sb.AppendLine("'class': 'confirm-no',");
sb.AppendLine("'action': function () { } // Nothing to do in this case. You can as well omit the action property.");
sb.AppendLine("}");
sb.AppendLine("}");
sb.AppendLine("});");
sb.AppendLine("});");
sb.AppendLine("});");
sb.AppendLine("</script>");
return sb.ToString();
}