1. 10 important things:
原文
簡體版
2. tips and tricks:
只有簡體版Orz
另一篇簡體版
2009年4月8日 星期三
2009年4月6日 星期一
在GridView內實現編輯、刪除
如果要在GridView內做到編輯或刪除的動作
有兩種作法:
(1)加入CommandField
(2)加入TemplateField
重點:從一般模式進入Edit要指定EditIndex,而且要執行DataBind()才會進入編輯模式(顯示TextBox)!!如果是用後端餵DataSource的方式,要記得再餵一次!!!
作法大致如下:
(1)加入CommandField
後端要處理GridView的RowEditing、RowCancelingEdit、RowDeleting、RowUpdating等事件
例如:
(2)加入TemplateField
CommandName目的是為了待會處理RowCommand事件時辨別是Edit、Delete or Cancel
CommandArgument則是為了要知道哪列資料要修改或刪除
後端程式碼則只要處理RowCommand事件
如下:
事實上,
方法(1)使用CommandField也是會觸發RowCommand事件
只不過我們忽略他而已
而且RowCommand事件會比RowEditing、RowCancelingEdit..等事件先被觸發!
有兩種作法:
(1)加入CommandField
(2)加入TemplateField
重點:從一般模式進入Edit要指定EditIndex,而且要執行DataBind()才會進入編輯模式(顯示TextBox)!!如果是用後端餵DataSource的方式,要記得再餵一次!!!
作法大致如下:
(1)加入CommandField
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:CommandField ShowEditButton="True" ShowDeleteButton="True"/>
<asp:BoundField DataField="ProgramName" HeaderText="ProgramName"/>
<asp:BoundField DataField="iconid" HeaderText="iconid"/>
<asp:BoundField DataField="classid" HeaderText="classid"/>
</Columns>
</asp:GridView>
後端要處理GridView的RowEditing、RowCancelingEdit、RowDeleting、RowUpdating等事件
例如:
Protected Sub GridView1_RowEditing(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewEditEventArgs) Handles GridView1.RowEditing
'指定哪列資料進入EditMode
Me.GridView1.EditIndex = e.NewEditIndex
'宣告一個執行Query DB的 object(自訂class)
Dim DataObjUtil As New DataObjectUtility()
Me.GridView1.DataSource = DataObjUtil.GetDataTable("select programname,iconid,classid from tb_functionmenu", Me.Page)
'完成Bind才會讓該列進入EditMode!
Me.GridView1.DataBind()
End Sub
(2)加入TemplateField
<asp:GridView ID="GrvSPCKC" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:TemplateField>
<EditItemTemplate>
<asp:Button ID="BtnUpdate" runat="server" Text="更新" CommandName="UpdateRow" CommandArgument="<%# CType(Container,GridViewRow).RowIndex %>" />
<asp:Button ID="BtnCancel" runat="server" Text="取消" CommandName="CancelRow" CommandArgument="<%# CType(Container,GridViewRow).RowIndex %>" OnClientClick="return confirm('確定放棄編輯?');" />
</EditItemTemplate>
<ItemTemplate>
<asp:Button ID="BtnEdit" runat="server" Text="修改" CommandName="EditRow" CommandArgument="<%# CType(Container,GridViewRow).RowIndex %>" />
<asp:Button ID="BtnDel" runat="server" Text="刪除" CommandName="DelRow" CommandArgument="<%# CType(Container,GridViewRow).RowIndex %>" OnClientClick="return confirm('確定刪除?');" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField HeaderText="DFCD" DataField="dfcd" />
<asp:BoundField HeaderText="RVNO" DataField="rvno" />
</Columns>
</asp:GridView>
CommandName目的是為了待會處理RowCommand事件時辨別是Edit、Delete or Cancel
CommandArgument則是為了要知道哪列資料要修改或刪除
後端程式碼則只要處理RowCommand事件
如下:
Protected Sub GrvSPCKC_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles GrvSPCKC.RowCommand
'讀取傳入的列編號
Dim TrigerRowIndex As Integer = Convert.ToInt32(e.CommandArgument)
'根據CommandName參數呼叫各別函式處理
Select Case e.CommandName
Case "EditRow"
Me.ChangeToEditMode(TrigerRowIndex)
Case "CancelRow"
Me.CancelEditRow()
Case "DelRow"
Me.DeleteRow(TrigerRowIndex)
Case "UpdateRow"
Me.UpdateRow(TrigerRowIndex)
End Select
End Sub
事實上,
方法(1)使用CommandField也是會觸發RowCommand事件
只不過我們忽略他而已
而且RowCommand事件會比RowEditing、RowCancelingEdit..等事件先被觸發!
2009年3月31日 星期二
以程式方式加入網頁Head
//My first CSS
HtmlLink myCSS = new HtmlLink();
myCSS.Href = "~/somecss1.css";
myCSS.Attributes.Add("rel", "stylesheet");
myCSS.Attributes.Add("type", "text/css");
Page.Header.Controls.Add(myCSS);
//Here comes my second
myCSS = new HtmlLink();
myCSS.Href = "~/somecss2.css";
myCSS.Attributes.Add("rel", "stylesheet");
myCSS.Attributes.Add("type", "text/css");
Page.Header.Controls.Add(myCSS);
//JavaScript!
HtmlGenericControl myJavaScript = new HtmlGenericControl();
myJavaScript.TagName = "script";
myJavaScript.Attributes.Add("type", "text/javascript");
myJavaScript.InnerText = "alert('Hello');";
Page.Header.Controls.Add(myJavaScript);
//view source code
<link href="somecss1.css" rel="stylesheet" type="text/css" /><link href="somecss2.css" rel="stylesheet" type="text/css" /><script type="text/javascript">alert('Hello');</script>
缺點就是原始碼會串成一大串,很醜
如果在每個header元素加入這行:
Page.Header.Controls.Add(new LiteralControl("\r\n"));這樣source code就會變的美美地:
<link href="somecss1.css" rel="stylesheet" type="text/css" />
<link href="somecss2.css" rel="stylesheet" type="text/css" />
<script type="text/javascript">
alert('Hello');
</script>
2009年2月24日 星期二
Include external Jascript file and CSS style sheet
Include 外部 Javascript檔
重點: (1)script標籤要有close tag!
(2)使用"src"屬性而"非href"!!!
<script type="text/javascript" src="../Script/TreeView.js"></script>
InInclude 外部 CSS檔
重點: (1)link標籤不需close tag!
(2)使用"href"屬性!!!
<link rel=stylesheet type="text/css" href="../CssStyle/UserControl.css"/>
標籤:
CSS,
Javascript,
WebForm
2009年2月21日 星期六
為報表加入參數時的注意事項
一般來說
報表的參數通常用在報表在過濾資料或者查詢資料時
也就是我們把Query database與bind通通交給Crystal Report做
但是如果我們是利用程式手動餵DataTable給ReportDocument
再把這個ReportDocument指為CrystalReportViewer的ReportSource
參數還是可以具體的以"參數欄位"show值在報表上
例如:產生週、月、季報表時,除了基本的報表日期,
我們可以將user前一個步驟給定的週、月、季或年呈現在報表
讓閱讀報表時更明白資料內容。
指定報表參數三步驟
(1)在報表設計(.rpt)建立參數欄位,並拉至報表畫面中

