posts - 0,  comments - 1,  trackbacks - 0
          最近在做項目的時候,碰到了一個JSF的問題,就是輸入組件設置了readonly屬性之后,提交的時候就得不到該組件的值了,仔細研究了一番,才找到原因和解決方法。

          具體的現象是這樣的,一個輸入框需要設置為不能讓用戶更改,但可以通過javascript改變,改變后提交,則在服務器端得到改變后的值進行處理。這種需求應該也是非常常見的,可是在用JSF實現時,卻碰到了問題。具體JSF代碼如下:
          1       <h:form id="theForm">
          2         <h:inputText id="theValue" readonly="true" value="#{readonlyBean.theValue}"/>
          3         <h:commandButton value="Submit" action="#{readonlyBean.submit}"/>
          4         <af:outputText value="Click" onclick="editReadonly();"/>
          5       </h:form>
          第一個<h:inputText>就是我們要研究的對象,第二個<h:commandButton>是提交的按鈕,第三個<af:outputText>是為了有一個地方可以點擊,點擊后調用javascript來改變第一個組件的值,至于af是來自于ADF,ADF是Oracle的JSF實現,提供了更多的功能,為什么不用<h:outputText>呢?因為很奇怪,標準的JSF組件<h:outputText>竟然不接受onclick事件??傊?,調用的editReadonly()的javascript代碼如下:
          1         function editReadonly() {
          2             document.getElementById('theForm:theValue').value = "ABCD";
          3         }
          在服務器端,Managed Bean中的代碼如下:
           1 public class ReadonlyBean {
           2     private String theValue = "XYZ";
           3     
           4     public void setTheValue(String aValue) {
           5         this.theValue = aValue;
           6     }
           7 
           8     public String getTheValue() {
           9         return theValue;
          10     }
          11 
          12     public String submit() {
          13         System.out.println( this.getTheValue() );
          14         
          15         return null;
          16     }
          17 }
          以上代碼就是開始給theValue以初始值XYZ,然后在提交時打印出theValue的值。

          運行時,首先點擊"Click",看到頁面上的只讀輸入組件的值變成了ABCD,然后提交,發現服務器端打印出來的值仍然是XYZ,沒有得到該輸入框的新值。

          然而如果直接用HTML來完成這一功能時,頁面上有一個readonly的輸入框,提交到一個servlet,在servlet中從request中得到該輸入框的值打印出來,那么在用javascript改變了該輸入框的值后,打印出來的值是變化之后的值,說明標準的HTML的readonly的值是會提交的。

          怎么會這樣呢?JSF的輸入組件設為readonly之后似乎不提交自己的值?為了解決這一問題,首先查看JSF最后生成的HTML頁面的源代碼,似乎沒有任何問題,也是解析成一個標準的HTML的<input>,那說明在頁面這個值是確實存在,也被提交給JSF框架,只是在后臺處理時JSF忽略了該組件,這非常奇怪,為什么要采取這個和標準HTML不一致的行為?是不是當前使用的JSF的實現的問題?在換了好幾個JSF的實現之后(Oracle的實現,MyFaces的實現,Sun的RI實現),結果都是一樣,看來只有看看實現的源代碼才能找到原因了。

          下載了MyFaces 1.2的源代碼,然后首先找到HtmlInputText的renderer:HtmlTextRenderer,因為提交時首先調用組件的renderer的docode方法來解析request的參數。然后發現該類是擴展了HtmlTextRendererBase,之后發現是調用了HtmlRendererUtils.decodeUIInput()來解析的,在該方法的一開始,就發現如下語句:
          1         if(isDisabledOrReadOnly(component))
          2             return;
          這里充分說明了在JSF中readonly和disable一樣,都是不會將參數提交給后臺的。

          原因找到了,那為什么JSF會采用這種方式。解釋可能要回到JSF是一個組件的框架這一點上來。因為<h:inputText>是一個組件,那一個只讀的組件是不是就應該不能改變其值呢?

          最后則說一下怎么繞過這一限制,從而實現我們一開始想要的功能。實現的方法則只能是加一個隱藏的輸入組件,在javascript改變只讀輸入框時,也同時改變該隱藏的輸入組件的值,那么提交后就能得到這個隱藏輸入組件的值。
          posted on 2009-02-24 10:22 飛馬涼 閱讀(1680) 評論(1)  編輯  收藏


          FeedBack:
          # re: JSF中輸入組件的readonly屬性[未登錄]
          2013-06-04 12:45 | doudou
          好辦法,只能這樣了。  回復  更多評論
            

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2025年7月>
          293012345
          6789101112
          13141516171819
          20212223242526
          272829303112
          3456789

          留言簿

          文章檔案

          搜索

          •  

          最新評論

          主站蜘蛛池模板: 龙岩市| 鸡泽县| 海伦市| 威海市| 邹城市| 苏尼特左旗| 商城县| 砚山县| 西城区| 沁水县| 大宁县| 罗山县| 沛县| 铜山县| 昆山市| 区。| 玉门市| 绵阳市| 永安市| 晋中市| 凌云县| 庄河市| 宜兰县| 锦屏县| 和龙市| 江达县| 平湖市| 平遥县| 上饶市| 绥德县| 庆安县| 治县。| 静宁县| 灌南县| 兴业县| 都匀市| 洛南县| 青铜峡市| 龙游县| 浙江省| 灵璧县|