在 asp.net ,如果你在 .aspx.cs 頁面要取得目前頁面 url 的資訊,可以透過 Request.Url 。但如果你的程式是那種很有架構性的,也就是分了好幾層,如 MVC 之類,你可能有時候偷懶,希望在底層自己定義的類別裡,也想要抓取使用者目前頁面的 URL 資訊,這時候,Request.Url 就失效了。這時,你可以透過以下程式來完成 :
HttpContext.Current.Request.Url
HttpContext 是 .Net Framework 一個重要類別,他封裝了有關 HTTP 請求的所有 HTTP 特定的訊息。所以透過 HttpContext ,我們可以取得最原始的 HTTP 相關資訊。
參考:http://www.ourys.com/post/109.html
2010年3月31日 星期三
2010年3月18日 星期四
重新指定 SQL 自動編號
SQL Server 的資料欄位型態如果有設定為 IDENTITY,可以省下我們為資料編號的力氣。但如果你想要保留現有資料,且新資料要從指定的號碼開始編(例如:10000 開始),那可以使用下面三行指令來完成:
--關閉自動編號
SET IDENTITY_INSERT tmp_table ON
--重新指定自動編號起始位置
DBCC CHECKIDENT (tmp_table, reseed, 10000)
--開啟自動編號
SET IDENTITY_INSERT tmp_table OFF
參考:http://www.dotblogs.com.tw/chhuang/archive/2008/04/18/2944.aspx
--關閉自動編號
SET IDENTITY_INSERT tmp_table ON
--重新指定自動編號起始位置
DBCC CHECKIDENT (tmp_table, reseed, 10000)
--開啟自動編號
SET IDENTITY_INSERT tmp_table OFF
參考:http://www.dotblogs.com.tw/chhuang/archive/2008/04/18/2944.aspx
2010年3月5日 星期五
jQuery 民國年日曆
遇到有日期欄位的需求時,常常都會需要在旁邊加個小日曆以供挑選,這小日曆其實不難在網路上找到相關的免費又好用的程式。但是如果要強調以民國年來顯示,雖然知道一定會有人寫,但要找到好用又夠用的,還真的要花些時間。
就是因為找了好多炷香的時間,所以不得不將自己認為還不錯的日期挑選程式記錄下來。在羅必達工作室,我看到一篇 「jQuery DatePicker 日期選擇(民國年)」的文章,寫的真的很棒。如果對於作者開發的來龍去脈有興趣的話,可以進一步去參考他的文章。
擷取執行畫面如下:
測試程式:
就是因為找了好多炷香的時間,所以不得不將自己認為還不錯的日期挑選程式記錄下來。在羅必達工作室,我看到一篇 「jQuery DatePicker 日期選擇(民國年)」的文章,寫的真的很棒。如果對於作者開發的來龍去脈有興趣的話,可以進一步去參考他的文章。
擷取執行畫面如下:
測試程式:
<script type="text/javascript"> $(function() { //設定 tbx_DateNeed_start 為日期挑選欄位 $('input[id*=tbx_DateNeed_start]').datepicker({ dateFormat: 'yymmdd', showOn: 'button', buttonImageOnly: true, buttonImage: '../images/calendar.gif', formatYear:function(v){return '民國'+(v-1911)+'年';} }); }); </script>
2010年3月4日 星期四
jQuery 的 extend 與 fn.extend 差別
使用擴展的好處,是讓你透過 jQuery 去定義原先不存在的功能,方便你擴充 jQuery 既有的功能。在探討 jQuery 的擴展功能時,也因此就會分為兩類:靜態全域 ,或 需依附於元素。
jQuery.extended
所定義的 add 方法, jQuery 任何時候都可以叫用。
jQuery.fn.extend
所定義的 red 方法,必須是某個 jQuery 所挑選到的元素才能使用。如範例,符合 $('#test') 的所有元素,都可以執行 red( )。
上述所介紹,都是針對 jQuery 原先所沒有的功能而進行新增。但有個問題來了,假設如果原先就已經存在了某個方法 add( ),但擴展的方法也同樣有個方法 add( ),那不就鬧雙包?接下來的問題,則是要以誰的為主?是元配,還是新歡呢?通常都是只見新人笑,不見舊人哭囉~在 jQuery 官網上可以找到這問題的處理方式。
情況一:合併兩個物件,後面的物件內容會覆蓋前面的物件內容
情況二:合併兩個物件,後面物件內容裡的詳細屬性會覆蓋前面內容裡的詳細屬性(若前面內容裡的詳細屬性沒有重複,會被保留下來,也可視為深層合併)
情況三:合併兩個物件,但不會影響到這兩個物件的預設值。這是常見的 plug-in 開發模式作法。
綜合以上三個範例,
如果你想要對合併物件進行深層的物件合併,要在第一個參數加上 true
如果你不想影響2個合併物件的預設值,要採用情況三的開發模式
而其他,就是後面物件蓋掉前面物件了
參考:
1. http://blog.tugai.net/2009/07/22/jquery-fn-extend/
2.http://www.cnblogs.com/rhythmK/archive/2009/10/19/1585847.html
3.http://hzjavaeyer.group.javaeye.com/group/blog/232971
4.http://api.jquery.com/jQuery.extend/
- 靜態全域 (jQuery.extended)
定義後,只需使用 jQuery 的前置符號就可以使用。 - 需依附於元素(jQuery.fn.extend)
定義後,只針對 jQuery 所選取的元素有效。
jQuery.extended
所定義的 add 方法, jQuery 任何時候都可以叫用。
<script> jQuery.extend({ add: function(a, b) { return a + b; } }); alert($.add(3, 4)); //7 </script>
jQuery.fn.extend
所定義的 red 方法,必須是某個 jQuery 所挑選到的元素才能使用。如範例,符合 $('#test') 的所有元素,都可以執行 red( )。
<script> jQuery.fn.extend({ red: function() { return $(this).css('color', '#ff0000'); } }); $('#test').red(); </script>
上述所介紹,都是針對 jQuery 原先所沒有的功能而進行新增。但有個問題來了,假設如果原先就已經存在了某個方法 add( ),但擴展的方法也同樣有個方法 add( ),那不就鬧雙包?接下來的問題,則是要以誰的為主?是元配,還是新歡呢?通常都是只見新人笑,不見舊人哭囉~在 jQuery 官網上可以找到這問題的處理方式。
情況一:合併兩個物件,後面的物件內容會覆蓋前面的物件內容
var object1 = { apple: 0, banana: {weight: 52, price: 100}, cherry: 97 }; var object2 = { banana: {price: 200}, durian: 100 }; $.extend(object1, object2);
//結果 object1 === {apple: 0, banana: {price: 200}, cherry: 97, durian: 100}
情況二:合併兩個物件,後面物件內容裡的詳細屬性會覆蓋前面內容裡的詳細屬性(若前面內容裡的詳細屬性沒有重複,會被保留下來,也可視為深層合併)
var object1 = { apple: 0, banana: {weight: 52, price: 100}, cherry: 97 }; var object2 = { banana: {price: 200}, durian: 100 }; $.extend(true, object1, object2);
//結果 object1 === {apple: 0, banana: {weight: 52, price: 200}, cherry: 97, durian: 100}
情況三:合併兩個物件,但不會影響到這兩個物件的預設值。這是常見的 plug-in 開發模式作法。
var empty = {} var defaults = { validate: false, limit: 5, name: "foo" }; var options = { validate: true, name: "bar" }; var settings = $.extend(empty, defaults, options);
//結果 settings == { validate: true, limit: 5, name: "bar" } empty == { validate: true, limit: 5, name: "bar" }
綜合以上三個範例,
如果你想要對合併物件進行深層的物件合併,要在第一個參數加上 true
如果你不想影響2個合併物件的預設值,要採用情況三的開發模式
而其他,就是後面物件蓋掉前面物件了
參考:
1. http://blog.tugai.net/2009/07/22/jquery-fn-extend/
2.http://www.cnblogs.com/rhythmK/archive/2009/10/19/1585847.html
3.http://hzjavaeyer.group.javaeye.com/group/blog/232971
4.http://api.jquery.com/jQuery.extend/
2010年3月3日 星期三
網頁除錯工具 firebug
FireFox 提供了一個外掛的 plug-in 軟體:firebug 。可以透過它對網頁上的 javascript 進行除錯工作,甚至可支援 javascript 的單步執行除錯。在除錯過程中,也可以隨時顯示每個變數目前的數值狀況。相信對於網頁上複雜的 javascript 撰寫會有很大的幫助。
推薦幾個不錯的介紹網址:
http://blog.wu-boy.com/2010/01/05/1943/
http://caterpillar.onlyfun.net/Gossip/AjaxGossip/FireBug.html
http://getfirebug.com/enable
自己實際下載後,試著執行一段簡單的 code :
沒想到就出現 『主控台 panel is disabled』的訊息。
還好,原來是 firebug 預設就會關閉 主控台 的功能。只要去將主控台的下拉點選下去,並挑選 Enabled ,就可以正常執行了。
常用指令:
1. console.log(); 將變數的值輸出到主控台
2. debugger; 開始 單步除錯
推薦幾個不錯的介紹網址:
http://blog.wu-boy.com/2010/01/05/1943/
http://caterpillar.onlyfun.net/Gossip/AjaxGossip/FireBug.html
http://getfirebug.com/enable
自己實際下載後,試著執行一段簡單的 code :
<script> var a = "test"; console.log("a is %s ", a); </script>
沒想到就出現 『主控台 panel is disabled』的訊息。
常用指令:
1. console.log(); 將變數的值輸出到主控台
2. debugger; 開始 單步除錯
2010年3月2日 星期二
GridView 的 Sorting (排序) 、Paging(分頁) 與 DataSourceID 的關係
在 VS2005 提供了 GridView 控制項,一般的工具書都會介紹 GridView 控制項搭配 SqlDataSource 來介紹,一派輕鬆地告訴你,只要使用 GridView 的 DataSourceID ,之後如果要排序或分頁,只需將 GridView 的 AllowSorting 或 AllowPaging 設為 True,就可以自動完成排序或分頁的功能,不需要寫一行程式喔。
GridView 資料來源的取得,有兩種方式:一種是透過 DataSourceID, 另一種則是 DataSource。而這兩種方式,你只能選擇一種,不能太貪心。DataSourceID,他只能指定給 SqlDataSouce,AccessDataSource, ObjectDataSource, XmlDataSource 等使用。至於 DataSource,你可以給他 DataSet , DataView , DataTable...,或是任何有實作 IEnumerable, IListSource, IDataSource, IHierarchicalDatasource介面的都可以。
可是,也許是我們太過於期待 GridView 不需寫程式的特色,所以會舉一反三地將另一種狀況也希望 GridView 幫我們完成。如果今天我的 GridView 資料來源是使用 DataSource 而不是 DataSourceID,那 GridView 是否也可以自動幫我們完成排序或分頁工作呢?
很不幸的,不可以,雖然你可以看到 GridView 標頭出現可供排序的超連結符號,但你壓下去會出現:由 GridView 'gvtest' 引發但尚未處理的事件 Sorting。
你也可以看到出現了分頁的頁碼超連結,但當你壓下去,會出現:由 GridView 'gvtest' 引發但尚未處理的事件 PageIndexChanging。
這也沒得商量餘地,只得乖乖去寫幾段控制分頁或排序的程式了。
針對排序的功能:
你需要去撰寫 gv_Sorting( ) 的功能。
擷取一段 code 以便日後參考:
針對分頁的功能:
則需要撰寫 gv_PageIndexChanging( )功能
GridView 資料來源的取得,有兩種方式:一種是透過 DataSourceID, 另一種則是 DataSource。而這兩種方式,你只能選擇一種,不能太貪心。DataSourceID,他只能指定給 SqlDataSouce,AccessDataSource, ObjectDataSource, XmlDataSource 等使用。至於 DataSource,你可以給他 DataSet , DataView , DataTable...,或是任何有實作 IEnumerable, IListSource, IDataSource, IHierarchicalDatasource介面的都可以。
可是,也許是我們太過於期待 GridView 不需寫程式的特色,所以會舉一反三地將另一種狀況也希望 GridView 幫我們完成。如果今天我的 GridView 資料來源是使用 DataSource 而不是 DataSourceID,那 GridView 是否也可以自動幫我們完成排序或分頁工作呢?
很不幸的,不可以,雖然你可以看到 GridView 標頭出現可供排序的超連結符號,但你壓下去會出現:由 GridView 'gvtest' 引發但尚未處理的事件 Sorting。
你也可以看到出現了分頁的頁碼超連結,但當你壓下去,會出現:由 GridView 'gvtest' 引發但尚未處理的事件 PageIndexChanging。
這也沒得商量餘地,只得乖乖去寫幾段控制分頁或排序的程式了。
針對排序的功能:
你需要去撰寫 gv_Sorting( ) 的功能。
擷取一段 code 以便日後參考:
protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { ViewState["SortExpression"] = "gp_orgcdname"; //設定預設的排序欄位 ViewState["SortDirection"] = SortDirection.Ascending;//設定預設的排序方式 } } protected override void OnPreRender(EventArgs e) { BindData(); base.OnPreRender(e); } private void BindData() { //取得資料來源 DataView dv= ds.Select(new DataSourceSelectArguments() ) as DataView; if (dv != null) { //設定 排序方式 dv.Sort = string.Format("{0} {1}", ViewState["SortExpression"].ToString(), (SortDirection)ViewState["SortDirection"]==SortDirection.Ascending?"ASC":"DESC"); gv.DataSource = dv; gv.DataBind(); } } protected void gv_Sorting(object sender, GridViewSortEventArgs e) { ViewState["SortExpression"] = e.SortExpression; if (ViewState["SortExpression"].ToString() == e.SortExpression) ViewState["SortDirection"] = (SortDirection)ViewState["SortDirection"] == SortDirection.Ascending ? SortDirection.Descending : SortDirection.Ascending; else ViewState["SortDirection"] = SortDirection.Ascending; }
針對分頁的功能:
則需要撰寫 gv_PageIndexChanging( )功能
protected void gv_PageIndexChanging(object sender, GridViewPageEventArgs e) { gv.PageIndex = e.NewPageIndex; gv.DataBind(); }
2010年3月1日 星期一
在 VS2005 整合 jQuery UI Tabs
想在 VS2005 專案裡面套用 jQuery UI 的 Tabs (頁籤)功能,於是到了 http://jqueryui.com/demos/tabs/ 去挑選了一個自己喜歡的樣式,並加入到自己的專案中。可是,當我放了一個 Button 控制項後,就開始哀號了,因為只要頁面一有 Post Back 發生,jQuery UI 就會重新載入。如上面所示,假如我已經切換到第二個頁籤(逾期未簽)後,然後點選該頁籤下的任何一個會觸發 Post Back 的動作(包括排序也一樣),jQuery UI Tabs 就會重新跳回第一個頁籤。
所以,是不是應該偷偷放個什麼,好讓 Tabs 能夠記住目前的頁籤索引位置。
於是我在頁面上放了一個 hidden 欄位,並設定 runat="server" 。
<input type="hidden" id="hTag" runat="server" />
下一個問題,則是如何目前將頁籤的索引值寫入我的隱藏欄位 hTag ?我在 http://jqueryui.com/demos/tabs/ 的 Events 頁籤找到了 show 這個事件,測試了一下他所提供的 sample code,去攔 tabsshow 事件並加以利用。此外,抓取目前 Tabs 頁籤的方法為 .tabs('option', 'selected') ,於是將程式整理如下:
$(function(){ // Tabs $('#tabs').tabs().css("width","840px"); //hover states on the static widgets $('#dialog_link, ul#icons li').hover( function() { $(this).addClass('ui-state-hover'); }, function() { $(this).removeClass('ui-state-hover'); } ); $('#tabs').bind("tabsshow",function(event, ui) { GetIndex(); }); }); function GetIndex() {// 將目前的 Tab Index 存入 hTag 暫存 var $tabs = $('#tabs').tabs(); var $tagIndex=$tabs.tabs('option', 'selected'); $("input[id*=hTag]").val($tagIndex); }
程式到此,已經可以正確將目前 Tabs 頁籤切換時,將頁籤索引保存下來。但還有一個缺點,就是當頁面有 Post Back 發生時,還是沒辦法保留目前所在頁籤位置,會跳到預設的第一個。所以,需要在頁面一旦有 Post Back 時,將 Tabs 頁籤切換到目前所儲存的位置。而在 http://jqueryui.com/demos/tabs/ 的 Methods 裡有提供一個 select 方法,可以切換 Tabs 頁籤,於是就可以撰寫一段程式去完成這動作。
function SyncTab() {//如果目前的 hTag 有暫存資料,則將 Tab 與暫存資料同步 var $tagIndex=$("input[id*=hTag]").val(); if($tagIndex!='') { $('#tabs').tabs( 'select' , parseInt($tagIndex)); } }
這裡有個小地方需要注意,tabs('select', 數字參數 ) ,一定要記得傳數字參數進去,否則跳頁的效果會不正確。所以我用 parseInt( )來轉換為數字。
最後將 SyncTab() 函式放到 $(function(){ ... }) 裡面。
整個完整的 Code 如下:
<head> <script language="javascript" type="text/javascript" src="../js/jquery.js"></script> <script language="javascript" type="text/javascript" src="../js/jquery.url.min.js"></script> <link type="text/css" href="../css/cupertino/jquery-ui-1.8rc2.custom.css" rel="stylesheet" /> <script language="javascript" type="text/javascript" src="../js/jquery-ui-tab.js"></script> <script> $(function(){ // Tabs $('#tabs').tabs().css("width","840px"); //hover states on the static widgets $('#dialog_link, ul#icons li').hover( function() { $(this).addClass('ui-state-hover'); }, function() { $(this).removeClass('ui-state-hover'); } ); $('#tabs').bind("tabsshow",function(event, ui) { GetIndex(); }); //如果目前的 hTag 有暫存資料,則將 Tab 與暫存資料同步 SyncTab(); }); function GetIndex() {// 將目前的 Tab Index 存入 hTag 暫存 var $tabs = $('#tabs').tabs(); var $tagIndex=$tabs.tabs('option', 'selected'); $("input[id*=hTag]").val($tagIndex); } function SyncTab() {//如果目前的 hTag 有暫存資料,則將 Tab 與暫存資料同步 var $tagIndex=$("input[id*=hTag]").val(); if($tagIndex!='') { $('#tabs').tabs( 'select' , parseInt($tagIndex)); } } </script> </head> <body> <input type="hidden" id="hTag" runat="server" /> <div id="tabs"> <ul> <li><a href="#tabs-1">逾期未填</a></li> <li><a href="#tabs-2">逾期未簽</a></li></ul> <div id="tabs-1"> Page1 Content </div> <div id="tabs-2"> Page2 Content </div> </div> </body>
訂閱:
文章 (Atom)