(2)在負責產生報表內容的class檔中,建立一個function設定報表參數,例如:
(3)在設定CrystalReportViewer.ReportSource後執行步驟(2)的function

不過,經過測試後
反而是先指定指定ReportSource屬性再指定ParameterFieldInfo才不會出錯!!!
Ok,如果是WindowForm到這一步已經大功告成了
但是如果你像我一樣是寫web專案
你會發現操作CrystalReportViewer上的tool bar時報表內容會消失
顯然這與web先天無狀態有關
要處理這個問題只好把session搬出來了
我的作法是在設定CrystalReportViewer.ReportSource時
將ReportDocument的資料(DataTable)寫入Session:
本來想直接把ReportDocument物件寫入session
省掉Load、SetDataSource步驟,可惜失敗...只好用2個session分別記錄DataTable與rpt檔名
然後在page事件中再餵一次報表資料:
這裡有個小訣竅
千萬不要寫在PageLoad事件中
否則執行時會有意想不到的結果產生
(我的情況是換頁時頁碼會亂跳!!)
報表的參數通常用在報表在過濾資料或者查詢資料時
也就是我們把Query database與bind通通交給Crystal Report做
但是如果我們是利用程式手動餵DataTable給ReportDocument
再把這個ReportDocument指為CrystalReportViewer的ReportSource
參數還是可以具體的以"參數欄位"show值在報表上
例如:產生週、月、季報表時,除了基本的報表日期,
我們可以將user前一個步驟給定的週、月、季或年呈現在報表
讓閱讀報表時更明白資料內容。
指定報表參數三步驟
(1)在報表設計(.rpt)建立參數欄位,並拉至報表畫面中

