简体   繁体   English

AJAX删除JSF表单事件处理程序

[英]AJAX removes JSF form event handler

I have a JSF page with a form, with the following 2 somewhat nonstandard requirements: 我有一个带有表单的JSF页面,具有以下2个非标准要求:

  1. Some input components are only relevant for certain settings of other inputs. 某些输入组件仅与其他输入的某些设置相关。 Ie, if a certain value is chosen in a <h:selectOneMenu> , another field should be shown or hidden as appropriate. 即,如果在<h:selectOneMenu>选择了某个值,则应适当显示或隐藏另一个字段。

    This is handled via a <f:ajax render="@form"> and the rendered attribute. 这是通过<f:ajax render="@form">rendered属性来处理的。 Simple. 简单。

  2. I need to call some Javscript code on submit and reset before the request is posted to the server. 在将请求发布到服务器之前,我需要在提交重置时调用一些Javscript代码。

    This is handled by adding event handlers to the form element for the onsubmit and onreset events, via jQuery, in the $(document).ready() event handler. 这是通过在$(document).ready()事件处理程序中通过jQuery将事件处理程序添加到onsubmitonreset事件的form元素来处理的。 Not difficult either. 也不难。

What I however find is that once the AJAX POST request happens, the onsubmit and onreset event handlers disappear. 但是,我发现的是,一旦AJAX POST请求发生, onsubmitonreset事件处理程序就会消失。 Obviously the $(document).ready() handler is not activated again, so they are not recreated - but it is strange that they are removed. 显然$(document).ready()处理函数不会再次激活,因此不会重新创建它们-但是很奇怪,它们被删除了。

Can someone tell me what I am doing wrong, or a better (correct) way to accomplish this? 有人可以告诉我我做错了什么,还是一种更好的(正确的)方法来做到这一点?

Basic Facelets page for demonstration purposes: 用于演示目的的“基本Facelets”页面:

(no backing bean needed) (不需要辅助bean)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
>
<h:head>
    <title>Test page</title>
    <h:outputScript target="head" library="js" name="jquery.js" />
</h:head>
<h:body>
    <h:outputScript target="body">
        //Code just for debugging purposes
        function debugAjax(data) {
            console.log("AJAX onevent. Type=" + data.type + ", Status=" + data.status);
            debugEvents();
        }
        function debugEvents() {
            var evs = jQuery._data(document.getElementById('myform'), 'events');
            if (evs) {
                jQuery.each(evs, function(index, value) {
                    console.log(" - Event " + index + "=" + value);
                });
            } else {
                console.log(" - NO EVENTS");
            }
        }
    </h:outputScript>

    <h:outputScript target="body">
        jQuery(document).ready(function() {
            console.log("Adding handlers");
            jQuery("#myform").on({
                reset  : function() { console.log("RESET activated"); },
                submit : function() { console.log("SUBMIT activated"); }
            });
            debugEvents();
        })
    </h:outputScript>

    <h:form id="myform">
        <h:panelGrid columns="2">
            <h:outputLabel for="formType" value="Form type" />
            <h:selectOneMenu id="formType" value="#{formType}">
                <f:selectItem itemValue="1" itemLabel="Simple" />
                <f:selectItem itemValue="2" itemLabel="With additional data" />
                <f:selectItem itemValue="3" itemLabel="Another item" />

                <f:ajax render="@form" onevent="debugAjax" />
            </h:selectOneMenu>

            <ui:remove>conditionally displayed field</ui:remove>
            <h:outputLabel for="moreData" value="More data" rendered="#{formType eq '2'}" />
            <h:inputText id="moreData" value="#{moreData}"  rendered="#{formType eq '2'}" />
        </h:panelGrid>

        <h:commandButton type="reset" id="delete" value="Cancel" />
        <h:commandButton type="submit" id="submit" value="OK" />
    </h:form>
</h:body>
</html>

Console output: 控制台输出:

This is the output in my Javascript console (explanations inside {{}} added) 这是我的Javascript控制台中的输出(已添加{{}}中的说明)

{{Initial load of page}}
GET http://localhost:8080/xxx/test.jsf [HTTP/1.1 200 OK 6ms]
"Adding handlers"
" - Event reset=[object Object]"
" - Event submit=[object Object]"
{{reset/submit event handlers work as expected}}
{{now changing dropdown that fires AJAX}}
POST http://localhost:8080/xxx/test.jsf [HTTP/1.1 200 OK 9ms]
"AJAX onevent. Type=event, Status=begin"
" - Event reset=[object Object]"
" - Event submit=[object Object]"
"AJAX onevent. Type=event, Status=complete"
" - Event reset=[object Object]"
" - Event submit=[object Object]"
"AJAX onevent. Type=event, Status=success"
" - NO EVENTS"
{{reset/submit event handlers DON'T work, but standard form resetting/submitting still works}}

The test was run from Firefox, GlassFish 4.1 (13) (Mojarra 2.2.7). 该测试是从Firefox GlassFish 4.1(13)(Mojarra 2.2.7)运行的。

The simple answer is that the AJAX call should render only some or all contents inside the form. 简单的答案是,AJAX调用应该仅渲染表单的部分或全部内容。 In the above sample, it would do nicely to give an id to the <h:panelGrid> : 在上面的示例中,为<h:panelGrid>指定一个id会很好:

<h:panelGrid id="fieldgrid" columns="2">

... and then render that in the AJAX call: ...然后在AJAX调用中呈现:

<f:ajax render="fieldgrid" ... />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM