简体   繁体   English

使用JSF和primefaces通过JavaScript将表单数据传递到支持bean

[英]Passing form data through JavaScript into a backing bean using JSF and primefaces

I am trying to process a few lines of input data, using a JavaScript method that employs a Google provided geocoding service, and place that processed data into a backing bean. 我正在尝试使用采用Google提供的地理编码服务的JavaScript方法处理几行输入数据,并将处理后的数据放入后备bean中。

Users are presented with a login page in which they enter their address details. 向用户显示一个登录页面,在其中输入其地址详细信息。 As soon as the submit button is clicked, I try to geocode their address by calling a JavaScript method. 单击提交按钮后,我尝试通过调用JavaScript方法对地址进行地理编码。 This method reads the data entered by the user and sends it to the geocode service. 此方法读取用户输入的数据,并将其发送到地址解析服务。 This service takes a few miliseconds to complete. 这项服务需要花费几毫秒的时间才能完成。 As soon as it completes I wish to store the data it has found in the backing bean of the login page. 完成后,我希望将找到的数据存储在登录页面的后备bean中。

The following JavaScript function is used to geocode the address. 以下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);
          }
        });
      }

It stores its value in a hidden field placed inside the form. 它将其值存储在位于表单内部的隐藏字段中。 I do not know whether or not this is the best thing to do, it's simply something I have seen in many examples. 我不知道这是否是最好的方法,这只是我在许多示例中看​​到的。 I assume setting the value of this component will call the corresponding location setter in the loginBean. 我假设设置此组件的值将调用loginBean中的相应位置设置器。

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

I am trying to make this all happen using the button used to submit the form. 我正在尝试使用提交表单的按钮来实现所有这一切。

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

I do have to add that I am unsure of this construction. 我必须补充一点,我不确定这种结构。 Pressing the submit button probably loads the next page right away, without even giving the ajax call a chance. 按下提交按钮可能会立即加载下一页,甚至不会给ajax调用一个机会。

Trying to accomplish this has presented me with several problems. 试图做到这一点给我带来了几个问题。 Using the code above, the JavaScript function is never called. 使用上面的代码,永远不会调用JavaScript函数。 For sake of simplicity I have declared this function at the top of the page in a script tag. 为了简单起见,我在脚本标签的页面顶部声明了此函数。 The second problem is that it is unclear to me what is the best approach to pass this value from a JavaScript method to the loginBean. 第二个问题是,我不清楚将这种值从JavaScript方法传递到loginBean的最佳方法是什么。 Should I place some hidden tag inside the form and link it's value tag to a loginBean property? 我是否应该在表单中放置一些隐藏标签并将其value标签链接到loginBean属性? Should I add a listener to the ajax component? 我应该在ajax组件中添加一个侦听器吗?

The JavaScript callback function of the service should trigger the form submit (on success). 服务的JavaScript回调函数应触发表单提交(成功后)。 This way it would always have time to finish before the submit. 这样一来,提交之前总会有时间完成。

I am assuming you are good with javascript. 我假设您擅长javascript。

You can try a trick. 您可以尝试技巧。

  1. Along with command button use simple html button which would be visible and command button hidden in a div. 与命令按钮一起使用简单的html按钮,该按钮将可见,而命令按钮则隐藏在div中。
  2. When user clicks the simple html button perform your geolocation ajax call, on success and after updating hidden field, simply call javascript to programmatically click the hidden command button. 当用户单击简单的html按钮执行地理定位ajax调用时,成功后以及在更新隐藏字段之后,只需调用javascript以编程方式单击隐藏的命令按钮即可。

Hope this helps. 希望这可以帮助。

The <p:ajax/> is unnecessary and is the root cause why the javascript function isn't called. <p:ajax/>是不必要的,并且是未调用javascript函数的根本原因。 A quick and dirty way to get this done is. 一种快速而肮脏的方法可以完成此任务。 Get rid of <p:ajax/> . 摆脱<p:ajax/> <p:commandButton/> is sufficient for your use case as is. <p:commandButton/>足以满足您的使用情况。

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

Your mode of passing the variable will work, but isn't particularly efficient or secure. 您传递变量的方式可以使用,但是效率不高或不安全。

An alternative use primefaces' javascript api, addSubmitParam , to send the generated values to the backing bean as a request param 另一种方法是使用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);
      }
    });
  }

I would suggest something like: 我建议类似的东西:

<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);
      }
    });
  }

This approach uses PF widgets instead of relying on IDs which can change. 这种方法使用PF小部件,而不是依赖可以更改的ID。

Also, consider using Google address autocomplete API. 另外,请考虑使用Google地址自动填充API。 There is a JSF component for that. 有一个JSF组件。

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

相关问题 从JavaScript + JSF调用Backing bean方法 - Invoke Backing bean method from JavaScript + JSF 使用Primefaces JavaScript在服务器上的bean上调用JSF方法 - Using Primefaces JavaScript to call a JSF method on a bean on the server JSF 1.1-无需页面刷新即可备份bean的调用操作方法(通过ajax / javascript) - JSF 1.1-Calling action method of backing bean without page refresh(through ajax/javascript) 如何仅在加载页面时使用 javascript 调用 JSF 支持 bean 方法 - How to call JSF backing bean method using javascript only when The page is loaded 如何将JavaScript值传递给JSF EL和支持bean? - How to pass JavaScript values to JSF EL and backing bean? 获取JSF支持bean中JavaScript设置的隐藏值 - Get hidden value set by JavaScript in JSF backing bean 如何使用JavaScript将输入表单值以及整个页面HTML源代码传递给后备bean? - How to get the input form values along with whole page HTML source using JavaScript to pass it to backing bean? 使用JavaScript / Ajax排除将表单字段提交到支持Bean - Exclude a form field from being submitted to backing bean using JavaScript/Ajax 在bean jsf中使用javascript变量 - using javascript variable in bean jsf 将JSF(primefaces)托管bean变量传递给javascript函数 - To pass JSF(primefaces) managed bean variable to javascript function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM