【问题标题】:h:selectOneListBox not workingh:selectOneListBox 不工作
【发布时间】:2023-03-07 00:57:01
【问题描述】:

我有一个带有表单的简单 JSF 应用程序,其中一个控件是 selectOneListbox

<h:selectOneListbox style="width: 231px; height: 27px;position:absolute;left:400px;top:325px;" value="#{PatientsSearch.selectedDoctor}">
    <f:selectItems value="#{PatientsSearch.doctors}" var="d" itemLabel="#{d.name}" itemValue="#{d.name}" />
</h:selectOneListbox>

当我运行应用程序时,我可以看到正在填充的列表(即,PatientSearch.doctors 已正确检索),因此我可以从 selectOneListbox 中选择一项。在我选择了所需的项目后,该表单不再起作用。所有其他按钮似乎都处于空闲状态,它们不再对点击做出反应。但是,如果没有从 selectOneListbox 中选择任何内容,则所有按钮都会按预期工作(即它们在托管 bean 中触发它们的回调)。

我调试了应用程序并注意到,在列表中选择一个项目后,表单上其他按钮的回调在单击它们时不会被触发。 同样在调试器中,我从来没有看到 setSelectedDoctor() 像我预期的那样被调用(参见上面的 sn-p)。

我正在使用 JSF 的 Mojarra 2.0.1 实现。

我在这里错过了什么?


更新:这是整个表格:

    <h:form style="width: 876px; background-color: #FED981; padding-left: 60px; padding-top: 30px; margin-left: 80px; margin-top: 40px; color: #804000; font-style: normal; font-family: Verdana, Arial, Sans-Serif">
    <h:outputLabel style="position:absolute;left:200px;top:100px;" value="New appointment:"></h:outputLabel>
    <br>
    <br>
    <h:inputText style="width: 259px;position:absolute;left:200px;top:120px;" binding="#{PatientsSearch.inputText1}" valueChangeListener="#{PatientsSearch.lookForName}" immediate="true" id="inputText1" />
    <h:commandButton value ="Search patients by name:" style="width: 173px;position:absolute;left:465px;top:120px;" action="#{PatientsSearch.getPatientsByName}">
        <f:param name="day" value="#{request.getParameter('day')}" />
        <f:param name="month" value="#{request.getParameter('month')}" />
        <f:param name="year" value="#{request.getParameter('year')}" />  
    </h:commandButton>

    <br>
    <h:panelGroup id="pn_DETAILS_GRP" style="overflow:auto;position:absolute;top:155px;left:200px;width:300px;height:150px;solid black">
        <h:dataTable id="tb_USER_DETAILS" border="1" var="patient" value="#{PatientsSearch.patients}" style="width:300px;height:150px" rowClasses="oddRow, evenRow">
        <h:column id="name">
        <f:facet name="header">
        <h:outputText value="Name" style="font-size:10pt"/>
        </f:facet>
        <h:outputText value="#{patient.name}" style="font-size:8pt"/>
        </h:column>
        <h:column id="phone">
        <f:facet name="header">
        <h:outputText value="Phone" style="font-size:10pt"/>
        </f:facet>
        <h:outputText value="#{patient.phoneMobile}" style="font-size:8pt"/>
        </h:column>
        <h:column>
        <h:inputHidden id="patientId" value="#{patient.id}" />
        </h:column>
        </h:dataTable>
    </h:panelGroup>

    <h:inputHidden id="testId"  />

    <br><br><br>
    <h:outputLabel value="Choose doctor:" style="width: 200px;position:absolute;left:200px;top:325px;"></h:outputLabel>
    <h:selectOneListbox style="width: 231px; height: 27px;position:absolute;left:400px;top:325px;" value="#{PatientsSearch.selectedDoctor}" size="1">
        <f:selectItems value="#{PatientsSearch.doctors}" var="d"
            itemLabel="#{d.name}" itemValue="#{d.name}" />
    </h:selectOneListbox>
    <br><br><br>
    <h:commandButton value="Schedule" style="position:absolute;left:200px;top:430px;" action="#{PatientsSearch.scheduleAppointment}">
        <f:param name="day" value="#{request.getParameter('day')}" />
        <f:param name="month" value="#{request.getParameter('month')}" />
        <f:param name="year" value="#{request.getParameter('year')}" /> 
    </h:commandButton>

