2010年5月25日 星期二

ASP 頁面編碼造成自動 Refresh

今天遇到一個超怪的問題
我在ASP前面幾行讀取前頁submit過來的資料
將資料更新回DB

發現更新完成的訊息居然會重複alert 2次

查了好久的網路才查到一點眉目
可能是因為頁面編碼(Charset)的問題

我在HTML head中有寫一行
<meta http-equiv="Content-Type" content="text/html; charset=big5">
但其實這行的意義是指
此頁的表單資料要用什麼編碼方式submit出去
並非是指這頁要用什麼編碼方式顯示
詳見保哥寫的一篇[關於各瀏覽器對網頁與文字編碼的處理規則研究整理]

想要設定本頁要用什麼編碼方式顯示
在ASP中,要使用
<%response.charset = "big5"%>
加上這行,我的ASP就一切正常了

個人推測此次的原因為:

一開始沒有設定本頁顯示的編碼
所以一開始預設用utf-8編碼來顯示本頁資料
直到程式開始讀取DB的資料時
發現DB是用big5編碼儲存資料的
所以瀏覽器自動refresh本頁,改變編碼為big5

而更新DB的程式段剛好又在讀取DB資料之前
造成一開始用utf-8編碼顯示頁面時,進行更新,並alert更新完成的訊息
後來遇到程式讀取DB資料,自動refresh本頁後,不會再次更新,但會再alert更新完成的訊息

以此推論 :
因資料與頁面的編碼不符時
僅會refresh client端頁面資料 (並沒有對server再次發出request)
所以ASP程式段不會重複執行
但是client端的javascript全都會重複執行

但我剛好也有另一支程式也是用這種結構寫的
卻沒有這個問題
所以詳細原因還要在釐清...

另外補充一下 :
在 HTML head 中的程式段
好像不會依改變編碼而重新執行
<html>
   <head>
     <script language="javascript">
        alert("Hello World!");
     </script>
   </head>
   <body>

   </body>
</html>

2010年5月21日 星期五

ASP 讀取網站資料夾下檔案

用 ASP 讀取網站資料夾下所有檔案名稱 (包含子資料夾下的檔案)
function  : GetFiles
input 1 : 網站相對路徑
input 2 : 0 (int)
output : 2D Array
             (0, n) : 檔案的 FullName (包含網站相對路徑)
             (1, n) : 檔案的 Name

<%
   dim TemporaryFiles()
   function GetFiles(Path, FileCount)
      set fs = Server.CreateObject("Scripting.FileSystemObject")
      realfilepath = Server.Mappath(Path)
      if fs.FolderExists(realfilepath) = true then
         set folder = fs.GetFolder(realfilepath)
         ' 將目前資料夾下的檔案名稱放入陣列
         for each f in folder.files
            redim preserve TemporaryFiles(2, FileCount+1)
            TemporaryFiles(0, FileCount) = Path & "/" & f.Name
            TemporaryFiles(1, FileCount) = f.Name
            FileCount = FileCount + 1
         next
         ' 繼續找有沒有子資料夾, 有的話, 遞迴掃裡面的檔案和資料夾
         for each subfolder in folder.SubFolders
            call GetFiles(Path & "/" & subfolder.Name, FileCount)
         next
         set folder = nothing
      else
         redim TemporaryFiles(2, 1)
         TemporaryFiles(0, 0) = ""
         TemporaryFiles(1, 0) = "The path is not exist !"
      end if
      set fs = nothing
      GetFiles = TemporaryFiles
   end function
%>

<%
   ' 呼叫 function
   FileArray = GetFiles("UserUpload", 0)
   for i = 0 to ubound(FileArray,2)
      response.write FileArray(0,i) & <br>
      response.write FileArray(1,i) & <br>
   next
%>

HTML/CSS/Javascript 設定 Table 背景色

常搞不清楚 HTML , CSS , Javascript 設定 Table 背景色的語法
特別在這邊記錄一下

[ HTML ]
使用 bgcolor (table / tr / td 都適用)
範例:
   <table bgcolor="#FF0000" border="1">
      <tr><td>Line 1</td></tr>
      <tr><td>Line 2</td></tr>
   </table>
結果:
Line 1
Line 2


[ CSS ]
使用 background-color (table / tr / td 都適用)
範例:
   <table border="1">
      <tr style="background-color:#00FF00"><td>Line 1</td></tr>
      <tr><td>Line 2</td></tr>
   </table>
結果:
Line 1
Line 2


[ Javascript ]
使用 obj.style.backgroundColor (table / tr / td 都適用)
範例:
   <table border="1">
      <tr><td>Line 1</td></tr>
      <tr><td onmouseover="this.style.backgroundColor='#0000FF'"
                  onmouseout="this.style.backgroundColor=''">
            Line 2
      </td></tr>
   </table>
結果:
Line 1
Line 2

2010年5月18日 星期二

正規表達式彙整

順便整理一下 javascript / vbscript (ASP) / C#
三者的正規表達式使用方式

javascript
宣告var RegObj = /pattern/attribute;
屬性i: case-insensitive / g: global / m: multiline matching
比對RegObj.test(target_string);
return true / false
取出
符合文字
var Result = RegObj.exec(target_string);
搭配g, 可以重複使用exec(), 依序取出符合文字
取代
符合文字
target_string.replace(RegObj,replace_string);
return取代後的文字
搭配Global, 可以將所有符合的文字取代
參考 W3CSchools

vbscript (ASP)
宣告Set RegObj = new regexp
RegObj.Pattern = pattern
屬性RegObj.IgnoreCase = true | false
RegObj.Global = true | false
比對RegObj.test(target_string)
return true / false
取出
符合文字
Set Result = RegObj.execute(target_string)
return一個Collection, 以Result(0) 方式讀取
搭配Global, 可以取出所有符合的文字Collection
取代
符合文字
RegObj.replace(target_string,replace_string)
return取代後的文字
搭配Global, 可以將所有符合的文字取代
參考 MSDN

C#
宣告Regex RegObj = new Regex(pattern[,attribute]);
屬性RegexOptions.IgnoreCase / RegexOptions.Multiline ...
比對RegObj.IsMatch(target_string);
return true / false
取代
符合文字
RegObj.Replace(target_string,replace_string);
return取代後的文字
參考 MSDN, mikesdotnetting

ASP 正規表達式

前面寫了篇 Javascript 正規表達式
這邊當然也要補上一篇 ASP 正規表達式的用法

範例 :
<%
   Pwd = "9901"

   Set RegPwd = new regexp
   RegPwd.Pattern = "^\d{6,8}$"
   RegPwd.IgnoreCase = true  '// 忽視大小寫
  
   if RegPwd.Test(Pwd)=false then
      response.write "Password is error !" & "<br>"
   else
      response.write "Welcome !" & "<br>"
   end if
  
   TestStr = "Welcome 16547 to the show!"
  
   Set RegStr = new regexp
   RegStr.Pattern = "\d"
  
   RegStr.Global = true
   '//true:整個字串進行比對, false:只找出符合的第一個   
   '//Default 為false
  
   Set MatchObj = RegStr.Execute(TestStr)
   For each obj in MatchObj
      response.write obj & "<br>"
   Next
  
   response.write RegStr.Replace(TestStr,"") & "<br>"
  
%>

ASP 動態增加陣列長度

前面寫了篇 Javascript 動態增加陣列長度
這邊順便記錄一下 ASP 動態陣列的使用方式

一般 vbscript 宣告陣列是 dim Arr(10)
要使用動態陣列有 2個步驟

1. dim Arr()  <-- 這邊不要給陣列長度
2. redim [preserve] Arr(a)  <-- 利用 redim 重新定義陣列長度

ps.1 原先用 dim Arr(f) 方式宣告陣列, f 必須為常數, 也就是 1,2,3,...
  而 redim Arr(a) 方式宣告陣列, a 可以是變數, a = 5, redim Arr(a)

