[ASP.net/jQuery] 可拖拉呈現表格資料的jQuery Grid外掛 Flexigrid 和 ListView控制項的整合
差點忘了自己的客戶也是那種把Web程式當桌面程式用的人(汗
趕緊上網找幾個能夠替代GridView、ListView控制項的酷炫套件研究一下
40 Excellent jQuery Plugins To Work With Data Presentation and Grid Layout
15+ Best of jQuery Table Learn Web Design
尋找過程中,發現功能強大又有現成的ASP.net Code應該為jQuery Grid Plugin
但一到ASP.net的Demo頁準備下載ASP.net Sample Code時發現似乎有30天限制
滿可惜,所幸還有Flexigrid,雖是免費但功能不俗於jqGrid (而且Code Project也有人提供ASP.net WebForm/MVC的WebService範例程式碼)
以下,馬上快速瀏覽吧
首先到官網下載Flexigrid的壓縮檔(內含基本的.js、.css、還有一些圖片)
下載完解壓後,用Visual Studo打開此資料夾,這邊我是把它當作Web Site網站資料夾處理
然後加入index.aspx和Web.config檔
因為官網的壓縮檔沒有內附jQuery核心函式庫
所以請自行到jQuery官網下載,這邊我就使用Visual Studio內建提供的專案範本jQuery檔
然後展開css資料夾和js資料夾
先把jQuery核心函式庫和flexigrid.js還有flexigrid.css檔加入網頁的head區段(另外的pack檔,功能相同,只是檔案較小)
如下:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="js/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="js/flexigrid.js" type="text/javascript"></script>
<link href="css/flexigrid.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<div>
</div>
</form>
</body>
</html>
再來就是重點,到這邊會發現此壓縮檔內沒有Sample Code
沒有沒關係,到官網IE瀏覽器按F12抓出底下Demo範例程式碼即可
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="js/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="js/flexigrid.pack.js" type="text/javascript"></script>
<link href="css/flexigrid.pack.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
$(document).ready(init);
function init()
{
//Example 1
$('table.flexme1').flexigrid();
}
</script>
</head>
<body>
<form id="form1" runat="server">
<h1>Example 1 基本款</h1>
<table class="flexme1">
<thead>
<tr>
<th width="100">Col 1</th>
<th width="100">Col 2</th>
<th width="100">Col 3 is a long header name</th>
<th width="300">Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>This is data 1 with overflowing content</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
然後貼到Visual Studo的body區塊內,因為此table的class名稱為flexme1,所以jQuery的呼叫對象名稱也要稍微改一下
整體大概就像以下這樣:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="js/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="js/flexigrid.js" type="text/javascript"></script>
<link href="css/flexigrid.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
$(document).ready(init);
function init()
{
//Example 1
$('table.flexme1').flexigrid();
}
</script>
</head>
<body>
<form id="form1" runat="server">
<h1>Example 1 基本款</h1>
<table class="flexme1">
<thead>
<tr>
<th width="100">Col 1</th>
<th width="100">Col 2</th>
<th width="100">Col 3 is a long header name</th>
<th width="300">Col 4</th>
</tr>
</thead>
<tbody>
<tr>
<td>This is data 1 with overflowing content</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
<tr>
<td>This is data 1</td>
<td>This is data 2</td>
<td>This is data 3</td>
<td>This is data 4</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
這樣靜態網頁版就大功告成
先看執行結果有哪些功能:
感覺還不錯,只是少了點擊Header做欄位排序功能
接著馬上用GridView和ListView套看看
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="GridViewAndListView.aspx.cs"
Inherits="GridViewAndListView" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="js/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="js/flexigrid.js" type="text/javascript"></script>
<link href="css/flexigrid.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
$(document).ready(init);
function init() {
//Example 1
$('table.flexme1').flexigrid();
}
</script>
</head>
<body>
<form id="form1" runat="server">
<!--範例資料庫請至部落格"下載"分類下載-->
<asp:SqlDataSource runat="server" ID="sds_Employees" ConnectionString="<%$ ConnectionStrings:NorthwindChineseConnectionString %>"
SelectCommand="SELECT [EmployeeID], [EmployeeName], [Title], [Salary], [ManagerID] FROM [Employees] Order by EmployeeID" />
<div>
<!--注意把class加在GridView的成員CssClass-->
<asp:GridView runat="server" ID="gv_Employees" DataSourceID="sds_Employees" CssClass="flexme1" />
</div>
<div>
<asp:ListView ID="ListView1" runat="server" DataKeyNames="EmployeeID" DataSourceID="sds_Employees">
<ItemTemplate>
<tr>
<td>
<asp:Literal ID="EmployeeIDLabel" runat="server" Text='<%# Eval("EmployeeID") %>' />
</td>
<td>
<asp:Literal ID="EmployeeNameLabel" runat="server" Text='<%# Eval("EmployeeName") %>' />
</td>
<td>
<asp:Literal ID="TitleLabel" runat="server" Text='<%# Eval("Title") %>' />
</td>
<td>
<asp:Literal ID="SalaryLabel" runat="server" Text='<%# Eval("Salary") %>' />
</td>
<td>
<asp:Literal ID="ManagerIDLabel" runat="server" Text='<%# Eval("ManagerID") %>' />
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" runat="server" class="flexme1">
<thead>
<tr>
<th>
EmployeeID
</th>
<th>
EmployeeName
</th>
<th>
Title
</th>
<th>
Salary
</th>
<th>
ManagerID
</th>
</tr>
</thead>
<tbody>
<tr id="itemPlaceholder" runat="server">
</tr>
</tbody>
</table>
</LayoutTemplate>
</asp:ListView>
</div>
</form>
</body>
</html>
執行確認一下:
會發現那些酷炫的特效全沒了
而且觀察一下HTML原始碼:
我一直以為ListView是樣版之王,結果明明加了<thead>和<tbody>,最後卻沒呈現出來Orz…難怪微軟要推廣ASP.net MVC
呃,是小弟實力不足,趕緊拜一下估狗大嬸發現這篇:ASP.NET ListView - Render THEAD/TBODY Tags
所以ListView的table的runat=”server”拿掉應該就沒事(GridView想不到辦法,先註解它,放棄掉)
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="GridViewAndListView.aspx.cs"
Inherits="GridViewAndListView" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="js/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="js/flexigrid.js" type="text/javascript"></script>
<link href="css/flexigrid.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
$(document).ready(init);
function init() {
//Example 1
$('table.flexme1').flexigrid();
}
</script>
</head>
<body>
<form id="form1" runat="server">
<!--範例資料庫請至部落格"下載"分類下載-->
<asp:SqlDataSource runat="server" ID="sds_Employees" ConnectionString="<%$ ConnectionStrings:NorthwindChineseConnectionString %>"
SelectCommand="SELECT [EmployeeID], [EmployeeName], [Title], [Salary], [ManagerID] FROM [Employees] Order by EmployeeID" />
<div>
<!--注意把class加在GridView的成員CssClass-->
<%-- <asp:GridView runat="server" ID="gv_Employees" DataSourceID="sds_Employees" CssClass="flexme1" />--%>
</div>
<div>
<asp:ListView ID="ListView1" runat="server" DataKeyNames="EmployeeID" DataSourceID="sds_Employees">
<ItemTemplate>
<tr>
<td>
<asp:Literal ID="EmployeeIDLabel" runat="server" Text='<%# Eval("EmployeeID") %>' />
</td>
<td>
<asp:Literal ID="EmployeeNameLabel" runat="server" Text='<%# Eval("EmployeeName") %>' />
</td>
<td>
<asp:Literal ID="TitleLabel" runat="server" Text='<%# Eval("Title") %>' />
</td>
<td>
<asp:Literal ID="SalaryLabel" runat="server" Text='<%# Eval("Salary") %>' />
</td>
<td>
<asp:Literal ID="ManagerIDLabel" runat="server" Text='<%# Eval("ManagerID") %>' />
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" class="flexme1">
<thead>
<tr>
<th>
EmployeeID
</th>
<th>
EmployeeName
</th>
<th>
Title
</th>
<th>
Salary
</th>
<th>
ManagerID
</th>
</tr>
</thead>
<tbody>
<tr id="itemPlaceholder" runat="server">
</tr>
</tbody>
</table>
</LayoutTemplate>
</asp:ListView>
</div>
</form>
</body>
</html>
這次執行畫面變得稍稍不一樣,但Javascript有錯
觀察一下HTML程式碼:
很明顯這次<thead>和<tbody>有呈現出來,所以再和原本的靜態網頁比較一下
可以再發現每個<th>要給width
<table id="itemPlaceholderContainer" class="flexme1">
<thead>
<tr>
<th width="100">
EmployeeID
</th>
<th width="100">
EmployeeName
</th>
<th width="100">
Title
</th>
<th width="100">
Salary
</th>
<th width="100">
ManagerID
</th>
</tr>
</thead>
<tbody>
<tr id="itemPlaceholder" runat="server">
</tr>
</tbody>
</table>
補完width後再執行一次程式:
大功告成~
接著要玩一下官網Example 2的程式碼
直接在function init(){}裡
<script type="text/javascript">
$(document).ready(init);
function init() {
//Example 1
//$('table.flexme1').flexigrid();
$('.flexme1').flexigrid({ height: 'auto', striped: true }); //striped為true代表要隔列換色
}
</script>
可以發現Example 2的功能為,資料筆數有多少,Table的高度就自動調整符合該筆數的高度
接下來Example 3的功能,就有點複雜了,還好CodeProject上已經有人放出範例:
How To Use ASP.NET Web Service with FlexiGrid
還有ASP.net MVC:ASP.NET MVC Flexigrid sample
這邊就不介紹Example 3
接著要試一下ListView的新增、編輯、刪除功能,先把該補的Code補上去
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="GridViewAndListView.aspx.cs"
Inherits="GridViewAndListView" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="js/jquery-1.4.1.min.js" type="text/javascript"></script>
<script src="js/flexigrid.js" type="text/javascript"></script>
<link href="css/flexigrid.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
$(document).ready(init);
function init() {
//Example 1
//$('table.flexme1').flexigrid();
$('.flexme1').flexigrid({ height: 'auto', striped: true }); //striped為true代表要隔列換色
}
</script>
</head>
<body>
<form id="form1" runat="server">
<!--範例資料庫請至部落格"下載"分類下載-->
<asp:SqlDataSource runat="server" ID="sds_Employees" ConnectionString="<%$ ConnectionStrings:NorthwindChineseConnectionString %>"
SelectCommand="SELECT [EmployeeID], [EmployeeName], [Title], [Salary], [ManagerID] FROM [Employees]"
DeleteCommand="DELETE FROM [Employees] WHERE [EmployeeID] = @EmployeeID"
InsertCommand="INSERT INTO [Employees] ([EmployeeName], [Title], [Salary], [ManagerID]) VALUES (@EmployeeName, @Title, @Salary, @ManagerID)"
UpdateCommand="UPDATE [Employees] SET [EmployeeName] = @EmployeeName, [Title] = @Title, [Salary] = @Salary, [ManagerID] = @ManagerID WHERE [EmployeeID] = @EmployeeID">
<DeleteParameters>
<asp:Parameter Name="EmployeeID" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="EmployeeName" Type="String" />
<asp:Parameter Name="Title" Type="String" />
<asp:Parameter Name="Salary" Type="Int32" />
<asp:Parameter Name="ManagerID" Type="Int32" />
</InsertParameters>
<UpdateParameters>
<asp:Parameter Name="EmployeeName" Type="String" />
<asp:Parameter Name="Title" Type="String" />
<asp:Parameter Name="Salary" Type="Int32" />
<asp:Parameter Name="ManagerID" Type="Int32" />
<asp:Parameter Name="EmployeeID" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
<div>
<!--注意把class加在GridView的成員CssClass-->
<%-- <asp:GridView runat="server" ID="gv_Employees" DataSourceID="sds_Employees" CssClass="flexme1" />--%>
</div>
<div>
<asp:ListView ID="ListView1" runat="server" DataKeyNames="EmployeeID" DataSourceID="sds_Employees">
<EditItemTemplate>
<tr >
<td>
<asp:Literal ID="EmployeeIDLabel1" runat="server" Text='<%# Eval("EmployeeID") %>' />
</td>
<td>
<asp:TextBox ID="EmployeeNameTextBox" runat="server" Text='<%# Bind("EmployeeName") %>' />
</td>
<td>
<asp:TextBox ID="TitleTextBox" runat="server" Text='<%# Bind("Title") %>' />
</td>
<td>
<asp:TextBox ID="SalaryTextBox" runat="server" Text='<%# Bind("Salary") %>' />
</td>
<td>
<asp:TextBox ID="ManagerIDTextBox" runat="server" Text='<%# Bind("ManagerID") %>' />
</td>
<td>
<asp:Button ID="UpdateButton" runat="server" CommandName="Update" Text="更新" />
<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="取消" />
</td>
</tr>
</EditItemTemplate>
<InsertItemTemplate>
<tr style="">
<td>
<asp:Button ID="InsertButton" runat="server" CommandName="Insert" Text="插入" />
<asp:Button ID="CancelButton" runat="server" CommandName="Cancel" Text="清除" />
</td>
<td>
</td>
<td>
<asp:TextBox ID="EmployeeNameTextBox" runat="server" Text='<%# Bind("EmployeeName") %>' />
</td>
<td>
<asp:TextBox ID="TitleTextBox" runat="server" Text='<%# Bind("Title") %>' />
</td>
<td>
<asp:TextBox ID="SalaryTextBox" runat="server" Text='<%# Bind("Salary") %>' />
</td>
<td>
<asp:TextBox ID="ManagerIDTextBox" runat="server" Text='<%# Bind("ManagerID") %>' />
</td>
</tr>
</InsertItemTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Literal ID="EmployeeIDLabel" runat="server" Text='<%# Eval("EmployeeID") %>' />
</td>
<td>
<asp:Literal ID="EmployeeNameLabel" runat="server" Text='<%# Eval("EmployeeName") %>' />
</td>
<td>
<asp:Literal ID="TitleLabel" runat="server" Text='<%# Eval("Title") %>' />
</td>
<td>
<asp:Literal ID="SalaryLabel" runat="server" Text='<%# Eval("Salary") %>' />
</td>
<td>
<asp:Literal ID="ManagerIDLabel" runat="server" Text='<%# Eval("ManagerID") %>' />
</td>
<td>
<asp:Button Text="編輯" runat="server" CommandName="Edit" /><asp:Button Text="刪除" CommandName="Delete"
runat="server" OnClientClick="return confirm('確定刪除嗎?');" />
</td>
</tr>
</ItemTemplate>
<LayoutTemplate>
<table id="itemPlaceholderContainer" class="flexme1">
<thead>
<tr>
<th width="100">
EmployeeID
</th>
<th width="100">
EmployeeName
</th>
<th width="100">
Title
</th>
<th width="100">
Salary
</th>
<th width="100">
ManagerID
</th>
<th width="200">
異動
</th>
</tr>
</thead>
<tbody>
<tr id="itemPlaceholder" runat="server">
</tr>
</tbody>
</table>
</td> </table>
</LayoutTemplate>
</asp:ListView>
</div>
</form>
</body>
</html>
(控制項就用Button,LinkButton也可,或要用HyperLink超連結到另一頁做編輯也是可以)
執行畫面:
預設
按下編輯:
更新後:
再對Shadow按刪除:
按確定:
編號38的資料被刪除了。
這款jQuery 套件真神奇,居然可以整合ASP.net Server Control,原以為編輯、刪除的動作要另外用jQuery寫
不過ListView的InsertItemTemplate確實不見了,要做新增動作的話,只好在ListView的外面做一個超連結,連結到新增資料的頁面處理,這邊就不Demo
接下來要模擬這套件能不能搭配手寫分頁
偷懶一點,畫面上拉兩個Button
分別撈1~10筆的資料和11~20筆的資料
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public partial class GridViewAndListView : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
sds_Employees.SelectCommand = @"Select * from (SELECT [EmployeeID], [EmployeeName], [Title], [Salary], [ManagerID],
Row_Number() Over (Order by EmployeeID) As rowNo FROM [Employees] ) subTable Where rowNo Between 1 And 10 ";
ListView1.DataBind();
}
protected void Button2_Click(object sender, EventArgs e)
{
sds_Employees.SelectCommand = @"Select * from (SELECT [EmployeeID], [EmployeeName], [Title], [Salary], [ManagerID],
Row_Number() Over (Order by EmployeeID) As rowNo FROM [Employees] ) subTable Where rowNo Between 11 And 20 ";
ListView1.DataBind();
}
}
執行畫面(預設):
按下第一個按鈕後:
確實撈出1~10筆
不過經過測試若我把畫面拉成以下這樣:
再按一次第二個按鈕:
Table畫面欄位會再被洗回來,要想保留剛剛拉過畫面的狀態,這裡就不知道該如何處理了^_^”
以上,這款套件滿有趣的,以下懶人包(.net 4 WebSite)附靜態網頁版可以玩玩看