ASP.NET WebPages と Razor(cshtml)の組み合わせに相性のよいTableソリューションを求め歩いていたところ DataTablase に続いて w2ui という優れたライブラリを発見。
w2ui はレイアウト、グリッド、ツールバー、サイドバー、タブ、フォーム、ポップアップその他のユーティリティで構成されるライブラリですが、軽量設計で使いやすくまとまっています。
今回Gridを試したわけですが、このGridの優れたところは、ページングの概念を捨てて「無限スクロール」を導入したこと。しかもその動作は軽快です。
DataTablesと同様にサーバーへは form data、サーバーからはJSONによる応答です。form dataの仕様がこちらのほうが簡単で使いやすいかもしれません。また、
開発中の Ver 1.4 には拙翻訳を提供したので
日本語表記の利用も可能です。
jQuery DataTablesでやったことと同じことを w2ui を使って再現してみます。
1: @{
2: if (IsPost)
3: {
4: if (UrlData[0] == "GetList" )
5: {
6: var all = System.Globalization.CultureInfo.GetCultures(System.Globalization.CultureTypes.AllCultures).AsEnumerable<System.Globalization.CultureInfo>();
7: var filtered = all;
8: int iDisplayStart = Request["offset"].AsInt(0);
9: int iDisplayLength = Request["limit"].AsInt(10);
10: bool sorted = false;
11: for (int i = 0; Request[String.Format("sort[{0}][field]", i)] != null; i++)
12: {
13: String fld = Request[String.Format("sort[{0}][field]", i)];
14: bool asc = Request[String.Format("sort[{0}][direction]", i)] == "asc";
15: switch( fld)
16: {
17: case "Name":
18: filtered = asc ? filtered.OrderBy(m => m.Name) : filtered.OrderByDescending(m => m.Name);
19: break;
20: case "DisplayName":
21: filtered = asc ? filtered.OrderBy(m => m.DisplayName) : filtered.OrderByDescending(m => m.DisplayName);
22: break;
23: case "TwoLetterISOLanguageName":
24: filtered = asc ? filtered.OrderBy(m => m.TwoLetterISOLanguageName) : filtered.OrderByDescending(m => m.TwoLetterISOLanguageName);
25: break;
26: case "ThreeLetterISOLanguageName":
27: filtered = asc ? filtered.OrderBy(m => m.ThreeLetterISOLanguageName) : filtered.OrderByDescending(m => m.ThreeLetterISOLanguageName);
28: break;
29: }
30: sorted = true;
31: }
32: if (!sorted) { filtered = filtered.OrderBy(m => m.Name); }
33: for (int i = 0; Request[String.Format("search[{0}][field]", i)] != null; i++)
34: {
35: String fld = Request[String.Format("search[{0}][field]", i)];
36: String sSearch = Request[String.Format("search[{0}][value]", i)];
37: if (!String.IsNullOrEmpty(sSearch))
38: {
39: switch (fld)
40: {
41: case "Name":
42: filtered = filtered.Where(m => m.Name.Contains(sSearch));
43: break;
44: case "DisplayName":
45: filtered = filtered.Where(m => m.DisplayName.Contains(sSearch));
46: break;
47: case "TwoLetterISOLanguageName":
48: filtered = filtered.Where(m => m.TwoLetterISOLanguageName.Contains(sSearch));
49: break;
50: case "ThreeLetterISOLanguageName":
51: filtered = filtered.Where(m => m.ThreeLetterISOLanguageName.Contains(sSearch));
52: break;
53: }
54: }
55: }
56: var output = new
57: {
58: status = "success",
59: total = filtered.Count(),
60: records = filtered.Skip(iDisplayStart).Take(iDisplayLength).AsEnumerable().Select((o, i) => new { recid = o.Name, o.Name, o.DisplayName, o.TwoLetterISOLanguageName, o.ThreeLetterISOLanguageName })
61: };
62: Response.ContentType = "application/json";
63: Response.Write(Json.Encode(output));
64: Response.End();
65: return;
66: }
67: }
68: }
69: <script src="http://ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.js"></script>
70: <link rel="stylesheet" href="http://w2ui.com/src/w2ui-1.3.min.css" type="text/css" />
71: <script src="http://w2ui.com/src/w2ui-1.3.min.js"></script>
72: <script>
73: $(document).ready(function () {
74: $('#sampleTable').w2grid({
75: name: 'grid',
76: header: 'List of Names',
77: show: {
78: toolbar: true,
79: footer: true
80: },
81: columns: [
82: { field: 'Name', caption: 'Name', size: '20%', sortable: true, attr: 'align=center' },
83: { field: 'DisplayName', caption: 'DisplayName', size: '30%', sortable: true, resizable: true },
84: { field: 'TwoLetterISOLanguageName', caption: 'TwoLetterISOLanguageName', size: '30%', sortable: true, resizable: true },
85: { field: 'ThreeLetterISOLanguageName', caption: 'ThreeLetterISOLanguageName', size: '30%', resizable: true }
86: ],
87: searches: [
88: { field: 'Name', caption: 'Name', type: 'text' },
89: { field: 'DisplayName', caption: 'DisplayName', type: 'text' },
90: { field: 'TwoLetterISOLanguageName', caption: 'TwoLetterISOLanguageName', type: 'text' },
91: ],
92: sortData: [{ field: 'Name', direction: 'ASC' }],
93: url: '@Href(Request.AppRelativeCurrentExecutionFilePath,"GetList")'
94: });
95: });
96: </script>
97: <div>
98: <div id="sampleTable" style="height: 600px;">
99: </div>
100: </div>