JSF中输入组件的readonly属性

最近在做项目的时候,碰到了一个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改变只读输入框时,也同时改变该隐藏的输入组件的值,那么提交后就能得到这个隐藏输入组件的值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值