ugrás a tartalomhoz

AJAX form post

Jazoja · 2012. Jan. 28. (Szo), 22.55
Van egy HTML FORM-om, amit JS/XMLHttpRequest segítségével szeretném POST-olni.
A FORM nagy mennyiségű dinamikusan generált INPUT CHECKBOX elemet tartalmaz, a felhasználó által kiválasztottak értékeit (value/name?) szeretném elküldeni.

A SEND függvény az alábbi hibával leáll: (Firefox9+FireBug)
  1. Component returned failure code: 0x80460001 (NS_ERROR_CANNOT_CONVERT_DATA)  
  2. XMLHttpRequestObjectForSavingCategories.send(document.forms["categories_form"]);  
A hibával kapcsolatban nem sok infót találtam, de úgy látom függvény STRING-et várna.

Van valami egyszerű módja, hogy a CHECKBOX-ok értékét el tudjam küldeni? (pl. beépített konvertáló függvény)
Vagy jobb ha nekiállok ismerkedni valamely JS keretrendszerrel? (pl. jQuery és társai)
 
1

Ha a kódot mutatnád ami a

Karvaly84 · 2012. Jan. 28. (Szo), 23.18
Ha a kódot mutatnád ami a hibát dobja az többet elárulna, ezek a NS_ERROR meg hasonlók semmit nem árulnak el, csak azt, hogy egy DOM függvényben van a hiba.

Ha a XMLHttpRequestObjectForSavingCategories egy XMLHttpRequest példánya és "POST" kérést akarsz küldeni, akkor nem a form-ot kell neki átadni, mert az egy "object" típus, és a form "submit" eseményéhez kötnék egy eseményfigyelőt, amiben a checkbox-ok értékeit escape-elve név érték párokban tenném a send metódus paraméterébe, és letiltanám a form elküldését.
2

a kód

Jazoja · 2012. Jan. 29. (V), 01.44
Kicsit rövidítettem a nevén. A hibát a .send()-es sorban dobja.
  1. var XHRSaveCats = new XMLHttpRequest();  
  2. function saveCategories()  
  3. {  
  4.     var dataSource = "<?php echo site_url()?>/catUpdate.php";  
  5.     if(XHRSaveCats)   
  6.     {  
  7.         XHRSaveCats.open("POST", dataSource,true);  
  8.         XHRSaveCats.setRequestHeader('Content-Type''multipart/form-data');  
  9.         XHRSaveCats.send(document.forms["categories_form"]);  
  10.         XHRSaveCats.onreadystatechange = function()  
  11.         {  
  12.             if (XHRSaveCats.readyState == 4)  
  13.             {  
  14.                 if (XHRSaveCats.status == 200)   
  15.                 {  
  16.                     var ret = XHRSaveCats.responseText;  
  17.                     alert(ret);  
  18.                 }  
  19.                 else  
  20.                 {  
  21.                     alert("Error code " + XHRSaveCats.status);  
  22.                 }  
  23.             }  
  24.         }  
  25.   
  26.         XMLHttpRequestObjectForSaving.send(null);  
  27.     }  
  28. }  
Így néz ki a generált HTML FORM (egy része) az INPUT CHECKBOX-okkal:
  1. <form action="http://localhost/catUpdate.php" method="post" name="categories_form">  
  2.  <div id="buttons">  
  3.   <button id="SaveCats" title="Kategóriák mentése szerverre" type="button" onclick="saveCategories();">Kategóriák mentése szerverre</button>  
  4.   </div>  
  5.   <div id="div-0">  
  6.    <label>Főkategóriák:</label>  
  7.    <input id="cat-5" type="checkbox" name="Ajándék" value="post" onchange="openCloseSubCategory(5);" checked="">Ajándék  
  8.    <input id="cat-124" type="checkbox" name="Aktuális" value="post" onchange="openCloseSubCategory(124);">Aktuális  
  9.    <input id="cat-1" type="checkbox" name="Egyéb" value="post" onchange="openCloseSubCategory(1);" checked="">Egyéb  
  10.    <input id="cat-25" type="checkbox" name="Nincs kategorizálva" value="post" onchange="openCloseSubCategory(25);">Nincs kategorizálva  
  11.    <input id="cat-131" type="checkbox" name="Összes" value="post" onchange="openCloseSubCategory(131);">Összes  
  12.  </div>  
  13. </form>  
3

Na hát ez számomra több

Karvaly84 · 2012. Jan. 29. (V), 08.45
Na hát ez számomra több helyen is vérzik!

1. var dataSource = "<?php echo site_url()?>/catUpdate.php";
Ide valami épkézláb URL kell, nem pedig PHP echo mert azt max. a szerver oldalon írja ki a PHP, ez pedig a böngészőben fut.

2. XHRSaveCats.setRequestHeader('Content-Type', 'multipart/form-data');
helyett pl.: XHRSaveCats.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');

3. XHRSaveCats.send(document.forms["categories_form"]);
A send() metodust arra használhatod "POST" kérésnél hogy a "query string"-et teszed bele amikor küldöd a kérést. egy ilyesmire gondolok:
ajandek=true&aktualis=false
A form elemek "name" attributumában ne használj ékezetet, és az értékeket pl a encodeURIComponent() függvény segítségével escape-eld.

Most megiszom a reggeli kávém, aztán a HTML kódodra mutatok egy szebb megoldást, ha addig nem sikerül.

Ui.: egyébként a XMLHttpRequestObjectForSaving.send(null); mit csinál?

Ui.: Ui.: Az onreadystatchange eseménykezelőt az open() metódus hívása elött állítsd be, a te kódodban nincs jelentősége, de az open() kiváltja az "readystataechange" eseményt.
5

1. var dataSource = "<?php

kuka · 2012. Jan. 29. (V), 16.18
1. var dataSource = "<?php echo site_url()?>/catUpdate.php";
Ide valami épkézláb URL kell, nem pedig PHP echo mert azt max. a szerver oldalon írja ki a PHP, ez pedig a böngészőben fut.
Nincs azzal semmi gond, elvégre a PHP echo is kiírhat épkézláb URL-t. Azaz, ahogy a PHP generálhat HTML-t, úgy generálhat JavaScriptet is. (Persze feltéve, hogy az adott kód át is halad a PHP értelmezőn.)
6

Egy működő kódot módosítottam

Jazoja · 2012. Jan. 29. (V), 16.31
Csak néhány gyors válasz, aztán átnézem a kódod.

1. var dataSource = "<?php echo site_url()?>/catUpdate.php";
Ide valami épkézláb URL kell, nem pedig PHP echo mert azt max. a szerver oldalon írja ki a PHP, ez pedig a böngészőben fut.

Konkrétan itt PHP->JS adatátadás történik, azaz az oldal generálásakor teszi oda az URL-t. Ez WP alatt van, nekem műkszik.

3. XHRSaveCats.send(document.forms["categories_form"]);
A send() metodust arra használhatod "POST" kérésnél hogy a "query string"-et teszed bele amikor küldöd a kérést. egy ilyesmire gondolok:
ajandek=true&aktualis=false

Volt már működő kódom, amivel adatokat kértem le szerverről, hogy mit azt meg url-ben kódoltam. Egy ilyen működőt kezdtem áthegeszteni és valami módot keresni arra, hogy ne kelljen nekem JS-el végigmenni a DOM-on és a FORM elemeit kivadászva átalakítani egy URL kódolt formába.
Sima FORM-ot küldésekor (hagyományos AJAX nélküli módon) a FORM összes elemét automatikusan bekódolja (gondolom a böngésző).

Ui.: egyébként a XMLHttpRequestObjectForSaving.send(null); mit csinál?

Asszem ezzel zárja be a kapcsolatot.
4

Na valami ilyesmit