(2)在負責產生報表內容的class檔中,建立一個function設定報表參數,例如:
'paramName=報表參數名稱,與rpt檔中的"參數欄位"相同
'paramValue=報表參數值
Public Sub AddParameter(ByVal paramName As String, ByVal paramValue As String)
Dim ParamField As New ParameterField()
Dim ParamDiscreteValue As New ParameterDiscreteValue()
Dim ParamFields As New ParameterFields()
ParamField.ParameterFieldName = paramName
ParamDiscreteValue.Value = paramValue
ParamField.CurrentValues.Add(ParamDiscreteValue)
ParamFields.Add(ParamField)
'把Show報表的CrystalReportViewer物件的ParameterFieldInfo屬性指定為
'剛建立的ParameterFields物件
Me.RptViewer.ParameterFieldInfo = ParamFields
'release resource
ParamField = Nothing
ParamFields = Nothing
ParamDiscreteValue = Nothing
End Sub
簡單來說報表參數的架構是:
ParameterFields集合物件下包含多個ParameterField
一個ParameterField的CurrentValues屬性(Class ParameterValues)
又是集合多個ParameterValue物件....
(上面我以ParameterDiscreteValue物件表示,因為ParameterValue有兩個子類別:
ParameterDiscreteValue與ParameterRangeValue。)
感覺設定ParameterValue有點麻煩
有ParameterFields、ParameterField
又有ParameterValues、ParameterValue
可以理解報表參數可能不只一個,但是為何Value也要用個集合來放??
用MSDN的例子說明:
假若銷售統計報表有"City"這個參數
想要知道Taipei、Kaohsiung這兩個city的銷售情況時
就可以分別指定兩個ParameterValue物件的Value為Taipei、Kaohsiung.....right?
因為報表參數的設計理念是透過報表執行查詢與過濾資料
如果只是單純呈現參數欄位是比較看不出它的作用的
(3)在設定CrystalReportViewer.ReportSource後執行步驟(2)的function
雖然,根據MSDN說明,在指定ReportSource屬性前要先指定ParameterFieldInfo,
否則會出現要求輸入參數值的畫面。例如:

