2012年2月23日 星期四

javascript 上的 reverse()


字串的反轉,在 SQL、C# 使用 Reverse 就可以輕鬆完成。但同樣的需求發生在 javascript 上,卻有點不一樣。在 javascript 裡,並非不支援 Reverse,而是 Reverse 的對象不是字串,而是陣列。所以在使用上,就不能直接呼叫使用,必須稍微做些調整。

看了網路上所介紹到方法,大約可分成兩類:

第一種:透過迴圈方式,將字串由後往前抓一遍
String.prototype.reverse = function() {
    var s = "";
    var i = this.length;
    while (i>0) {
        s += this.substring(i-1,i);
        i--;
    }
    return s;
}

var s="paladin";
alert(s.reverse());
 

第二種:把字串轉成陣列,並將陣列反轉後再組成字串
String.prototype.reverse=function(){return this.split("").reverse().join("");}

var s="paladin";
alert(s.reverse());

個人還蠻喜歡第二種寫法,太簡潔了。日後只需要用:


alert("paladin".split('').reverse().join(''));

就可以把名字倒過來寫了。

此外,還有一個很少使用到的 html 標籤 <bdo>,它可以不透過 javascript 就直接將字串反轉,甚至 <bdo> 標籤裡頭所包含的物件呈現順序也是可以自行設定為由右至左或由左至右,只需去設定 dir 屬性即可(rtl:由右至左,ltr:由左至右)。
<div><bdo dir="rtl">paladin <img alt="1" /> <img alt="2" /></bdo></div>
參考:
01:Reverse-a-txet
02:How do you reverse a string in place in JavaScript?
03:HTML <bdo> Tag

2012年2月20日 星期一

讓 GridView 具有簡單又不失專業的 EmptyDataTemplate


使用 GridView 時,如果它的資料來源沒資料時,顯示個「找不到、0筆資料...」類的訊息,似乎可以讓使用者很清楚的區別。這個功能只需要在 <EmptyDataTemplate>做些訊息的設定即可。但如果是希望即使沒資料,也必須讓 GridView 的 Header 都顯示出來,或是有自訂的樣式時,那要怎麼處理呢?

我在 sidesofmarch 的「Cleaning up the GridView’s EmptyDataTemplate (damn those tables!)」發現了作者的怒吼,認為與其花很多時間在研究 <EmptyDataTemplate>,不如簡單地去判斷是否資料來源有資料,如果沒有,則隱藏目前的 GridView,再進一步去顯示自己所要顯示的資訊。

另外也比較了「ListView EmptyDataTemplate - how to use EmptyDataTemplate」這篇文章,透過 CSS 的定義去達成效果,似乎比較符合自己目前的期待,但如果能夠有更簡單一點的作法,會比較漂亮一些。

更仔細點觀察 GridView ,當我有設定 <EmptyDataTemplate> 且資料來源為 0 時,如果 GridView 原先有放了 4 個欄位,則 <EmptyDataTemplate> 會產生一段 HTML Code:

<tr class="Theader"><td colspan="4"></td></tr>

不管日後在  <EmptyDataTemplate> 放任何東西,都會放在 <td colspan="4"> 裡面,如此就會讓我原先已經套好視覺的 GrideView 顯得與既有的其它 GridView 看起來就會有點不一樣,有點怪,有點壞。

不過,我發現,如果在 <EmptyDataTemplate> 設定一個自訂的 <tr>:

<tr><th>上傳文件</th><th>上傳日期</th><th>說明</th><th>建檔人</th></tr>

,則所產生出來的 HTML,就會有兩個 <tr>,也就是:

<tr><td colspan="4"></td></tr>
<tr><th>上傳文件</th><th>上傳日期</th><th>說明</th><th>建檔人</th></tr>





這樣子的效果,除了第一個 <tr>會讓畫面很突兀外,基本上都已經滿足我的需求了。為了讓第一個 <tr>在畫面上消失,我試著使用 jQuery 把它隱藏起來。

在  <EmptyDataTemplate> 裡,我放入:
<tr class="tr_empty"><th>上傳文件</th><th>上傳日期</th><th>說明</th><th>建檔人</th></tr>


jQuery 則是:
<script>
    $(function () {

        $(".tr_empty").each(function () {

            $(this).parent().find("tr").first().hide();

        });

    });

</script>


這段 jQuery,是在頁面上搜尋所有有定義 class name 為 tr_empty 的物件,往上找到他的父親,<tbody>,再從 <tbody> 裡面往下搜尋第一個 <tr>,並將其隱藏。

這樣就可以將第一個 <tr>隱藏,只剩下我所要呈現的第二個 <tr>

參考:
01:Cleaning up the GridView’s EmptyDataTemplate (damn those tables!)
02:ListView EmptyDataTemplate - how to use EmptyDataTemplate

2012年2月17日 星期五

讓頁尾永遠放在下面

一般來說,網頁的頁首應該要擺最上面,頁尾要擺最下面,中間則是放些比較正經的內容。但如果某個頁面實在乏善可陳,就容易出現頁尾下方空出一大片空白的現象,如何把頁尾永遠放到最下面,真的只是「面子」問題,單純就是看得比較順眼就是了。


在「jQuery教學-重現DIV區塊高度100%的夢想」提到了 autoheight.js ,會透過 jQuery 去計算扣掉頁首、頁尾後需要擴展的內文高度,實際練習後發現非常簡單,真不愧為作者所號稱的懶人包。

使用時,記得將 jQuery 以及  autoheight.js 引用:


 
<script src="Scripts/jquery-1.6.4.min.js" type="text/javascript"></script>
<script src="Scripts/autoheight.js" type="text/javascript"></script>

