如何使用一个按钮来计算和通过JavaScript验证,然后提交和导航

时间:2013-02-05 20:46:23

标签: javascript jsf-2 primefaces

我有一个js-function codeAddress(),它通过google maps javascript api完成一个地址,并设置一个全局js-variable valid = true,如果已识别完整地址。它还会使用完成的地址更新<p:inputText>的值。

现在我想要一个<p:commandButton>

  1. 执行codeAddress()
  2. 如果valid = true提交表单,则<p:inputText>中的地址会保存在addressBean
  3. 导航到下一页
  4. if valid = false触发jsf-validator消息
  5. 不幸的是,我的设置仍无法使用valid作为确定下一页的基本值。看来,这个值太晚了提交给bean。

    这是我的jsf代码:

    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:p="http://primefaces.org/ui">
    <h:head>
            <script src="https://maps.googleapis.com/maps/api/js?v=3&amp;sensor=false"></script>
    </h:head>
    <h:body>
        <h:outputScript name="jsf.js" library="javax.faces" target="head"/>
        <h:outputScript library="js" name="bugMaps.js" />
        <body onload="initialize()" />
        <h:form id="addressForm" onsubmit="codeAddress();">
            <p:inputText id="address" required="true"
                validatorMessage="Please enter a valid address." validator="#{addressBean.validate()}">
                <p:ajax update=":addressForm:addressValidate" />
            </p:inputText>
            <h:message id="addressValidate" for=":addressForm:address"/>
            <p:commandButton value="submit"
                onclick="codeAddress();"/>
            <p:inputText id="fullAddress" value="#{addressBean.fullAddress}" />
            <p:inputText id="valid" value="#{addressBean.valid}" />
        </h:form>   
    </h:body>
    </html>
    

    这是bugMaps.js:

    var geocoder;
    var map;
    var valid;
    
    function initialize() {
        geocoder = new google.maps.Geocoder();
    }
    
    function codeAddress() {
    
        var address = (document.getElementById('addressForm:address').value + ", Germany");
        geocoder.geocode({'address' : address},function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var latLong = results[0].geometry.location;
                var latitude = results[0].geometry.location.lat();
                var longitude = results[0].geometry.location.lng();
                var country, postal_code, locality, street_number, route;
                for (i = 0; i < results[0].address_components.length; ++i) {
                    var component = results[0].address_components[i];
                    if (!locality && component.types.indexOf("locality") > -1)
                        locality = component.long_name;
                    else if (!postal_code && component.types.indexOf("postal_code") > -1)
                        postal_code = component.long_name;
                    else if (!country && component.types.indexOf("country") > -1)
                        country = component.long_name;
                    else if (!street_number && component.types.indexOf("street_number") > -1)
                        street_number = component.long_name;
                    else if (!route && component.types.indexOf("route") > -1)
                        route = component.long_name;
                }
    
                if (typeof latLong != "undefined"
                    && typeof latitude != "undefined"
                    && typeof longitude != "undefined"
                    && typeof route != "undefined"
                    && typeof street_number != "undefined"
                    && typeof postal_code != "undefined"
                    && typeof locality != "undefined"
                    && typeof country != "undefined"){
                    valid = true;
    
                }
                else{
                    valid=false;
                };
                document.getElementById('addressForm:fullAddress').value = results[0].formatted_address;
    
                jsfSubmit();
    
            }
            else{
                alert('Geocode was not successful for the following reason: '+ status);
                valid=false;
    
            }
        }); 
    };
    
    function navigateToAnotherPage(data){
        if(valid){
            document.location.href='nextPage.xhtml';
        }
    };
    
    function jsfSubmit(){
        jsf.ajax.request(this, event, {execute:"@form", onevent:navigateToAnotherPage});
        alert("nothing"); // FIXME: without this useful alert bean keeps old values and display them on nextPage
    };
    

    这是我的AddressBean.java:

    package hoho.main.managebean;
    
    import java.io.Serializable;
    
    import javax.enterprise.context.SessionScoped;
    import javax.faces.application.FacesMessage;
    import javax.faces.component.UIComponent;
    import javax.faces.component.UIInput;
    import javax.faces.context.FacesContext;
    import javax.faces.validator.ValidatorException;
    import javax.inject.Named;
    
    import com.sun.faces.util.MessageFactory;
    
    @Named
    @SessionScoped
    public class AddressBean implements Serializable {
    
        private static final long serialVersionUID = 1L;
        private String fullAddress;
        private boolean valid = false;
    
        public void validate(FacesContext context,
                UIComponent toValidate, Object value) {
            if(!valid){
                  String client = toValidate.getClientId(context);  
                  FacesMessage msg = MessageFactory.getMessage(UIInput.REQUIRED_MESSAGE_ID, client);  
                  throw new ValidatorException(msg);
            }
        }
    
        public String getFullAddress() {
            return fullAddress;
        }
    
        public void setFullAddress(String fullAddress) {
            this.fullAddress = fullAddress;
        }
    
        public boolean isValid() {
            return valid;
        }
    
        public void setValid(boolean valid) {
            this.valid = valid;
        }
    
    }
    

    这是nextPage.xhtml:

    <html xmlns="http://www.w3.org/1999/xhtml"
        xmlns:h="http://java.sun.com/jsf/html"
        xmlns:f="http://java.sun.com/jsf/core"
        xmlns:ui="http://java.sun.com/jsf/facelets"
        xmlns:p="http://primefaces.org/ui">
    <h:head>
    </h:head>
    <h:body>
    
        <h:outputText value="#{addressBean.fullAddress}" />
    
    </h:body>
    </html>
    