不過,經過測試後
反而是先指定指定ReportSource屬性再指定ParameterFieldInfo才不會出錯!!!
Ok,如果是WindowForm到這一步已經大功告成了
但是如果你像我一樣是寫web專案
你會發現操作CrystalReportViewer上的tool bar時報表內容會消失
顯然這與web先天無狀態有關
要處理這個問題只好把session搬出來了
我的作法是在設定CrystalReportViewer.ReportSource時
將ReportDocument的資料(DataTable)寫入Session:
Public Sub ConfigReport(ByVal paramRptFileName As String, ByVal paramRptData As DataTable)
Me._ReportDocument = New ReportDocument()
Session("RptFileName") = Me.GetReportPhysicPath(paramRptFileName)
Me._ReportDocument.Load(Session("RptFileName"))
Me._ReportDocument.SetDataSource(paramRptData)
Me.RptViewer.ReportSource = Me._ReportDocument
Me.RptViewer.DataBind()
Session("ReportData") = paramRptData
End Sub
本來想直接把ReportDocument物件寫入session
省掉Load、SetDataSource步驟,可惜失敗...只好用2個session分別記錄DataTable與rpt檔名
然後在page事件中再餵一次報表資料:
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
If IsPostBack Then
If Session("ReportData") IsNot Nothing Then
Me._ReportDocument = New ReportDocument()
Me._ReportDocument.Load(Session("RptFileName"))
Me._ReportDocument.SetDataSource(Session("ReportData"))
Me.RptViewer.ReportSource = Me._ReportDocument
Me.RptViewer.DataBind()
Else
RaiseEvent ReportSessionTimeOut()
End If
End If
End Sub
這裡有個小訣竅
千萬不要寫在PageLoad事件中
否則執行時會有意想不到的結果產生
(我的情況是換頁時頁碼會亂跳!!)
標籤:
CrystalReport,
WebForm,
WindowForm
2009年2月12日 星期四
Ajax UpdatePannel注意事項
在 ASP.NET 2.0 預設實現 AJAX 有二種方式,一種是 CallBack 機制,另一種是 ASP.NET AJAX 的 UpdatePanel。只要是在 UpdatePanel 中的控制項,它需要在執行 AJAX 非同步更新時維護所有子控制項的狀態,所以需傳遞更多的資訊。如果沒有傳輸量的問題,UpdatePanel 無疑是實現 AJAX 的完美機制。[參考ASP.NET魔法學苑]。因為它讓畫面看起來不會Full PostBack,讓操作者感覺互動效果與使用一般應用程式相同。但是如果你在aspx頁面寫了JavaScript code要讓畫面onLoad時觸發執行,不論你是寫在body標籤的onLoad屬性或者寫成這樣:
都只會讓alwaysDo()在第一次載入網頁時才會執行
之後的互動都不會觸發!
理由很簡單,因為畫面無Full PostBack所以瀏覽器始終存在第一次進來時的內容(HTML source code)
那如果這樣做呢?
看起來好像可以
因為RegisterStartupScript()就是在頁面註冊一段"當頁面載入後可立即執行的Script"
不過,遇到UpdatePannel還是沒輒
實際上,不論是RegisterStartupScript()或其他ClientScriptManager的Shared Method設計用意
是希望讓開發人員在後端"動態"加入Script到頁面中
當畫面載入瀏覽器後,我們用[檢視原始碼]的功能都可以看到被我們註冊的Script
但是,遇到UpdatePannel,因為頁面根本沒刷新
它回到後端後只是利用Ajax的CallBack技巧把要更改的內容置換掉
(雖然看起來畫面有變,實際上它的原始碼根本沒變,與第一次進來時相同!)
除非拿掉UpdatePannel,這樣頁面每次都可以"徹底"刷新,Script才有機會執行!
幸好,微軟發現這個問題了
在.Net Framework 2.0之後
只要有用到UpdatePannel的畫面
請用ScriptManager取代ClientScriptManager,例如:
<html>
<head>
<script type="text/javascript">
function alwaysDo( ) {
alert("hello!");
}
alwaysDo( );
</script>
</head>
<body>
.......
</body>
</html>
都只會讓alwaysDo()在第一次載入網頁時才會執行
之後的互動都不會觸發!
理由很簡單,因為畫面無Full PostBack所以瀏覽器始終存在第一次進來時的內容(HTML source code)
那如果這樣做呢?
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.ClientScript.RegisterStartupScript(GetType(Page), "", "alert('hello!');", True)
End Sub
看起來好像可以
因為RegisterStartupScript()就是在頁面註冊一段"當頁面載入後可立即執行的Script"
不過,遇到UpdatePannel還是沒輒
實際上,不論是RegisterStartupScript()或其他ClientScriptManager的Shared Method設計用意
是希望讓開發人員在後端"動態"加入Script到頁面中
當畫面載入瀏覽器後,我們用[檢視原始碼]的功能都可以看到被我們註冊的Script
但是,遇到UpdatePannel,因為頁面根本沒刷新
它回到後端後只是利用Ajax的CallBack技巧把要更改的內容置換掉
(雖然看起來畫面有變,實際上它的原始碼根本沒變,與第一次進來時相同!)
除非拿掉UpdatePannel,這樣頁面每次都可以"徹底"刷新,Script才有機會執行!
幸好,微軟發現這個問題了
在.Net Framework 2.0之後
只要有用到UpdatePannel的畫面
請用ScriptManager取代ClientScriptManager,例如:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
ScriptManager.RegisterStartupScript(Me.Page,GetType(Page), "", "alert('hello!');", True)
End Sub
2009年1月13日 星期二
指定網頁資源的路徑
如果要指定畫面中控制項的href或src屬性
有兩種方式:
理論上絕對路徑肯定不會出錯,但是它太長了
相對路徑好像比較簡單
不過當畫面有層層目錄
或者有用到user control
那問題就很煩了
Asp.Net提供一種指定根目錄的方式 "~/"
例如: src="~/forms/form_img/a.jpg"
表示存在網站根目錄下的[forms]資料夾,裡面的[form_img]資料夾,裡面的a.jpg檔
看起來用這個只是少打一點字
其實不然,
因為如果我們把1.aspx搬到其他目錄中(這個我們常做,尤其專案越做越大,目錄結構越建越多層)
我們不用去改src的路徑了(前提是img沒有被搬動)
用這個方式有個限制
就是只有後端程式碼或者server端的控制項才可以用!
所以如果是html元件就不行
然後asp.net會負責把"~/"出現的地方在轉成html code時加上網站的根目錄(請自己try)
另外,如果User control中要link css or javascript 檔
看到一篇還不錯的作法
有兩種方式:
(1)絕對位置
就是完整URL
例如:目前畫面路徑為http://localhost/web1/forms/1.aspx
如果在1.aspx裡有一張圖放在http://localhost/web1/forms/form_img/a.jpg
則路徑指定為src="http://localhost/web1/forms/form_img/a.jpg"
(2)相對位置
也就是相對於"目前畫面"的位置。
所以上一個例子來說
如果以相對位置來表示
因為a.jpg位在與1.aspx相同目錄內的form_img子目錄
所以路徑指定為src="form_img/a.jpg"
那如果圖放在http://localhost/web1/web_img/a.jpg
即1.aspx的上層目錄內的web_img子目錄
則路徑指定為src="../web_img/a.jpg"
其中".."表示[上一層]目錄
理論上絕對路徑肯定不會出錯,但是它太長了
相對路徑好像比較簡單
不過當畫面有層層目錄
或者有用到user control
那問題就很煩了
Asp.Net提供一種指定根目錄的方式 "~/"
例如: src="~/forms/form_img/a.jpg"
表示存在網站根目錄下的[forms]資料夾,裡面的[form_img]資料夾,裡面的a.jpg檔
看起來用這個只是少打一點字
其實不然,
因為如果我們把1.aspx搬到其他目錄中(這個我們常做,尤其專案越做越大,目錄結構越建越多層)
我們不用去改src的路徑了(前提是img沒有被搬動)
用這個方式有個限制
就是只有後端程式碼或者server端的控制項才可以用!
所以如果是html元件就不行
然後asp.net會負責把"~/"出現的地方在轉成html code時加上網站的根目錄(請自己try)
另外,如果User control中要link css or javascript 檔
看到一篇還不錯的作法
<link type="text/css" rel="Stylesheet" href='<%=ResolveUrl("~/UserControl/css/top.css")%>'/>
<script type="text/javascript" language="javascript" src='<%=ResolveUrl("~/UserControl/js/check.js")%>'></script>
2008年12月22日 星期一
前端Script呼叫後端事件處理函式
__doPostBack(TargetObjID,EventArgs)是Asp.net轉成html code會自動加進來的script function
目的在於驅動後端處理函式動作
例如
__doPostBack("Btn1","");
就會馬上執行Btn1.Click的事件處理函式
事實上,Asp.Net元件幾乎都是利用這種方式postBack
我們可以這樣做:
拉一個DropDownList到畫面,
然後把AutoPostBack打開
執行網頁後再看看它的原始碼:
提醒一下:doPostBack前面的底線是"兩條",只打一條會出錯的!
還有,如果兩個參數都是空字串""
那PostBack回去就只會做Page_Load()
目的在於驅動後端處理函式動作
例如
__doPostBack("Btn1","");
就會馬上執行Btn1.Click的事件處理函式
事實上,Asp.Net元件幾乎都是利用這種方式postBack
我們可以這樣做:
拉一個DropDownList到畫面,
然後把AutoPostBack打開
執行網頁後再看看它的原始碼:
<form name="form1" method="post" action="testpage.aspx" id="form1">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__LASTFOCUS" id="__LASTFOCUS" value="" />
</div>
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['form1'];
if (!theForm) {
theForm = document.form1;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
<select name="DropDownList1" onchange="javascript:setTimeout('__doPostBack(\'DropDownList1\',\'\')', 0)" id="DropDownList1"></select>
</form>
提醒一下:doPostBack前面的底線是"兩條",只打一條會出錯的!
還有,如果兩個參數都是空字串""
那PostBack回去就只會做Page_Load()
標籤:
.Net,
Javascript,
WebForm
2008年12月17日 星期三
VBScript Event Handler
我們知道在Html元素中如果要加入事件
必須在html標籤中加入對應的事件屬性和事件處理函式的名稱
如:
但是如果要用VBScript的話,onClick屬性就可以省了!
如:
但是html元素必須加上name屬性!
因為它是用來判斷要呼叫哪個事件處理函式
也就是在VBScript中事件處理函式必須定義成Sub name_event()
參考資料:VBScript vs JavaScript for Event
必須在html標籤中加入對應的事件屬性和事件處理函式的名稱
如:
<script language="VBScript">
function btnClick(){
alert("Hello!");
}
</script>
<intput type="button" onClick="btnClick()">
</pre>
但是如果要用VBScript的話,onClick屬性就可以省了!
如:
<script language="VBScript">
Sub btnGreeting_OnClick()
MsgBox("Hello!")
End Sub
</script>
<input type="button" name="btnGreeting">
但是html元素必須加上name屬性!
因為它是用來判斷要呼叫哪個事件處理函式
也就是在VBScript中事件處理函式必須定義成Sub name_event()
參考資料:VBScript vs JavaScript for Event
2008年11月5日 星期三
在Web環境下快速彈出新視窗
傳統彈出新視窗的作法
都是用Javascript的window.open()method
但是它反應時間還蠻慢的
其實如果客戶的標準瀏覽器是IE
我們可以改用window.showModalDialog() or window.showModelessDialog()
兩個function的差別是showModalDialog() 彈出的視窗沒關掉前不能操作主畫面(類似對話框alert)
語法:
vReturnValue = window.showModalDialog(sURL [, vArguments] [, sFeatures])
(1)vReturnValue: 子視窗的傳回值
(2)sURL: 子視窗的URL (必要項)
(3)vArguments: 傳入子視窗的參數(非必要)
(4)sFeatures: 視窗外觀屬性(字串型別)
舉個例子:
在主畫面TextBox填入值,按下送出按鈕把值傳到彈出的子畫面的TextBox中,同樣的,在子畫面也可以傳回值給主畫面。
主畫面的script:
子畫面的Script:
說明:
1. window.dialogArguments是當呼叫showModalDialog()有傳入參數時才有值..(即"self")
2. var returnObj=Object();是Javascript宣告物件的語法,宣告之後就可以指定屬性值
如:returnObj.returnValue=document.getElementById('ChilText2').value;
3. window.returnValue就是指定showModalDialog()的傳回值
都是用Javascript的window.open()method
但是它反應時間還蠻慢的
其實如果客戶的標準瀏覽器是IE
我們可以改用window.showModalDialog() or window.showModelessDialog()
兩個function的差別是showModalDialog() 彈出的視窗沒關掉前不能操作主畫面(類似對話框alert)
語法:
vReturnValue = window.showModalDialog(sURL [, vArguments] [, sFeatures])
(1)vReturnValue: 子視窗的傳回值
(2)sURL: 子視窗的URL (必要項)
(3)vArguments: 傳入子視窗的參數(非必要)
(4)sFeatures: 視窗外觀屬性(字串型別)
舉個例子:
在主畫面TextBox填入值,按下送出按鈕把值傳到彈出的子畫面的TextBox中,同樣的,在子畫面也可以傳回值給主畫面。
主畫面的script:
function OpenNewWindow() {
var returnObj
var passingValue=document.getElementById('PareText1').value;
//開啟子畫面傳入本身視窗
returnObj=window.showModalDialog("PopWindow.aspx",self,'dialogHeight:100px;');
//讀取子畫面的回傳並填入母畫面
document.getElementById('PareText2').value=returnObj.returnValue;
}
子畫面的Script:
//來自母畫面的參數
var Parent=window.dialogArguments;
//要回傳的參數
var returnObj=Object();
//讀取母畫面的參數並塞值
document.getElementById('ChilText1').value=Parent.document.getElementById('PareText1').value;
function ReturnToParent() {
//把值腮入欲傳回的Object
//把Object傳回母畫面
returnObj.returnValue=document.getElementById('ChilText2').value;
window.returnValue=returnObj;
window.close();
}
說明:
1. window.dialogArguments是當呼叫showModalDialog()有傳入參數時才有值..(即"self")
2. var returnObj=Object();是Javascript宣告物件的語法,宣告之後就可以指定屬性值
如:returnObj.returnValue=document.getElementById('ChilText2').value;
3. window.returnValue就是指定showModalDialog()的傳回值
標籤:
Javascript,
WebForm
2008年10月29日 星期三
getElementsByTagName vs. getElementsByName
上一篇"多個RadioButtonList設為相同Group"裡面有用到getElementsByTagName
有人會說既然有把name(即paramOldName)傳入,何不直接使用getElementsByName
就不需要多這個判斷式
這裡說一下理由 (這部份要感謝昌琰)
因為getElementsByName找到的Object只能改name以外的屬性!!
我試過了連ID也可以改,就是只有name不能被修改
所以只好用getElementsByTagName收集大範圍的物件,再透過if判斷式過濾
By Felix
有人會說既然有把name(即paramOldName)傳入,何不直接使用getElementsByName
就不需要多這個判斷式
if(ObjArray[i].type == "radio" && ObjArray[i].name == paramOldName)
這裡說一下理由 (這部份要感謝昌琰)
因為getElementsByName找到的Object只能改name以外的屬性!!
我試過了連ID也可以改,就是只有name不能被修改
所以只好用getElementsByTagName收集大範圍的物件,再透過if判斷式過濾
By Felix
標籤:
DOM,
Javascript,
WebForm
2008年10月28日 星期二
把多個RadioButtonList設為相同Group
問題: 如果頁面上有多組RadioButtonList,要做到這幾組RadioButtonList間都只能單選,例如:
50cc機車 125cc機車 150cc以上機車
休旅車 跑車 房車
如果上下兩排各是一個RadioButtonList如何讓他們都屬與同一group
當然,我們可以只用html的radio button做到,只要name屬性設為一樣。但是如果想透過程式動態產生那些選項,RadioButtonList還蠻好用的。可惜它沒有name or groupname這個property可用!
我的作法是做一個含RadioButtonList的UserControl:
//javascript
使用這個UserControl的畫面的.vb檔
By Felix
50cc機車 125cc機車 150cc以上機車
休旅車 跑車 房車
如果上下兩排各是一個RadioButtonList如何讓他們都屬與同一group
當然,我們可以只用html的radio button做到,只要name屬性設為一樣。但是如果想透過程式動態產生那些選項,RadioButtonList還蠻好用的。可惜它沒有name or groupname這個property可用!
我的作法是做一個含RadioButtonList的UserControl:
Partial Class UCRadioBtnList
Inherits System.Web.UI.UserControl
Private _GroupName As String
'提供設定RadioButton項目
Public WriteOnly Property Items() As String()
Set(ByVal value As String())
Dim ItemTemp As ListItem
For Each v As String In value
ItemTemp = New ListItem(v)
Me.RadioButtonList.Items.Add(ItemTemp)
Next
End Set End Property
'提供設定RadioButtonList的RroupName
Public Property GroupName() As String
Get
Return Me._GroupName
End Get
Set(ByVal value As String)
Me._GroupName = value
'把GropuName存在ViewState中,預防postback時消失
If IsNothing(Me.ViewState("GroupName")) Then
Me.ViewState("GroupName") = value
End If
End Set
End Property
'註冊一行會呼叫 function SetSameGroup( )的script到畫面
Private Sub SetSameGroup()
Dim StrScript As String
StrScript = "SetSameGroup('" & Me.ClientID & "$RadioButtonList','" &
Me.ViewState ("GroupName") & "');" & vbNewLine
ScriptManager.RegisterStartupScript(Me.Page, Me.Page.GetType(), Me.RadioButtonList.ClientID, StrScript, True)
End Sub
'畫面載入時都在註冊一次script(因為script在postback後就會自動消失)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.SetSameGroup()
End Sub
End Class
//javascript
function SetSameGroup(paramOldName, paramGroupName) {
var ObjArray = document.getElementsByTagName("Input");
var StrTemp;
for (i = 0; i < ObjArray.length; i++) {
if(ObjArray[i].type == "radio" && ObjArray[i].name == paramOldName) {
StrTemp = ObjArray[i].parentNode.innerHTML.replace(paramOldName, paramGroupName);
ObjArray[i].parentNode.innerHTML = StrTemp;
}
}
}
使用這個UserControl的畫面的.vb檔
Dim ArrayListSource1 As String() = {"aa", "bb", "cc", "dd"}
Dim ArrayListSource2 As String() = {"ee", "ff", "gg", "hh"}
Me.UCRadioBtnList1.Items = ArrayListSource1 '加入選項
Me.UCRadioBtnList2.Items = ArrayListSource2
Me.UCRadioBtnList1.GroupName = "sss" '設定GroupName
Me.UCRadioBtnList2.GroupName = "sss"
By Felix
標籤:
DOM,
Javascript,
WebForm
訂閱:
文章 (Atom)