Передача данных формы через JavaScript в вспомогательный компонент с использованием JSF и простых лиц

Я пытаюсь обработать несколько строк входных данных, используя метод JavaScript, в котором используется служба геокодирования, предоставленная Google, и помещаю обработанные данные в резервный компонент.

Пользователям предоставляется страница входа, на которой они вводят свои адресные данные. Как только нажимается кнопка отправки, я пытаюсь геокодировать их адрес, вызывая метод JavaScript. Этот метод считывает введенные пользователем данные и отправляет их в службу геокодирования. Выполнение этой службы занимает несколько миллисекунд. Как только он завершится, я хочу сохранить данные, которые он нашел, в компоненте поддержки страницы входа.

Следующая функция 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?


person malebox    schedule 26.02.2013    source источник
comment
Это опечатка или у вас действительно onstart="codeAddress"? Если это замените это на onstart="codeAddress()".   -  person partlov    schedule 26.02.2013
comment
Извините, это действительно была опечатка.   -  person malebox    schedule 26.02.2013
comment
@malebox, если ваш js не вызывается, это означает, что вы не включили его должным образом на свою страницу <h:outputScript name="js/myFile.js" target="head" />, поместите файл js в папку WebContent\resource   -  person Daniel    schedule 26.02.2013
comment
@Daniel, OP говорит, что его js определен в поле зрения   -  person kolossus    schedule 26.02.2013


Ответы (4)


Функция обратного вызова JavaScript службы должна инициировать отправку формы (в случае успеха). Таким образом, у него всегда будет время закончить до отправки.

person Christophe Roussy    schedule 26.02.2013

Я предполагаю, что вы хорошо разбираетесь в javascript.

Вы можете попробовать трюк.

  1. Наряду с командной кнопкой используйте простую html-кнопку, которая будет видна, а командная кнопка скрыта в div.
  2. Когда пользователь нажимает простую кнопку html, выполните вызов ajax для геолокации, в случае успеха и после обновления скрытого поля просто вызовите javascript, чтобы программно нажать кнопку скрытой команды.

Надеюсь это поможет.

person baba.kabira    schedule 26.02.2013

<p:ajax/> не нужен и является основной причиной, по которой функция javascript не вызывается. Быстрый и грязный способ сделать это. Избавьтесь от <p:ajax/>. <p:commandButton/> достаточно для вашего варианта использования как есть.

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

Ваш режим передачи переменной будет работать, но не особенно эффективен или безопасен.

В качестве альтернативы можно использовать javascript API Primefaces, addSubmitParam, для отправки сгенерированных значений в вспомогательный компонент в качестве параметра запроса.

    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);
      }
    });
  }
person kolossus    schedule 26.02.2013

Я бы предложил что-то вроде:

<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 вместо того, чтобы полагаться на идентификаторы, которые могут меняться.

Кроме того, рассмотрите возможность использования API автозаполнения адресов Google. Для этого есть компонент JSF.

person rootkit    schedule 26.02.2013