问题
I have a js-function codeAddress() that processess the data from address and updates the values of fullAddress and validField.
The data of fullAddress and validField is passed by <p:ajax> to the backing bean, but the setter methods seem to get called one request delayed.
The alert() at the end of codeAddress shows the correct new data.
When address has onchange="test()" everything works fine an the backing beans setter methods are called as they should without any delay.
I am clueless what might be wrong here.
my jsf code:
<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&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">
<p:inputText id="address" onchange="codeAddress()">
<p:ajax process="fullAddress validField"/>
</p:inputText>
<p:message id="addressValidate" for=":addressForm:validField"/>
<p:commandButton value="submit" />
<p:inputText id="fullAddress" value="#{addressBean.fullAddress}" />
<p:inputText id="validField" value="#{addressBean.valid}" />
</h:form>
</h:body>
</html>
my JS:
var geocoder;
var map;
var valid = false;
var fullAddress = "none";
function initialize() {
geocoder = new google.maps.Geocoder();
}
function test(){
fullAddress = Math.random();
document.getElementById('addressForm:fullAddress').value = fullAddress;
}
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;
fullAddress = results[0].formatted_address;
}
else{
valid=false;
fullAddress="none";
};
}
else{
valid=false;
fullAddress="none";
}
document.getElementById('addressForm:fullAddress').value = fullAddress;
document.getElementById('addressForm:validField').value = valid;
alert(fullAddress + valid);
});
};
回答1:
This is not a duplicate question.
The first fault was using <p:ajax> to submit data that was to be altered by JS, because the ajax request is already prepared while the script is still running.
The second mistake was to use the non-cross-browser-compatible jsf.ajax.request.
Now I simply deleted the <p:ajax> and use a solution with jQuery. This function is simply called from the geocoders callback function:
function jsfSubmit(){
document.getElementById('addressForm:fullAddress').value = fullAddress;
document.getElementById('addressForm:validField').value = valid;
$.ajax({type:'POST', data:$('#addressForm').serialize(), success: function(response) {
if(valid){
var destPage = 'nextPage.xhtml';
window.location = destPage;
}
}});
};
来源:https://stackoverflow.com/questions/14857860/javascript-and-pajax-behave-strange