Karvaly84 · 2012. Jan. 29. (V), 11.04
Na valami ilyesmit kéne:
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"  
  3.     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">  
  4. <html xmlns="http://www.w3.org/1999/xhtml">  
  5. <head>  
  6. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
  7. <title>Post request with XMLHttpRequest</title>  
  8. </head>  
  9. <body>  
  10.     <form action="http://localhost/catUpdate.php" method="post"  
  11.         id="categories_form" name="categories_form">  
  12.         <div id="buttons">  
  13.         <!--  
  14.         Feltételezem HTML5-ben írtad a kódot. A button elem nem illik egy form  
  15.         űrlap elembe.  
  16.           
  17.         Az alábbi type="button" helyett type="submit", az ugyanis kiváltja  
  18.         az űrlapon a "submit" eseményt amit elkapunk, ennek hatására dolgozzuk  
  19.         fel az űrlapot, így megoldható, hogy kikapcsolt JavaScript esetén is  
  20.         működjün az űrlap.  
  21.            
  22.         <button id="SaveCats" title="Kategóriák mentése szerverre" type="button"  
  23.                 onclick="saveCategories();">Kategóriák mentése szerverre</button>  
  24.         -->  
  25.         <input id="SaveCats" title="Kategóriák mentése szerverre" type="submit"  
  26.             value="Kategóriák mentése szerverre" />  
  27.         </div>  
  28.         <div id="div-0">  
  29.             <!--  
  30.             A label elemet egy kijelölt űrlapelemhez szokás használni.  
  31.             Pl. minden input elemhez külön-külön.  
  32.               
  33.             <label>Főkategóriák:</label>  
  34.             -->  
  35.             <p>  
  36.                 Főkategóriák:  
  37.                 <input class="savedCategorie" type="checkbox" name="Ajandek" value="5" />  
  38.                 Ajándék  
  39.                 <input class="savedCategorie" type="checkbox" name="Aktualis" value="124" />  
  40.                 Aktuális  
  41.                 <input class="savedCategorie" type="checkbox" name="Egyeb" value="1" />  
  42.                 Egyéb  
  43.                 <input class="savedCategorie" type="checkbox" name="NincsKategorizalva" value="25" />  
  44.                 Nincs kategorizálva  
  45.                 <input class="savedCategorie" type="checkbox" name="Osszes" value="130" />  
  46.                 Összes   
  47.             </p>  
  48.         </div>  
  49.     </form>  
  50.     <script type="text/javascript">  
  51.     var categories, savedCategories, XHRSaveCats, i;  
  52.       
  53.     categories = document.getElementById("categories_form");  
  54.       
  55.     savedCategories = categories.getElementsByClassName("savedCategorie");  
  56.       
  57.     // Ez a funkció gondolom kinyitja/bezárja az alkategoriákat.  
  58.     function openCloseSubCategory() {  
  59.         if (this.checked) {  
  60.             console.log("Open " + this.value + ". sub categorie!");  
  61.         } else {  
  62.             console.log("Close " + this.value + ". sub categorie!");  
  63.         }  
  64.     }  
  65.       
  66.     for (i = 0; i < savedCategories.length; i++) {  
  67.         savedCategories[i].addEventListener("change", openCloseSubCategory, false);  
  68.     }  
  69.       
  70.     ////////////////////////////////////////////////////////////////////////////  
  71.     // Űrlap feldolgozás  
  72.     ////////////////////////////////////////////////////////////////////////////  
  73.       
  74.     // Az XHR objektum "readystatechange" eseményéhez.  
  75.     function checkReadyState() {  
  76.         var ret;  
  77.         if (this.readyState === 4 && this.status === 200) {  
  78.             ret = this.responseText;  
  79.             console.log("Response: " + ret);  
  80.         }  
  81.     }  
  82.       
  83.     // Az XHR objektum send() metódusához.  
  84.     function createQueryString(query) {  
  85.         var str = "", k;  
  86.         for (k in query) {  
  87.             if (query.hasOwnProperty(k)) {  
  88.                 if (str) {  
  89.                     str += "&";  
  90.                 }  
  91.                 str += k + "=" + encodeURIComponent(query[k]);  
  92.             }  
  93.         }  
  94.         return str;  
  95.     }  
  96.       
  97.     XHRSaveCats = new XMLHttpRequest();  
  98.       
  99.     function saveCategories(event) {  
  100.         var param = {}, i;  
  101.         event.preventDefault();  
  102.         for (i = 0; i < savedCategories.length; i++) {  
  103.             if (savedCategories[i].checked) {  
  104.                 param[savedCategories[i].name] = "true";  
  105.             } else {  
  106.                 param[savedCategories[i].name] = "false";  
  107.             }  
  108.         }  
  109.         console.log("POST request: " + (param = createQueryString(param)));  
  110.         XHRSaveCats.onreadystatechange = checkReadyState;  
  111.         XHRSaveCats.open("POST", categories.action, true);  
  112.         XHRSaveCats.setRequestHeader("Content-Type",  
  113.             "application/x-www-form-urlencoded");  
  114.         XHRSaveCats.send(param);  
  115.     }  
  116.       
  117.     categories.addEventListener("submit", saveCategories, false);  
  118.     </script>  
  119. </body>  
  120. </html>  
7

Lépésről-lépésre 1.

Jazoja · 2012. Jan. 29. (V), 17.50
A következő módosításokat csináltam (eddig):

1. átírtam a gombot, és eltávolítottam a "onClick" részt
  1. <button type='button' onClick="saveCategories();">  
  1. <input type='submit'>  
2. a FORM-ra akasztok egy eseménykezelőt, ami SUBMIT eseménynél meghívja a "saveCategories" függvényt
  1. var categories = document.getElementById("categories_form");  
  2. categories.addEventListener("submit", saveCategories, false);  
3. ami az eseményt az "event" paraméteren veszi át, és rögtön kikapcsolom az alap eseményt (hogy ne POST-olja és írányítsa át az oldalt)
  1. function saveCategories(event)  
  2. {  
  3.   event.preventDefault();  
  4.   ...  
  5. }  
folyt. köv.
8

Lépésről-lépésre 2.

Jazoja · 2012. Jan. 30. (H), 22.02
4. Az összes INPUT CHECKBOX közös osztályba kerül (ez nálam "catCB")
5. mentés előtt lekérem az összes ilyen osztályba tartozó elemet
  1. catCBs = categories.getElementsByClassName("catCB");  
6. majd egy for ciklussal összeállítok egy stringet
  1. var CatsInURLmessage="";  
  2. for (var i=0; i<catCBs.length;i++)  
  3. {  
  4.   if(catCBs[i].checked==true)  
  5.     CatsInURLmessage+=catCBs[i].value+"="+catCBs[i].checked+"&";  
  6. }  
7. nyitok egy kapcsolatot a FORM "action" tagjában szereplő címhez
  1. XHRSaveCats.open("POST", categories.action,true);  
8. és elküldöm az üzenetet
  1. XHRSaveCats.send(CatsInURLmessage);  
9. amit szerver oldalon már fel tudok dolgozni
  1. foreach($_POST as $cat=>$state)  
  2. {  
  3.   if($state == "true")  
  4.   {  
  5.     $categories[$i]=$cat;  
  6.     $i++;  
  7.   }  
  8. }  
Kérdés:
A kiválasztott kategóriák azonosítóit nem lehet elküldeni csak egy sima tömbként?
9

A kiválasztott kategóriák

Karvaly84 · 2012. Jan. 31. (K), 13.08
A kiválasztott kategóriák azonosítóit nem lehet elküldeni csak egy sima tömbként?

Mit értesz "azonosító" alatt?

Hasznos linkek:

XMLHttpRequest.send() - Nem tanulmányoztam mélyen, mert eddig nem volt ilyenekre szükségem, de van lehetőség a send() metódusban object típusú adatot átadni.

FormData()
10

Azonosítók tömbként

Jazoja · 2012. Feb. 1. (Sze), 14.19
Mit értesz "azonosító" alatt?

Az INPUT CHECKBOX "value" mezőjében tárolt értéket (egész szám).
A szervernek igazából csak ezekre a számokra (wordpress post kategória azonosító) van szüksége.

Jelenleg <id>=<value> párokban küldöm az adatokat URL-be kódolva, ami kb így néz ki:
localhost/catUpdate.php?1=true&53=true&12=true&...
Itt a <value> effektíve felesleges, mert csak a "true" (azaz bejelölt CHECKBOX) értékeket küldök, minden <id> mellé.

De nekem ez is elég lenne: 1,53,12,...
vagy valami JS tömb, a kategóriák azonosítóival, amit utána PHP POST már tud kezelni.

A .send() fgv.-t majd este átnézem.