龍行天下

            政 博
          隨筆 - 23, 文章 - 0, 評(píng)論 - 12, 引用 - 0
          數(shù)據(jù)加載中……

          2006年5月3日

          FckEditor中文配置手冊(cè)詳細(xì)說(shuō)明

          javascript調(diào)用方式:
          ------------------------------------
          <script. type=”text/javascript” src=”FCKeditor/fckeditor.js”></scrīpt>
          <textarea name=”content” cols=”80″ rows=”4″>
          </textarea>
          <script. type=”text/javascript”>
          var FCKeditor = new FCKeditor(”content”);
          oFCKeditor.BasePath = “FCKeditor/”;
          oFCKeditor.Height = 400;
          oFCKeditor.ToolbarSet = “Default”;
          oFCKeditor.ReplaceTextarea();
          </script>
          ------------------------------------
          如果想要使用從數(shù)據(jù)庫(kù)讀來(lái)的文本數(shù)據(jù)或者是后臺(tái)來(lái)自文件的txt/html文本數(shù)據(jù)。
          只要在
          ------------------------------------
          <textarea name=”content” cols=”80″ rows=”4″>
          </textarea>
          ------------------------------------
          中加入自己的顯示內(nèi)容的formbean對(duì)應(yīng)字段即可
          ------------------------------------
          <textarea name=”content” cols=”80″ rows=”4″>
          <c:out value=”${contentData}” />
          </textarea>
          ------------------------------------
          這樣內(nèi)容就會(huì)被顯示在FCKeditor編輯框中了,點(diǎn)擊提交按鈕以后就可以在后臺(tái)的相應(yīng)java action中得到content參數(shù)中的內(nèi)容就是頁(yè)面上FCKeditor中的內(nèi)容數(shù)據(jù)了。可以在struts/jsf中使用。
          ====================================
          由于給FCKeditor瘦身,所以常會(huì)報(bào)缺少對(duì)象支持等錯(cuò)誤,只要在FCKeditor/editor/lang中加上相應(yīng)的js語(yǔ)言文件即可。如果加載頁(yè)面失敗(FCKeditor未定義)還有一個(gè)可能就是引用FCKeditor/fckeditor.js文件路徑不對(duì)!
          關(guān)于FCKeditor瘦身要點(diǎn)如下:
          1.將FCKeditor目錄下及子目錄下所有以“_”下劃線開(kāi)頭的文件夾刪除
          2.FCKeditor根目錄下只保留fckconfig.js, fckeditor.js, fckstyles.xml, fcktemplates.xml,其余全部刪除
          3.將editor/filemanager/upload目錄下文件及文件夾清空
          4.將/editor/filemanager/browser/default/connectors/下的所有文件刪除
          5.還可以將editor/skins目錄下的皮膚文件刪除,只留下default一套皮膚(如果你不需要換皮膚的話)
          6.還可以將editor/lang目錄下文件刪除,只保留en.js, fcklanguagemanager.js, zh-cn.js, zh.js文件
          7.如果你是使用javascrīpt來(lái)調(diào)用加載FCKeditor,那么就不需要在web.xml中配置fckeditor的tag文件。
          8.還有一個(gè)問(wèn)題剛開(kāi)始使用FCKeditor的人常會(huì)遇到就怎么控制它的toolbar的大小和元素排列,其實(shí)很簡(jiǎn)單。
          在fckconfig.js中用這樣的標(biāo)簽[]來(lái)劃分每行的元素的多少,這樣就可以控制toolbar的長(zhǎng)短和大小了,具體示例參看:fckconfig.js中的toolbarset[”Default”]
          ====================================
          用fckconfig.js中的一些選項(xiàng)來(lái)控制toolbarset中控件的功能,實(shí)現(xiàn)功能裁剪:
          1):取消超鏈接中的瀏覽服務(wù)器和上傳功能,方法如下:
          ------------------------------------
          FCKConfig.LinkBrowser = true;
          FCKConfig.LinkUpload = true;
          改為:
          FCKConfig.LinkBrowser = false;
          FCKConfig.LinkUpload = false;
          ------------------------------------
          2):取消圖片鏈接中的瀏覽服務(wù)器和上傳功能,方法如下:
          ------------------------------------
          FCKConfig.ImageUpload = true;
          FCKConfig.ImageBrowser = true;
          改為:
          FCKConfig.ImageUpload = false;
          FCKConfig.ImageBrowser = false;
          ------------------------------------
          3):Dlg Button中取消高級(jí)功能,方法如下:
          FCKConfig.LinkDlgHideAdvanced = false ;
          FCKConfig.ImageDlgHideAdvanced = false ;
          改為:
          FCKConfig.ImageDlgHideAdvanced = true ;
          FCKConfig.LinkDlgHideTarget = true ;
          ------------------------------------
          下一篇介紹FCKeditor的上傳和瀏覽服務(wù)器功能,以及如何在里面實(shí)現(xiàn)動(dòng)態(tài)
          超連接,轉(zhuǎn)發(fā)到servlet經(jīng)過(guò)filter以后去調(diào)用服務(wù)器的action
          如何實(shí)現(xiàn)對(duì)應(yīng)用戶瀏覽自己的圖片的列表實(shí)現(xiàn)!
          ====================================
          FCKeditor集成java servlet可以實(shí)現(xiàn)文件的上傳和服務(wù)器端列表讀取功能FCKeditor自己提供了兩個(gè)servlet來(lái)分別實(shí)現(xiàn)上傳文件功能,和讀取服務(wù)器端文件列表功能,這兩個(gè)servlet分別為:
          com.fredck.FCKeditor.connector.ConnectorServlet(讀取文件列表)
          com.fredck.FCKeditor.uploader.SimpleUploaderServlet(實(shí)現(xiàn)文件上傳)
          1.瀏覽服務(wù)器端文件列表
          ------------------------------------
          web.xml文件中,比如:ConnectorServlet中的配置選項(xiàng):
          <init-param>
          <param-name>baseDir</param-name>
          <param-value>/UserFiles/</param-value>
          </init-param>
          意思是在瀏覽服務(wù)器上的baseDir配置指定里面的所有文件及其目錄結(jié)構(gòu)列表。
          如果你的baseDir沒(méi)有配置,Connector將會(huì)自動(dòng)創(chuàng)建一個(gè)默認(rèn)的文件夾
          UserFiles,對(duì)應(yīng)的ConnectorServlet中init()方法中代碼如下:
          ------------------------------------
          baseDir = getInitParameter(”baseDir”);
          if (baseDir == null)
          baseDir = “/UserFiles/”;
          ------------------------------------
          還想說(shuō)一下的是,F(xiàn)CKeditor的client調(diào)用server的servlet方法采用的是Ajax思想來(lái)實(shí)現(xiàn)。當(dāng)你點(diǎn)擊瀏覽服務(wù)器(browser server)的時(shí)候就會(huì)觸發(fā)一個(gè)異步的javascrīpt + xmlhttp的調(diào)用響應(yīng),后臺(tái)的servlet會(huì)去完成你要請(qǐng)求的事件,然后數(shù)據(jù)以xml方式返回給client來(lái)解析。很明顯,你要實(shí)現(xiàn)去數(shù)據(jù)庫(kù)或者其他的文件系統(tǒng)請(qǐng)求列表,你只要修改
          ConnectorServlet中兩個(gè)私有方法:getFolders 和 getFiles
          讓它去你指定的地方得到文件列表即可,這樣你的文件可以放在任何你指定目錄下。多說(shuō)一句,很多人都想知道個(gè)人blog系統(tǒng)中怎么實(shí)現(xiàn)上傳文件以后對(duì)應(yīng)用戶瀏覽自己的列表的,我的做法很簡(jiǎn)單,建立你用戶名的文件夾,你上傳只能上傳到你的目錄夾,瀏覽可以通過(guò)程序指定瀏覽對(duì)應(yīng)用戶下的文件夾即可,這個(gè)時(shí)候你要修改Connectorservlet中的路徑即可!
          ------------------------------------
          2.超連接重定位問(wèn)題
          ------------------------------------
          FCKeditor可以插入超連接,實(shí)現(xiàn)對(duì)文件的預(yù)覽功能,只要我們稍微改變我們可以使FCKeditor編輯器支持對(duì)任意文件系統(tǒng)下的任意文件的客戶端瀏覽和下載保存!FCKeditor本來(lái)提供的是相對(duì)URL超鏈接,只要我們修改ConnectorServlet中傳遞給客戶端的地址的時(shí)候,把它改寫(xiě)成絕對(duì)URL然后再通過(guò)我們自己的filter的servlet實(shí)現(xiàn)重定向去一個(gè)下載/瀏覽文件的struts的action方法就可以實(shí)現(xiàn)在客戶端對(duì)超連接文件的下載和瀏覽!說(shuō)一下具體做法吧:
          1):修改ConnectorServlet傳遞給客戶端javascrīpt的路徑,代碼如下:
          String currentUrl = “http://” + request.getserver +request.getServerPort + request.getContextPath + resourcePath;
          以上代碼請(qǐng)?jiān)贑onnectorServlet的doGet()里面拼裝!在調(diào)用CreateCommonXml()私有方法的時(shí)候參數(shù)傳入:
          myEl.setAttribute(”path”,currentPath);
          myEl.setAttribute(”url”,currentUrl);
          提醒一下resourcePath為在web.xml配置文件中ConnectorServlet中的一個(gè)初始化參數(shù)配置,等一下利用filter實(shí)現(xiàn)對(duì)超連接的重定位就提取URL中的這個(gè)配置參數(shù)來(lái)判斷,配置如下:
          <init-param>
          <param-name>resourcePath</param-name>
          <param-value>/fileSystem/</param-value>
          </init-param>
          2):建立你的filter servlet,實(shí)現(xiàn)對(duì)URL的截獲,對(duì)符合要求的URL進(jìn)行重定位到你的對(duì)應(yīng)action中去即可
          3):實(shí)現(xiàn)你的對(duì)應(yīng)action來(lái)實(shí)現(xiàn)文件的上傳和下載功能即可!
          4):擴(kuò)展功能-實(shí)現(xiàn)對(duì)URL的加密,對(duì)連接的URL中加上一串字符,最后幾位作為算法校驗(yàn),對(duì)不符合要求的URL連接,filter將會(huì)拒絕重定位到指定action。此外利用自己寫(xiě)的擴(kuò)展類還可以實(shí)現(xiàn)對(duì)超連接的文件類型進(jìn)行限制,比如你只能超連接JPG|GIF|DOC|TXT|HTML等幾種后綴名的文件,對(duì)其他文件即使你指定超連接也讓你瀏覽和下載,這些都可以在web.xml中通過(guò)修改對(duì)應(yīng)servlet的配置文件的初始化參數(shù)實(shí)現(xiàn)。
          3.頁(yè)面javascrīpt修改
          ------------------------------------
          瀏覽服務(wù)器的功能對(duì)應(yīng)的html/javascrīpt相關(guān)的文件為:browser.html和frmresourcelist.html對(duì)應(yīng)你想傳遞的信息你可以append在文件名的字符串后面,在GetFileRowHtml()的javascrīpt函數(shù)中實(shí)現(xiàn)對(duì)文件名的截取,這樣client只會(huì)顯示文件名,而你可以得到文件的數(shù)據(jù)庫(kù)唯一標(biāo)識(shí),任何你想要的信息你都可以通過(guò)修改ConnectorServlet中的私有方法getFiles()來(lái)實(shí)現(xiàn),只要修改頁(yè)面frmresurcelist.html中的GetFileRowHtml()中傳入變量fileName即可。你還可以在點(diǎn)擊選中文件的時(shí)候?qū)崿F(xiàn)一個(gè)你自己的Ajax調(diào)用,一切取決你的項(xiàng)目需要!
          4.我不是一個(gè)javascrīpt高手,其實(shí)如果我對(duì)javascrīpt了解多一些也許對(duì)客戶端的代碼修改以后做出更眩的功能。可以更好的完成對(duì)FCKeditor裁剪。
          -------------------------------------
          5.注意點(diǎn)
          -------------------------------------
          無(wú)論怎么修改別人的東西,請(qǐng)一定尊重開(kāi)源精神!
          很多人配置好了FCKeditor的上傳功能以后常會(huì)遇到xmlhttp request 404 error,后面是一串路徑,其實(shí)就是你的servlet-mapping中的路徑不對(duì),你只要把xmlhttp request errot 404 后面跟的路徑,copy到你的web.xml中對(duì)應(yīng)紅色文字的位置,如下:
          <servlet-mapping>
          <servlet-name>Connector</servlet-name>
          <url-pattern>/FCKeditor/editor/filemanager/browser/default/connectors/jsp/connector</url-pattern>
          </servlet-mapping>
          別忘了SimpleUploader的servlet-mapping也要做同樣的修改!
          還有一個(gè)錯(cuò)誤就是http 500錯(cuò)誤,這個(gè)可能是你的URL請(qǐng)求不對(duì),應(yīng)該和FCKeditor沒(méi)關(guān)系的!
          ======================================
          fckconfig.js總配置文件,可用記錄本打開(kāi),修改后將文件存為utf-8 編碼格式。找到:
          --------------------------------------
          FCKConfig.TabSpaces = 0;
          改為:
          FCKConfig.TabSpaces = 1;
          即在編輯器域內(nèi)可以使用Tab鍵。
          如果你的編輯器還用在網(wǎng)站前臺(tái)的話,比如說(shuō)用于留言本或是日記回復(fù)時(shí),那就不得不考慮安全了,
          在前臺(tái)千萬(wàn)不要使用Default的toolbar,要么自定義一下功能,要么就用系統(tǒng)已經(jīng)定義好的Basic,
          也就是基本的toolbar,找到:
          --------------------------------------
          FCKConfig.ToolbarSets[”Basic”] = [
          [’Bold’,'Italic’,'-’,'OrderedList’,'UnorderedList’,'-’,/*’Link’,*/’Unlink’,'-’,'Style’,'FontSize’,'TextColor’,'BGColor’,'-’,
          ‘Smiley’,'SpecialChar’,'Replace’,'Preview’] ];
          這是改過(guò)的Basic,把圖像功能去掉,把添加鏈接功能去掉,因?yàn)閳D像和鏈接和flash和圖像按鈕添加功能都能讓前臺(tái)頁(yè)直接訪問(wèn)和上傳文件, fckeditor還支持編輯域內(nèi)的鼠標(biāo)右鍵功能。
          FCKConfig.ContextMenu = [’Generic’,/*’Link’,*/’Anchor’,/*’Image’,*/’Flash’,'Select’,'Textarea’,'Checkbox’,'Radio’,'TextField’,'HiddenField’,
          /*’ImageButton’,*/’Button’,'BulletedList’,'NumberedList’,'TableCell’,'Table’,'Form’];
          這也是改過(guò)的把鼠標(biāo)右鍵的“鏈接、圖像,F(xiàn)LASH,圖像按鈕”功能都去掉。
          找到:
          FCKConfig.FontNames = ‘Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana’;
          加上幾種我們常用的字體
          FCKConfig.FontNames = ‘宋體;黑體;隸書(shū);楷體_GB2312;Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana’;
          添加文件 /TestFCKeditor/test.jsp:
          ----------------------------------------
          <%@ page language=”java” import=”com.fredck.FCKeditor.*” %>
          <%@ taglib uri=”/TestFCKeditor” prefix=”FCK” %>
          <script. type=”text/javascript” src=”/TestFCKeditor/FCKeditor/fckeditor.js”></script>
          <%–
          三種方法調(diào)用FCKeditor
          1.FCKeditor自定義標(biāo)簽 (必須加頭文件 <%@ taglib uri=”/TestFCKeditor” prefix=”FCK” %> )
          2.script腳本語(yǔ)言調(diào)用 (必須引用 腳本文件 <script. type=”text/javascript” src=”/TestFCKeditor/FCKeditor/fckeditor.js”></script> )
          3.FCKeditor API 調(diào)用 (必須加頭文件 <%@ page language=”java” import=”com.fredck.FCKeditor.*” %> )
          –%>
          <%–
          <form. action=”show.jsp” method=”post” target=”_blank”>
          <FCK:editor id=”content” basePath=”/TestFCKeditor/FCKeditor/”
          width=”700″ height=”500″ skinPath=”/TestFCKeditor/FCKeditor/editor/skins/silver/”
          toolbarSet = “Default”>
          內(nèi)容
          </FCK:editor>
          <input type=”submit” value=”Submit”>
          </form>
          –%>
          <form. action=”show.jsp” method=”post” target=”_blank”>
          <table border=”0″ width=”700″>
          <tr>
          <td>
          <textarea id=”content” name=”content” style=”WIDTH: 100%; HEIGHT: 400px”>input</textarea>
          <script. type=”text/javascript”>
          var FCKeditor = new FCKeditor(’content? ;
          oFCKeditor.BasePath = “/TestFCKeditor/FCKeditor/” ;
          oFCKeditor.Height = 400;
          oFCKeditor.ToolbarSet = “Default” ;
          oFCKeditor.ReplaceTextarea();
          </script>
          <input type=”submit” value=”Submit”>
          </td>
          </tr>
          </table>
          </form>
          <%–
          <form. action=”show.jsp” method=”post” target=”_blank”>
          <%
          FCKeditor oFCKeditor ;
          oFCKeditor = new FCKeditor( request, “content” ) ;
          oFCKeditor.setBasePath( “/TestFCKeditor/FCKeditor/” ) ;
          oFCKeditor.setValue( “input” );
          out.println( oFCKeditor.create() ) ;
          %>
          <br>
          <input type=”submit” value=”Submit”>
          </form>
          –%>
          添加文件/TestFCKeditor/show.jsp:
          <%
          String content = request.getParameter(”content”);
          out.print(content);
          %>
          ====================================
          1、適時(shí)打開(kāi)編輯器
          ------------------------------------
          很多時(shí)候,我們?cè)诖蜷_(kāi)頁(yè)面的時(shí)候不需要直接打開(kāi)編輯器,而在用到的時(shí)候才打開(kāi),這樣一來(lái)有很好的用戶體驗(yàn),另一方面可以消除FCK在加載時(shí)對(duì)頁(yè)面打開(kāi)速度的影響,點(diǎn)擊“Open Editor”按鈕后才打開(kāi)編輯器界面。
          實(shí)現(xiàn)原理:
          使用JAVASCRIPT版的FCK,在頁(yè)面加載時(shí)(未打開(kāi)FCK),創(chuàng)建一個(gè)隱藏的TextArea域,這個(gè)TextArea
          的name和ID要和創(chuàng)建的FCK實(shí)例名稱一致,然后點(diǎn)擊”Open Editor”按鈕時(shí),通過(guò)調(diào)用一段函數(shù),使用
          FCK的ReplaceTextarea()方法來(lái)創(chuàng)建FCKeditor,代碼如下:
          ------------------------------------
          <script. type=”text/javascript”>
          <!–
          function showFCK(){
          var FCKeditor = new FCKeditor( ‘fbContent’ ) ;
          oFCKeditor.BasePath = ‘/FCKeditor/’ ;
          oFCKeditor.ToolbarSet = ‘Basic’ ;
          oFCKeditor.Width = ‘100%’ ;
          oFCKeditor.Height = ‘200′ ;
          oFCKeditor.ReplaceTextarea() ;
          }
          //–>
          </script>
          <textarea name=”fbContent” id=”fbContent”></textarea>
          2、使用FCKeditor 的 API
          -------------------------------------
          FCKeditor編輯器,提供了非常豐富的API,用于給End User實(shí)現(xiàn)很多想要定制的功能,比如最基本的數(shù)據(jù)驗(yàn)證,如何在提交的時(shí)候用JS判斷當(dāng)前編輯器區(qū)域內(nèi)是否有內(nèi)容,F(xiàn)CK的API提供了GetLength()方法;
          再比如如何通過(guò)腳本向FCK里插入內(nèi)容,使用InsertHTML()等;
          還有,在用戶定制功能時(shí),中間步驟可能要執(zhí)行FCK的一些內(nèi)嵌操作,那就用ExecuteCommand()方法。
          詳細(xì)的API列表,請(qǐng)查看FCKeditor的Wiki。而常用的API,請(qǐng)查看FCK壓縮包里的_samples/html/sample08.html。此處就不貼代碼了。
          3、外聯(lián)編輯條(多個(gè)編輯域共用一個(gè)編輯條)
          --------------------------------------
          這個(gè)功能是2.3版本才開(kāi)始提供的,以前版本的FCKeditor要在同一個(gè)頁(yè)面里用多個(gè)編輯器的話,得一個(gè)個(gè)創(chuàng)建,現(xiàn)在有了這個(gè)外聯(lián)功能,就不用那么麻煩了,只需要把工具條放在一個(gè)適當(dāng)?shù)奈恢茫竺婢涂梢詿o(wú)限制的創(chuàng)建編輯域了。
          要實(shí)現(xiàn)這種功能呢,需要先在頁(yè)面中定義一個(gè)工具條的容器:<div id=”xToolbar”></div>,然后再根據(jù)這個(gè)容器的id屬性進(jìn)行設(shè)置。
          JAVASCRIPT實(shí)現(xiàn)代碼:
          --------------------------------------
          <div id=”xToolbar”></div>
          FCKeditor 1:
          <script. type=”text/javascript”>
          <!–
          // Automatically calculates the editor base path based on the _samples directory.
          // This is usefull only for these samples. A real application should use something like this:
          // oFCKeditor.BasePath = ‘/fckeditor/’; // ‘/fckeditor/’ is the default value.
          var sBasePath = document.location.pathname.substring(0,document.location.pathname.lastIndexOf(’_samples’));
          var FCKeditor = new FCKeditor( ‘FCKeditor_1′ );
          oFCKeditor.BasePath = sBasePath;
          oFCKeditor.Height = 100;
          oFCKeditor.Config[ ‘ToolbarLocation’ ] = ‘Out:parent(xToolbar)’;
          oFCKeditor.Value = ‘This is some <strong>sample text</strong>. You are using FCKeditor.’;
          oFCKeditor.Create();
          //–>
          </script>
          <br />
          FCKeditor 2:
          <script. type=”text/javascript”>
          <!–
          FCKeditor = new FCKeditor( ‘FCKeditor_2′ );
          oFCKeditor.BasePath = sBasePath;
          oFCKeditor.Height = 100;
          oFCKeditor.Config[ ‘ToolbarLocation’ ] = ‘Out:parent(xToolbar)’;
          oFCKeditor.Value = ‘This is some <strong>sample text</strong>. You are using FCKeditor.’;
          oFCKeditor.Create();
          //–>
          </script>
          -------------------------------------
          此部分的詳細(xì)DEMO請(qǐng)參照_samples/html/sample11.html,_samples/html/sample11_frame.html
          4、文件管理功能、文件上傳的權(quán)限問(wèn)題
          -------------------------------------
          一直以來(lái)FCKeditor的文件管理部分的安全是個(gè)值得注意,但很多人沒(méi)注意到的地方,雖然FCKeditor在各個(gè)Release版本中一直存在的一個(gè)功能就是對(duì)上傳文件類型進(jìn)行過(guò)濾,但是她沒(méi)考慮過(guò)另一個(gè)問(wèn)題:到底允許誰(shuí)能上傳?到底誰(shuí)能瀏覽服務(wù)器文件?
          之前剛開(kāi)始用FCKeditor時(shí),我就出現(xiàn)過(guò)這個(gè)問(wèn)題,還好NetRube(FCKeditor中文化以及FCKeditor ASP版上傳程序的作者)及時(shí)提醒了我,做法是去修改FCK上傳程序,在里面進(jìn)行權(quán)限判斷,并且再在fckconfig.js里把相應(yīng)的一些功能去掉。但隨之FCK版本的不斷升級(jí),每升一次都要去改一次配置程序fckconfig.js,我發(fā)覺(jué)厭煩了,就沒(méi)什么辦法能更好的控制這種配置么?事實(shí)上,是有的。
          在fckconfig.js里面,有關(guān)于是否打開(kāi)上傳和瀏覽服務(wù)器的設(shè)置,在創(chuàng)建FCKeditor時(shí),通過(guò)程序來(lái)判斷是否創(chuàng)建有上傳瀏覽功能的編輯器。首先,我先在fckconfig.js里面把所有的上傳和瀏覽設(shè)置全設(shè)為false,接著我使用的代碼如下:
          JAVASCRIPT版本:
          -------------------------------------
          <script. type=”text/javascript”>
          var FCKeditor = new FCKeditor( ‘fbContent’ );
          <% if power = powercode then %>
          oFCKeditor.Config[’LinkBrowser’] = true;
          oFCKeditor.Config[’ImageBrowser’] = true;
          oFCKeditor.Config[’FlashBrowser’] = true;
          oFCKeditor.Config[’LinkUpload’] = true;
          oFCKeditor.Config[’ImageUpload’] = true;
          oFCKeditor.Config[’FlashUpload’] = true;
          <% end if %>
          oFCKeditor.ToolbarSet = ‘Basic’;
          oFCKeditor.Width = ‘100%’;
          oFCKeditor.Height = ‘200′;
          oFCKeditor.Value = ‘’;
          oFCKeditor.Create();
          </script>
          -------------------------------------
          在按鈕旁邊加文字
          -------------------------------------
          打開(kāi) editor/js/ 兩個(gè)js文件
          fckeditorcode_gecko.js
          fckeditorcode_ie.js
          第一個(gè)是支持非ie瀏覽器的
          第二個(gè)文件是支持ie瀏覽器的
          搜索 FCKToolbarButton,可以看到許多類似這樣的語(yǔ)句:
          case ‘Save’:B = new FCKToolbarButton(’Save’, FCKLang.Save, null, null, true, null, 3); break;
          ‘Save’是按鈕英文名字
          FCKToolbarButton 的四個(gè)參數(shù)分別是:
          按鈕命令名稱,按鈕標(biāo)簽文字,按鈕工具提示,按鈕樣式,按鈕是否在源代碼模式可見(jiàn),按鈕下拉菜單其中將第4項(xiàng)參數(shù)設(shè)置為 FCK_TOOLBARITEM_ICONTEXT 即可使按鈕旁邊出現(xiàn)文字,注意沒(méi)有引號(hào)。
          例如:
          case ‘Preview’:B = new FCKToolbarButton(’Preview’, FCKLang.Preview, null, FCK_TOOLBARITEM_ICONTEXT, true, null, 5);
          這樣我們就可以將 我們經(jīng)常用的3種模式源代碼、預(yù)覽、全屏編輯按鈕都加上文字了。
          解釋fck樣式的工作原理
          -------------------------------------
          fck的樣式設(shè)置涉及到了兩個(gè)文件,一個(gè)是你定義好的樣式表文件.css,另一個(gè)是告訴fck樣式表如何使用的xml文件,兩個(gè)文件確一不可。
          css文件的位置是不做要求的,但是需要你在應(yīng)用的編輯器的頁(yè)面上插入樣式表文件的鏈接。這樣才能顯示出來(lái)樣式。
          fckstyles.xml 在與editor目錄同級(jí)的目錄下。該文件定義了那些樣式可以使用在那些標(biāo)簽里面。
          這就是fck自帶的樣式xml定義:
          <?xml version=”1.0″ encoding=”utf-8″ ?>
          <Styles>
          <Style name=”Image on Left” element=”img”>
          <Attribute name=”style” value=”padding: 5px; margin-right: 5px” />
          <Attribute name=”border” value=”2″ />
          <Attribute name=”align” value=”left” />
          </Style>
          <Style name=”Image on Right” element=”img”>
          <Attribute name=”style” value=”padding: 5px; margin-left: 5px” />
          <Attribute name=”border” value=”2″ />
          <Attribute name=”align” value=”right” />
          </Style>
          <Style name=”Custom Bold” element=”span”>
          <Attribute name=”style” value=”font-weight: bold;” />
          </Style>
          <Style name=”Custom Italic” element=”em” />
          <Style name=”Title” element=”span”>
          <Attribute name=”class” value=”Title” />
          </Style>
          <Style name=”Code” element=”span”>
          <Attribute name=”class” value=”Code” />
          </Style>
          <Style name=”Title H3″ element=”h3″ />
          <Style name=”Custom Ruler” element=”hr”>
          <Attribute name=”size” value=”1″ />
          <Attribute name=”color” value=”#ff0000″ />
          </Style>
          </Styles>
          每一個(gè)<style>將來(lái)會(huì)生成一個(gè)樣式的菜單項(xiàng)。name名稱就是顯示在菜單里的文字;element定義了該樣式可以應(yīng)用在那種html標(biāo)簽上,<Attribute>的 name 指定了將會(huì)修改標(biāo)簽的哪個(gè)屬性來(lái)應(yīng)用樣式,value則是修改成的值。
          看這個(gè):
          <Style name=”Title” element=”span”>
          <Attribute name=”class” value=”Title” />
          </Style>
          如果你在fck選定了文字 “經(jīng)典論壇 》 前臺(tái)制作與腳本專欄 》 FCKeditor 實(shí)戰(zhàn)技巧 - 1 》 編輯帖子” 應(yīng)用該樣式 則原來(lái)文字就會(huì)變成<span class=”Title”>經(jīng)典論壇 》 前臺(tái)制作與腳本專欄 》 FCKeditor 實(shí)戰(zhàn)技巧 - 1 》 編輯帖子</span>
          注意:如果編輯器呈整頁(yè)編輯狀態(tài),那么整頁(yè)里面也需要插入樣式表鏈接才能顯示出來(lái)樣式。
          ============================================
          FCKeditor JavaScript. API(翻譯整理)
          原文地址:http://wiki.fckeditor.net/Developer%27s_Guide/Javascript_API
          --------------------------------------------
          FCK 編輯器加載后,將會(huì)注冊(cè)一個(gè)全局的 FCKeditorAPI 對(duì)象。
          FCKeditorAPI 對(duì)象在頁(yè)面加載期間是無(wú)效的,直到頁(yè)面加載完成。如果需要交互式地知道 FCK 編輯器已經(jīng)加載完成,可使用“FCKeditor_OnComplete”函數(shù)。
          <script. type=”text/javascript”>
          function FCKeditor_OnComplete(editorInstance) {
          FCKeditorAPI.GetInstance(’FCKeditor1′).Commands.GetCommand(’FitWindow’).Execute();
          }
          </script>
          在當(dāng)前頁(yè)獲得 FCK 編輯器實(shí)例:
          var Editor = FCKeditorAPI.GetInstance(’InstanceName’);
          從 FCK 編輯器的彈出窗口中獲得 FCK 編輯器實(shí)例:
          var Editor = window.parent.InnerDialogLoaded().FCK;
          從框架頁(yè)面的子框架中獲得其它子框架的 FCK 編輯器實(shí)例:
          var Editor = window.FrameName.FCKeditorAPI.GetInstance(’InstanceName’);
          從頁(yè)面彈出窗口中獲得父窗口的 FCK 編輯器實(shí)例:
          var Editor = opener.FCKeditorAPI.GetInstance(’InstanceName’);
          獲得 FCK 編輯器的內(nèi)容:
          oEditor.GetXHTML(formatted); // formatted 為:true|false,表示是否按HTML格式取出
          也可用:
          oEditor.GetXHTML();
          設(shè)置 FCK 編輯器的內(nèi)容:
          oEditor.SetHTML(”content”, false); // 第二個(gè)參數(shù)為:true|false,是否以所見(jiàn)即所得方式設(shè)置其內(nèi)容。此方法常用于“設(shè)置初始值”或“表單重置”操作。
          插入內(nèi)容到 FCK 編輯器:
          oEditor.InsertHtml(”html”); // “html”為HTML文本
          檢查 FCK 編輯器內(nèi)容是否發(fā)生變化:
          oEditor.IsDirty();
          在 FCK 編輯器之外調(diào)用 FCK 編輯器工具條命令:
          命令列表如下:
          --------------------------------------------
          DocProps, Templates, Link, Unlink, Anchor, BulletedList, NumberedList, About, Find, Replace, Image, Flash, SpecialChar, Smiley, Table, TableProp, TableCellProp, UniversalKey, Style, FontName, FontSize, FontFormat, Source, Preview, Save, NewPage, PageBreak, TextColor, BGColor, PasteText, PasteWord, TableInsertRow, TableDeleteRows, TableInsertColumn, TableDeleteColumns, TableInsertCell, TableDeleteCells, TableMergeCells, TableSplitCell, TableDelete, Form, Checkbox, Radio, TextField, Textarea, HiddenField, Button, Select, ImageButton, SpellCheck, FitWindow, Undo, Redo
          --------------------------------------------
          使用方法如下:
          --------------------------------------------
          oEditor.Commands.GetCommand(’FitWindow’).Execute();
          --------------------------------------------

          posted @ 2008-01-09 12:52 feingto 閱讀(2998) | 評(píng)論 (0)編輯 收藏

          FCKEditor的賦值和取值操作

          1、獲取編輯器中HTML內(nèi)容

          function getEditorHTMLContents(EditorName)

              
          var oEditor = FCKeditorAPI.GetInstance(EditorName); 
              
          return(oEditor.GetXHTML(true)); 
          }


          2、獲取編輯器中文字內(nèi)容(在博客發(fā)布時(shí)獲取無(wú)html代碼摘要使用)

          function getEditorTextContents(EditorName)

              
          var oEditor = FCKeditorAPI.GetInstance(EditorName); 
              
          return(oEditor.EditorDocument.body.innerText); 
          }


          3、設(shè)置編輯器中內(nèi)容

          function SetEditorContents(EditorName, ContentStr)

              
          var oEditor = FCKeditorAPI.GetInstance(EditorName) ; 
              oEditor.SetHTML(ContentStr) ; 
          }

          posted @ 2008-01-09 12:51 feingto 閱讀(2086) | 評(píng)論 (1)編輯 收藏

          Script.aculo.us開(kāi)發(fā)系列(八):使用DropDrag定義拖拽行為

           

          在不同的瀏覽器上默認(rèn)的拖拽能解決的問(wèn)題相當(dāng)少,所以有很多的框架都能實(shí)現(xiàn)這么個(gè)功能.使用拖拽行為能很好的改善用戶體驗(yàn),尤其是在購(gòu)物的時(shí)候能讓用戶感到很新奇和體面.Script.aculo.us使用了三個(gè)類實(shí)現(xiàn)拖拽和排序,它們是Draggable,Droppable,Sortable.要實(shí)現(xiàn)一個(gè)完整的拖拽行為,需要Draggable,和Droppable的配合使用,由于這連個(gè)類的方法比較多,我只選取比較實(shí)用的幾個(gè)方法進(jìn)行介紹.還是老規(guī)矩,先看看Demo:http://www1.qcxy.hb.cn/qphy/Script_Aculo_Us/DragDrop.html

          Draggable

          new Draggable("DraggableId"[,options])

          主要選項(xiàng)

          • snap:推拽的最小單位,默認(rèn)為false,可以是數(shù)組或者函數(shù),將這個(gè)屬性設(shè)置為[50,50],意味著最小的位移單位是50px,50px,如果設(shè)置為一個(gè)函數(shù),這個(gè)函數(shù)的參數(shù)為(x,y),這個(gè)x,y指示當(dāng)前的絕對(duì)坐標(biāo),函數(shù)應(yīng)該返回二維數(shù)組,上面的例子中的Drag(UnAcceptable)推拽到頁(yè)面的左上角是就會(huì)"吸附"上去,就是因?yàn)楹瘮?shù)的作用,詳細(xì)見(jiàn)源碼
          • revert:推拽完畢之后是否回到原來(lái)的位置,默認(rèn)為false,也可以是一個(gè)函數(shù),這個(gè)函數(shù)必須返回true/false
          • handle:"提手",移動(dòng)整個(gè)塊的時(shí)候通常不需要在整個(gè)塊的區(qū)域都可以拖拽,比如移動(dòng)一個(gè)欄目,通常只需要拖拽標(biāo)題(比如Google的個(gè)性化主頁(yè)),將該屬性設(shè)置為標(biāo)題的Id
          • ghosting:推拽的過(guò)程中是否顯示"影子",默認(rèn)為false
          • constraint:限制能拖動(dòng)的方向,默認(rèn)的兩個(gè)方向都可以,可以設(shè)置為"vertical","horizontal"的任意
          • zindex:"影子"的z-Index屬性
          • scroll:拖拽出視圖范圍是否顯示自動(dòng)滾動(dòng)
          • scrollSensitivity/scrollSpeed:默認(rèn)值分為為20/15,控制滾動(dòng)的敏感度和滾動(dòng)速度
          • delay:拖拽前的延時(shí),開(kāi)始拖拽后經(jīng)過(guò)這個(gè)時(shí)間才"回過(guò)神來(lái)"

          這里需要說(shuō)明的是并非所有的標(biāo)簽都支持該行為,詳細(xì)的情況請(qǐng)參閱官方文檔

          API

          • onStart:開(kāi)始拖拽調(diào)用該函數(shù),接受兩個(gè)參數(shù)(obj,oEvent)前者是$(DraggableId),后者是當(dāng)前事件的event對(duì)象
          • onDrag:在拖拽過(guò)程中反復(fù)的調(diào)用該函數(shù),同樣接受兩個(gè)參數(shù)(obj,oEvent)
          • change:在onDrag后調(diào)用,也會(huì)反復(fù)調(diào)用
          • onEnd:拖拽行為結(jié)束調(diào)用,即鼠標(biāo)彈起時(shí)激發(fā)
          • destroy():該方法銷毀元素的拖拽行為

          Droppables

          Droppables(注意是復(fù)數(shù)形式)是一個(gè)抽象類,不能被實(shí)例化,只有一些靜態(tài)方法,常用的方法有add和move,分別增加可放置元素,和去除可放置元素

          add方法:Dropables.add("ContainerId"[,options]),常用的選項(xiàng)

          • accept: 數(shù)組或者字符串,表示該容器接受的元素的className的集合,默認(rèn)的任何元素都接收
          • hoverclass:當(dāng)符合接受要求的元素拖至容器上時(shí),其className
          • onDrop():被拖拽的符合要求的元素在這里放置時(shí)調(diào)用該函數(shù),接受三個(gè)參數(shù)(draggable,droppable,oEvent),draggable是被拖拽元素,droppable是被放置元素,oEvent當(dāng)前事件對(duì)象

          remove("ContainerId"),該方法去除容器的放置行為

          (上面例子的源代碼)

          Sortable

          Sortable是一組可以通過(guò)拖拽交換位置的元素,可以先看看實(shí)例(

          serialize(sortable)方法:該方法返回當(dāng)前容器內(nèi)元素的次序,但是要求子元素的id必須以"item_"開(kāi)頭,且返回格式有講究,看下面的例子

          <div id="horizontalSortable" class="item" style="margin-top:20px; height:40px;">
                <div id="item_5">IE</div>
                <div id="item_6">FireFox</div>
                <div id="item_7">Safari</div>
                <div id="item_8">Opera</div>
          </div>

          Sortable.create("horizontalSortable",
          {
               ghosting:true,
               tag:'div',
               constraint:'horizontal',
               hoverclass:'hoverClass2'
          });

          Sortable.serialize('horizontalSortable')
          //-->horizontalSortable[]=5&horizontalSortable[]=6&horizontalSortable[]=7&horizontalSortable[]=8

          最后看一個(gè)例子,前面提到的containment選項(xiàng)在某些情況下很有用,比如要實(shí)現(xiàn)兩個(gè)容器里的元素可以互相交換子元素,即從一個(gè)容器拖至令一個(gè)容器中.來(lái)看下面的例子

          <script type="text/javascript">
            Sortable.create('sortUlLeft',{containment:['sortUlLeft','sortUlRight'], dropOnEmpty:
          true,ghosting:true,constraint:false,hoverclass:'hoverClass'});
            Sortable.create('sortUlRight',{containment:['sortUlLeft','sortUlRight'], dropOnEmpty:
          true,ghosting:true,constraint:false,hoverclass:'hoverClass'});

          </script>

          上面的例子可以實(shí)現(xiàn)sortUlLeft,和sortUlRight的子元素互相交換

          posted @ 2008-01-05 14:14 feingto 閱讀(563) | 評(píng)論 (0)編輯 收藏

          用script.aculo.us實(shí)現(xiàn)像google suggest自動(dòng)完成功能

           

          實(shí)現(xiàn)像google suggest自動(dòng)完成功能

          首先創(chuàng)建一個(gè)jsp

          <%@ page language="java" pageEncoding="UTF-8"%>

          <html>
          <head>
          <script type="text/javascript" src="js/prototype.js"></script>
          <script type="text/javascript" src="js/effects.js"></script>
          <script type="text/javascript" src="js/controls.js"></script>
          <style>
          div.auto_complete {
            width: 350px;
            background: #fff;
          }
          div.auto_complete ul {
            border:1px solid #888;
            margin:0;
            padding:0;
            width:100%;
            list-style-type:none;
          }
          div.auto_complete ul li {
            margin:0;
            padding:3px;
          }
          div.auto_complete ul li.selected {
            background-color: #ffb;
          }
          div.auto_complete ul strong.highlight {
            color: #800;
            margin:0;
            padding:0;
          }
          </style>

          </head>
          <body>
          <input type="text" id="autocomplete"/>
          <div id="results" class="auto_complete"></div>
          <script type="text/javascript">
           new Ajax.Autocompleter(
            "autocomplete",
            "results",
            "list.html", {
             method: "GET"
            }
           );
          </script>
          </body>
          </html>

           

          list.html

          <ul>
          <li>Aria</li>
          <li>Aaaa</li>
          <li>Afdsa</li>
          <li>bsa</li>
          </ul>

          上面list.html采用靜態(tài)頁(yè)面返回列表,讀者可以使用動(dòng)態(tài)頁(yè)面返回結(jié)果。

          posted @ 2008-01-03 09:20 feingto 閱讀(1963) | 評(píng)論 (3)編輯 收藏

          怎么避免瀏覽器緩存靜態(tài)文件

          對(duì)于動(dòng)態(tài)文件,比如 index.asp?id=...  或者 index.aspx?id=... 相信有經(jīng)驗(yàn)的程序員都知道怎樣禁止瀏覽器緩存數(shù)據(jù)了.
          但是對(duì)于靜態(tài)文件(css,jpg,gif等等), 在什么場(chǎng)合下面我們需要禁止瀏覽器緩存他們,怎么做?

          本文討論的主題是如何防緩存, 尤其是如何防止靜態(tài)文件被緩存..


          在  RE:對(duì)博客園URL的一些調(diào)整建議, 二級(jí)域名不利于客戶端瀏覽器緩存 一文中,我提到了怎么最大化的
          利用瀏覽器緩存功能,來(lái)提高客戶端瀏覽速度, 減輕服務(wù)器負(fù)擔(dān)的.

          但是事物總是一分為二的,并不是所有的場(chǎng)合都要使用緩存的. 有時(shí)候我們的數(shù)據(jù)被緩存了反而會(huì)給我們帶來(lái)麻煩.

          對(duì)于動(dòng)態(tài)數(shù)據(jù)(從數(shù)據(jù)庫(kù)讀取生成的那些),我們可以通過(guò)以下方法來(lái)禁止瀏覽器緩存。

          'asp 為例 禁止緩存

          Response.Buffer 
          = True 
          Response.ExpiresAbsolute 
          = Now() - 1 
          Response.Expires 
          = 0 
          Response.CacheControl 
          = "no-cache" 
          Response.AddHeader 
          "Pragma""No-Cache" 

          對(duì)于Ajax 的請(qǐng)求(不管是靜態(tài)數(shù)據(jù)還是動(dòng)態(tài)數(shù)據(jù)):

          //以下三種方法使用其中任何一種方法都可以
          xmlhttp.setRequestHeader("Cache-Control","no-cache");  
          //或者
          xmlhttp.setRequestHeader("If-Modified-Since","0");
          //或者
          xmlhttp.Open(url+'?rnd='+Math.random(),....)

          如果使用 prototype.js  , 用類似這樣的代碼 
          new Ajax.Request(url,{method:"get",requestHeaders:["Cache-Control","no-cache"]})
          或者
          new Ajax.Request(url,{method:"get",requestHeaders:["If-Modified-Since","0"]})
           

          什么情況下,要禁止靜態(tài)文件緩存:
          1、經(jīng)常可能要改動(dòng)的 js, css.
                 比如 一個(gè)html 文件, test.html 在 1.0版本中。可能是這樣
               <script src="common.js"></script>
               修改后  v1.1版本:
           <script src="common.js"></script>
           <script src="foo.js"></script>
             新增加了一個(gè)foo.js  同時(shí),也改動(dòng)了common.js , 在common.js 中定義了新的類,并在foo.js 中使用了common.js. 

          在這種情況下如果以前用戶瀏覽過(guò) 1.0版本的 html 文件,那么他的瀏覽器自動(dòng)緩存了 common.js
          當(dāng)他瀏覽新版本的時(shí)候,因?yàn)槭褂玫氖?v1.1的 foo.js 和 v1.0的 common.js ,這樣將導(dǎo)致腳本出錯(cuò)。


          解決方法探討:
            因?yàn)閏ss,js 是通過(guò) <script src=....> 這種方式加載的,所以,很難使用 asp 的那種服務(wù)器端禁止緩存的辦法。也很難使用ajax的通過(guò)設(shè)置 http請(qǐng)求頭的辦法禁止使用緩存。

          看來(lái)隨機(jī)數(shù)是個(gè)好辦法。

          //方法一:
          document.write("<script src='test.js?rnd="+Math.random()+"'></s"+"cript>")

          //方法二:
          var js=document.createElement("script")
          js.src
          ="test.js"+Math.random()
          document.body.appendChild(js)


          但是,如果采用隨機(jī)數(shù)的話, js文件將永遠(yuǎn)得不到緩存,每次都必須重新從服務(wù)器加載,即使沒(méi)有任何更改。
          大家如果經(jīng)常上國(guó)外網(wǎng)站的話,可以看到他們通常采用這樣的方式來(lái)解決:
          <script src="test.js?ver=113"></script>
          其中 ver=113 的 113就是版本號(hào),一般都是采用 CVS 或其他工具生成的開(kāi)發(fā)版本號(hào)。

          這樣真正做到了應(yīng)該緩存的時(shí)候緩存靜態(tài)文件,當(dāng)版本有更新的時(shí)候從獲取最新的版本,并更新緩存。
          對(duì)于圖像 <img src="test.jps?ver=在CVS的版本號(hào)"> 來(lái)有效利用和更新緩存.


          唉,現(xiàn)在在CSDN的Web版,不知道有多少人在重復(fù)問(wèn)著同一個(gè)問(wèn)題。“怎么通過(guò)程序刪除清空客戶端的瀏覽器緩存”.........

           

          未完待續(xù):

          下一篇:  利用瀏覽器緩存來(lái)改善用戶體驗(yàn)。。。。Ajax模式之預(yù)先加載

          敬請(qǐng)關(guān)注,等我寫(xiě)完再加上鏈接

          posted @ 2008-01-03 09:19 feingto 閱讀(2569) | 評(píng)論 (1)編輯 收藏

          AJAX框架/庫(kù)比較和選擇:ECHO2, GWT, DOJO, PROTOTYPE, JQUERY

          看了幾篇中英文的AJAX庫(kù)/框架比較文章,為方便選擇使用,特歸納如下:
          首先,要在兩個(gè)類別中選擇,一個(gè)是編譯類,一個(gè)是非編譯類別。
          Echo2/GWT是將JAVA代碼編譯成JAVASCRIPT,乍看很方便,不用掌握J(rèn)S也能做出炫目界面。但這只適于不會(huì)或者不想了解JS的情況,對(duì)于還是想完全控制和定制界面的項(xiàng)目就不適合。
          另外,有一種觀點(diǎn)認(rèn)為JAVA->JS轉(zhuǎn)換是一種低級(jí)語(yǔ)言向高級(jí)語(yǔ)言轉(zhuǎn)換,本身沒(méi)有意義。有點(diǎn)像去學(xué)匯編,然后再找個(gè)工具把匯編語(yǔ)言代碼轉(zhuǎn)換成C代碼來(lái)用。我雖然沒(méi)完全想通這個(gè)觀點(diǎn),不過(guò),我一直用C/C++,這幾年才逐漸發(fā)現(xiàn)JAVA確實(shí)是一種進(jìn)化。沒(méi)準(zhǔn)別人說(shuō)的是對(duì)的呢?
          在Echo2和GWT中,GWT大部分工作是在客戶端,盡量少跟SERVER打交道,適合大型網(wǎng)站運(yùn)用;ECHO2信奉“用到才加載”的信條,所以會(huì)有大量向SERVER的訪問(wèn),適合企業(yè)應(yīng)用。另外,個(gè)人覺(jué)得ECHO2是個(gè)更全面的的一站式框架,界面也非常炫。但它的開(kāi)發(fā)工具要收費(fèi)。
          再談非編譯類別,它們包括DOJO、PROTOTYPE、JQEURY,下面一一介紹:
          先說(shuō)PROTOTYPE,它比較輕量極,能讓你的代碼更加簡(jiǎn)化。最經(jīng)典莫過(guò)于“美圓函數(shù)”:
          document.getElementById(’elementid’) 變成$(’elementid’)
          它加強(qiáng)了JS語(yǔ)言的可開(kāi)發(fā)性,降低了學(xué)習(xí)JS的門檻。
          DOJO最吸引人的是它的事件系統(tǒng)和豐富的可定制組件。它可以用形如下面的語(yǔ)句為各種HTML元素加入事件:
          dojo.event.connect(someNode, "onclick", doStuff);
          正由于DOJO提供了強(qiáng)大功能,它分成了許多包,可以分別包含使用。
          JQUERY也提供了美圓函數(shù),它的插件系統(tǒng)也提供象DOJO的組件,但它沒(méi)有PROTOTYPE那樣簡(jiǎn)潔,也沒(méi)有DOJO這么多的組件供使用,但它兼收兩家優(yōu)點(diǎn),并且個(gè)頭不大,文檔也算完整,所以說(shuō)它介乎于前述兩者之間。
          所以,如果你需要非常完整的工具組件請(qǐng)用DOJO,如果你想優(yōu)化你的JS代碼,提高書(shū)寫(xiě)技巧請(qǐng)用PROTOTYPE,如果你想兩者兼顧就用JQUERY。

          posted @ 2007-12-30 20:37 feingto 閱讀(485) | 評(píng)論 (0)編輯 收藏

          prototype.js開(kāi)發(fā)筆記

               摘要: Table of Contents 1. Programming Guide 1.1. Prototype是什么? 1.2. 關(guān)聯(lián)文章 1.3. 通用性方法 1.3.1. 使用 $()方法 1.3.2. 使用$F()方法 1.3.3. 使用$A()方法 1.3.4. 使用$H()方法 1.3.5. 使用$R()方法 1.3.6. 使用Try.these()方...  閱讀全文

          posted @ 2007-12-30 18:07 feingto 閱讀(419) | 評(píng)論 (0)編輯 收藏

          Prototype 1.5 Ajax 使用教程

          2.3  Prototype對(duì)Ajax的支持

          作為一個(gè)Ajax開(kāi)發(fā)框架,Prototype對(duì)Ajax開(kāi)發(fā)提供了有力的支持。在Prototype中,與Ajax相關(guān)的類和對(duì)象包括:Ajax、Ajax.Responsders、Ajax.Base、Ajax.Request、Ajax. PeriodicalUpdater和Ajax.Updater,圖2-3所示為這些類和對(duì)象之間的關(guān)系及其常用屬性和方法,下面分別對(duì)這些類和對(duì)象進(jìn)行介紹。

          圖2-3  Prototype中Ajax相關(guān)類和對(duì)象關(guān)系示意圖

          2.3.1  Ajax對(duì)象

          Ajax對(duì)象為其他的Ajax功能類提供了最基本的支持,它的實(shí)現(xiàn)如2.2.7節(jié)中例2-10所示,其中包括一個(gè)方法getTransport和一個(gè)屬性activeRequestCount。getTransport方法返回一個(gè)XMLHttpRequest對(duì)象,activeRequestCount屬性代表正在處理中的Ajax請(qǐng)求的個(gè)數(shù)。

          2.3.2  Ajax.Base類

          Ajax.Base類是Ajax.Request類和Ajax.PeriodicalUpdater類的基類。它提供了3個(gè)方法:

          l  setOptions:設(shè)置Ajax操作所使用的選項(xiàng)。

          l  responseIsSuccess:判斷Ajax操作是否成功。

          l  responseIsFailure:判斷Ajax操作是否失敗(與responseIsSuccess相反)。

          Ajax.Base類的主要作用是提取出一些公用的方法,其他類通過(guò)繼承的方式使用這些方法,實(shí)現(xiàn)代碼復(fù)用。

          2.3.3  Ajax.Request類

          這是Prototype中最經(jīng)常使用的一個(gè)Ajax相關(guān)類。Ajax.Request類的方法通常是內(nèi)部使用的,因此這里就不一一列舉,有興趣的讀者可以參考Prototype的源代碼。這里重點(diǎn)講講如何使用Ajax.Request類,首先給出一個(gè)最簡(jiǎn)單的Ajax.Request類的應(yīng)用示例,如例2-11所示,注意示例中的黑體字。

          例2-11  Ajax.Request類應(yīng)用示例

          Ajax.Request測(cè)試頁(yè)面:

          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

          <html>

              <head>

                  <title>chapter 3</title>

                  <script type="text/javascript" language="javascript"

                   src="prototype.js" ></script>

                  <script type="text/javascript" language="javascript">

                  function test() {

                      // 創(chuàng)建Ajax.Request對(duì)象,發(fā)起一個(gè)Ajax請(qǐng)求

                      var myAjax = new Ajax.Request(

                          'data.html', // 請(qǐng)求的URL

                          {

                              method: 'get',  // 使用GET方式發(fā)送HTTP請(qǐng)求

                              onComplete: showResponse // 指定請(qǐng)求成功完成時(shí)需要執(zhí)行的方法

                          }

                      );

                  }

                  function showResponse(response) {

                      $('divResult').innerHTML = response.responseText;

                  }

                  </script>

              </head>

              <body>

              <input type="button" value="click" onclick="test()" />

              <div id="divResult" />

              </body>

          </html>

          data.html

          <input type="text" id="name" />

          <input type="button" value="Click Me" onclick="sayHi()">

          Ajax.Request對(duì)象在初始化時(shí)需要提供兩個(gè)參數(shù):第1個(gè)參數(shù)是將要請(qǐng)求頁(yè)面的URL,這里使用的data.html是一個(gè)普通的HTML靜態(tài)頁(yè)面;第2個(gè)參數(shù)是Ajax操作的選項(xiàng),在Prototype中并沒(méi)有專門為Ajax操作選項(xiàng)定義一個(gè)類,通常都是像例2-11這樣,通過(guò)匿名對(duì)象的方式設(shè)置Ajax操作的參數(shù)。在例2-11中,Ajax操作選項(xiàng)具有兩個(gè)屬性:method表示HTTP請(qǐng)求方式,默認(rèn)是POST方式;onComplete指定了Ajax操作完成以后(即XMLHttpRequest對(duì)象的status屬性為4時(shí)),頁(yè)面將要執(zhí)行的函數(shù)。當(dāng)然,Ajax操作還包括很多其他選項(xiàng),如表2-1所示。

          表2-1  Ajax操作選項(xiàng)屬性含義

          屬性名稱

          含義

          method

          HTTP請(qǐng)求方式(POST/GET/HEAD)。

          parameters

          在HTTP請(qǐng)求中傳入的URL格式的值列表,即URL串中問(wèn)號(hào)之后的部分。

          asynchronous

          是否做異步XMLHttpRequest請(qǐng)求。

          postBody

          在POST請(qǐng)求方式下,傳入請(qǐng)求體中的內(nèi)容。

          requestHeaders

          和請(qǐng)求一起被傳入的HTTP頭部列表,這個(gè)列表必須含有偶數(shù)個(gè)項(xiàng)目,因?yàn)榱斜碇忻績(jī)身?xiàng)為一組,分別代表自定義部分的名稱和與之對(duì)應(yīng)的字符串值。

          onXXXXXXXX

          在HTTP請(qǐng)求、響應(yīng)的過(guò)程中,當(dāng)XMLHttpRequest對(duì)象狀態(tài)發(fā)生變化時(shí)調(diào)用的響應(yīng)函數(shù)。響應(yīng)函數(shù)有5個(gè):onUninitialized、onLoading、onLoaded、onInteractive和onComplete。傳入這些函數(shù)的參數(shù)可以有2個(gè),其中第1個(gè)參數(shù)是執(zhí)行HTTP請(qǐng)求的XMLHttpRequest對(duì)象,第2個(gè)參數(shù)是包含被執(zhí)行的X-JSON響應(yīng)的HTTP頭。

          onSuccess

          Ajax操作成功完成時(shí)調(diào)用的響應(yīng)函數(shù),傳入的參數(shù)與onXXXXXXXX相同。

          onFailure

          Ajax操作請(qǐng)求完成但出現(xiàn)錯(cuò)誤時(shí)調(diào)用的響應(yīng)函數(shù),傳入的參數(shù)與onXXXXXXXX相同。

          onException

          Ajax操作發(fā)生異常情況時(shí)調(diào)用的響應(yīng)函數(shù),它可以接收2個(gè)參數(shù),其中第1個(gè)參數(shù)是執(zhí)行HTTP請(qǐng)求的XMLHttpRequest對(duì)象,第2個(gè)參數(shù)是異常對(duì)象。

          2.3.4  Ajax.Updater類

          例2-11使用Ajax.Request類實(shí)現(xiàn)了頁(yè)面的局部刷新效果,而這樣類似的功能在Ajax應(yīng)用中是經(jīng)常使用的。因此,為了簡(jiǎn)化這種工作,Prototype框架從Ajax.Requet類中派生出一個(gè)子類——Ajax.Updater。與Ajax.Request相比,Ajax.Updater的初始化多了一個(gè)container參數(shù),該參數(shù)代表將要更新的頁(yè)面元素的id。例2-11的功能通過(guò)Ajax.Updater的實(shí)現(xiàn),會(huì)變得更加簡(jiǎn)單,如例2-12所示。

          例2-12  Ajax.Updater類的應(yīng)用示例

          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

          <html>

              <head>

                  <title>chapter 3</title>

                  <script type="text/javascript" language="javascript"

                   src="prototype.js" ></script>

                  <script type="text/javascript" language="javascript">

                  function test() {

                      var myAjax = new Ajax.Updater(

                          'divResult', // 更新的頁(yè)面元素

                          'data.html', // 請(qǐng)求的URL

                          {

                              method: 'get'

                          }

                      );

                  }

                  </script>

              </head>

              <body>

              <input type="button" value="click" onclick="test()" />

              <div id="divResult" />

              </body>

          </html>

          此外,Ajax.Updater類還有另外一個(gè)功能,如果請(qǐng)求的頁(yè)面內(nèi)容中包括JavaScript腳本,Ajax.Updater類可以執(zhí)行其中的腳本,只需要在Ajax操作選項(xiàng)中增加屬性“evalScripts: true”即可。對(duì)例2-11中的data.html進(jìn)行修改,在其中加入JavaScript腳本,如例2-13所示。

          例2-13  data.html

          <script language="javascript" type="text/javascript">

          sayHi = function() {

              alert("Hello, " + $F('name') + "!");

          }

          </script>

          <input type="text" id="name" />

          <input type="button" value="Click Me" onclick="sayHi()">

          調(diào)用Ajax.Updater的JavaScript腳本修改為:

          function test() {

              var myAjax = new Ajax.Updater(

                  'divResult', // 更新的頁(yè)面元素

                  'data.html', // 請(qǐng)求的URL

                  {

                      method: 'get',

                      evalScripts: true

                  }

              );

          }

          這樣就可以使用data.html頁(yè)面的內(nèi)容更新當(dāng)前頁(yè)面中的<div>元素divResult,并且執(zhí)行data.html頁(yè)面中包含的JavaScript腳本。

          這里需要注意的是例2-13中sayHi函數(shù)的寫(xiě)法,如果寫(xiě)成

          function sayHi() {

              alert("Hello, " + $F('name') + "!");

          }

          或者

          var sayHi = function() {

              alert("Hello, " + $F('name') + "!");

          }

          程序是不能正常運(yùn)行的。這是因?yàn)锳jax.Updater執(zhí)行腳本是通過(guò)eval的方式,而不是將腳本內(nèi)容引入到當(dāng)前頁(yè)面,直接聲明的function sayHi或者用var聲明的sayHi函數(shù),其作用域只是在這段腳本內(nèi)部,外部的其他腳本不能訪問(wèn)sayHi函數(shù)。而按照例2-13的方式聲明的函數(shù),其作用域是整個(gè)window。

          2.3.5  Ajax.PeriodicalUpdater類

          和Ajax.Request類相似,Ajax.PeriodicalUpdater類也繼承自Ajax.Base類。在一些Ajax應(yīng)用中,需要周期性地更新某些頁(yè)面元素,例如天氣預(yù)報(bào)、即時(shí)新聞等等。實(shí)現(xiàn)這樣的功能通常要使用JavaScript中的定時(shí)器函數(shù)setTimeout、clearTimeout等,而有了Ajax.PeriodicalUpdater類可以很好地簡(jiǎn)化這類編碼工作。

          新建一個(gè)Ajax. PeriodicalUpdater類的實(shí)例需要指定3個(gè)參數(shù):

          l  container:將要更新的頁(yè)面元素id;

          l  url:請(qǐng)求的URL地址;

          l  options:Ajax操作選項(xiàng)。

          和Ajax.Updater類相似,Ajax.PeriodicalUpdater類也支持動(dòng)態(tài)執(zhí)行JavaScript腳本,只需在Ajax操作選項(xiàng)中增加(evalScripts: true)屬性值即可。

          Ajax.PeriodicalUpdater類支持兩個(gè)特殊的Ajax操作選項(xiàng):frequency和decay。frequency參數(shù)很容易理解,既然是定時(shí)更新頁(yè)面元素,或者定時(shí)執(zhí)行腳本,那么多長(zhǎng)時(shí)間更新或者執(zhí)行一次呢?frequency指的就是兩次Ajax操作之間的時(shí)間間隔,單位是秒,默認(rèn)值為2秒。

          如果僅指定frequency參數(shù),程序會(huì)按照固定的時(shí)間間隔執(zhí)行Ajax操作。這樣的更新策略合理嗎?答案取決于請(qǐng)求URL中數(shù)據(jù)的更新頻率。如果請(qǐng)求的數(shù)據(jù)會(huì)很有規(guī)律地按照固定頻率改變,那么只要設(shè)置一個(gè)合適的frequency值,就可以很有效地實(shí)現(xiàn)頁(yè)面的定時(shí)更新。然而實(shí)際應(yīng)用中的數(shù)據(jù)往往不會(huì)那么理想,例如新聞,可能在一天中只有特定的一段時(shí)間更新頻率會(huì)很高,而在其他時(shí)間則幾乎沒(méi)有變化。經(jīng)常遇到這樣的情況該怎么辦呢?Ajax.PeriodicalUpdater類支持的decay屬性就是為了解決這個(gè)問(wèn)題而產(chǎn)生的。當(dāng)option中帶有decay屬性時(shí),如果請(qǐng)求返回的數(shù)據(jù)與上次相同,那么下次進(jìn)行Ajax操作的時(shí)間間隔會(huì)乘以一個(gè)decay的系數(shù)。

          為了比較明顯地看到decay屬性的效果,在請(qǐng)求的測(cè)試頁(yè)面中加入記錄時(shí)間的腳本,代碼如例2-14所示。

          例2-14  Ajax.PeriodicalUpdater類應(yīng)用示例

          ex10.html

          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

          <html>

              <head>

                  <title>chapter 3</title>

                  <script type="text/javascript" language="javascript"

                   src="prototype.js" ></script>

                  <script type="text/javascript" language="javascript">

                  var str='';

                  var intcount=0;

                  function test() {

                      var myAjax = new Ajax.PeriodicalUpdater(

                          'divResult', // 定時(shí)更新的頁(yè)面元素

                          'script1.html', // 請(qǐng)求的URL

                          {

                              method: 'get', // HTTP請(qǐng)求的方式為GET

                              evalScripts: true, // 是否執(zhí)行請(qǐng)求頁(yè)面中的腳本

                              frequency: 1, // 更新的頻率

                              decay: 1 // 衰減系數(shù)

                          }

                      );

                  }

                  </script>

              </head>

              <body>

              <input type="button" value="click" onclick="test()" />

              <div id="divResult" ></div>

              <div id="divResult2" ></div>

              </body>

          </html>

          script1.html:

          <script language="javascript" type="text/javascript">

          // Ajax.PeriodicalUpdater調(diào)用函數(shù)計(jì)數(shù)

          // 在<div>元素divResult2中增加一行結(jié)果,并記錄當(dāng)前時(shí)間和

          // Ajax.PeriodicalUpdater的調(diào)用次數(shù)

          intcount++;

          str = $('divResult2').innerHTML;

          $('divResult2').innerHTML = str + "count = " + intcount+ ": " + new Date() + "<br>";

          </script>

          例2-14的運(yùn)行結(jié)果如圖2-4所示。

          圖2-4  Ajax.PeriodicalUpdater類應(yīng)用示例

          可以看到,由于請(qǐng)求返回的數(shù)據(jù)一直沒(méi)有發(fā)生變化,每次請(qǐng)求時(shí)間的間隔是上一次的2倍(decay=2)。如果某一次請(qǐng)求返回的數(shù)據(jù)發(fā)生了變化,那么執(zhí)行請(qǐng)求的時(shí)間間隔則恢復(fù)到初始值。

          2.3.6  Ajax.Responders對(duì)象

          Ajax.Responders對(duì)象維護(hù)了一個(gè)正在運(yùn)行的Ajax對(duì)象列表,在需要實(shí)現(xiàn)一些全局的功能時(shí)就可以使用它。例如,在Ajax請(qǐng)求發(fā)出以后需要提示用戶操作正在執(zhí)行中,而操作返回以后則取消提示。利用Ajax.Responders對(duì)象就可以實(shí)現(xiàn)這樣的功能,如例2-15所示。

          例2-15  Ajax.Responders對(duì)象應(yīng)用示例

          <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

           "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

          <html>

              <head>

                  <title>chapter 3</title>

                  <script type="text/javascript" language="javascript"

                   src="prototype.js" ></script>

                  <script type="text/javascript" language="javascript">

                  function test() {

                      var myAjax = new Ajax.Request(

                          'data.html',

                          {

                              method: 'get',

                              onComplete: showResponse

                          }

                      );

                  }

                  function showResponse(response) {

                      $('divResult').innerHTML = response.responseText;

                  }      

                  var handle = {

                      onCreate: function() {

                          Element.show('loading'); // 當(dāng)創(chuàng)建Ajax請(qǐng)求時(shí),顯示loading

                      },

                      onComplete: function() {

                          // 當(dāng)請(qǐng)求成功返回時(shí),如果當(dāng)前沒(méi)有其他正在運(yùn)行中的Ajax請(qǐng)求,隱藏loading

                          if (Ajax.activeRequestCount == 0) {

                              Element.hide('loading');

                          }

                      }

                  };

                  // 將handle注冊(cè)到全局的Ajax.Responders對(duì)象中,使其生效

                  Ajax.Responders.register(handle);

                  </script>

              </head>

              <body>

              <input type="button" value="click" onclick="test()" />

              <div id="divResult" ></div>

              <div id='loading' style="display:none">

                  <img src="loading.gif">Loading...

              </div>

              </body>

          </html>

          例2-15中定義了一個(gè)handle對(duì)象,其中包含onCreate和onComplete函數(shù)。頁(yè)面中發(fā)出任何一個(gè)Ajax請(qǐng)求時(shí)都會(huì)調(diào)用onCreate方法,而請(qǐng)求完成時(shí)都會(huì)調(diào)用onComplete方法。例2-15的運(yùn)行結(jié)果如圖2-5所示。

          posted @ 2007-12-30 18:03 feingto 閱讀(568) | 評(píng)論 (0)編輯 收藏

          對(duì)xml進(jìn)行增、刪、改的很好例子

          rule.hta
          ================

          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
          <HTML>
          <HEAD>
          <TITLE>XML Editer</TITLE>
          <HTA:APPLICATION ID="oHTA"
          APPLICATIONNAME="myApp"
          BORDER="thick"
          BORDERSTYLE="normal"
          CAPTION="yes"
          ContextMenu="yes"
          ICON=""
          MAXIMIZEBUTTON="yes"
          MINIMIZEBUTTON="yes"
          scroll="no"
          selection="no"
          SHOWINTASKBAR="yes"
          SINGLEINSTANCE="yes"
          SYSMENU="yes"
          VERSION="1.0"
          WINDOWSTATE="normal"
          >

          <style type="text/css">
          </style>
          </HEAD>

          <script language="javascript">

          // load the xml file
          var xmlDoc = new ActiveXObject("Msxml2.DOMDocument");
          xmlDoc.async = false;
          xmlDoc.resolveExternals = false;
          xmlDoc.load("rule.xml");

          // load the xsl file
          var xslDoc = new ActiveXObject("Msxml2.FreeThreadedDOMDocument");
          xslDoc.async = false;
          xslDoc.resolveExternals = false;
          xslDoc.load("rule.xsl");

          // create the xslt object
          var xslt = new ActiveXObject("Msxml2.XSLTemplate");
          xslt.stylesheet = xslDoc;
          var xslProc = xslt.createProcessor();
          xslProc.input = xmlDoc;

          var checked_count = 0;
          var cur_page = 1;
          var total_page = 1;

          function OutputDocument(number){
          xslProc.addParameter("ename", number);
          xslProc.addParameter("startno", (cur_page - 1)*10);
          xslProc.addParameter("endno", cur_page*10);
          xslProc.transform();

          return xslProc.output;
          }

          function delete_node(node){
          if( node.hasChildNodes() ) { 
          var kids = node.childNodes; 
          for(var i=0;i<kids.length;i++) { 
          delete_node(kids);
          }
          }
          node.parentNode.removeChild(node);
          }

          function delete_rule(id){
          var node = xmlDoc.selectSingleNode("/rules/rule[event/id="+id+"]");
          delete_node(node);
          }

          function modify_node(node){
          node.selectSingleNode("event/id").text = modify_id.value;
          node.selectSingleNode("event/name").text = modify_name.value;
          if( modify_state.checked ) {
          node.selectSingleNode("enable").text = "true";
          } else {
          node.selectSingleNode("enable").text = "false";
          }
          }

          function modify_rule(id){
          var node = xmlDoc.selectSingleNode("/rules/rule[event/id="+id+"]");
          modify_node(node);
          }

          function add_rule(){
          var id = xmlDoc.createElement("id");
          id.appendChild(xmlDoc.createTextNode(add_id.value));
          var name = xmlDoc.createElement("name");
          name.appendChild(xmlDoc.createTextNode(add_name.value));

          var event = xmlDoc.createElement("event");
          event.appendChild(id);
          event.appendChild(name);

          var enable = xmlDoc.createElement("enable");
          if( add_state.checked ) {
          enable.appendChild(xmlDoc.createTextNode("true"));
          } else {
          enable.appendChild(xmlDoc.createTextNode("false"));
          }

          var rule = xmlDoc.createElement("rule");
          rule.appendChild(event);
          rule.appendChild(enable);

          var parent = xmlDoc.selectSingleNode("/rules");
          if( parent.hasChildNodes() ) {
          parent.insertBefore(rule, parent.firstChild);
          } else {
          parent.appendChild(rule);
          }
          }

          function gotoPage(pageno){
          if( pageno < 1 ) {
          cur_page = 1;
          } else if( pageno >= total_page ) {
          cur_page = total_page;
          } else {
          cur_page = pageno;
          }
          Transform();
          }

          function saveXML(){
          xmlDoc.save("rule.xml");
          }

          function protectsubmit(val){
          if( val == 1 ) { //add
          if( add_id.value < 10000 || add_name.value == "" ) {
          window.alert("事件號(hào)必須是5位整數(shù)且事件名不能為空");
          } else if( xmlDoc.selectSingleNode("/rules/rule/event/id[. = " + add_id.value + "]") ) {
          window.alert("事件號(hào)" + add_id.value + "已經(jīng)存在");
          } else {
          add_rule();
          saveXML();
          Transform();
          }
          } else if( val == 2 ) { //modify
          var id = viewTable.rows[getFirstCheckedLine()].cells[2].innerText;
          if( modify_id.value < 10000 || modify_name.value == "" ) {
          window.alert("事件號(hào)必須是5位整數(shù)且事件名不能為空");
          } else if( id != modify_id.value && xmlDoc.selectSingleNode("/rules/rule/event/id[. = " + modify_id.value + "]") ) {
          window.alert("事件號(hào)" + modify_id.value + "已經(jīng)存在");
          } else {
          if( confirm("確認(rèn)修改?") ) {
          modify_rule(id);
          saveXML();
          Transform();
          }
          }
          } else if( val == 3 ) { //delete
          if( !confirm("確認(rèn)刪除?") ) {
          return;
          }
          for( var i = 1; i < viewTable.rows.length; i++ ) {
          var id = viewTable.rows.cells[2].innerText;
          if( eval("viewchk_" + id + ".checked") == true ) {
          delete_rule(id)
          }
          }
          saveXML();
          Transform();
          } else if( val == 4 ) { //select all
          checked_count = viewTable.rows.length - 1;
          for( var i = 1; i < viewTable.rows.length; i++ ) {
          var id = viewTable.rows.cells[2].innerText;
          eval("viewchk_" + id + ".checked = true");
          }
          changeState();
          } else if( val == 5 ) { //cancel all
          checked_count = 0;
          for( var i = 1; i < viewTable.rows.length; i++ ) {
          var id = viewTable.rows.cells[2].innerText;
          eval("viewchk_" + id + ".checked = false");
          }
          changeState();
          }
          }

          function getFirstCheckedLine(){
          for( var i = 1; i < viewTable.rows.length; i++ ) {
          var id = viewTable.rows.cells[2].innerText;
          if( eval("viewchk_" + id + ".checked") == true ) {
          return i;
          }
          }
          return 0;
          }

          function checkOVItem(val){
          if( eval("viewchk_" + val+".checked") == true ) {
          checked_count++;
          } else {
          checked_count--;
          }
          changeState();
          }

          function changeState(){
          if( checked_count ) {
          delete_btn.disabled = false;
          cancel_all_btn.disabled = false;
          } else {
          delete_btn.disabled = true;
          cancel_all_btn.disabled = true;
          }
          if( (checked_count + 1) == viewTable.rows.length ) {
          select_all_btn.disabled = true;
          } else {
          select_all_btn.disabled = false;
          }

          if( checked_count == 1 ) {
          modify_btn.disabled = false;
          modify_id.disabled = false;
          modify_name.disabled = false;
          modify_state.disabled = false;
          var id = getFirstCheckedLine();
          modify_id.value = viewTable.rows(id).cells(2).innerText;
          modify_name.value = viewTable.rows(id).cells(3).innerText;
          if( viewTable.rows(id).cells(1).innerText == "有效" ) {
          modify_state.checked = true;
          } else {
          modify_state.checked = false;
          }
          } else {
          modify_btn.disabled = true;
          modify_id.disabled = true;
          modify_name.disabled = true;
          modify_state.disabled = true;
          modify_id.value="請(qǐng)選擇一條規(guī)則";
          modify_name.value="請(qǐng)選擇一條規(guī)則";
          }
          }

          function showPageInfo(){
          if( total_item.value == 0 ) {
          total_page = 1;
          } else {
          total_page = Math.floor((9 + parseInt(total_item.value)) / 10);
          }
          var txt = " 共"+total_item.value+"條記錄";
          var prev_page = cur_page - 1;
          var next_page = parseInt(cur_page) + 1;
          if( cur_page > 1 ) {
          txt += " <input type='button' value='<' onClick='gotoPage(" + prev_page + ")'/>"
          } else {
          txt += " <input type='button' value='<' onClick='gotoPage(" + prev_page + ")' disabled/>"
          }
          if( cur_page < total_page ) {
          txt += " <input type='button' value='>' onClick='gotoPage(" + next_page + ")'/>"
          } else {
          txt += " <input type='button' value='>' onClick='gotoPage(" + next_page + ")' disabled/>"
          }

          txt += " 第<input type='text' id='page_number' size='4' maxlength='4' value='" + cur_page + "' onBlur='gotoPage(this.value)'/>頁(yè) 共" + total_page + "頁(yè)";
          page_info.innerHTML = txt;
          // window.alert(txt);
          }

          function Transform(){
          var txt = document.getElementById("ename").value;
          var str = OutputDocument(txt);
          rule_list.innerHTML = str;
          checked_count = 0;
          showPageInfo();
          changeState();
          // window.alert(str);
          }
          </script>

          <BODY onLoad="Transform()">

          <table width="550" border="1" cellpadding="0" cellspacing="0" style="border-collapse:collapse;">
          <tr>
          <td>
          <table width="100%" border="0" cellpadding="0" cellspacing="0" style="border-collapse:collapse;">
          <TR height=5><td colspan=10 style="font-size:0px;"></td></TR>
          <TR height=25>
          <td colspan=3 align=center>事件名包含:</td>
          <td colspan=3 align=center><input type="text" value="" id="ename" size="35" maxlength="16"/></td>
          <td colspan=4><input type="button" value="搜索" onClick="Transform()"/></td>
          </TR>
          <TR height=1><td colspan=10 bgcolor=#2b7297></td></TR>
          <TR height=30>
          <td width=45 align=center><b>添加</b></td>
          <td width=5 align=center><font color=gray>|</font></td>
          <td width=50 align=center>事件號(hào)</td>
          <td width=55 align=center><input type="text" name="add_id" value="" size="5" maxlength="5" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')"></td>
          <td width=55 align=center>事件名</td>
          <td width=* align=center><input type="text" name="add_name" maxlength="48" value=""></td>
          <td width=70 align=center>是否使用</td>
          <td width=30 align=center>
          <input type='checkbox' name='add_state' checked>
          </td> 
          <td width=5 align=center><font color=gray>|</font></td>
          <td width=70 align=center><input type="button" name="add_btn" value="確定" onClick="protectsubmit(1)"></td>
          </TR>
          <TR height=1><td colspan=10 bgcolor=#2b7297></td></TR>
          <TR height=30>
          <td width=45 align=center><b>修改</b></td>
          <td width=5 align=center><font color=gray>|</font></td>
          <td width=50 align=center>事件號(hào)</td>
          <td width=55 align=center>
          <input type="text" name="modify_id" value="<請(qǐng)選擇一條規(guī)則>" size="5" maxlength="5" onkeyup="this.value=this.value.replace(/\D/g,'')" onafterpaste="this.value=this.value.replace(/\D/g,'')" disabled></td>
          <td width=55 align=center>事件名</td>
          <td width=* align=center>
          <input type="text" name="modify_name" maxlength="48" value="<請(qǐng)選擇一條規(guī)則>" disabled></td>
          <td width=70 align=center>是否使用</td>
          <td width=30 align=center>
          <input type='checkbox' name='modify_state' disabled>
          </td> 
          <td width=5 align=center><font color=gray>|</font></td>
          <td width=70 align=center><input type="button" name="modify_btn" value="確定" onClick="protectsubmit(2)"></td>
          </TR>
          <TR height=1><td colspan=10 bgcolor=#2b7297></td></TR>
          <TR height=30>
          <td colspan=5 align=left class=tablefont></td>
          <td align=right><input type="button" name="select_all_btn" value="全部選擇" onClick="protectsubmit(4)"></td>
          <td colspan=2 align=right><input type="button" name="cancel_all_btn" value="全部不選" onClick="protectsubmit(5)" disabled></td>
          <td align=center></td>
          <td align=center><input type="button" name="delete_btn" value="刪除" onClick="protectsubmit(3)" disabled></td>
          </TR>
          <TR height=30><td colspan=4>規(guī)則列表</td><TD colspan=6 align=right><div id="page_info" name="page_info"/></TR>
          <TR>
          <TD colspan=10><div id="rule_list" name="rule_list"/></TD>
          </TR>
          <TR height=5><td colspan=10></td></TR>
          </table>
          </td>
          </tr>
          <tr>
          </tr>
          </table>

          </BODY>
          </HTML>


          rule.xml
          ============
          <?xml version="1.0" encoding="GB2312"?>
          <?xml:stylesheet type="text/xsl" href="rule.xsl"?>
          <rules>
          <rule>
          <event>
          <id>10001</id>
          <name>TFTP下載文件</name>
          </event>
          <enable>false</enable>
          </rule>
          <rule>
          <event>
          <id>10002</id>
          <name>TFTP上傳文件</name>
          </event>
          <enable>false</enable>
          </rule>
          <rule>
          <event>
          <id>10003</id>
          <name>telnet登錄成功</name>
          </event>
          <enable>false</enable>
          </rule>

          </rules>

          rule.xsl
          =============
          <?xml version="1.0" encoding="GB2312"?>
          <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
          <xsl:strip-space elements="*"/>
          <xsl:output method= "html"/>
          <xsl:param name="ename">undefined</xsl:param>
          <xsl:param name="startno">undefined</xsl:param>
          <xsl:param name="endno">undefined</xsl:param>

          <xsl:template match="/">
          <html>
          <body>
          <xsl:apply-templates select="rules"/>
          </body>
          </html>
          </xsl:template>

          <xsl:template match="rules">
          <input type="hidden" name="total_item">
          <xsl:attribute name="value"><xsl:value-of select="count(rule[contains(event/name, $ename)])"/></xsl:attribute>
          </input>
          <TABLE id="viewTable" name="viewTable" width="100%" border="1" bordercolor="#85979f" cellSpacing="0" cellPadding="0" style="border-collapse:collapse;">
          <tr height="25">
          <TD width="10%" align="center">選擇</TD>
          <TD width="10%" align="center">狀態(tài)</TD>
          <TD width="10%" align="center">事件號(hào)</TD>
          <TD width="*" align="center">事件名</TD>
          </tr>

          <xsl:for-each select='rule[contains(event/name, $ename)]'>
          <xsl:sort select="event/id"/>
          <xsl:if test="position()> $startno and position()<= $endno">
          <tr>
          <td align="center">
          <input type='checkbox'>
          <xsl:attribute name="name">viewchk_<xsl:value-of select="event/id"/></xsl:attribute>
          <xsl:attribute name="value"><xsl:value-of select="event/id"/></xsl:attribute>
          <xsl:attribute name="onClick">checkOVItem(<xsl:value-of select="event/id"/>)</xsl:attribute>
          </input>
          </td>
          <xsl:choose>
          <xsl:when test="enable[. = 'true']">
          <td align="center">有效</td>
          </xsl:when>
          <xsl:otherwise>
          <td align="center">禁用</td>
          </xsl:otherwise>
          </xsl:choose>
          <td align="center"><xsl:value-of select="event/id"/></td>
          <td><xsl:value-of select="event/name"/></td>
          </tr>
          </xsl:if>
          </xsl:for-each>
          </TABLE>
          </xsl:template>

          </xsl:stylesheet>

          posted @ 2007-12-29 15:44 feingto 閱讀(362) | 評(píng)論 (0)編輯 收藏

          prototype.js 1.4版開(kāi)發(fā)者手冊(cè)(強(qiáng)烈推薦)

               摘要: .reference table{border:1px dashed darkblue;} .reference th{border:1px dashed darkblue;color:white;background-color:darkblue;} .reference td{border:1px dashed darkblue;corlor:black;background-color:w...  閱讀全文

          posted @ 2007-12-29 14:59 feingto 閱讀(340) | 評(píng)論 (0)編輯 收藏

          showModalDialog/showModelessDialog實(shí)例,父窗口向子窗口傳遞值,子窗口設(shè)置父窗口的值,子窗口關(guān)閉的時(shí)候返回值到父窗口.關(guān)閉刷新父窗口

          下面是showModalDialog/showModelessDialog使用例子,父窗口向子窗口傳遞值,子窗口設(shè)置父窗口的值,子窗口關(guān)閉的時(shí)候返回值到父窗口.關(guān)閉刷新父窗口,希望對(duì)象我這樣的WEB開(kāi)發(fā)的菜鳥(niǎo)有所幫助.

          (一)showModalDialog使用例子,父窗口向子窗口傳遞值,子窗口設(shè)置父窗口的值,子窗口關(guān)閉的時(shí)候返回值到父窗口.


          farther.html
          ---------------------------
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD>
          <TITLE> New Document </TITLE>
          <META NAME="Generator" CONTENT="EditPlus">
          <META NAME="Author" CONTENT="">
          <META NAME="Keywords" CONTENT="">
          <META NAME="Description" CONTENT="">
          <script language="javascript">
          <!--
          function openChild(){

          var k = window.showModalDialog("child.html",window,"dialogWidth:335px;status:no;dialogHeight:300px");
          if(k != null)
          document.getElementById("txt11").value = k;
          }
          //-->
          </script>
          </HEAD>

          <BODY>
          <br>傳遞到父窗口的值:<input id="txt9" type="text" value="3333333333333"><br>
          返回的值:<input id="txt11" type="text"><br>
          子窗口設(shè)置的值:<input id="txt10" type="text"><br>


          <input type ="button" value="openChild" onclick="openChild()">
          </BODY>
          </HTML>
          ---------------------------------------------------------------
          child.html
          --------
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD>
          <TITLE> New Document </TITLE>
          <META NAME="Generator" CONTENT="EditPlus">
          <META NAME="Author" CONTENT="">
          <META NAME="Keywords" CONTENT="">
          <META NAME="Description" CONTENT="">
          <meta http-equiv="Expires" CONTENT="0">
          <meta http-equiv="Cache-Control" CONTENT="no-cache">
          <meta http-equiv="Pragma" CONTENT="no-cache">

          </HEAD>

          <BODY>
          <br>父窗口傳遞來(lái)的值:<input id="txt0" type="text"><br>
          輸入要設(shè)置父窗口的值:<input id="txt1" type="text"><input type ="button" value="設(shè)置父窗口的值" onclick="setFather()"><br>
          輸入返回的值:<input id="txt2" type="text"><input type ="button" value="關(guān)閉切返回值" onclick="retrunValue()">
          <input type ="button" value="關(guān)閉刷新父窗口" onclick="">

          </BODY>
          </HTML>

          <script language=javascript>
          <!--
          var k=window.dialogArguments;
          //獲得父窗口傳遞來(lái)的值
          if(k!=null)
           {
           document.getElementById("txt0").value = k.document.getElementById("txt9").value;
           }
           //設(shè)置父窗口的值
          function setFather()
          {
           k.document.getElementById("txt10").value = document.getElementById("txt1").value
          }
          //設(shè)置返回到父窗口的值
          function retrunValue()
          {
          var s = document.getElementById("txt2").value;
          window.returnValue=s;
          window.close();
          }
          //-->
          </script>

          ----------------------------
          說(shuō)明:
          由于showModalDialog緩存嚴(yán)重,下面是在子窗口取消客戶端緩存的設(shè)置.也可以在服務(wù)器端取消緩存,參考:
          http://adandelion.cnblogs.com/articles/252137.html
          <meta http-equiv="Expires" CONTENT="0">
          <meta http-equiv="Cache-Control" CONTENT="no-cache">
          <meta http-equiv="Pragma" CONTENT="no-cache">
          ------------------------------------------------------------------------------------------------------------------------
          (二)下面是關(guān)閉刷新父窗口的例

          farther.html
          ---------------------------
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD>
          <TITLE> New Document </TITLE>
          <META NAME="Generator" CONTENT="EditPlus">
          <META NAME="Author" CONTENT="">
          <META NAME="Keywords" CONTENT="">
          <META NAME="Description" CONTENT="">
          <script language="javascript">
          <!--
          function openChild()
          {

           var k = window.showModalDialog("child.html",window,"dialogWidth:335px;status:no;dialogHeight:300px");
           if(k == 1)//判斷是否刷新
           {
            alert('刷新');
            window.location.reload();
           }
          }
          //-->
          </script>
          </HEAD>

          <BODY>
          <br>傳遞到父窗口的值:<input id="txt9" type="text" value="3333333333333"><br>
          <input type ="button" value="openChild" onclick="openChild()">
          </BODY>
          </HTML>
          ----------------------------------------------------
          child.html
          --------
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
          <HTML>
          <HEAD>
          <TITLE> New Document </TITLE>
          <META NAME="Generator" CONTENT="EditPlus">
          <META NAME="Author" CONTENT="">
          <META NAME="Keywords" CONTENT="">
          <META NAME="Description" CONTENT="">
          <meta http-equiv="Expires" CONTENT="0">
          <meta http-equiv="Cache-Control" CONTENT="no-cache">
          <meta http-equiv="Pragma" CONTENT="no-cache">

          </HEAD>

          <BODY>
          <br>父窗口傳遞來(lái)的值:<input id="txt0" type="text"><br>

          <input type ="button" value="關(guān)閉刷新父窗口" onclick="winClose(1)">
          <input type ="button" value="關(guān)閉不刷新父窗口" onclick="winClose(0)">

          </BODY>
          </HTML>

          <script language=javascript>
          <!--
          var k=window.dialogArguments;
          //獲得父窗口傳遞來(lái)的值
          if(k!=null)
           {
           document.getElementById("txt0").value = k.document.getElementById("txt9").value;
           }

          //關(guān)閉窗口返回是否刷新的參數(shù).
          function winClose(isRefrash)
          {

          window.returnValue=isRefrash;
          window.close();
          }
          //-->
          </script>

          --------------------------
          說(shuō)明
          1.下面是取消客戶端緩存的:
          <meta http-equiv="Expires" CONTENT="0">
          <meta http-equiv="Cache-Control" CONTENT="no-cache">
          <meta http-equiv="Pragma" CONTENT="no-cache">
          也可以在服務(wù)器端取消緩存,參考:
          http://adandelion.cnblogs.com/articles/252137.html

          2.向父窗口傳遞闡述在ASP.NET中也可以是用aaa.aspx?id=1的方式傳遞.

          3.不刷新父窗口的話在父窗口中直接這樣一來(lái)設(shè)置可以.
          <script>
          window.showModalDialog("child.html",window,"dialogWidth:335px;status:no;dialogHeight:300px");
          </script>
          4.在子窗口中若要提交頁(yè)面的話要加入:,這樣就不會(huì)打開(kāi)新窗口了.
          <head>
          <base target="_self">
          </HEAD>

          本文參考了:http://dev.csdn.net/develop/article/15/15113.shtm ,里面有showModalDialog/showModelessDialog的詳細(xì)使用說(shuō)明

          posted @ 2007-12-29 14:33 feingto 閱讀(1400) | 評(píng)論 (0)編輯 收藏

          制作Javascript彈出窗口技巧九則

                  經(jīng)常上網(wǎng)的朋友可能會(huì)到過(guò)這樣一些網(wǎng)站,一進(jìn)入首頁(yè)立刻會(huì)彈出一個(gè)窗口,或者按一個(gè)連接或按鈕彈出,通常在這個(gè)窗口里會(huì)顯示一些注意事項(xiàng)、版權(quán)信 息、警告、歡迎光顧之類的話或者作者想要特別提示的信息。其實(shí)制作這樣的頁(yè)面效果非常的容易,只要往該頁(yè)面的HTML里加入幾段Javascript代碼 即可實(shí)現(xiàn)。下面俺就帶您剖析它的奧秘。

            1、最基本的彈出窗口代碼
            其實(shí)代碼非常簡(jiǎn)單:
            < SCRIPT LANGUAGE="javascript">
            < !--
            window.open ("page.html")
            -->
            < /SCRIPT>
            因?yàn)檫@是一段Javascript代碼,所以它們應(yīng)該放在< SCRIPT LANGUAGE="javascript">之間。 < !-- 和 -->是對(duì)一些版本低的瀏覽器起作用,在這些老瀏覽器中不會(huì)將標(biāo)簽中的代碼作為文本顯示出來(lái)。要養(yǎng)成這個(gè)好習(xí)慣啊。
            window.open ("page.html") 用于控制彈出新的窗口page.html,如果page.html不與主窗口在同一路徑下,前面應(yīng)寫(xiě)明路徑,絕對(duì)路徑(http://)和相對(duì)路徑(../)均可。
            用單引號(hào)和雙引號(hào)都可以,只是不要混用。
            這一段代碼可以加入HTML的任意位置,< head>和< /head>之間可以,< body>間< /body>也可以,越前越早執(zhí)行,尤其是頁(yè)面代碼長(zhǎng),又想使頁(yè)面早點(diǎn)彈出就盡量往前放。 也可以,越前越早執(zhí)行,尤其是頁(yè)面代碼長(zhǎng),又想使頁(yè)面早點(diǎn)彈出就盡量往前放。

            2、經(jīng)過(guò)設(shè)置后的彈出窗口
            下面再說(shuō)一說(shuō)彈出窗口的設(shè)置。只要再往上面的代碼中加一點(diǎn)東西就可以了。我們來(lái)定制這個(gè)彈出的窗口的外觀,尺寸大小,彈出的位置以適應(yīng)該頁(yè)面的具體情況。
            < SCRIPT LANGUAGE="javascript">
            < !--
            window.open ("page.html", "newwindow", "height=100, width=400, top=0, left=0, toolbar=no, menubar=no, scrollbars=no, resizable=no,location=no, status=no")
            //寫(xiě)成一行
            -->
            < /SCRIPT>
            參數(shù)解釋:
            < SCRIPT LANGUAGE="javascript"> js腳本開(kāi)始;
            window.open 彈出新窗口的命令;
            "page.html" 彈出窗口的文件名;
            "newwindow" 彈出窗口的名字(不是文件名),非必須,可用空"代替;
            height=100 窗口高度;
            width=400 窗口寬度;
            top=0 窗口距離屏幕上方的象素值;
            left=0 窗口距離屏幕左側(cè)的象素值;
            toolbar=no 是否顯示工具欄,yes為顯示;
            menubar,scrollbars 表示菜單欄和滾動(dòng)欄。
            resizable=no 是否允許改變窗口大小,yes為允許;
            location=no 是否顯示地址欄,yes為允許;
            status=no 是否顯示狀態(tài)欄內(nèi)的信息(通常是文件已經(jīng)打開(kāi)),yes為允許;
            < /SCRIPT> js腳本結(jié)束

            3、用函數(shù)控制彈出窗口
            下面是一個(gè)完整的代碼:
            < html>
            < head>
            < script LANGUAGE="JavaScript">
            < !--
            function openwin() {
            window.open ("page.html", "newwindow", "height=100, width=400, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no")
            //寫(xiě)成一行
            }
            //-->
            < /script>
            < /head>
            < body onload="openwin()">
            ...任意的頁(yè)面內(nèi)容...
            < /body>
            < /html>
            這里定義了一個(gè)函數(shù)openwin(),函數(shù)內(nèi)容就是打開(kāi)一個(gè)窗口。在調(diào)用它之前沒(méi)有任何用途。
            怎么調(diào)用呢?
            方法一:< body onload="openwin()"> 瀏覽器讀頁(yè)面時(shí)彈出窗口;
            方法二:< body onunload="openwin()"> 瀏覽器離開(kāi)頁(yè)面時(shí)彈出窗口;
            方法三:用一個(gè)連接調(diào)用:< a href="#" onclick="openwin()">打開(kāi)一個(gè)窗口< /a>
            注意:使用的"#"是虛連接。
            方法四:用一個(gè)按鈕調(diào)用:< input type="button" onclick="openwin()" value="打開(kāi)窗口">

            4、同時(shí)彈出2個(gè)窗口
            對(duì)源代碼稍微改動(dòng)一下:
            < script LANGUAGE="JavaScript">
            < !--
            function openwin() {
            window.open ("page.html", "newwindow", "height=100, width=100, top=0, left=0,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no")
            //寫(xiě)成一行
            window.open ("page2.html", "newwindow2", "height=100, width=100, top=100, left=100,toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no")
            //寫(xiě)成一行
            }
            //-->
            < /script>
            為避免彈出的2個(gè)窗口覆蓋,用top和left控制一下彈出的位置不要相互覆蓋即可。最后用上面說(shuō)過(guò)的四種方法調(diào)用即可。
            注意:2個(gè)窗口的name(newwindows和newwindow2)不要相同,或者干脆全部為空。OK?

            5、主窗口打開(kāi)文件1.htm,同時(shí)彈出小窗口page.html
            如下代碼加入主窗口< head>區(qū):
            < script language="javascript">
            < !--
            function openwin() {
            window.open("page.html","","width=200,height=200")
            }
            //-->
            < /script>
            加入< body>區(qū):
            < a href="1.htm" onclick="openwin()">open< /a>即可

            6、彈出的窗口之定時(shí)關(guān)閉控制
            下面我們?cè)賹?duì)彈出的窗口進(jìn)行一些控制,效果就更好了。如果我們?cè)賹⒁恍《未a加入彈出的頁(yè)面(注意是加入到page.html的HTML中,可不是主頁(yè)面中,否則...),讓它10秒后自動(dòng)關(guān)閉是不是更酷了?
            首先,將如下代碼加入page.html文件的< head>區(qū):
            < script language="JavaScript">
            function closeit() {
            setTimeout("self.close()",10000) //毫秒
            }
            < /script>
            然后,再用< body onload="closeit()"> 這一句話代替page.html中原有的< BODY>這一句就可以了。(這一句話千萬(wàn)不要忘記寫(xiě)啊!這一句的作用是調(diào)用關(guān)閉窗口的代碼,10秒鐘后就自行關(guān)閉該窗口。)

            7、在彈出窗口中加上一個(gè)關(guān)閉按鈕
            < FORM>
            < INPUT TYPE="BUTTON" VALUE="關(guān)閉" onClick="window.close()">
            < /FORM>
            呵呵,現(xiàn)在更加完美了!

            8、內(nèi)包含的彈出窗口---一個(gè)頁(yè)面兩個(gè)窗口
            上面的例子都包含兩個(gè)窗口,一個(gè)是主窗口,另一個(gè)是彈出的小窗口。通過(guò)下面的例子,你可以在一個(gè)頁(yè)面內(nèi)完成上面的效果。
            < html>
            < head>
            < SCRIPT LANGUAGE="JavaScript">
            function openwin()
            {
            OpenWindow=window.open("", "newwin", "height=250, width=250,toolbar=no,scrollbars="+scroll+",menubar=no");
            //寫(xiě)成一行
            OpenWindow.document.write("< TITLE>例子< /TITLE>")
            OpenWindow.document.write("< BODY BGCOLOR=#ffffff>")
            OpenWindow.document.write("< h1>Hello!< /h1>")
            OpenWindow.document.write("New window opened!")
            OpenWindow.document.write("< /BODY>")
            OpenWindow.document.write("< /HTML>")
            OpenWindow.document.close()
            }
            < /SCRIPT>
            < /head>
            < body>
            < a href="#" onclick="openwin()">打開(kāi)一個(gè)窗口< /a>
            < input type="button" onclick="openwin()" value="打開(kāi)窗口">
            < /body>
            < /html>
            看看OpenWindow.document.write()里面的代碼不就是標(biāo)準(zhǔn)的HTML嗎?只要按照格式寫(xiě)更多的行即可。千萬(wàn)注意多一個(gè)標(biāo)簽或少一個(gè)標(biāo)簽就會(huì)出現(xiàn)錯(cuò)誤。記得用OpenWindow.document.close()結(jié)束啊。

            9、終極應(yīng)用--彈出的窗口之Cookie控制
            回想一下,上面的彈出窗口雖然酷,但是有一點(diǎn)小毛病(沉浸在喜悅之中,一定沒(méi)有發(fā)現(xiàn)吧?)比如你將上面的腳本放在一個(gè)需要頻繁經(jīng)過(guò)的頁(yè)面里(例如首頁(yè)),那么每次刷新這個(gè)頁(yè)面,窗口都會(huì)彈出一次,是不是非常煩人?:-(
            有解決的辦法嗎?當(dāng)然有!我們使用cookie來(lái)控制一下就可以了。首先,將如下代碼加入主頁(yè)面HTML的< HEAD>區(qū):
            < script>
            function openwin(){
            window.open("page.html","","width=200,height=200")
            }
            function get_cookie(Name) {
            var search = Name + "=" var returnvalue = "";
            if (document.cookie.length > 0) {
            offset = document.cookie.indexOf(search)
            if (offset != -1) {
            offset += search.length
            end = document.cookie.indexOf(";", offset);
            if (end == -1)
            end = document.cookie.length;
            returnvalue=unescape(document.cookie.substring(offset, end))
            }
            }
            return returnvalue;
            }
            function loadpopup(){
            if (get_cookie("popped")=="){
            openwin()
            document.cookie="popped=yes"
            }
            }
            < /script>
            然后,用< body onload="loadpopup()">(注意不是openwin而是loadpop啊!)替換主頁(yè)面中原有的< BODY>這一句即可。你可以試著刷新一下這個(gè)頁(yè)面或重新進(jìn)入該頁(yè)面,窗口再也不會(huì)彈出了。真正的Pop-Only-Once!
            寫(xiě)到這里彈出窗口的制作和應(yīng)用技巧基本上算是完成了,俺也累壞了,一口氣說(shuō)了這么多,希望對(duì)正在制作網(wǎng)頁(yè)的朋友有所幫助俺就非常欣慰了。
            需要注意的是,JS腳本中的的大小寫(xiě)最好前后保持一致。 

          posted @ 2007-12-29 14:24 feingto 閱讀(305) | 評(píng)論 (0)編輯 收藏

          jsp中的時(shí)間操作

          jsp中的時(shí)間操作

          經(jīng)常看見(jiàn)jsp版里有人問(wèn)時(shí)間操作的問(wèn)題,這些問(wèn)題一般包括:取當(dāng)前時(shí)間,把一個(gè)指定的字符串時(shí)間轉(zhuǎn)化成時(shí)間類型,求兩個(gè)時(shí)間之間的天數(shù),求一段時(shí)間以前的時(shí)間,求一段時(shí)間以后的時(shí)間,在這里就把這些問(wèn)題匯總一下。
          <%@  page  contentType="text/html;charset=gb2312"%>
          <%@ page import="java.text.*"%>
          <%@ page import="java.util.*"%>
          <%
          //字符串轉(zhuǎn)化成時(shí)間類型(字符串可以是任意類型,只要和SimpleDateFormat中的格式一致即可)
          java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("M/dd/yyyy hh:mm:ss a",java.util.Locale.US);
          java.util.Date d = sdf.parse("5/13/2003 10:31:37 AM"); 
          out.println(d);
          out.println("<br>");
          SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
          String mDateTime1=formatter.format(d);
          out.println(mDateTime1);
          out.println("<br>");
          out.println(d.getTime());
          out.println("<br>");
          //當(dāng)前時(shí)間
          Calendar cal  = Calendar.getInstance();
          //  SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss");
          SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd  HH:mm:ss G E D F w W a E F");
          String mDateTime=formatter.format(cal.getTime());
          out.println(mDateTime);
          out.println("<br>");
          //1年前日期
          java.util.Date myDate=new java.util.Date(); 
          long myTime=(myDate.getTime()/1000)-60*60*24*365;
          myDate.setTime(myTime*1000);
          String mDate=formatter.format(myDate);
          out.println(mDate);
          out.println("<br>");
          //明天日期
          myDate=new java.util.Date();
          myTime=(myDate.getTime()/1000)+60*60*24;
          myDate.setTime(myTime*1000);
          mDate=formatter.format(myDate);
          out.println(mDate);
          out.println("<br>");
          //兩個(gè)時(shí)間之間的天數(shù)
          SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
          java.util.Date date= myFormatter.parse("2003-05-1");
          java.util.Date mydate= myFormatter.parse("1899-12-30");
          long  day=(date.getTime()-mydate.getTime())/(24*60*60*1000);
          out.println(day);
          out.println("<br>");
          //加半小時(shí)
          SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
          java.util.Date date1 = format.parse("2002-02-28 23:16:00");
          long Time=(date1.getTime()/1000)+60*30;
          date1.setTime(Time*1000);
          String mydate1=formatter.format(date1);
          out.println(mydate1);
          out.println("<br>");
          //年月周求日期
          SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM F E");
          java.util.Date date2= formatter2.parse("2003-05 5 星期五");
          SimpleDateFormat formatter3 = new SimpleDateFormat("yyyy-MM-dd");
          String mydate2=formatter3.format(date2);
          out.println(mydate2);
          out.println("<br>");
          //求是星期幾
          mydate= myFormatter.parse("2001-1-1");
          SimpleDateFormat formatter4 = new SimpleDateFormat("E");
          String mydate3=formatter4.format(mydate);
          out.println(mydate3);
          out.println("<br>");
          %>

          posted @ 2006-05-10 10:41 feingto 閱讀(675) | 評(píng)論 (1)編輯 收藏

          hibernate的中文問(wèn)題的解決方案

          系統(tǒng)配置:win2k3 server,jsdk 1.5.0 rc,mysql 4.0.20a,hibernate 2.1.0 ,elcipse 3.0.1
          問(wèn)題描述:在使用hibernate作為數(shù)據(jù)持久層的方案時(shí),照樣會(huì)遇到中文問(wèn)題,具體情況時(shí)插入到數(shù)據(jù)庫(kù)中的漢字顯示為??,顯示數(shù)據(jù)時(shí)漢字為??
          探索: 經(jīng)過(guò)試驗(yàn)發(fā)現(xiàn)與漢字編碼有關(guān)的地方有以下兩處,一個(gè)是數(shù)據(jù)庫(kù)連接url ,一個(gè)是編程時(shí)獲取Configuration 類的實(shí)例的語(yǔ)句的方式。
          方案1:
          ??? * 編程時(shí)獲取Configuration 類的實(shí)例的語(yǔ)句為
          ??? * new Configuration().addClass(xx.class);
          ??? 必須在hibernate.properties文件里數(shù)據(jù)庫(kù)連接url后加上?characterEncoding=gbk&useUnicode=true
          方案2:
          ??? * 編程時(shí)獲取Configuration 類的實(shí)例的語(yǔ)句為
          ??? * new Configuration().configure().
          ??? 在hibernate.cfg.xml文件的<session-factory/>塊中設(shè)置
          ??????? <property name="connection.useUnicode">true</property>
          ??????? <property name="connection.characterEncoding">UTF-8</property>
          ??? 或編程時(shí)寫(xiě):
          ????? Properties extraProperties = new Properties();
          ????? extraProperties.put("hibernate.connection.useUnicode", "true");
          ????? extraProperties.put("hibernate.connection.characterEncoding", "UTF-8");
          ????? myConfiguration.addProperties(extraProperties);

          原來(lái)懷疑與xml頁(yè)面的編碼有關(guān)試了一下,好像不起作用。

          posted @ 2006-05-08 14:42 feingto 閱讀(458) | 評(píng)論 (2)編輯 收藏

          在Struts框架內(nèi)實(shí)現(xiàn)圖片上傳 (轉(zhuǎn)載:http://www.aygfsteel.com/Todayfreeman/)

          這個(gè)問(wèn)題讓我郁悶了兩三天時(shí)間,最后才發(fā)現(xiàn)問(wèn)題是在JSP端? <html:form action="/uploadsAction"? enctype="multipart/form-data"? >
          標(biāo)簽如果少了"? enctype="multipart/form-data" ?服務(wù)器就會(huì)報(bào)錯(cuò),
          下面把代碼貼出來(lái).

          JSP端
          ?<html:errors />
          ????????? <html:form action="/uploadsAction"? enctype="multipart/form-data"? >
          ??????????? <html:file property="theFile" />?
          ???????????? <html:radio property="upType" value="a" />CSVFileReader
          ???????????? <html:radio property="upType" value="b" />FileUp??????
          ??????????? <html:submit value="OK"? />
          ????????? </html:form>
          FormBean中將屬性定義為FormFile,geter seter 方法依舊.
          Action 中的代碼如下:實(shí)現(xiàn)將圖片上傳至UPLOAD文件夾內(nèi) 如果文件大于20K或是寬&高超過(guò)規(guī)定范圍的,會(huì)重新勾畫(huà).實(shí)現(xiàn)對(duì)上傳圖片的控制.
          當(dāng)然這只是測(cè)試Action沒(méi)有跳轉(zhuǎn)頁(yè)面..

          package upload;

          import org.apache.struts.action.ActionMapping;
          import org.apache.struts.action.ActionForm;
          import javax.servlet.http.HttpServletRequest;
          import javax.servlet.http.HttpServletResponse;
          import org.apache.struts.action.ActionForward;
          import org.apache.struts.action.Action;
          import org.apache.struts.upload.*;
          import java.io.IOException;
          import java.awt.Image;
          import java.awt.image.BufferedImage;
          import com.sun.image.codec.jpeg.JPEGImageEncoder;
          import com.sun.image.codec.jpeg.JPEGCodec;

          import java.io.File;
          import java.io.BufferedInputStream;
          import java.io.BufferedOutputStream;
          import java.io.FileOutputStream;

          public class UploadAction extends Action {
          ??? public ActionForward execute(ActionMapping actionMapping,
          ???????????????????????????????? ActionForm actionForm,
          ???????????????????????????????? HttpServletRequest servletRequest,
          ???????????????????????????????? HttpServletResponse servletResponse)throws Exception {
          ??????? System.out.println("asdasdasdasdasdasd");
          ??????? UploadForm uploadForm = (UploadForm) actionForm;
          ??????? FormFile pic =? uploadForm.getPic();
          ??????? String picname = pic.getFileName();
          ??????? String uploadFileName = servletRequest.getSession()
          ??????????????????????????????? .getServletContext()
          ??????????????????????????????? .getRealPath("upload")+"\\"+picname;
          ??????? File upliadFile = new File(uploadFileName);
          ??????? BufferedInputStream bis = null;
          ??????? Image image = null;
          ??????? BufferedOutputStream bos = null;
          ??????? try{
          ??????? if(pic.getFileSize()<2*1024*1024){
          ??????? bis = new BufferedInputStream(pic.getInputStream());
          ??????? image = javax.imageio.ImageIO.read(bis);
          ??????? int width = image.getWidth(null);
          ??????? int height = image.getHeight(null);
          ??????? int w = 160;
          ??????? int h = 120;
          ??????? if(width>w||height>h){
          ??????? BufferedImage bi = new BufferedImage(w,h,
          ???????????????????????????????????????????? BufferedImage.TYPE_INT_RGB);
          ??????? bi.getGraphics().drawImage(image,0,0,w,h,null);
          ??????? bos = new BufferedOutputStream(new FileOutputStream(
          ???????upliadFile));
          ??????? JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bos);
          ?????encoder.encode(bi);
          ??????? System.out.println(width * height);
          ??????? }else{
          ??????? bos = new BufferedOutputStream(new FileOutputStream(upliadFile));
          ??????? byte[] date = new byte[5*1024];
          ??????? int len = bis.read(date);
          ??????? while (len!=-1){
          ??????????? bos.write(date);
          ??????????? len = bis.read(date);
          ??????? }
          ??????? }
          ??????? }
          ???????????? return actionMapping.findForward("ok");
          ??????? }catch(Exception e){
          ??????? e.printStackTrace();
          ??? } finally {
          ??????? try {
          ??????????? if (bis != null)
          ??????????????? bis.close();
          ??????? } catch (IOException e1) {

          ??????????? e1.printStackTrace();
          ??????? }
          ??????? try {
          ??????????? if (bos != null)
          ??????????????? bos.close();
          ??????? } catch (IOException e2) {

          ??????????? e2.printStackTrace();
          ??????? }
          ??? }

          ??????? return actionMapping.findForward("ok");
          ??? }
          }

          posted @ 2006-05-03 20:09 feingto 閱讀(969) | 評(píng)論 (0)編輯 收藏

          Struts1.2中配置數(shù)據(jù)源

          軟件環(huán)境:Tomcat5.5.15,Eclipse3.1.2,MyEclipse4.1,MySQL5.0.15,Resin3.0.18

          配置過(guò)程:

          一、下載必要的jar包。有四個(gè)包要下載(網(wǎng)上有貼子說(shuō)只要下面前三個(gè)包就可以了,但我在配置的時(shí)候如果沒(méi)有第四個(gè)包會(huì)報(bào)錯(cuò))。
          http://apache.linuxforum.net/dist/jakarta/commons/dbcp/binaries/commons-dbcp-1.2.zip
          http://apache.linuxforum.net/dist/jakarta/commons/pool/binaries/commons-pool-1.2.zip
          http://apache.linuxforum.net/dist/jakarta/struts/struts-legacy/struts-legacy-1.0.zip
          http://apache.linuxforum.net/dist/jakarta/commons/collections/binaries/commons-collections-3.1.zip
          把這四個(gè)jar包放到web應(yīng)用的WEB-INF/lib目錄下,還有要把MySQL的驅(qū)動(dòng)程序包也放到這里(也可以把數(shù)據(jù)庫(kù)的驅(qū)動(dòng)包放到%Tomcat_Home%/common/lib目錄下或%Resin_Home%/lib目錄下,這樣在啟動(dòng)Web服務(wù)器的時(shí)候就會(huì)加載這個(gè)包,服務(wù)器和Web應(yīng)用都可以使用驅(qū)動(dòng)程序類)

          二、在struts-config.xml中添加Data Source。MyEclipse的Design模式下可以可視化地編輯struts-config.xml和添加Data Source,但它在struts-config.xml中生成的數(shù)據(jù)源的代碼是錯(cuò)誤的!就是因?yàn)檫@個(gè)耽誤了我很多時(shí)間!
          我們手工編輯代碼:

            <data-sources>
              <data-source key="datasource" type="org.apache.commons.dbcp.BasicDataSource">
                <set-property property="password" value="admin" />
                <set-property property="minCount" value="3" />
                <set-property property="maxCount" value="10" />
                <set-property property="username" value="admin" />
                <set-property property="driverClassName" value="com.mysql.jdbc.Driver" />
                <set-property property="description" value="test" />
                <set-property property="url" value="jdbc:mysql://localhost/test" />
                <set-property property="readOnly" value="false" />
                <set-property property="autoCommit" value="true" />
              </data-source>
            </data-sources>

          如果要配置多個(gè)data source,可以給每個(gè)data source指定不同的key,然后在程序中根據(jù)key指定要引用的數(shù)據(jù)源。

          三、測(cè)試數(shù)據(jù)源。配置好以后就可以在ActionServlet中使用了。

            DataSource ds = getDataSource(request,"datasource");
            Connection conn = ds.getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SQL String");

          附: Struts1.1中struts-config.xml的配置:

            <data-sources >
              <data-source key="datasource" type="org.apache.struts.util.GenericDataSource">
                <set-property property="password" value="admin" />
                <set-property property="minCount" value="2" />
                <set-property property="maxCount" value="10" />
                <set-property property="user" value="admin" />
                <set-property property="driverClass" value="com.mysql.jdbc.Driver" />
                <set-property property="description" value="test" />
                <set-property property="url" value="jdbc:mysql://localhost/test" />
                <set-property property="readOnly" value="false" />
                <set-property property="autoCommit" value="true" />
              </data-source>
            </data-sources>

          注意:藍(lán)色字體的部分是1.1和1.2在配置上不一樣的地方。

          posted @ 2006-05-03 20:05 feingto 閱讀(1905) | 評(píng)論 (1)編輯 收藏

          Struts+Hibernate開(kāi)發(fā)實(shí)踐 分頁(yè)的實(shí)現(xiàn)

          在進(jìn)行web應(yīng)用開(kāi)發(fā)的時(shí)候經(jīng)常要進(jìn)行分頁(yè)處理,經(jīng)常看到一些人在問(wèn)分頁(yè)處理的問(wèn)題,現(xiàn)在我把自己的處理方法寫(xiě)在這兒,希望能對(duì)需要進(jìn)行分頁(yè)處理的朋友有所幫助。

          一、在struts中分頁(yè)有兩種結(jié)構(gòu):
          ??? 1. 在Action中通過(guò)DAO查詢出所有的記錄,然后加到session或request對(duì)象中,傳到客戶端,由JSP進(jìn)行分頁(yè)。這種方法對(duì)于在數(shù)據(jù)量少的時(shí)候很方便,也不影響速度。
          ??? 2.在Action中每次通過(guò)DAO只查詢出一頁(yè)的記錄,再傳給JSP頁(yè)面。這種結(jié)構(gòu)對(duì)于數(shù)據(jù)量大的程序很好,但對(duì)于數(shù)據(jù)量小的情況,會(huì)增加對(duì)服務(wù)器的請(qǐng)求,加大服務(wù)器的負(fù)載。
          ?????
          二、Hibernate查詢
          ??? 由于在Hibernate中直接提供了對(duì)數(shù)據(jù)庫(kù)定點(diǎn)定量的查詢方法,所以我采用的是第2種方法。

          如:
          從第1萬(wàn)條開(kāi)始取出100條記錄
          Query q = session.createQuery("from Cat as c");
          q.setFirstResult(10000);
          q.setMaxResults(100);
          List l = q.list();

          三、具體實(shí)現(xiàn)

          ?1.Pager類

          package com.jpcf.db.helper;

          import java.math.*;

          public class Pager {
          ? private int totalRows; //總行數(shù)
          ? private int pageSize = 10; //每頁(yè)顯示的行數(shù)
          ? private int currentPage; //當(dāng)前頁(yè)號(hào)
          ? private int totalPages; //總頁(yè)數(shù)
          ? private int startRow; //當(dāng)前頁(yè)在數(shù)據(jù)庫(kù)中的起始行

          ? public Pager() {
          ? }

          ? public Pager(int _totalRows) {
          ??? totalRows = _totalRows;
          ??? totalPages=totalRows/pageSize;
          ??? int mod=totalRows%pageSize;
          ??? if(mod>0){
          ????? totalPages++;
          ??? }
          ??? currentPage = 1;
          ??? startRow = 0;
          ? }

          ? public int getStartRow() {
          ??? return startRow;
          ? }

          ? public int getTotalPages() {
          ??? return totalPages;
          ? }

          ? public int getCurrentPage() {
          ??? return currentPage;
          ? }

          ? public int getPageSize() {
          ??? return pageSize;
          ? }

          ? public void setTotalRows(int totalRows) {
          ??? this.totalRows = totalRows;
          ? }

          ? public void setStartRow(int startRow) {
          ??? this.startRow = startRow;
          ? }

          ? public void setTotalPages(int totalPages) {
          ??? this.totalPages = totalPages;
          ? }

          ? public void setCurrentPage(int currentPage) {
          ??? this.currentPage = currentPage;
          ? }

          ? public void setPageSize(int pageSize) {
          ??? this.pageSize = pageSize;
          ? }

          ? public int getTotalRows() {
          ??? return totalRows;
          ? }

          ? public void first() {
          ??? currentPage = 1;
          ??? startRow = 0;
          ? }

          ? public void previous() {
          ??? if (currentPage == 1) {
          ????? return;
          ??? }
          ??? currentPage--;
          ??? startRow = (currentPage - 1) * pageSize;
          ? }

          ? public void next() {
          ??? if (currentPage < totalPages) {
          ????? currentPage++;
          ??? }
          ??? startRow = (currentPage - 1) * pageSize;
          ? }

          ? public void last() {
          ??? currentPage = totalPages;
          ??? startRow = (currentPage - 1) * pageSize;
          ? }

          ? public void refresh(int _currentPage) {
          ??? currentPage = _currentPage;
          ??? if (currentPage > totalPages) {
          ????? last();
          ??? }
          ? }

          }

          Pager類用于計(jì)算首頁(yè)、前一頁(yè)、下一頁(yè)、尾頁(yè)的在數(shù)據(jù)庫(kù)中的起始行,當(dāng)前的頁(yè)碼。

          2.PagerHelp類

          package com.jpcf.db.helper;

          import javax.servlet.http.*;

          public class PagerHelper {

          ? public static Pager getPager(HttpServletRequest httpServletRequest,int totalRows) {

          ??? //定義pager對(duì)象,用于傳到頁(yè)面
          ??? Pager pager = new Pager(totalRows);

          ??? //從Request對(duì)象中獲取當(dāng)前頁(yè)號(hào)
          ??? String currentPage = httpServletRequest.getParameter("currentPage");

          ??? //如果當(dāng)前頁(yè)號(hào)為空,表示為首次查詢?cè)擁?yè)
          ??? //如果不為空,則刷新pager對(duì)象,輸入當(dāng)前頁(yè)號(hào)等信息
          ??? if (currentPage != null) {
          ????? pager.refresh(Integer.parseInt(currentPage));
          ??? }

          ??? //獲取當(dāng)前執(zhí)行的方法,首頁(yè),前一頁(yè),后一頁(yè),尾頁(yè)。
          ??? String pagerMethod = httpServletRequest.getParameter("pageMethod");

          ??? if (pagerMethod != null) {
          ????? if (pagerMethod.equals("first")) {
          ??????? pager.first();
          ????? } else if (pagerMethod.equals("previous")) {
          ??????? pager.previous();
          ????? } else if (pagerMethod.equals("next")) {
          ??????? pager.next();
          ????? } else if (pagerMethod.equals("last")) {
          ??????? pager.last();
          ????? }
          ??? }
          ??? return pager;
          ? }
          }

          PageHelper這個(gè)類,我不用說(shuō)應(yīng)該也知道用來(lái)干嘛了

          3.DAO類

          package com.jpcf.db.dao;

          import com.jpcf.db.model.*;
          import com.jpcf.db.helper.HibernateUtil;
          import net.sf.hibernate.*;
          import java.util.*;
          import com.jpcf.db.controller.*;

          public class VehiclePropertyDAO {

          ? public Collection findWithPage(int pageSize, int startRow) throws HibernateException {
          ??? Collection vehicleList = null;
          ??? Transaction tx = null;
          ??? try {
          ????? Session session = HibernateUtil.currentSession();
          ????? tx = session.beginTransaction();
          ????? Query q = session.createQuery("from VehicleProperty vp");
          ????? q.setFirstResult(startRow);
          ????? q.setMaxResults(pageSize);
          ????? vehicleList = q.list();
          ????? tx.commit();
          ??? } catch (HibernateException he) {
          ????? if (tx != null) {
          ??????? tx.rollback();
          ????? }
          ????? throw he;
          ??? } finally {
          ????? HibernateUtil.closeSession();
          ??? }
          ??? return vehicleList;
          ? }

          ? public int getRows(String query) throws HibernateException {
          ??? int totalRows = 0;
          ??? Transaction tx = null;
          ??? try {
          ????? Session session = HibernateUtil.currentSession();
          ????? tx = session.beginTransaction();
          ????? totalRows = ((Integer) session.iterate(query).next()).intValue();
          ????? tx.commit();
          ??? } catch (HibernateException he) {
          ????? if (tx != null) {
          ??????? tx.rollback();
          ????? }
          ????? throw he;
          ??? } finally {
          ????? HibernateUtil.closeSession();
          ??? }

          ??? return totalRows;
          ? }

          }
          DAO類我就貼這些分頁(yè)需要的代碼了。
          “from VehicleProperty vp”也可以用一個(gè)參數(shù)傳進(jìn)來(lái),有興趣的自己改一下吧

          4.Action

          下面是在Action中用到的代碼:
          ? public ActionForward execute(ActionMapping actionMapping,
          ???????????????????????????????????? ActionForm actionForm,
          ???????????????????????????????????? HttpServletRequest httpServletRequest,
          ???????????????????????????????????? HttpServletResponse httpServletresponse) {
          ???? Collection clInfos = null;//用于輸出到頁(yè)面的記錄集合
          ???? int totalRows;//記錄總行數(shù)
          ???? VehiclePropertyDAO vehicleDAO = new VehiclePropertyDAO();

          ??? //取得當(dāng)前表中的總行數(shù)
          ??? try {
          ????? totalRows = vehicleDAO.getRows("select count(*) from VehicleProperty");
          ??? } catch (Exception ex) {
          ????? servlet.log(ex.toString());
          ????? return actionMapping.findForward(Constants.FAILURE);
          ??? }

          ??? //通過(guò)PagerHelper類來(lái)獲取用于輸出到頁(yè)面的pager對(duì)象
          ??? Pager pager=PagerHelper.getPager(httpServletRequest,totalRows);

          ??? //取出從startRow開(kāi)始的pageSize行記錄
          ??? try {
          ????? clInfos = vehicleDAO.findWithPage(pager.getPageSize(), pager.getStartRow());
          ??? } catch (Exception ex) {
          ????? servlet.log(ex.toString());
          ????? return actionMapping.findForward(Constants.FAILURE);
          ??? }

          ??? //把輸出的記錄集和pager對(duì)象保存到request對(duì)象中
          ??? httpServletRequest.setAttribute("CLINFOS", clInfos);
          ??? httpServletRequest.setAttribute("PAGER", pager);

          ??? return actionMapping.findForward(Constants.SUCCESS);
          ? }

          ?? 查詢語(yǔ)句select count(*) from VehicleProperty 也可以換成你需要的任意的條件(select count(*)?

          from VehicleProperty where ..)


          5.JSP頁(yè)面使用

          下面就是在JSP中的應(yīng)用了:

          <td colspan="8" align="right" class="head">
          ?? 第<bean:write name="PAGER" property="currentPage"/>頁(yè)?
          ?? 共<bean:write name="PAGER" property="totalPages"/>頁(yè)?
          ?? <html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&pageMethod=first"?
          paramName="PAGER" paramProperty="currentPage" paramId="currentPage">首頁(yè)</html:link>
          ?? <html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&pageMethod=previous"?
          paramName="PAGER" paramProperty="currentPage" paramId="currentPage">上一頁(yè)</html:link>
          ?? <html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&pageMethod=next"?
          paramName="PAGER" paramProperty="currentPage" paramId="currentPage">下一頁(yè)</html:link>
          ?? <html:link action="/bussiness/clInfo/queryWithPage.do?method=queryWithPage&pageMethod=last"?
          paramName="PAGER" paramProperty="currentPage" paramId="currentPage">尾頁(yè)</html:link>
          </td>

          ?? 解釋一下這一行:"/bussiness/clInfo/queryWithPage.do?method=queryWithPage&pageMethod=first
          method=queryWithPage 是由于我的Action繼承的是DispatchAction,需要一個(gè)method參數(shù)
          pageMethod=first 是用來(lái)在PageHelper類中判斷執(zhí)行哪個(gè)操作

          四、總結(jié)

          ??? 我做的這個(gè)也只是一個(gè)借鑒,還有很多沒(méi)有實(shí)現(xiàn)的,比如還可以加一下 go 直接到第n頁(yè)的功能。
          ??? 其實(shí)最關(guān)鍵的是把當(dāng)前頁(yè)號(hào)和要執(zhí)行的是功能(上一頁(yè),下一頁(yè))的參數(shù)從頁(yè)面?zhèn)鬟M(jìn)來(lái),在Action中就可以根據(jù)這兩個(gè)參數(shù)去取下一個(gè)頁(yè)面上要顯示的記錄集了。

          posted @ 2006-05-03 20:04 feingto 閱讀(414) | 評(píng)論 (0)編輯 收藏

          struts中的分頁(yè)實(shí)例

          struts中的分頁(yè)實(shí)例?
          ??
          ??? 這僅是一個(gè)入門實(shí)例,簡(jiǎn)潔實(shí)用,從網(wǎng)上整理而來(lái),供參考。這里僅列出部分文件,其它文件、數(shù)據(jù)庫(kù)及目錄結(jié)構(gòu)請(qǐng)從本站下載。
          一、struts-config.xml配置,主要是配數(shù)據(jù)庫(kù),這里用access。
          <?xml version="1.0" encoding="ISO-8859-1" ?>

          <!DOCTYPE struts-config PUBLIC
          ????????? "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
          ????????? "


          <struts-config>
          <data-sources>
          ?? <data-source key="dataSource" type="org.apache.commons.dbcp.BasicDataSource">
          ??????????? <set-property property="driverClassName" value="sun.jdbc.odbc.JdbcOdbcDriver" />
          ??????????? <set-property property="url" value="jdbc:odbc:page" />
          ??????????? <set-property property="username" value="admin" />
          ??????????? <set-property property="password" value="" />
          ??????????? <set-property property="maxActive" value="20" />
          ??????????? <set-property property="maxWait" value="5000" />
          ??????????? <set-property property="defaultAutoCommit" value="true" />
          ??????????? <set-property property="defaultReadOnly" value="false" />
          ??????????? <set-property property="validationQuery" value="SELECT 1" />
          ??????????? <set-property property="removeAbandoned" value="true" />
          ??????????? <set-property property="removeAbandonedTimeout" value="120" />????????????
          ??????????? <set-property property="encoding" value="false" />????????????
          ??????? </data-source>

          ?</data-sources>
          ? <form-beans>
          ? </form-beans>
          ? <global-forwards>
          ? </global-forwards>

          ? <action-mappings>
          ? <action path="/page" type="page.DataSourceAction" scope="request">
          ? <forward name="success" path="/pagetest.jsp"/>
          ? </action>
          ? </action-mappings>

          ? <controller>
          ? </controller>
          </struts-config>

          二、Action類
          用 page.do?start=1 來(lái)顯示第一個(gè)頁(yè)面?
          參數(shù)說(shuō)明:?
          ? list:信息列表?
          ? start:開(kāi)始位置?
          ? page:每頁(yè)顯示的信息數(shù)目?
          ? pages: 總頁(yè)數(shù)
          ? previous:上頁(yè)開(kāi)始位置?
          ? next:下頁(yè)開(kāi)始位置?

          package page;
          import org.apache.struts.action.*;
          import javax.servlet.http.*;

          import java.util.*;
          import javax.sql.*;
          import java.sql.*;
          import bean.*;

          public class DataSourceAction extends Action {

          ?public DataSourceAction(){}
          ?
          ?public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request,
          ?HttpServletResponse response) throws Exception {???
          ? try{
          ????? DataSource ds=this.getDataSource(request,"dataSource");???
          ????? Connection con = ds.getConnection();
          ????? Statement stmt = con.createStatement();
          ????? ResultSet resultSet = stmt.executeQuery("select count(*) from book" );?
          ????? resultSet.next();?
          ????? int data_num=resultSet.getInt(1);?
          ????? int start=1;
          ????? int page = 4; //每頁(yè)的記錄數(shù)。
          ????? int pages=data_num/page;
          ????? if(data_num%page!=0)
          ???????? pages++;
          ????? if(request.getParameter("start")!=null)
          ????????? start = Integer.parseInt(request.getParameter("start"));?
          ????? if(request.getParameter("go")!=null){
          ??????????????? int go = Integer.parseInt(request.getParameter("go"));?
          ??????????????? if(go<=1)
          ????????????????? start=1;
          ??????????????? else if(go>pages)
          ????????????????? start=(pages-1)*page+1;
          ??????????????? else?
          ?????????????????? start=(go-1)*page+1;
          ?????? }?
          ?????
          ????? String sql = "SELECT * FROM book where id>="+start+" and id<"+(start+page);
          ????? resultSet = stmt.executeQuery(sql);??
          ????? ArrayList list = new java.util.ArrayList();?
          ????? while(resultSet.next())
          ????? {??
          ??????? int id=resultSet.getInt("id");
          ??????? String name = resultSet.getString("name");
          ??????? String author = resultSet.getString("author");
          ??????? String price = resultSet.getString("price");
          ??????? System.out.println("開(kāi)始數(shù)據(jù)封裝:name="+name+"author="+author+"price="+price);
          ??????? Book book= new Book(id,name,author,price);???????
          ??????? list.add(book);
          ????? }
          ??? con.close();
          ??? request.setAttribute("pages",new Integer(pages));
          ??? request.setAttribute("list",list);
          ??? //request.setAttribute("start", new Integer(start));?
          ??? request.setAttribute("page", new Integer(page));?

          ??????? // if there is a previous page, set the previous variable?
          ??????? int previous = start-page;?
          ??????? if ( previous>=0 ){?
          ??????????? request.setAttribute("previous", new Integer(previous));?
          ??????????? System.out.println ("previous:" + previous);?
          ??????? }?

          ??????? // if there is a next page, set the next variable?
          ??????? int next = start+page;?
          ??????? if ( next<=data_num ){?
          ??????????? request.setAttribute("next", new Integer(next));?
          ??????????? System.out.println ("next:" + next);?
          ??????? }?

          ?? }catch(SQLException e){
          ????????? e.printStackTrace();
          ????????? System.out.println("數(shù)據(jù)庫(kù)連接出現(xiàn)異常");
          ????? }?
          ???
          ???????????? return (mapping.findForward("success"));
          ? }?
          }


          三、bean類Book.java
          package bean;
          import java.sql.*;
          import java.util.ArrayList;
          public class Book {
          ?int id;
          ?private String bookname; //書(shū)名
          ?private String author;?? //作者
          ?private String price;??? //價(jià)格
          ?
          public Book(int id,String name,String author,String price){
          ?this.id=id;
          ?this.bookname=name;
          ?this.author=author;
          ?this.price=price;
          }

          public int getId(){?
          ??????? return id;?
          ??? }?

          ?public String getAuthor() {
          ? return author;
          ?}

          ?public void setAuthor(String author) {
          ? this.author = author;
          ?}

          ?public String getBookname() {
          ? return bookname;
          ?}

          ?public void setBookname(String bookname) {
          ? this.bookname = bookname;
          ?}
          ?
          ?public String getPrice(){
          ???? return this.price;?
          ?}
          ?
          ?public void setPrice(String price){
          ???? this.price=price;?
          ?}
          ?
          }
          四、分頁(yè)的jsp頁(yè)面pagetest.jsp,用了jstl中的c標(biāo)記。
          <%@ page contentType="text/html; charset=gb2312" language="java"%>
          <%@ page import="java.util.*" %>
          <%@ page import="bean.*" %>
          <%@ taglib prefix="c" uri="
          <%@ taglib uri="/tags/struts-bean" prefix="bean" %>
          <%@ taglib uri="/tags/struts-html" prefix="html" %>
          <%@ taglib uri="/tags/struts-logic" prefix="logic" %>

          <logic:iterate id="book" name="list" type="bean.Book">?
          ??????????? <br><html:link??
          ??????????????????? paramId="id" paramName="book" paramProperty="id"?
          ??????????????????? page="/messagedetail.do">?
          ??????????????????? <bean:write name="book" property="bookname" />?
          ??????????????? </html:link>?
          </logic:iterate>?

          <form action="/TestPage/page.do">
          ?? <logic:present name="previous">?
          ??????????? <html:link??
          ??????????????????? paramId="start" paramName="previous"?
          ??????????????????? page="/page.do">?
          ??????????????????? 上一頁(yè)?
          ??????????????? </html:link>?
          ?? </logic:present>?

          ?? <logic:present name="next">?
          ????????????? <html:link??
          ??????????????????? paramId="start" paramName="next"?
          ??????????????????? page="/page.do">?
          ??????????????????? 下一頁(yè)?
          ??????????????? </html:link>?
          ?? </logic:present>?

          每頁(yè)<c:out value="${page}"/>條記錄,共<c:out value="${pages}"/>頁(yè)? 跳到<input type="text"? name="go" size="3" maxlength="30" >
          <input type="submit" value="go" >
          </form>
          ?????????

          ?

          OK!!!!
          五、測(cè)試,請(qǐng)下載本實(shí)例的目錄結(jié)構(gòu)TestPage,放入tomcat的webapps下,在瀏覽器中輸入:
          ???
          http://127.0.0.1:8080/TestPage/page.do?
          來(lái)源: java學(xué)習(xí)室
          ?

          posted @ 2006-05-03 20:04 feingto 閱讀(632) | 評(píng)論 (0)編輯 收藏

          一個(gè)高效簡(jiǎn)潔的Struts分頁(yè)方法

          在網(wǎng)上看了幾個(gè)Structs分頁(yè),感覺(jué)不是很完善,于是根據(jù)自己的經(jīng)驗(yàn),寫(xiě)了一個(gè)相對(duì)高效簡(jiǎn)潔的分頁(yè)方法。由于本人水平有限,如果大家有什么更好的想法,歡迎不吝賜教。
            
            一、 開(kāi)發(fā)環(huán)境
            
            我的開(kāi)發(fā)環(huán)境是:JBuilder x + Weblogic 8.1 + Oracle 9i + Windows 2003 ,如果朋友們的開(kāi)發(fā)環(huán)境不一樣亦無(wú)妨。
            
            二、開(kāi)發(fā)思路
            
            既然講的是Struts,那自然離不了MVC,分頁(yè)顯示也是如此。
            
            1、 建立數(shù)據(jù)庫(kù)和對(duì)應(yīng)的表,本例的表是TCertificate。
            
            2、 建立適當(dāng)?shù)哪P徒M件,對(duì)應(yīng)你要查詢數(shù)據(jù)庫(kù)中的表。這部分由DAO數(shù)據(jù)訪問(wèn)層來(lái)實(shí)現(xiàn),如果有的朋友對(duì)DAO不熟悉可以查詢一下相關(guān)資料。本例由CertificateDAO.java來(lái)實(shí)現(xiàn)。
            
            3 、建立分頁(yè)所需要的模型組件,由javaBean來(lái)充當(dāng),并與CertificateDAO實(shí)現(xiàn)分離。網(wǎng)上介紹的很多方法,都存在著數(shù)據(jù)與分頁(yè)組件藕合的現(xiàn)象,這也是本方法與其它分頁(yè)方法的主要不同之處。
            
            4、建立控制器組件,這部分由Struts 中的Action來(lái)實(shí)現(xiàn)。主要負(fù)責(zé)將實(shí)例化CertificateDAO,只取要顯示的數(shù)據(jù)記錄,存入ArrayList對(duì)象然后返回,并放到 request中。而分頁(yè)部分則根據(jù)分頁(yè)條件,單獨(dú)進(jìn)行構(gòu)造,避免了與DAO混在一起的情況發(fā)生。網(wǎng)上其它介紹的一些分頁(yè)方法中,基本上都是一次性讀出所有查詢的數(shù)據(jù),然后再由分頁(yè)相關(guān)組件進(jìn)行構(gòu)造。這樣,如果數(shù)據(jù)量大的話,很容易形成瓶頸。在本例中由于不是一次性地讀出查詢的所有數(shù)據(jù),而只是讀出一個(gè)頁(yè)面要顯示的數(shù)據(jù)記錄,這就節(jié)省了很多不必要的數(shù)據(jù)傳輸,提高了效率。本例中為CertificateAction.java。
            
             5、建立視圖組件,這部分由jsp來(lái)充當(dāng),為了不出現(xiàn)java 代碼,我們使用Struts提供的標(biāo)簽庫(kù),主要負(fù)責(zé)從request中取出剛剛放入的對(duì)象,通過(guò)反復(fù)調(diào)用CertificateAction以及 action參數(shù),而實(shí)現(xiàn)分頁(yè)顯示。本例中為listcertificate.jsp。
            
            6、 建立并配置struts-config.xml。
            
            三、實(shí)例代碼
            
            確定好上面的開(kāi)發(fā)思路后,代碼的實(shí)現(xiàn)就有單可循了。
            
            1、建數(shù)據(jù)庫(kù)和相應(yīng)的表。
            
            2、數(shù)據(jù)邏輯層的相關(guān)代碼。
            
            1)、通用的DAO類:CommonDAO.java
            
            這是一個(gè)很多DAO都要繼承到的通用DAO類,是我根據(jù)實(shí)踐總結(jié)出來(lái)的,為了減少篇幅,這里只顯示和本例相關(guān)的代碼。
            
            java代碼:
            
            代碼:
            --------------------------------------------------------------------------------
            package com.xindeco.business ;
            import java.io.*;
            import java.sql.*;
            import java.util.*;
            import javax.sql.*;
            import java.lang.IllegalAccessException;
            import java.lang.reflect.InvocationTargetException;
            import org.apache.commons.beanutils.BeanUtils;
            public class DAO
            {
            protected DataSource ds;
            /**
            * 說(shuō)明:取得當(dāng)前查詢的總記錄數(shù)
            */
            public int getRows ()
            {
            return this.count;
            }
            public void rsHandler (ResultSet rs, int offset, int limit)
            {
            try
            {
            count = 0;
            rs.absolute ( -1) ;
            count = rs.getRow () ;
            if (offset <= 0)
            {
            rs.beforeFirst () ;
            }
            else
            {
            rs.absolute (offset) ;
            }
            }
            catch (Exception e)
            {
            e.printStackTrace () ;
            }
            }
            public DAO(DataSource ds) {
            this.ds = ds;
            }
            
            public void setDataSource(DataSource ds) {
            this.ds = ds;
            }
            
            protected void close(ResultSet rs) {
            if (rs != null) {
            try {
            rs.close();
            } catch (SQLException e) {
            }
            rs = null;
            }
            }
            
            protected void close(PreparedStatement pstmt) {
            if (pstmt != null) {
            try {
            pstmt.close();
            } catch (SQLException e) {
            }
            pstmt = null;
            }
            }
            protected void close(Connection conn) {
            if (conn != null) {
            try {
            conn.close();
            } catch (SQLException e) {
            e.printStackTrace();
            }
            conn = null;
            }
            }
            
            protected void rollback(Connection conn) {
            if (conn != null) {
            try {
            conn.rollback();
            } catch (SQLException e) {
            e.printStackTrace();
            }
            conn = null;
            }
            }
            }
            
            這個(gè)類主要是通過(guò)子類傳進(jìn)來(lái)的先進(jìn)結(jié)果集,取得查詢的記錄總數(shù),并對(duì)數(shù)據(jù)庫(kù)連接進(jìn)行簡(jiǎn)單的管理。
            
            2)、對(duì)數(shù)據(jù)庫(kù)進(jìn)行訪問(wèn):CertificateDAO.java
            
            java代碼:
            
            代碼:
            --------------------------------------------------------------------------------
            package com.xindeco.business;
            
            import java.io.*;
            import java.sql.*;
            import java.util.*;
            import javax.sql.*;
            
            import com.xindeco.common.dbconn.DbConn;
            
            public class CertificateDAO extends DAO
            {
            
            public NationDAO(DataSource ds) {
            super(ds);
            }
            
            public List findCertificateList(int offset,int limit) throws SQLException
            {
            int countRows = 0 ;
            ArrayList list = null ;
            Connection conn = null;
            PreparedStatement pstmt = null;
            ResultSet rs = null;
            try
            {
            conn = ds.getConnection();
            String sql =
            "SELECT certificateID, certificateCode,certificateName,photoURL,"
            + "description,graduateID FROM TCertificate " ;
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            /*對(duì)游標(biāo)進(jìn)行處理,rsHandler 方法在父類DAO中*/
            this.rsHandler(rs,offset,limit);
            if (rs != null && rs.next ())
            {
            list = new ArrayList () ;
            do
            {
            countRows++ ;
            list.add (rs2VO (rs)) ;
            }
            while ( (countRows++ < limit) && rs.next ()) ;
            }
            close(rs);
            close(pstmt);
            } catch (SQLException e) {
            close(rs);
            close(pstmt);
            rollback(conn);
            e.printStackTrace();
            }
            finally {
            close(conn);
            }
            return list ;
            }
            
            private CertificateVO rs2VO (ResultSet rs)
            {
            try
            {
            CertificateVO certificateVO = new CertificateVO () ;
            certificateVO.setCertificateID (rs.getInt ("certificateID")) ;
            certificateVO.setCertificateCode (rs.getString ("certificateCode")) ;
            certificateVO.setCertificateName (rs.getString ("certificateName")) ;
            certificateVO.setPhotoURL (rs.getString ("photoURL")) ;
            certificateVO.setDescription (rs.getString ("description")) ;
            certificateVO.setGraduateID (rs.getInt ("graduateID")) ;
            return certificateVO ;
            }
            catch (Exception ex)
            {
            ex.printStackTrace () ;
            return null ;
            }
            }
            }
            
            findCertificateList(int offset,int limit)是查得所有要顯示的數(shù)據(jù),并放入ArrayList中。看過(guò)網(wǎng)上有些例子,把數(shù)據(jù)記錄放入ArrayList的動(dòng)作過(guò)程直接在while循環(huán)體里完成,如果字段多的話,會(huì)造成方法過(guò)于寵大,又不美觀。這里,數(shù)據(jù)記錄放入ArrayList的動(dòng)作過(guò)程由rs2VO方法完成,就比較整潔了。另外,if (rs != null && rs.next ()) 配合while ( (countRows++ < limit) && rs.next ()) 是為了程序的健壯性考慮的,稍分析一下不難得出結(jié)論。
            
            3、建立控制器組件:CertificateAction.java
            
            java代碼:
            
            代碼:
            --------------------------------------------------------------------------------
            package com.xindeco.presentation;
            
            import javax.sql.* ;
            import java.util.* ;
            
            import javax.servlet.http.* ;
            import javax.servlet.* ;
            
            import org.apache.struts.action.* ;
            import org.apache.struts.util.* ;
            
            import com.xindeco.common.Pager;
            import com.xindeco.business.graduatedata.CertificateDAO ;
            
            public class CertificateAction
            extends Action
            {
            private static final int PAGE_LENGTH = 5 ; //每頁(yè)顯示5條記錄
            public ActionForward execute (ActionMapping mapping, Actionform form,
            HttpServletRequest request,
            HttpServletResponse response)
            {
            ActionForward myforward = null ;
            String myaction = mapping.getParameter () ;
            
            if (isCancelled (request))
            {
            return mapping.findForward ("failure") ;
            }
            if ("".equalsIgnoreCase (myaction))
            {
            myforward = mapping.findForward ("failure") ;
            }
            else if    ("LIST".equalsIgnoreCase (myaction))
            {
            myforward = performList (mapping, form, request, response) ;
            }
            else
            {
            myforward = mapping.findForward ("failure") ;
            }
            return myforward ;
            }
            
            private ActionForward performList (ActionMapping mapping,
            Actionform actionform,
            HttpServletRequest request,
            HttpServletResponse response)
            {
            try
            {
            DataSource ds = (DataSource) servlet.getServletContext().getAttribute(Action.DATA_SOURCE_KEY);
            
            CertificateDAO  certificateDAO = new CertificateDAO (ds) ;
            
            int offset = 0;  //翻頁(yè)時(shí)的起始記錄所在游標(biāo)
            int length = PAGE_LENGTH;
            String pageOffset = request.getParameter("pager.offset");
            if (pageOffset == null || pageOffset.equals("")) {
            offset = 0;
            } else {
            offset = Integer.parseInt(pageOffset);
            }
            List certificateList = certificateDAO .findCertificateList (offset,length) ;
            int size = certificateDAO.getRows(); // 取得總記錄數(shù)
            String url = request.getContextPath()+"/"+mapping.getPath()+".do";
            String pagerHeader = Pager.generate(offset, size, length, url); //分頁(yè)處理
            
            request.setAttribute ("pager", pagerHeader) ;
            request.setAttribute ("list", certificateList) ;
            }
            catch (Exception e)
            {
            e.printStackTrace();
            return mapping.findForward ("error") ;
            }
            return mapping.findForward ("success") ;
            }
            }
            
            CertificateAction.java主要是把數(shù)據(jù)從DAO中取出,并放入一個(gè)ArrayList 中,然后通過(guò)配置文件再軟件View的JSP頁(yè)。
            
            5、建立視圖listcertificate.jsp文件。
            
            jsp代碼:
            
            代碼:
            --------------------------------------------------------------------------------
            
            <%@ page contentType="text/html; charset=GBK" %>
            <%@ taglib uri="/WEB-INF/struts-template.tld" prefix="template" %>
            <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
            <%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
            <%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
            
            <table bgcolor="#666666" cellpadding="1" cellspacing="0" border="0" width="500">
            <tr>
            <td>
            <table cellpadding="0" cellspacing="0" border="0" width="500">
            <tr>
            <td bgcolor="#fecc51">&</td>
            </tr>
            </table>
            </td>
            </tr>
            <tr>
            <td>
            <table cellpadding="0" cellspacing="0" border="0" width="500">
            <tr>
            <td bgcolor="#d6e0ed">
            &&<bean:message key="label.list4certificate"/>
            </td>
            </tr>
            <tr bgcolor="#FFFFFF">
            <td width="5%"></td><td width="19%"></td><td width="76%"></td>
            </tr>
            <tr>
            <td>
            <table bgcolor="#f2f2f2" width="500" cellspacing="0" border="0">
            <tr bgcolor="#bacce1">
            <td><b><bean:message key="Certificate.select"/> </b></td>
            <td><b><bean:message key="Certificate.certificateID"/> </b></td>
            <td><b><bean:message key="Certificate.certificateCode"/></b></td>
            <td><b><bean:message key="Certificate.certificateName"/></b></td>
            <td><b><bean:message key="Certificate.view"/></b></td>
            </tr>
            
            <bean:write name="pager" property="description"/>
            <logic:equal name="pager" property="hasPrevious" value="true">
            <a href="/graduatedata/list.do?viewPage=<bean:write name="pager" property="previousPage"/>" class="a02">
            Previous
            </a>
            </logic:equal>
            <logic:equal name="pager" property="hasNext" value="true">
            <a href="/graduatedata/list.do?viewPage=<bean:write name="pager" property="nextPage"/>" class="a02">
            Next
            </a>
            </logic:equal>
            
            <logic:notEmpty name="list" scope="request">
            <logic:iterate id="certificate" name="list" type="com.xindeco.business.graduatedata.CertificateVO"scope="request">
            <tr bgcolor="#FFFFFF">
            <td><html:text property="name" value="<bean:write name="certificate" property="certificateID" scope="page"/>"/>
            </td>
            <td> <bean:write name="certificate" property="certificateID" scope="page"/></td>
            <td> <bean:write name="certificate" property="certificateCode" scope="page"/></td>
            <td> <bean:write name="certificate" property="certificateName" scope="page"/></td>
            <td> <bean:write name="certificate" property="photoURL" scope="page"/></td>
            </tr>
            </logic:iterate>
            </logic:notEmpty>
            </table>
            </td>
            </tr>
            </table>
            </td>
            </tr>
            </table>
            
            6、對(duì)應(yīng)的配置文件struts-config.xml。
            
            java代碼:
            
            代碼:
            --------------------------------------------------------------------------------
            <?xml version="1.0" encoding="UTF-8"?>
            <!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.1//EN" "  <struts-config>
            <form-beans>
            <form-bean name="certificateform" type="com.xindeco.presentation.graduatedata.Certificateform" />
            </form-beans>
            <global-forwards>
            <forward name="error" path="/error/error.jsp" />
            </global-forwards>
            <action-mappings>
            <action name="certificateform" parameter="LIST" path="/graduatedata/list" scope="request" type="com.xindeco.presentation.graduatedata.CertificateAction" validate="true">
            <forward name="success" path="/graduatedata/listcertificate.jsp" />
            </action>
            </action-mappings>
            ……
            </struts-config>
            
            7、最后當(dāng)然是最重要的分頁(yè)代碼了:Pager.java
            
            java代碼:
            
            代碼:
            --------------------------------------------------------------------------------
            package com.xindeco.common;
            
            import java.util.* ;
            public class Pager {
            private static int MAX_PAGE_INDEX = 10; //頁(yè)腳顯示多少頁(yè)
            private static String HEADER = "Result page";
            
            public static String generate(int offset, int length, int size, String url) {
            if (length > size) {
            String pref;
            if (url.indexOf("?") > -1) {
            pref = "&";
            } else {
            pref = "?";
            }
            String header = "<font face='Helvetica' size='-1'>"+HEADER+": ";
            if (offset > 0) {
            header += "&<a href=\""+url+pref+"pager.offset="+(offset-size)+"\">[<< Prev]</a>\n";
            }
            int start;
            int radius = MAX_PAGE_INDEX/2*size;
            if (offset < radius) {
            start = 0;
            } else if(offset < length-radius) {
            start = offset - radius;
            } else {
            start = (length/size-MAX_PAGE_INDEX)*size;
            }
            for(int i=start;i<length && i < start + MAX_PAGE_INDEX*size;i+=size) {
            if (i == offset) {
            header += "<b>"+(i/size+1)+"</b>\n";
            } else {
            header += "&<a href=\""+url+pref+"pager.offset="+i+"\">"+(i/size+1)+"</a>\n";
            }
            }
            if(offset < length - size) {
            header += "&<a href=\""+url+pref+"pager.offset="+((int)offset+(int)size)+"\">[Next >>]</a>\n";
            }
            header += "</font>";
            return header;
            } else {
            return "";
            }
            }
            }
            
            這部分代碼的實(shí)現(xiàn)相當(dāng)簡(jiǎn)潔,但已經(jīng)足夠完成所需了。

          posted @ 2006-05-03 20:04 feingto 閱讀(318) | 評(píng)論 (0)編輯 收藏

          用struts上傳文件

          用到的類import org.apache.struts.upload.FormFile;

          Jsp上傳頁(yè)面:

          ?

          <%@ page contentType="text/html; charset=GBK" %>

          <html>

          <head>

          <title>

          strutsUploadForm

          </title>

          </head>

          <body bgcolor="#ffffff">

          <h1>

          上傳測(cè)試

          </h1>

          <form action="uploadTestAction.do" method="post" enctype="multipart/form-data" name="form1">

          ? <p>文本

          ??? <input name="theText" type="text" id="theText">

          </p>

          ? <p>文件

          ??? <input name="theFile" type="file" id="theFile">

          </p>

          ? <p>保存到

          ??? <input name="saveTo" type="text" id="saveTo">

          </p>

          ? <p>

          ??? <input type="submit" name="Submit" value="提交">

          </p>

          </form>

          </body>

          </html>

          ?

          ?

          actionForm

          ?

          package hehe;

          ?

          import org.apache.struts.action.*;

          import javax.servlet.http.*;

          import org.apache.struts.upload.FormFile;

          ?

          public class UploadTestForm extends ActionForm {

          ? private String saveTo;

          ? private String theText;

          ? private org.apache.struts.upload.FormFile theFile;//文件框?qū)?yīng)的是formFile類型

          ? public String getSaveTo() {

          ??? return saveTo;

          ? }

          ? public void setSaveTo(String saveTo) {

          ??? this.saveTo = saveTo;

          ? }

          ? public org.apache.struts.upload.FormFile getTheFile() {

          ??? return theFile;

          ? }

          ? public void setTheFile(org.apache.struts.upload.FormFile theFile) {

          ??? this.theFile = theFile;

          ? }

          ? public String getTheText() {

          ??? return theText;

          ? }

          ? public void setTheText(String theText) {

          ??? this.theText = theText;

          ? }

          ? public ActionErrors validate(ActionMapping actionMapping, HttpServletRequest httpServletRequest) {

          ??? /**@todo: finish this method, this is just the skeleton.*/

          ??? if(!this.getTheFile().getContentType().equals("image/pjpeg")){

          ????? System.out.println("不是jpg");

          ??? }//可以判斷類型

          ??? if(this.getTheFile().getFileSize()>100){

          ????? System.out.println("長(zhǎng)度大于1000");

          ??? }//可以判斷大小

          ??? return null;

          ? }

          ? public void reset(ActionMapping actionMapping, HttpServletRequest httpServletRequest) {

          ??? saveTo = null;

          ??? theFile = null;

          ??? theText = null;

          ? }

          }

          ?

          ?

          Action

          ?

          package hehe;

          ?

          import org.apache.struts.action.*;

          import org.apache.struts.upload.FormFile;

          import javax.servlet.http.*;

          import java.io.*;

          ?

          public class UploadTestAction

          ??? extends Action {

          ? public ActionForward execute(ActionMapping actionMapping,

          ?????????????????????????????? ActionForm actionForm,

          ?????????????????????????????? HttpServletRequest request,

          ?????????????????????????????? HttpServletResponse response) {

          ??? UploadTestForm uploadForm = (UploadTestForm) actionForm;

          ??? FormFile file = uploadForm.getTheFile();

          ??? String path = uploadForm.getSaveTo();

          ??? String theText = uploadForm.getTheText();

          ??? try {

          ????? InputStream input = file.getInputStream();//能從FormFile中獲得輸入流

          ????? OutputStream output = new FileOutputStream(path);

          ????? int bytesReader = 0;

          ????? byte[] readbuffer = new byte[8192];

          ????? while ( (bytesReader = input.read(readbuffer, 0, 8192)) != -1) {

          ??????? output.write(readbuffer, 0, bytesReader);

          ????? }

          ????? output.close();

          ??? }

          ??? catch (Exception e) {

          ????? e.printStackTrace();

          ??? }

          ??? request.setAttribute("theText", theText);

          ??? request.setAttribute("fileName", file.getFileName());//上傳的文件名

          ??? request.setAttribute("fileSize", new Integer(file.getFileSize()));//文件大小

          ??? request.setAttribute("fileType", file.getContentType());//文件類型

          ??? return actionMapping.findForward("success");

          ? }

          }

          ?

          ?

          結(jié)果頁(yè)面

          ?

          <%@ page contentType="text/html; charset=GBK" %>

          <html>

          <head>

          <title>

          strutsUploadResult

          </title>

          </head>

          <body bgcolor="#ffffff">

          <h1>

          上傳結(jié)果

          </h1>

          文件名:<%=request.getAttribute("fileName")%><br />

          文本:<%=request.getAttribute("theText")%><br />

          文件類型:<%=request.getAttribute("fileType")%><br />

          文件大小:<%=request.getAttribute("fileSize")%><br />

          </body>

          </html>

          posted @ 2006-05-03 20:03 feingto 閱讀(1166) | 評(píng)論 (1)編輯 收藏

          Hibernate查詢解決方案

               摘要: 第一部分: Hibernate 提供的查詢接口或其方法 (此部分不做深究,請(qǐng)參考 hibernate 手冊(cè)) ????? ?????? 1 。...  閱讀全文

          posted @ 2006-05-03 20:03 feingto 閱讀(429) | 評(píng)論 (0)編輯 收藏

          struts在URI后面?zhèn)鲄?shù)的問(wèn)題

          在struts標(biāo)簽<html:link>的page屬性指定的URI后面?zhèn)鬟f參數(shù)可以有幾種方式:
          1.若明確參數(shù)名和參數(shù)值則直接在URI后輸出,
          如:<html:link page="/test.do?action=add">add</html:link>

          2.對(duì)于參數(shù)值不確定的,paramName和paramProperty來(lái)輸出,用paramId屬性指定參數(shù)名。
          對(duì)于paramName指定的對(duì)象應(yīng)該存在于page、request、session、application其中之一。一般來(lái)說(shuō),是從Action類傳過(guò)來(lái)的,作為request的屬性之一(requst.setAttribute("name",object))。
          如果paramName指定的對(duì)象是action的ActionForm,則無(wú)需使用request.setAttribute方法。
          例:<html:link page="/test.do" paramId="userid" paramName="uid">uname</html:link>
          若參數(shù)值是一個(gè)bean對(duì)象的屬性值(比如ActionForm,或者集合中存放的對(duì)象)則:
          <html:link page="/test.do" paramId="userid" paramName="user" paramProperty="uid">uname</html:link>

          3.若兩個(gè)參數(shù),一個(gè)確定一個(gè)不確定,則是以上兩種方法的結(jié)合,即:
          <html:link page="/test.do?action=modify" paramId="userid" paramName="uid">modify</html:link>

          4.對(duì)于多個(gè)參數(shù)的問(wèn)題,可以使用一個(gè)HashMap集合對(duì)象來(lái)存放所有的參數(shù)名及對(duì)應(yīng)的參數(shù)值的方式,paramName屬性值指定為該HashMap集合對(duì)象即可。
          舉例:
          <%
          //代碼理想的位置應(yīng)該是在action中
          //可以在jsp頁(yè)面測(cè)試
          ? java.util.HashMap pms = new java.util.HashMap();
          ? pms.put("code", "001002");
          ? pms.put("name", "tester");
          ? pms.put("alias", new String[]{"matin","jack"});
          ? request.setAttribute("params", pms);
          %>
          <html:link action="/test.do" name="params" >test</html:link>
          編譯后的結(jié)果:<a href="/test.do?code=001002&name=tester&alias=matin&alias=jack">test</a>
          這種方式雖然可以解決傳多參數(shù)的問(wèn)題,但是實(shí)現(xiàn)起來(lái)也比較麻煩,特別是對(duì)記錄集中的數(shù)據(jù)逐條列出的時(shí)候

          5.針對(duì)有的網(wǎng)友在<html:link>標(biāo)簽中嵌入使用jsp腳本(scriptlet)的問(wèn)題,
          例如:
          <html:link page="/test.do?code=<%=varible%>">add</html:link>,這種寫(xiě)法是錯(cuò)誤的,是無(wú)法編譯的。
          有的網(wǎng)友認(rèn)為在struts標(biāo)簽內(nèi)是不允許使用jsp腳本的,這種說(shuō)法也不準(zhǔn)確。如果前面的寫(xiě)法改成:
          <html:link page="<%="/test.do?code="+varible%>">add</html:link>,就可以被執(zhí)行,但是要注意URL相對(duì)路徑的問(wèn)題。

          雖然在struts標(biāo)簽中嵌入jsp腳本不是真正意義上的struts應(yīng)用,但是有時(shí)在委曲求全的情況下也只能如此了,除非使用自定義標(biāo)簽。比如在form表單中可能需要根據(jù)具體數(shù)據(jù)讓某個(gè)字段是只讀的,就可以用嵌入jsp腳本來(lái)實(shí)現(xiàn):
          <%
          boolean rdonly=false;
          if(2==2) rdonly=true;
          %>
          <html:text property="userid" readonly="<%=rdonly%>" />


          6.另外一種比較變態(tài)的方法,既不是真正意義上的struts,也不符合x(chóng)ml規(guī)范。那就是在<a>標(biāo)簽中用<bean:write>標(biāo)簽輸出參數(shù)值。
          如:<a href="test.do?uid=<bean:write name="user" property="userid"/>&name=<bean:write name="user" property="username"/>">test</a>

          posted @ 2006-05-03 20:02 feingto 閱讀(888) | 評(píng)論 (0)編輯 收藏

          struts錯(cuò)誤和信息的處理

          1. 錯(cuò)誤和信息的處理 .

          首先在資源文件中定義錯(cuò)誤信息和普通信息 . :MessageResources.properties 中定義如下 :

          java 代碼 :?



          #
          # Resources
          for testing <html:errors> tag.
          #

          errors.header=<table>
          errors.footer=</table>
          errors.prefix=<tr><td>
          errors.suffix=</td></tr>

          property1error1=Property 1,
          Error 1
          property2error1=Property 2,
          Error 1
          property2error2=Property 2,
          Error 2
          property2error3=Property 2,
          Error 3
          property3error1=Property 3,
          Error 1
          property3error2=Property 3,
          Error 2
          globalError=Global
          Error

          #
          # Resources
          for testing <html:messages> tag.
          #

          messages.header=<table>
          messages.footer=</table>

          property1message1=Property 1, Message 1
          property2message1=Property 2, Message 1
          property2message2=Property 2, Message 2
          property2message3=Property 2, Message 3
          property3message1=Property 3, Message 1
          property3message2=Property 3, Message 2
          globalMessage=Global Message

          ?



          在程序中定義錯(cuò)誤和信息類 , 這個(gè)例子寫(xiě)在 JSP

          java 代碼 :?



          <%
          ? ? ? ActionErrors errors =
          new ActionErrors();
          ? ? ? errors.add("property1",
          new ActionError("property1error1"));
          ? ? ? errors.add("property2",
          new ActionError("property2error1"));
          ? ? ? errors.add("property2",
          new ActionError("property2error2"));
          ? ? ? errors.add("property2",
          new ActionError("property2error3"));
          ? ? ? errors.add("property3",
          new ActionError("property3error1"));
          ? ? ? errors.add("property3",
          new ActionError("property3error2"));
          ? ? ? errors.add(ActionErrors.GLOBAL_ERROR,
          new ActionError("globalError"));
          ? ? ? request.setAttribute(Globals.ERROR_KEY, errors);

          ? ? ? ActionMessages messages =
          new ActionMessages();
          ? ? ? messages.add("property1",
          new ActionMessage("property1message1"));
          ? ? ? messages.add("property2",
          new ActionMessage("property2message1"));
          ? ? ? messages.add("property2",
          new ActionMessage("property2message2"));
          ? ? ? messages.add("property2",
          new ActionMessage("property2message3"));
          ? ? ? messages.add("property3",
          new ActionMessage("property3message1"));
          ? ? ? messages.add("property3",
          new ActionMessage("property3message2"));
          ? ? ? messages.add(ActionMessages.GLOBAL_MESSAGE,
          new ActionMessage("globalMessage"));
          ? ? ? request.setAttribute(Globals.MESSAGE_KEY, messages);
          ? ? %>

          ?





          顯示錯(cuò)誤 :

          java 代碼 :?



          <html:errors property="property1" />
          <html:errors property="property2" />

          ?


          顯示信息 :

          java 代碼 :?



          <html:messages property="property1" message="
          true " id="msg" header="messages.header" footer="messages.footer">
          ? ? ? ? ? ? <tr>
          ? ? ? ? ? ? ? <td>
          ? ? ? ? ? ? ? ? ? ? ?<%= pageContext.getAttribute("msg") %>
          ? ? ? ? ? ? ? </td>
          ? ? ? ? ? ? </tr>
          ? ? ? ? ? </html:messages>

          <html:messages message="
          true " id="msg" header="messages.header" footer="messages.footer">
          ? ? ? ? ? ? <tr>
          ? ? ? ? ? ? ? <td>
          ? ? ? ? ? ? ? ?<%= pageContext.getAttribute("msg") %>
          ? ? ? ? ? ? ? </td>
          ? ? ? ? ? ? </tr>
          </html:messages>

          ?

          ?

          posted @ 2006-05-03 20:02 feingto 閱讀(1035) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 新邵县| 尼勒克县| 高雄市| 商水县| 嵊泗县| 仪征市| 漳浦县| 故城县| 宁海县| 东兴市| 玉门市| 紫阳县| 丁青县| 大方县| 双流县| 保靖县| 汝州市| 沂南县| 济阳县| 乐亭县| 金川县| 醴陵市| 长汀县| 历史| 雷波县| 光泽县| 昆明市| 子长县| 上饶市| 微博| 宜阳县| 资阳市| 敦化市| 德阳市| 玉龙| 木兰县| 启东市| 吴川市| 镇原县| 沙湾县| 普洱|