23. november 2008 - 03:06Der er
41 kommentarer og 2 løsninger
HTML form og javascript
Hej gutter,
Nu har jeg søgt google igennem og har ikke fundet frem til noget helt brugbart endnu.
Jeg har brug for at lave en form på min side. I denne form skal der ved et af text input field være en knap man kan trykke på hvorefter info om hvad der er skrevet ind i dette field bliver sendt til et popup vindue (som jeg så har et script kørende i der tager info via fx post eller get). I popup vindue vil man så få resultat tilbage med 3 forskellige info der skal placeres i 3 af de andre text fields tilbage på den første side.
Man kan f.eks. ha' en side med en masse sql udtræk, og for ikke at loade den igen, kan det være nyttigt at ha' f.eks. en side som ændrer på siden der submittes fra.
En løsning kan jo være ren javascript, uden en popup. En anden er at bruge en iframe, og submitte til den, så undgås også popup, hvilket som regel jo er "pain in the ass"
Nu er det et php script som skal køres ud fra hvad der indtastes i det input field.
Hvis man kan gøre det uden et popup vindue.. Så er det fint med mig. Jeg søger bare at i kan smide et eksempel til mig på hvordan det gøres i form af koden jf. de forskellige input fields og osv.
Artiklen på w3schools.com er - som langt de fleste andre af hans artikler/tutorials - forvrøvlet og fyldt med alvorlige fejl, mangler og udeladelser. Faktisk har artiklen kun meget lidt med Ajax at gøre! :o|
cyfer >> I princippet kan du skrive sådan i dit HTML-dokument:
<script type="text/javascript"> (function(){if(window.XMLHttpRequest)return;var o=null,s,a=["MSXML2.XMLHTTP.6.0", "MSXML2.XMLHTTP.3.0","Msxml2.XMLHTTP","Microsoft.XMLHTTP"];for(var i=0,j=a.length;i<j;s=a[i],i++){try{if(o=new ActiveXObject(s))break}catch(e){}}window.XMLHttpRequest=o?function(){return new ActiveXObject(s)}:null;o=null})();
function AjaxTransport(sQuery, sUrl, fnCallBack) { var me = this; this.oHttp = new XMLHttpRequest(); this.oHttp.open("post", sUrl, true); this.oHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8"); this.oHttp.onreadystatechange = function(){ fnCallBack.apply(me) }; this.oHttp.send(sQuery); }
function getInfo() { var oInp = document.getElementById("inp"); var sQuery = "contxt=getInfo&input=" + encodeURIComponent(oInp.value); new AjaxTransport(sQuery, "ajax_response.php", myCallBack); }
function myCallBack() { if (this.oHttp.readyState<4) return; if (this.oHttp.status!=200) return alert("Could not connect to server document."); var oResp = eval("("+this.oHttp.responseText+")"); if (oResp.error) return alert(oResp.error);
- og sådan i dit PHP-dokument (ajax_response.php):
<?php function getInfo($oJson, $input) { // Brug $input til at hente/beregne // informationer, der skal returneres // og læg dem i et array på json-objektet: $oJson->info = array("Info #1", "Info #2", "Info #3"); }
// Opret et tomt objekt: $oJson = new stdClass;
if (isset($_POST["contxt"])) { switch ($_POST["contxt"]) { case "getInfo": getInfo($oJson, $_POST["info"]); break;
default: $oJson->error = "Context not known."; } } else $oJson->error = "Context not supplied.";
Klientkoden er ikke 'ægte' OOP, men vi kommer ud i en lang omgeng, hvis det skal laves helt 'efter bogen'. Det funker og er skrevet i så valid kode, som det kan. Dog må du som altid selv sørge for sikkerhed på serveren ;o)
Hej olebole, mange tak - det var lige det jeg søgte. Et eksempel som jeg kunne leje og lære med. Jeg er dog ikke 100% med på hvordan jeg får implementeret min egen php med din.
På nuværende tidspunkt ryger info #1,2,3 jo tilbage til felterne lige gyldigt hvad der står i felt 1. Jeg forstår ikke helt hvor infoen om hvad der er i felt 1 er henne og hvordan jeg får den tjekket op med mit script. Jeg går ud fra at jeg blot skal erstatte de arrays oppe i toppen med det som mit script så returnerer..
Jeg har ingen anelse om, hvad du skal gøre, da jeg jo ikke ved, hvorfra dine informationer kommer. Derfor skrev jeg kommentaren:
// Brug $input til at hente/beregne // informationer, der skal returneres // og læg dem i et array på json-objektet:
$input indeholder det, der står i dit felt. Det er derfor blot at bruge den til at hente/beregne de informationer, der skal returneres.
De tre stk. info, du får ud af at bearbejde $input, skal så bare lægges som de tre elementer i array'et: $oJson->info = array("Info #1", "Info #2", "Info #3");
Skriver brugeren "Øl, isse og horn-i-panden" i det første felt, kommer der altså til at stå: "Øl, isse og horn-i-panden: noget" "Øl, isse og horn-i-panden: noget andet" "Øl, isse og horn-i-panden: noget tredie"
- i dine tre felter. Håber, det forklarer lidt bedre =)
Jeg har brugt JSON ( http://json.org/ ) til at returnere data. Når jeg udskriver den JSON-encodede datastreng i PHP-dokumentet, ser den således ud (med det foregående eksempel): {"info": ["Øl, isse og horn-i-panden: noget", "Øl, isse og horn-i-panden: noget andet", "Øl, isse og horn-i-panden: noget tredie"]}
De variabler, jeg sender med til serveren, sætter jeg her: var oInp = document.getElementById("inp"); var sQuery = "contxt=getInfo&input=" + encodeURIComponent(oInp.value);
Med variablen 'contxt' fortæller jeg serverscriptet, hvad det er for en handling, jeg gerne vil have det til at udføre.
Variablen 'input' er det, brugeren har skrevet i input-feltet - encoded på passende vis med JS-funktionen 'encodeURIComponent'.
I scriptet påserveren tjekker jeg, hvad det er, der skal gøres ved den aktuelle forespørgsel:
// Tjek først, om der overhovedet er sat en contxt-variabel. // Ellers gå til 'else' og returner en fejl if (isset($_POST["contxt"])) { // Tjek, hvad det er, klienten vil have foretaget switch ($_POST["contxt"]) { case "getInfo": getInfo($oJson, $_POST["info"]); break;
default: $oJson->error = "Context not known."; } } else $oJson->error = "Context not supplied.";
Du kan med andre ord bruge det samme dokument 'ajax_response.php' til mange forskellige forespørgsler. Du tilføjer bare ekstra cases til switch'en - og foretager dig noget i overensstemmelse med værdien af den medsendte contxt-variabel
Heh nej det ved du jo selvfølgelig ikke.. Men det som jeg ligesom ikke kunne finde ud af var faktisk at jeg ikke syntes at $input returnerede noget som helst ... :\ Er helt med på at få de korrekte info sat ind i de arrays der.. Men det kræver jo som sagt at jeg kan beregne inputtet fra felt 1.. Hvilket jeg ikke synes jeg kan.
Kan du prøve at give et eksempel på at der ved teksten "mintest" i felt 1 skal returneres noget tekst og eller ikke returneres noget... Så kan jeg nok nemmere gennemskue din logik :)
Prøv eksemplet fra (23/11-2008 15:08:54) og se, om ikke du får returneret det, som du skriver i input-feltet - plus de tre strenge. Husk, det er vigtigt, feltet har den korrekte id - eller at du retter linjen: var oInp = document.getElementById("inp");
- og husk, det _skal_ være en id attribut ... _ikke_ en name attribut ;o)
Jeg kan også vise dig et andet eksempel, hvis det gør det nemmere. Jeg forudsætter, du har en DB-tabel med brugere - og at brugeren skal hente informationer om en brstemt bruger ved at indtaste hans brugernavn:
function getInfo($oJson, $input) { // Brug $input til at hente/beregne // informationer, der skal returneres // og læg dem i et array på json-objektet: $sql = "SELECT `sex`, `age`, `height` FROM `TABEL_NAVN` WHERE `username`='".$input."'"; $res = @mysql_query($sql); if (mysql_error()!=0) { $oJson->error = "Database request error: " . mysql_error(); return; } $row = mysql_fetch_assoc($res); $oJson->info = array($row["sex"], $row["age"], $row["height"]); }
Jeg er overhovedet ikke med på hvordan jeg trækker det rene data ud som bruger har indtastet i felt 1 på form siden. Alt det andet med hvor jeg skal indsætte de data der skal returneres er jeg helt med på.. Det er blot det brugerindtastede tekst jeg ikke fatter hvor jeg får fra.
Jeg ved godt at du forsøger at lære mig noget ved ikke at give mig den "færdige løsning". Men personligt får jeg mere ud af at kunne se hvordan det skal se ud og lære fra det og så modificere det til det jeg skal bruge det til i sidste ende.
Nej, faktisk er jeg nu slet ikke så pædagogisk i denne situation. Jeg kan bare ikke give dig en tydeligere eller mere færdig løsning, da jeg ikke ved, hvad det er, du skal gøre. Jeg kender stadig ikke applikation - og forholdene omkring din informations hentning =)
Dette skrev jeg egentlig før din seneste kommentar og kopierede teksten, da jeg så, du havde kommenteret. Nu paster jeg det lige ind igen ... det ser ud, somom du er på rette vej ;o)
PS: Grunden til, jeg ikke skriver: $res = mysql_query($sql) or die (mysql_error());
- er, at man jo aldrig ser PHP-dokumentet direkte. Derfor undertrykker jeg en evt. fejl med '@' - og behandler den efterfølgende, så vores klient kan bruge fejlen:
Nej du kan selvfølgelig ikke begynde at lave løsninger for mig jf. det script jeg selv sidder og roder med.. Men det er heller ikke det jeg søger, jeg kan sagtens rode rundt med det selv. Mit problem er at jeg ikke kan få lov til at beregne det input der kommer fra textfield 1 på form siden.
Jeg prøver fx meget simpelt at teste om der er noget i $input ved at lade den sende det skrevne tilbage til et af felterne.. Og feltet er bare tomt :\
function getInfo($oJson, $input) { // Brug $input til at hente/beregne // informationer, der skal returneres // og læg dem i et array på json-objektet: $oJson->info = array($input, "tekst1", "test2"); }
Indsæt denne alert i AjaxTransport: this.oHttp.onreadystatechange = function(){ fnCallBack.apply(me) }; alert(sQuery); this.oHttp.send(sQuery);
- og denne i myCallBack: if (this.oHttp.readyState<4) return; if (this.oHttp.status!=200) return alert("Could not connect to server document."); alert(this.oHttp.responseText); var oResp = eval("("+this.oHttp.responseText+")");
PS: Husk, at navnet i POST-array'et kommer fra denne linje: var sQuery = "contxt=getInfo&input=" + encodeURIComponent(oInp.value);
Ordet 'input' i strengen, er altså det, der definerer navnet i POST-array'et ... ikke name eller id på feltet. Id på feltet bruges kun i java script: var oInp = document.getElementById("inp");
- men det sendes ikke med til serveren. Kan det mon være dér, fejlen ligger? =)
Hvis jeg nu kigger på dit eksempel med mysql database opslag på $input. Der gør du jo ikke andet end at få den til at kigge i $input..... Er der intet i $input variablen eller hvad er det du siger? Det forstår jeg ikke.
Selvtak - og undskyld, min manglende test bragte os derud! :o|
Anyway, så er det ofte bøvlet at debugge serverscriptet i Ajax applikationer. Selvom vi aldrig nåede dertil, skal du lige have et tip. Du kan bruge dennne debug/log funktion i et Ajax response dokument:
Den kan du bruge flere steder - f.eks: case "getInfo": logMyError("Post-variablen info i switchen: ".$_POST["info"]); getInfo($oJson, $_POST["info"]); break;
- og: function getInfo($oJson, $input) { logMyError("Variablen input i getInfo: ".$input);
Det var, da jeg før sad og skrev dette - og mere præcist det sidste eksempel - at jeg opdagede fejlen ;o)
Nu, vi har fundet fejlen, vil jeg i øvrigt gerne vise en anden version af PHP-funktionen:
function getInfo($oJson, $input) { // Brug $input til at hente/beregne // informationer, der skal returneres // og læg dem i et array på json-objektet: $sql = "SELECT `sex`, `age`, `height` FROM `TABEL_NAVN` WHERE `username`='".$input."'"; $res = @mysql_query($sql); if (mysql_error()!=0) { $oJson->error = "Database request error: " . mysql_error(); return; } $oJson->info = mysql_fetch_object($res); }
Så kommer JSON-strengen til at se sådan ud: {"info": {"sex":"m", "age":53, "height":183}}
- hvilket betyder, du i stedet for et array, skal behandle et objekt på klienten: document.getElementById("info_1").value = oResp.info.sex; document.getElementById("info_2").value = oResp.info.age; document.getElementById("info_3").value = oResp.info.height;
- og man kunne vel passende udvide med: if (mysql_num_rows($res)>0) $oJson->info = mysql_fetch_object($res); else $oJson->error = "Could not find a match in database.";
PS: Husk, at du aldrig må slå op i en DB med et direkte bruger input. Der skal på en eller anden måde sikres mod SQL-injections ;o)
Jamen jeg takker i hvertfald mange gange. Kan så oplyse at jeg slet ikke slår op i en mysql database men sidder med en preg_match forespørgsel på et .txt dokument.
Og du får hermed point som du har fortjent. Jeg tror jeg er godt kørende nu men skal nok spørge igen hvis der er noget :)
Ja, gør endelig det. Under alle omstændigheder kom vi da meget godt rundt, så du også vil kunne bruge Ajax til MySQL-forspørgsler (hvis du altså gemmer adressen til tråden). Tak for points ;o)
Når du engang skal til at hente data og skrive det ind i mere komplekse HTML-strukturer (tabelrækker eller 'klumper' af andre elementer), bør du gøre på samme måde. Undgå (af mange grunde) at udskrive HTML på serveren og indsætte med innerHTML på klienten. I stedet bør data stadig formateres i JSON (eller evt. XML) på serveren og indsættes med DOM på klienten.
Spørg, når/hvis du engang kommer dertil - og meget gerne med en reference til denne tråd, så jeg ved, hvad vi har været igennem ;o)
Hmm jeg ved at serveren sender header som iso-8859-1.. Men denne skulle jeg gerne lave om på mine sider med meta's. Jeg kan ikke se hvor jeg skulle gøre noget galt.
Følgende der har noget at gøre med tegnsætning at gøre, har jeg på html siden der udfører scriptet:
<<??>?xml version="1.0" encoding="utf-8"?> // Ekstra tegn fordi det er en php side... <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <script src="includes/scripts/ajax_lookup.js" type="text/javascript" charset="utf-8"></script>
Jeg burde vel være dækket ind? Har ikke noget på selve .js siden, men det burde vel ikke have noget at sige?
Hmmm... Jeg har lige tjekket op på skidtet igen.. Jeg prøvede lige at sætte en æøå tekst manuelt ind i array der bliver sendt tilbage til javascriptet.. Og der virkede fint.. Så det må være undervejs i min hentning af data.. Endten i preg_match fortolkningen eller i txt. dokumentet (som btw. er et "plain text document (text/plain)" ifølge properties. Ved ikke om det kan være der fejlen ligger?
Nå ja, så fik jeg rettet det. Jeg fik lige tjekket op på mit .txt dokument som var som du antydede iso-8859-1. Fik åbnet op for det i bluefish og rettet det til. Hvordan kan det være at det hele skal være utf-8 egentlig, bare af ren nysgærighed.. :)
Unicode i form af utf-8 dækker langt de fleste sprog og deres 'sære' specialbogstaver, mens ANSI i form af iso-8859-1 dækker de skandinaviske.
ANSI funktionerne til encoding af URL'er blev deprecated i JavaScript 1.5 og erstattet af Unicode funktioner. Derfor er iso-8859-1 de facto deprecated - og specielt i Ajax sammenhæng, hvor man er afhængig af URL-encoding via JS
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.