1 个答案:

答案 0 :(得分:2)

您可以在javascript中使用jsf.ajax.request来提交表单。一个例子是

        function navigateToAnotherPage(data){
            //When the request is completed, we are safe to navigate to another page.
            if(data.status == "success"){
                alert("callback is invoked");
                //Go to another page
                document.location.href='destpage.xhtml';
            }
        }

        function jsfSubmit(){
            alert("Do your logic here");
            jsf.ajax.request(this, event, {execute:"@form", onevent:navigateToAnotherPage});
        }

将此函数绑定到jsf组件

        <h:commandButton type="button" value="javascriptSubmit" onclick="jsfSubmit()"/>

完整的参考资料如下:http://docs.oracle.com/cd/E17802_01/j2ee/javaee/javaserverfaces/2.0/docs/js-api/symbols/jsf.ajax.html

但是,我不知道如何通过javascript调用支持bean方法。所以我总是使用两个按钮。单击第一个按钮时的javascript进程逻辑,然后在第二个按钮上触发单击事件,该按钮提交表单并导航到另一个页面。当然第二个按钮是display:none。而且,它更简单。

此外,验证不起作用,因为验证总是在更新辅助bean之前发生。我没有在javascript中的javascript var valid和支持bean中的boolean valid之间看到任何链接。但是,如果使用javascript更新<p:inputText id="valid" value="#{addressBean.valid}" />,请提交输入字段,更新支持bean valid并使用此布尔变量进行验证,然后验证将始终失败。这是因为在boolean valid更新之前(例如,true),首先调用验证方法(因此验证方法可能使用过时的valid

四处走动,您将验证器附加到<p:inputText id="valid" value="#{addressBean.valid}" />而不是<p:inputText id="address" required="true"...../>。现在,您可以使用value中的validate(FacesContext context, UIComponent toValidate, Object value)获取输入字段的值。这里的值是您在页面的输入字段中放置的值(或javascript put)(因此它始终是最新的)。

请注意,此时支持bean中的valid尚未更新。如果验证结果正常,则valid会更新并设置为您刚刚获得的value。如果验证失败,则valid不会更新。

总之,流程是0.构建/恢复组件树。转换,验证。 2.更新辅助bean中的值。 3. call backing bean方法4.渲染页面。