将p:calendar设为只读

问题描述:

我想将 <p:calendar> 设为只读只能由于问题从日历中选择日期(但这不是解决方案).

I want to make <p:calendar> readonly so that users can only choose a date from the calendar because of this issue (this is not a solution though).

为此,我正在做readonly="#{facesContext.renderResponse}",如答案所述,

For this to be so, I'm doing readonly="#{facesContext.renderResponse}" as mentioned by this answer like,

<p:calendar id="calendarId" 
        value="#{bean.property}" 
        converter="#{jodaTimeConverter}" 
        pattern="dd-MMM-yyyy hh:mm:ss a" 
        showOn="button" 
        readonly="#{facesContext.renderResponse}" 
        effect="slideDown"
        required="true" 
        showButtonPanel="true" 
        navigator="true"/>

这有效,但是在加载页面时(在地址栏中键入URL,然后按Enter键),facesContext.renderResponse返回false,并且日历不再是只读的.当我按<p:commandButton>提交表单时,它的值为true.

This works but when the page is loaded (typing the URL in the address bar and then pressing the enter key), facesContext.renderResponse returns false and the calendar is no longer readonly. It evaluates to true, when I submit the form by pressing <p:commandButton>.

那么,如何在加载页面时使日历变为只读状态?

So, how to make the calendar readonly, when the page is loaded?

P.S:我正在使用PrimeFaces 3.5和Mojarra 2.1.9.

P.S : I'm using PrimeFaces 3.5 and Mojarra 2.1.9.

自JSF 2.0以来,该行为的确发生了变化. FacesContext#getRenderResponse() 仅在 FacesContext#renderResponse() 被显式调用 .以前,这是在每个GET请求的还原视图阶段发生的.但是,由于引入了<f:viewParam>,当存在至少一个视图参数时,JSF将不再这样做,它将继续执行每个单个阶段,而不会跳过任何阶段以正确处理视图参数.

The behavior has indeed changed since JSF 2.0. The FacesContext#getRenderResponse() only returns true if FacesContext#renderResponse() is explicitly been called. Previously this happened during restore view phase of every GET request. However, since the introduction of <f:viewParam>, JSF will not do that anymore when at least one view parameter is present, it will just continue executing every single phase without skipping any phase in order to properly process the view parameters.

您的页面中显然有一个<f:viewParam>.完全没问题,但是作为测试,请尝试将其删除,并且还会看到它在普通的GET请求上也返回true.

You apparently have a <f:viewParam> in your page. That's totally fine, but as a test, try removing it and you'll see that it returns true on a plain GET request as well.

基本上,您有2种解决方法:

You've basically 2 options to get around it:

  1. 检查 FacesContext#isPostback() .它总是在GET请求上返回false.

readonly="#{not facesContext.postback or facesContext.renderResponse}"

  • 检查 FacesContext#getCurrentPhaseId() .您只会得到难看的代码(幻数).

  • Check the FacesContext#getCurrentPhaseId() instead. You only end up with uglier code (magic numbers).

    readonly="#{facesContext.currentPhaseId.ordinal eq 6}"
    

    如果您使用的是 OmniFaces ,则可以使其变得不那么难看.

    If you're using OmniFaces, you could make it less ugly.

    <o:importConstants type="javax.faces.event.PhaseId" />
    ...
    readonly="#{facesContext.currentPhaseId eq PhaseId.RENDER_RESPONSE}"