11/23/2008

[ASP.Net]GridView攻略05-在編輯列使用其他控制項(下拉式選單或日曆)

(1)編輯列加入javscript日曆
GridView攻略04-編輯資料列這篇文章中,我們可以看到一個小問題,編輯列中明明就是編輯日期,為什麼沒有跳出日曆讓使用者選擇,自己用鍵盤輸入不是不可以,但這個介面也太不友善了吧,而且少了一種又酷又炫的感覺XD


因此,現在我想試著在日期編輯的文字輸入方塊加入日曆,讓我們用滑鼠點選文字輸入方塊準備輸入日期的時候會自動跳出一個小日曆供使用者選擇。就如同下圖的結果:

image


首先,我們需要有些前置作業,因為我使用的日曆是jQuery的plugin 所以你需要準備
1.jQuery library(這裡)

2.UI Datepicker(這裡)
jQuery是什麼?這邊稍微提一下。jQuery是一個很棒的Javascript Framework,有效的選擇器Selector可以讓很多事情都變簡單,而眾多的UI外掛是我選擇它的很大原因。如果你對jQuery不熟悉或不清楚它的用法可以參考其他先進的教學:)
jQuery神奇的選擇器(Selector):簡睿IT隨筆:Xuite日誌
jQuery 學習心得筆記 (1)
jQuery 教學 - 基礎篇

該準備的東西準備好了,我們就接續GridView攻略04-編輯資料列文章內的範例繼續做下去吧。先在<head>裡面加上相關的js和css檔案。
<link rel="stylesheet" href="App_Themes/themes/default/ui.all.css" type="text/css"
media="screen">

<script type="text/javascript" src="js/jquery-1.2.6.min.js"></script>

<script type="text/javascript" src="js/ui/ui.core.js"></script>

<script type="text/javascript" src="js/ui/ui.datepicker.js"></script>

<script type="text/javascript" src="js/ui/i18n/ui.datepicker-zh-TW.js"></script>

接著加上這個用來呼叫DatePicker的javascript方法。
<script type="text/javascript">
function clickDatePicker(txtID)
{
$("#" + txtID).datepicker();
$("#" + txtID).focus();
$("#" + txtID).datepicker();
}
</script>


在這裡我發現到一個很奇怪的事情,GridView跟jQuery的Datepicker外掛似乎有些不相容?在這裡原本只要呼叫datepicker()一次,日曆就應該顯示,可是我實際嘗試以後發現我必須點一下Textbox→點其他東西→再回來點Textbox,日曆才會順利出現,所以才有了以上的clickDatePicker這個方法,用來模擬我的動作,讓日曆正常顯示


最後,在GridView的RowDataBound這個事件加上呼叫clickDatePicker這個方法的相關程式。RowDataBound是GridView逐行繫結資料列的時候發生的事件。
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowState.ToString().Contains("Edit"))
{

TextBox txtDate = (TextBox)e.Row.FindControl("edtDate");
txtDate.Attributes["onclick"] = string.Format(@"javascript:clickDatePicker('{0}');"
, txtDate.ClientID);
}
}

上面程式檢查了目前資料列的狀態,如果是編輯模式,我們就設定關於日期的那個Textbox在client端的onclick事件。用FindControl方法可以取得目前資料列中的子控制項。透過Attributes["onclick"]屬性可以設定相關的javascript程式碼。

(2)編輯列加入下拉式選單

看完上面加入日曆的範例,對於要在GridView的編輯列加入其他控制項,應該有些頭緒了吧。這裡就用下拉式選單為例子再說一次。因為這個例子沒有特別適合用下拉式選單(DropDownList)的欄位,所以我隨便挑了數量當做目標。在ASPX,先把GridView數量欄位的EditTemplate修改一下。加上了一個下拉式選單(DropDownList ),並設定TextBox的display為none,讓他不顯示在螢幕上。
<EditItemTemplate>
<asp:TextBox ID="edtNum" runat="server" Width="30px" Text='<%# Bind("num") %>' Style="display: none;"></asp:TextBox>
<asp:DropDownList ID="ddlNum" runat="server">
</asp:DropDownList>
</EditItemTemplate>

接著,在CS中,我們在RowDataBound事件中加入一些程式。
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowState.ToString().Contains("Edit"))
{

TextBox txtDate = (TextBox)e.Row.FindControl("edtDate");
txtDate.Attributes["onclick"] = string.Format(@"javascript:clickDatePicker('{0}');"
, txtDate.ClientID);


DropDownList ddlNum = (DropDownList)e.Row.FindControl("ddlNum");
for (int i = 0; i < 400; i++)
{
ddlNum.Items.Add(new ListItem(i.ToString(), i.ToString()));
}


TextBox edtNum = (TextBox)e.Row.FindControl("edtNum");

for (int i = 0; i < ddlNum.Items.Count; i++)
{
if (ddlNum.Items[i].Text == edtNum.Text)
{
ddlNum.SelectedIndex = i;
}
}
}
}
第一個for迴圈是用來初始化下拉式選單裡面的選項,第二個for迴圈用來比對文字輸入方塊(Textbox)和下拉式選單,找出下拉式選單中哪個選項與Textbox數量相同。
image
雖然這個範例有點冗長==",但聊勝於無,我們從這裡還是可以了解到在編輯列放置控制項的精髓就是RowDataBound事件的靈活使用


PS:在這裡沒有提到,但是應該要處理的就是Updating事件中,我們原本用FindControl找的是TextBox,現在要記得改成DropDownList喔~!

1 意見:

Anonymous 提到...

thnx for sharing

張貼意見