考虑以下jsf页面:
<h:body>
<h:form id="SessionStartDialog">
<table>
<tr>
<td class="label">
<h:outputLabel
value="Enter your username:"
for="UsernameField"/>
</td>
<td class="input">
<h:inputText
id="UsernameField"
value="#{login.username}"
validator="#{login.validateUsername}"
tabindex="1">
<f:ajax render="SelectWorkingSetListbox
StartSessionButton UsernameMessage" />
</h:inputText>
<h:message
id="UsernameMessage"
for="UsernameField" />
</td>
</tr>
<tr>
<td class="label">
<h:outputLabel
value="Choose a working-set:"
for="SelectWorkingSetListbox"/>
</td>
<td class="input">
<h:selectOneMenu
id="SelectWorkingSetListbox"
tabindex="2"
disabled="#{!login.showWorkingSets}"
value="#{login.selectedWorkingSetName}">
<f:selectItems
value="#{login.workingSetNames}"/>
<f:ajax />
</h:selectOneMenu>
</td>
</tr>
</table>
<h:commandButton
id="StartSessionButton"
styleClass="StartSessionButton"
disabled="#{!login.showWorkingSets}"
value="Start Session"
tabindex="3"
action="#{login.startSession}" >
<f:ajax execute="@form"/>
</h:commandButton>
</h:form>
</h:body>
其中的某些内容导致Safari报告ajax和完整请求混合的错误。我不明白为什么,因为所有导致请求的组件都包含<f:ajax>
- 标签。这有什么问题?
更新:
我创建了一个触发此错误的最小示例:
<h:body>
<h:form>
<f:ajax render="TextField">
<h:inputText value="#{theBean.text}" />
</f:ajax>
<h:outputText id="TextField" value="#{theBean.text}" />
</h:form>
</h:body>
theBean
是一个简单的视图范围bean,text
是String
类型的属性。由于某种原因,这会在Safari 5.1中触发以下消息:
httpError:Http Transport返回0状态代码。这是 通常是混合ajax和完整请求的结果。这通常是 出于性能和数据完整性的原因,这是不受欢迎的。
更新2 这样做的原因似乎是在enter
字段内点击input
始终会触发完整表单提交。我不知道如何防止这种情况。如第一个示例所示,我希望用户输入用户名,然后启用表单的其他组件(仅当用户名已知时)。我该如何正确实现?
答案 0 :(得分:1)
问题的原因在于,在没有<h:commandButton>
的情况下(在第一个示例中它最初被禁用,在第二个示例中,没有),按回车将触发整个提交表格,导致问题中显示的错误。
现在的解决方案是始终启用<h:commandButton>
。由于启用了<f:ajax>
,因此会阻止完整提交。
P.S。:我发布了这个答案,为其他人展示了一个可能的解决方案。我仍然想知道是否有更好的解决方案(不需要<h:commandButton>
存在的解决方案。)
答案 1 :(得分:1)
我会抓取<form>
上的 Enter 键,而是触发按下此键的onchange
元素上的<input>
。
<h:form onkeydown="enterToChange(event)">
...
</h:form>
与
function enterToChange(event) {
if (event.keyCode == 13 && event.target.tagName != 'textarea') {
event.stopPropagation(); // Don't bubble up.
event.preventDefault(); // Prevent default behaviour (submitting the form).
event.target.onchange(); // Trigger onchange where key was actually pressed.
}
}
请注意,这会忽略textareas上的回车键,您当然希望保留预期的行为(插入新行)。
如果有必要,您可以添加额外的检查以查看提交按钮是否不是disabled
,如果是这种情况,那么只需让活动开始。