ps.2 preserve 是 option, 代表是否要保留原本陣列中的資料
  如果是多維陣列, 設了 preserve 後, 只能變動最後一維的長度
  (如果 redim 後的陣列長度小於原先長度, 超出長度的資料會消失)

範例 :
<%
   dim MyArray()
   for i=1 to 9
      redim preserve MyArray(i)
      MyArray(i-1) = i*5
   next
   ' 陣列最後長度是10 (0~9)
   ' 所存資料有9個, 依序為5,10,15,...,45
%>

CSS Hack

現在寫網頁最討厭的就是瀏覽器不同
CSS 顯示的效果也不同
所以這邊記錄一下各瀏覽器支援的 CSS Hack 寫法

p=property / v=value
p:v;p:v \9;*p:v;_p:v;p:v !important;
Firefox
IE6
IE7
IE8

範例 :
<style type="text/css">
   #container {
      width:200px; /* for Firefox */
      width:205px \9; /* for IE8 */
      *width:210px; /* for IE7 */
      _width:215px; /* for IE6 */
   }
</style>

2010年5月17日 星期一

Javascript 更新畫面

前面寫了一篇 子頁更新母頁畫面(showModalDialog)
這邊來寫一下一般的更新畫面方式

[更新自己這頁]
<script language="javascript">
   //第一種方法 : history.go()
   history.go(0);
   //第二種方法 : window.location.reload()
   window.location.reload();
   //第三種方法 : window.location.href
   window.location.href = window.location.href;
</script>

[更新父頁]
<script language="javascript">
   /* 以window.open開出來的新視窗 */
   /* 父頁就是window.opener */
   window.opener.history.go(0);
   window.opener.location.reload();
   window.opener.location.href = window.opener.location.href;

   /* 以window.showModalDialog開出來的新視窗 */
   /* 父頁就是window.dialogArguments */
   /* (父頁的window.showModalDialog()第2個參數要傳入window) */
   window.dialogArguments.history.go(0);
   window.dialogArguments.location.reload();
   window.dialogArguments.location.href =
                  window.dialogArguments.location.href;
   //其中,IE8針對showModalDialog好像只支援location.href的方式
</script>

Javascript 正規表達式

常常用到正規表達式
所以記錄一下在 Javascript 中的用法

<script language="javascript">
   var str = "46 Ladys and Gentleman~\nWelcome 12 to the show !";
   document.write("Test string : <br>" + str.replace("\n","<br>") + "<br><br>");
 
   var RegStr_NoGlobal = /\d/;
   /* 使用g(Global)參數時,RegExp在做test()或exec()時 */
   /* 會保存一個指標lastIndex,記錄上次查詢結束的位置。 */
   /* 第一次test()後,lastIndex就指向字串結尾 */
   /* 第二次test()由結尾開始查,啥都查不到,就傳回false,*/
   /* 然後再把lastIndex重設為0。 */
   var RegStr_Global = /\d/g;
   var RegStr_NoIgnoreCase = /wel/;
   var RegStr_IgnoreCase = /wel/i;
   var RegStr_NoMultiLine = /^Wel/;
   var RegStr_MultiLine = /^Wel/m;
   var RegStr_Variable = /[a-z]+([a-z]{2}) /gi;
 
   var result;
 
   result = RegStr_NoGlobal.exec(str);
   document.write("No-Global Round1 : " + result + "<br>");
   result = RegStr_NoGlobal.exec(str);
   document.write("No-Global Round2 : " + result + "<br>");
 
   result = RegStr_Global.exec(str);
   document.write ("Global Round1 : " + result + "<br>");
   result = RegStr_Global.exec(str);
   document.write ("Global Round2 : " + result + "<br><br>");
 
   result = RegStr_NoIgnoreCase.exec(str);
   document.write("No-IgnoreCase : " + result + "<br>");
 
   result = RegStr_IgnoreCase.exec(str);
   document.write("IgnoreCase : " + result + "<br><br>");
 
   result = RegStr_NoMultiLine.exec(str);
   document.write("No-MultiLine : " + result + "<br>");
 
   result = RegStr_MultiLine.exec(str);
   document.write("MultiLine : " + result + "<br><br>");
 
   result = RegStr_Variable.exec(str);
   document.write("Match string : " + result[0] + " , Match variable : " + result[1] + "<br>");
   result = RegStr_Variable.exec(str);
   document.write("Match string : " + result[0] + " , Match variable : " + result[1] + "<br>");
   result = RegStr_Variable.exec(str);
   document.write("Match string : " + result[0] + " , Match variable : " + result[1] + "<br>");
   result = RegStr_Variable.exec(str);
   document.write("Match string : " + result[0] + " , Match variable : " + result[1] + "<br>");
   result = RegStr_Variable.exec(str);
   document.write("Match string : " + result[0] + " , Match variable : " + result[1] + "<br>");
