1

我正在尝试使用采用 Google 提供的地理编码服务的 JavaScript 方法处理几行输入数据,并将处理后的数据放入支持 bean。

用户会看到一个登录页面,他们可以在其中输入他们的地址详细信息。单击提交按钮后,我尝试通过调用 JavaScript 方法对其地址进行地理编码。此方法读取用户输入的数据并将其发送到地理编码服务。此服务需要几毫秒才能完成。一旦完成,我希望将它找到的数据存储在登录页面的支持 bean 中。

以下 JavaScript 函数用于对地址进行地理编码。

    function codeAddress() {
        alert('coding address');
        geocoder = new google.maps.Geocoder();
        postcode = document.getElementById('loginForm:address').value;

        geocoder.geocode( { 'address': address}, function(results, status) {
          if (status == google.maps.GeocoderStatus.OK) {
              alert('setting location: '+results[0].geometry.location);
              document.getElementById('loginForm:location').value = results[0].geometry.location;
          } else {
            alert('Geocode was not successful for the following reason: ' + status);
          }
        });
      }

它将其值存储在表单内的隐藏字段中。我不知道这是否是最好的做法,这只是我在很多例子中看到的。我假设设置此组件的值将调用 loginBean 中相应的位置设置器。

    <h:inputHidden id="location" value="#{loginBean.location}" />

我正在尝试使用用于提交表单的按钮来实现这一切。

        <p:commandButton id="submitButton" value="login"
            action="#{loginBean.doLogin}"
            styleClass="blue login" update="growl">
                <p:ajax event="click" onstart="codeAddress()" />
        </p:commandButton>

我必须补充一点,我不确定这种结构。按下提交按钮可能会立即加载下一页,甚至没有给 ajax 调用机会。

试图做到这一点给我带来了几个问题。使用上面的代码,JavaScript 函数永远不会被调用。为简单起见,我在页面顶部的脚本标记中声明了此函数。第二个问题是我不清楚将这个值从 JavaScript 方法传递到 loginBean 的最佳方法是什么。我应该在表单中放置一些隐藏标签并将其值标签链接到 loginBean 属性吗?我应该向 ajax 组件添加一个侦听器吗?

4

4 回答 4

0

服务的 JavaScript 回调函数应该触发表单提交(成功时)。这样,它总是有时间在提交之前完成。

于 2013-02-26T11:28:43.073 回答
0

我会建议类似:

<h:form>
<p:inputText widgetVar="widget_postcode" value="#{backingBean.address}"/>
<p:inputText style="display:none;" widgetVar="widget_geocode" value="#{backingBean.geocode}"/>
<p:commandButton id="submitButton" value="login" type="button" 
            styleClass="blue login" onclick="codeAddress();">
        </p:commandButton>
<p:remoteCommand name="sendData" process="@form" update="growl"/>
</h:form>



function codeAddress() {
    alert('coding address');
    geocoder = new google.maps.Geocoder();
    postcode = widget_postcode.getJQ().val();

    geocoder.geocode( { 'address': address}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
          alert('setting location: '+results[0].geometry.location);
         widget_geocode.getJQ().val(results[0].geometry.location);
         sendData();
      } else {
        alert('Geocode was not successful for the following reason: ' + status);
      }
    });
  }

这种方法使用 PF 小部件,而不是依赖可以更改的 ID。

此外,请考虑使用 Google 地址自动完成 API。为此有一个 JSF 组件。

于 2013-02-26T18:18:25.960 回答
0

我假设你擅长 javascript。

你可以尝试一个技巧。

  1. 与命令按钮一起使用简单的 html 按钮,该按钮将可见,命令按钮隐藏在 div 中。
  2. 当用户单击简单的 html 按钮执行您的地理定位 ajax 调用时,成功并在更新隐藏字段后,只需调用 javascript 以编程方式单击隐藏的命令按钮。

希望这可以帮助。

于 2013-02-26T14:20:38.253 回答
0

<p:ajax/>是不必要的,是不调用 javascript 函数的根本原因。完成这项工作的一种快速而肮脏的方法是。摆脱<p:ajax/>. <p:commandButton/>对于您的用例来说已经足够了。

    <p:commandButton id="submitButton" onclick="codeAddress();" value="login" action="#{loginBean.doLogin}" styleClass="blue login" update="growl"/>

您传递变量的模式将起作用,但不是特别有效或安全。

另一种方法是使用 primefaces 的 javascript api,addSubmitParam将生成的值作为请求参数发送到支持 bean

    function codeAddress() {
    alert('coding address');
    geocoder = new google.maps.Geocoder();
    postcode = document.getElementById('loginForm:address').value;

    geocoder.geocode( { 'address': address}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
          alert('setting location: '+results[0].geometry.location);
         PrimeFaces.addSubmitParam(results[0].geometry.location); //addSubmitParam sends a request parameter
      } else {
        alert('Geocode was not successful for the following reason: ' + status);
      }
    });
  }
于 2013-02-26T14:34:54.680 回答