在網頁的排版上,將頁首、內文、Footer 分別各放在一個 Div 裡,參考一下作者所提供的類別定義:


  • none="ture"->直接取得實際高度,排除所有CSS的設,如:border、margin、padding等。
  • _height="none"->扣除高度。
  • _height="auto"->高度100%
所以我的頁面上,大至會有以下安排:
   <div _height="none"> 頁首
   <div _height="auto"> 內文
   <div _height="none"> 頁尾

如此便可以簡單達成頁首、頁尾分別擺放在網頁的上面以及下面。

參考:梅問題:jQuery教學-重現DIV區塊高度100%的夢想

備份下載 :autoheight.js

2012年2月15日 星期三

福禍相依

《韓非‧解老》解釋福與禍的關係時說:「人有禍則心畏懼,心畏懼則行端直,行端直則思慮熟,思慮熟則明事理。」反之,「人有福則富貴至,富貴至則衣食美,衣食美則驕心生,驕心生則行邪僻而動棄理」。

因此,人活在世界上,要經常保持警覺狀態,如老子所說:「保此道者不欲盈。夫唯不盈,故能敝而新成。」常常讓自己處在不圓滿的狀態中,就會自我要求,繼續成長。不管遇到壞事還是好事,都要看長遠一點。順利的時候,要提醒自己居安思危;倒楣的時候,也千萬不要灰心喪氣。

舉一個千年前吳越的故事來說明。吳王夫差的爸爸名為闔閭,他在對越國的一場戰役中,受到勾踐的突擊而傷重不治。臨死前,召喚夫差於榻前對他說:「你會忘了勾踐殺父的仇怨嗎?」夫差回答:「誓不敢忘!」待夫差即位後,他命令大臣,每天早朝時,都要提醒他三次:「夫差,你忘了勾踐的殺父之仇了嗎?」。然後夫差就會馬上回答:「誓不敢忘,父仇不共戴天!」。

夫差每天都要這樣砥礪自己、提醒自己,於是做到了: 「人有禍則心畏懼,心畏懼則行端直,行端直則思慮熟,思慮熟則明事理。

果然夫差的努力並沒有白費,在下一場的吳越 PK 戰中,夫差大敗勾踐,逼得勾踐不只讓越國成為吳國的屬國,還自願到吳國當奴僕。自此開始,勾踐開始不斷地把金銀財寶、絕世美女,一車一車載往吳國的王宮中。夫差自從報仇之後,每天上朝時,也就免了「你會忘了勾踐殺父的仇怨嗎?」的劇碼,開始享受越國所提供的大量美女與金銀財寶了。

沒多久,「人有福則富貴至,富貴至則衣食美,衣食美則驕心生,驕心生則行邪僻而動棄理」就開始靈驗了。夫差開始因貪戀美色而多日不上班,老臣伍子胥嘮叨久了,更因此而開始加深這對君臣間的裂痕,最後伍子胥竟被夫差賜死。

在此同時,勾踐也開始模仿夫差早先的勵志作法。史記記載著:「吳既赦越,越王勾踐返國,乃苦身焦思,置膽於坐,坐臥即仰膽,飲食亦嚐膽也」,開始了所謂的「臥薪嘗膽」的生活。「人有禍則心畏懼,心畏懼則行端直,行端直則思慮熟,思慮熟則明事理。」這句話的力量,又再次被體現了,只是這次已從夫差換成勾踐。


參考:

01:原來老子這樣說
02:千秋商祖范蠡

踩到 AjaxControlToolkit 3.5 的地雷


今天開開心的下載了最新版的 AjaxControlToolkit 4.0,也把它整合到我的 VS2010,想測測 Tab 功能。但腦筋突然閃過「User 那邊只有 .Net 3.5 的環境」,就只好再回去下載 AjaxControlToolkit 3.5。

我將 VS2010 的環境調整為 .net framework 3.5 ,也同時將  AjaxControlToolkit 3.5 加入了參考,但執行時,卻跑了錯誤出來。

AjaxControlToolkit requires ASP.NET Ajax 4.0 scripts. Ensure the correct version of the scripts are referenced. If you are using an ASP.NET ScriptManager, switch to the ToolkitScriptManager in AjaxControlToolkit.dll.

真是奇怪了,明明就下載 AjaxControlToolkit 3.5 的版本,卻要求我要用 4.0 ,這樣對嗎?仔細消化了這一段錯誤訊息,終於瞭解了他想要描述甚麼。不過這突然讓我反省到,自己所寫的系統發出錯誤訊息時,往往只是「系統發生錯誤,請聯絡 XXX」。相較之下,人家已經比我詳細多了。

原來我在使用 AjaxControlToolkit 所提供的元件時,依例都會在頁面最上面擺放一個 <asp:scriptmanager id="ScriptManager1" runat="server"> </asp:scriptmanager>,但是這個錯誤訊息,是叫我不要使用 ScriptManager ,改成用 ToolkitScriptManager。問題是,要怎麼改才對呢? 原來,是要改成以下方式:

<asp:toolkitscriptmanager id="ScriptManager1" runat="server"></asp:toolkitscriptmanager>

如此修改後,程式就可以正常執行了。另外,In 91 有說章立民老師文章中提及的「為了讓JavaScript檔案能夠先壓縮再下載,以便提昇下載效率並降低請求(Request)次數,請大家在設計ASP.NET AJAX網頁時,應該盡量使用ToolkitScriptManager來取代ScriptManager。」,倒是意外的發現。

參考:http://www.dotblogs.com.tw/hatelove/archive/2009/02/17/7211.aspx