</script>

Javascript 動態增加陣列長度

記錄一下 Javascript 如何動態增加陣列長度
只要使用 splice function 就 ok 囉~

範例 :
<script language="javascript">
  /* Array.splice(要插入新元素的位置, */
  /*                     要刪除插入新元素位置後的舊元素個數, */
  /*                     新元素值1, */
  /*                     新元素值2, */
  /*                     ... )           */
   function Case1()
   {
       myArray = new Array(3);
       myArray[0] = "Row1";
       myArray[1] = "Row2";
       myArray[2] = "Row3";
       myArray.splice(myArray.length ,0 ,"Row4");
       /* result: Row1 Row2 Row3 Row4 */
   }

   function Case2()
   {
       myArray = new Array(3);
       myArray[0] = "Row1";
       myArray[1] = "Row2";
       myArray[2] = "Row3";
       myArray.splice(1 ,1 ,"Row4", "Row5");
       /* result: Row1 Row4 Row5 Row3 */
   }
</script>

Where條件區分大小寫(T-SQL)

最近查了一下 SQL Server 中如何區分文字(英文)資料的大小寫
所以記錄一下 :

  重點就是要在 Where 條件的欄位後面加上
  Collate SQL_Latin1_General_CP1_CS_AS
  (CS 代表 Case Sensitive)

範例 :
  SELECT * FROM (
   SELECT 'Test' AS Col1
  ) AS A
  WHERE Col1 Collate SQL_Latin1_General_CP1_CS_AS = 'test'

[參考TechNet]

2010年5月16日 星期日

子頁更新母頁畫面(showModalDialog)

最近頻繁地使用到 window.showModalDialog()
跳出子視窗新增 / 刪除資料, 再更新(Refresh)母視窗的畫面
所以這邊記錄一下當中做法

[showModalDialog 參數]
dialogHeightdialogHeight=150px;
dialogWidthdialogWidth=400px;
dialogLeftdialogLeft=100px;
dialogTopdialogTop=50px;
centercenter=yes;
helphelp=no;
resizableresizable=no;
statusstatus=no;
scrollscroll=yes;

子頁更新母頁:
[母頁.htm]
<script language="javascript">
   function OpenChild()
   {
      DialogParam = "dialogWidth=100px;dialogHeight=400px;";
      DialogParam += "status=no;resizable=no";
      window.showModalDialog("子頁.htm",window,DialogParam);
   }

   function RefreshPage()
   {
      var RefreshLink = document.getElementById("RefreshLink");
      RefreshLink.href = "母頁.htm";
      RefreshLink.click();
   }
</script>
<body>
   <a id="RefreshLink" style="display:none"></a>

[子頁.htm]
<script language="javascript">
   function RefreshParent()
   {
      window.dialogArguments.RefreshPage();
   }
</script>

ps.這種方式也適用於showModalDialog出來的視窗
再使用showModalDialog開新視窗
不過,第一個showModalDialog視窗頁面要加一行
<head>
   <base target="_self">
因為showModalDialog視窗預設所有Link都會另開視窗
加了這行後,點選更新畫面Link就會在自己這頁動作
不會另開視窗