Melewati data formulir melalui JavaScript ke backing bean menggunakan JSF dan primefaces

Saya mencoba memproses beberapa baris data masukan, menggunakan metode JavaScript yang menggunakan layanan geocoding yang disediakan Google, dan menempatkan data yang diproses tersebut ke dalam backing bean.

Pengguna disajikan dengan halaman login di mana mereka memasukkan rincian alamat mereka. Segera setelah tombol kirim diklik, saya mencoba melakukan geocode alamat mereka dengan memanggil metode JavaScript. Metode ini membaca data yang dimasukkan oleh pengguna dan mengirimkannya ke layanan geocode. Layanan ini memerlukan waktu beberapa milidetik untuk diselesaikan. Segera setelah selesai saya ingin menyimpan data yang ditemukan di backing bean halaman login.

Fungsi JavaScript berikut digunakan untuk melakukan geocode alamat.

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

Ia menyimpan nilainya di bidang tersembunyi yang ditempatkan di dalam formulir. Saya tidak tahu apakah ini yang terbaik untuk dilakukan atau tidak, ini hanya sesuatu yang saya lihat di banyak contoh. Saya berasumsi pengaturan nilai komponen ini akan memanggil penyetel lokasi yang sesuai di loginBean.

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

Saya mencoba mewujudkan semua ini menggunakan tombol yang digunakan untuk mengirimkan formulir.

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

Saya harus menambahkan bahwa saya tidak yakin dengan konstruksi ini. Menekan tombol kirim mungkin akan langsung memuat halaman berikutnya, bahkan tanpa memberi kesempatan pada panggilan ajax.

Mencoba mencapai hal ini telah memberi saya beberapa masalah. Dengan menggunakan kode di atas, fungsi JavaScript tidak pernah dipanggil. Demi kesederhanaan saya telah mendeklarasikan fungsi ini di bagian atas halaman dalam tag skrip. Masalah kedua adalah tidak jelas bagi saya pendekatan apa yang terbaik untuk meneruskan nilai ini dari metode JavaScript ke loginBean. Haruskah saya menempatkan beberapa tag tersembunyi di dalam formulir dan menautkan tag nilainya ke properti loginBean? Haruskah saya menambahkan pendengar ke komponen ajax?


person malebox    schedule 26.02.2013    source sumber
comment
Apakah ini kesalahan pengetikan atau Anda memang mengalami onstart="codeAddress"? Jika sudah ganti ini dengan onstart="codeAddress()".   -  person partlov    schedule 26.02.2013
comment
Maaf, itu memang salah ketik.   -  person malebox    schedule 26.02.2013
comment
@malebox jika js Anda tidak dipanggil berarti Anda belum memasukkannya dengan benar di halaman Anda <h:outputScript name="js/myFile.js" target="head" /> , letakkan file js di folder WebContent\resource   -  person Daniel    schedule 26.02.2013
comment
@Daniel, OP mengatakan js-nya didefinisikan dalam tampilan   -  person kolossus    schedule 26.02.2013


Jawaban (4)


Fungsi panggilan balik JavaScript dari layanan harus memicu pengiriman formulir (jika berhasil). Dengan cara ini akan selalu ada waktu untuk menyelesaikannya sebelum diserahkan.

person Christophe Roussy    schedule 26.02.2013

Saya berasumsi Anda mahir dengan javascript.

Anda bisa mencoba sebuah trik.

  1. Seiring dengan tombol perintah gunakan tombol html sederhana yang akan terlihat dan tombol perintah disembunyikan dalam div.
  2. Ketika pengguna mengklik tombol html sederhana, lakukan panggilan ajax geolokasi Anda, jika berhasil dan setelah memperbarui bidang tersembunyi, cukup panggil javascript untuk mengklik tombol perintah tersembunyi secara terprogram.

Semoga ini membantu.

person baba.kabira    schedule 26.02.2013

<p:ajax/> tidak diperlukan dan merupakan penyebab utama mengapa fungsi javascript tidak dipanggil. Cara cepat dan kotor untuk menyelesaikan ini adalah. Singkirkan <p:ajax/>. <p:commandButton/> sudah cukup untuk kasus penggunaan Anda apa adanya.

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

Cara Anda meneruskan variabel akan berhasil, tetapi tidak terlalu efisien atau aman.

Alternatifnya gunakan api javascript primefaces, addSubmitParam, untuk mengirim nilai yang dihasilkan ke backing bean sebagai parameter permintaan

    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

Saya akan menyarankan sesuatu seperti:

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

Pendekatan ini menggunakan widget PF daripada mengandalkan ID yang dapat berubah.

Selain itu, pertimbangkan untuk menggunakan API pelengkapan otomatis alamat Google. Ada komponen JSF untuk itu.

person rootkit    schedule 26.02.2013