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

时间:2016-07-22 17:21:05

标签: jquery ajax jsf-2 event-handling

我有一个带有表单的JSF页面,其中有两个非标准的要求:

  1. 某些输入组件仅与其他输入的某些设置相关。即,如果在<h:selectOneMenu>中选择了某个值,则应在适当时显示或隐藏另一个字段。

    这是通过<f:ajax render="@form">rendered属性处理的。简单。

  2. 在将请求发布到服务器之前,我需要在提交重置上调用一些Javscript代码。

    通过在onsubmit事件处理程序中通过jQuery将事件处理程序添加到onreset$(document).ready()事件的表单元素来处理。也不难。

  3. 但我发现,一旦AJAX POST请求发生,onsubmitonreset事件处理程序就会消失。显然,$(document).ready()处理程序不会再次激活,因此不会重新创建它们 - 但奇怪的是它们被删除了。

    有人可以告诉我我做错了什么,或者更好(正确)的方法来实现这个目标吗?

    Basic Facelets页面用于演示目的:

    (不需要支持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>
    

    控制台输出:

    这是我的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}}
    

    测试是从Firefox,GlassFish 4.1(13)(Mojarra 2.2.7)进行的。

1 个答案:

答案 0 :(得分:0)

简单的答案是,AJAX调用应该只呈现表单中的部分或全部内容 。在上面的示例中,为id提供<h:panelGrid>会很好:

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

...然后在AJAX调用中呈现它:

<f:ajax render="fieldgrid" ... />
相关问题