</h:form>

【问题讨论】:

  • 您应该添加表单的其他部分,包括按钮。乍一看,这可能是验证错误的转换,您在某处有 h:messages 吗?
  • 这个表格没有按钮? 所有其他按钮似乎都处于空闲状态,它们不再对点击做出反应。 哪些? #{PatientsSearch.selectedDoctor}#{d.name} 的 getter/setter 是什么?
  • 嗨,你可以看到整个表格 - 我已经在上面添加了。有两个按钮,只有当我不选择 selectOneListbox 中的任何项目时它们才能正常工作。否则不会触发他们的回调。
  • 两个按钮都会发送所有表单,这是您想要的吗?我怀疑当您选择医生时出现转换错误,是 #{PatientsSearch.selectedDoctor}#{d.name} 字符串?
  • d.name 是一个字符串,PatientSearch.selectedDoctor 是一个医生类型。所以这个问题很可能是关于后者。我会把它变成一个字符串并检查。这就是您怀疑的问题所在,对吧?

标签: jsf jsf-2 mojarra


【解决方案1】:

根据 cmets,问题在于 #{d.name} 的类型与 #{PatientsSearch.selectedDoctor} 不同。在这种情况下,有两种解决方案:

  1. 保持一切不变,将 #{PatientsSearch.selectedDoctor} getter/setter 更改为 String 类型。
  2. 在支持 bean 中创建 SelectItem 列表,并将 #{PatientsSearch.selectedDoctor} getter/setter 更改为 String 类型。您还可以删除 itemValueitemLabel,因为支持 bean 已经为列表组件提供了现成的对象。
  3. f:selectItems 更改itemValue 属性并创建自定义转换器

我更喜欢第二种,因为它可以更好地分隔视图。应该这样改:

<h:selectOneListbox style="width: 231px; height: 27px;position:absolute;left:400px;top:325px;" value="#{PatientsSearch.selectedDoctor}" size="1">
    <f:selectItems value="#{PatientsSearch.doctors}" var="d" itemLabel="#{d.name}" />
    <f:converter convertId="doctorConverter" />
</h:selectOneListbox>

现在对于转换器,您可以这样启动它:

@FacesConverter(value="doctorConverter")
public class DoctorConverter implements Converter {

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {
        // Your code, select doctor from value ID for example.
    }

    @Override
    public String getAsString(FacesContext context, UIComponent component, Object value) {
        // Your code, return doctor ID from value.
    }
}

【讨论】:

  • 谢谢 Alexandre,你说的很有道理,但似乎比这更复杂。如果我使用 itemValue="#{d}",那么它比以前更糟:其他按钮即使是第一次也不起作用。另一种方法是将所有内容都设为字符串(即“selectedDoctor”),然后按钮似乎可以工作,但选择看起来很奇怪 - 所有 Doctor 对象似乎都是序列化和连接的,这就是我在“selectedDoctor”变量中得到的。看起来好像列表中的所有医生都被同时选中了。这太疯狂了,我相信我会放弃这个愚蠢的selectOneListbox
  • @Sorin-AlexandruCristescu 不幸的是我把你放在了错误的方向,你实际上需要一个转换器作为修改后的答案。
  • 对,我希望我可以在没有转换器的情况下做到这一点。但是也可以这样,我试试看,它必须工作....非常感谢。知道为什么字符串不起作用(正如我解释的那样)?我不应该为此需要转换器。
  • @Sorin-AlexandruCristescu 它真的取决于你想如何处理选择的数据,如果你只需要名称,例如,你可以保留itemValue="#{d.name}",只需将#{PatientsSearch.selectedDoctor}更改为字符串类型。但我不认为这很好。转换器唯一能做的就是把你的对象还给你,这是一个很好的想法,所以你只做一次转换器,无论你需要什么对象,你永远不会卡住。
  • 当然,我明白你的意思。但是,第一部分(使用 d.name 并将 selectedDoctor 作为字符串)不起作用:当我从 selectOneListbox 中选择某些内容时,selectedDoctor 设置为整个医生列表是一个字符串序列化的形式(不仅仅是名称我选择了)。这太疯狂了,我不知道为什么会这样。
猜你喜欢
  • 2012-10-25
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-16
  • 2021-01-10
  • 1970-01-01
  • 2019-01-19
相关资源
最近更新 更多