die SP-Ajax-Schnittstelle verwenden

Begonnen von dobra, Januar 16, 2010, 23:36:42

« vorheriges - nächstes »

0 Mitglieder und 1 Gast betrachten dieses Thema.

dobra

Ich möchte versuchen, die Verwendung der SP-Ajax-Schnittstelle anhand eines einfachen Beispiel zu erklären.

Die Aufgabe:
um zu vermeiden, dass sich Kunden mehrfach registrieren können, soll geprüft werden, ob die e-mail-Adresse bereits in der DB vorhanden ist.
wenn "nein" -> neuer Kunde ->  das Anmeldeformular wird normal abgesendet
wenn "ja" -> Kunde ist bereits registriert -> Anmeldeformular wird nicht abgesendet und Kunde bekommt einen entsprechende Meldung angezeigt



Für die Verwendung von Ajax-Funktionen muss der Ordner "ajax" mit den darin enthaltenen Dateien
   *  http/Request.js
   * JSON/Converter.pm
   * JSON/Parser.pm
   * json.js
   * JSON.pm
im Projektverzeichnis vorhanden sein und diese Dateien im WorkCenter in die "Dateien hinzufügen" Liste eingetragen sein.   
(dieser Ordner kann hier http://www.shoppilot.net/pf/index.php?topic=1371.msg4860#msg4860 runtergeladen werden)
mit
      <script type="text/javascript" src="../ajax/json.js"></script>
      <script type="text/javascript" src="../ajax/http/Request.js"></script>
in allen Vorlagen einbinden, in denen Ajax-Funktionen verwendet werden sollen.
Das braucht nur EINMAL eingebunden werden, egal wie viele unterschiedliche Funktionen dann verwendet werden.
(ist also z.B. ajaxsearch bereits installiert, sind diese Dateien bereits verfügbar und brauchen nicht nochmal eingebunden werden)

Damit stellt ShopPilot alle nötigen Voraussetzungen für die Verwendung von AJAX zur Verfügung.



Um jetzt eine Ajax-Funktion zu bauen, braucht man 3 Dateien die im Ajax-Ordner abgelegt werden:
name.html
name.js
name ipl

1) name.html enthält nichts außer
<!--spmacro:include(ajax/name.ipl)-->
Diese HTML-Datei bindet also die zugehörige .ipl Datei in die Seite auf der sie verwendet werden soll ein.
Dazu wird eine Infoseite mit beliebigem Namen angelegt und als Vorlage "name.html" eingetragen.

Der Aufruf in der Vorlage erfolgt über
<script type="text/javascript">
// Server-URL für die Ajax-Abfragen
var myname = "__xxpath__?ajax1200001280,__xxsession__";
</script>

wobei die Variablenname (var myname) wieder frei wählbar ist, als Seitennummer (im Beispiel 1200001280) ist hier DIE der neu angelegten Infoseite mit Vorlage "name.ipl" einzutragen.

2) name.js
Diese Datei enthält den JS-Teil der Funktion und muss mit
<script type="text/javascript" src="../ajax/name.js"></script>
in die Vorlage auf der diese Funktion verwendet werden soll, eingebunden werden.

3) name.ipl
hier werden die übergebenen Variablen entgegen genommen, verarbeitet und das Ergebnis zurück gegeben.
gearbeitet wird hier mit SSP
es können DB-Abfragen gemacht oder auch DB-Eiträge neu angelegt, geändert oder gelöscht werden.
Dazu aber später

"name" kann frei gewählt werden.
Es ist aber sinnvoll, allen 3 Dateien den selben Namen (einen möglichts aussagekräftigen, was diese Funktion machen soll) zu geben,
damit man, wenn man mal 10 oder 20 verschiedene Funktionsdateien hier liegen hat, diese auch später noch finden/zuordnen kann.

Für unser Beispiel nennen wir diese Dateien also mal
checkmail.html, checkmail.js und checkmail.ipl
und die Variable des Funktionsaufrufs
var mycheckmail = "__xxpath__?ajax1200001280,__xxsession__";
ACHTUNG! der Name ist frei wählbar - darf aber NICHT der selbe sein, wie der Funktionsname, mit dem die Funktion dann aufgerufen wird!
(Nachdem ich die Funktion "checkmail" nennen werden, verwende ich hier "mycheckmail")


Jetzt schauen wir uns mal die .js Datei näher an

// Wird aufgerufen wenn Formular abgesendet
var re = false;
function checkmail(){

if (-1 != mycheckmail.search(/__xxpath__\?/)) {
     return;
 }
 
 var mailaddress = document.getElementById('reg_mail').value;
 
 var postdata = {
method : 'testMail',
id : 0,
params : [mailaddress]
};
try {
req = new HTTP.Request(
{
uri: mycheckmail,
postbody: postdata.toJSONString(),
onSuccess: function (trans) {
var data;
try {
data = eval('('+trans.responseText+')'); // JSON "parsen"
} catch(e) {
return;  
}

var result = data['_testMail']; //Resultat der DB-Abfrage - Wenn 1 dann mail nicht eingetragen _> also neuer Kunde  
 
if (result == 0){  
document.getElementById("errortext").innerHTML = 'Sie haben bereits ein Kundenkonto unter dieser e-mail registriert!';
 re = false;
}
if (result == 1){
 re = true;
document.getElementById('loginF').submit();
}

}      
});
 
}
catch(e)
{
return;
}
if(re == true){
return true;
}
else{
return false;
}
}


function checkmail()  -> die Funktionsname, mit der die Funktion bei klick auf "Formular absenden" aufgerufen wird

if (-1 != mycheckmail.search(/__xxpath__\?/)) {
     return;
 }

 -> Abbruch, wenn die Ajax-Funktion nicht korrekt eingebunden ist
 
uri: mycheckmail,
(mycheckmail  -> der Variablennamr den wir bei der Server-URL für die Ajax-Abfragen verwendet haben)
 
var mailaddress = document.getElementById('reg_mail').value;  -> "reg_mail" ist die e-mail Input-Feld ID im Registrierungsformular

var postdata = {
      method : 'testMail',
      id : 0,
      params : [mailaddress]
   };

   
method : -> wird zum Aufruf in der ipl Datei gebraucht
params : -> die aus dem Formular übergebenen Parameter
wenn man mehrere Parameter übergeben will, werden diese mit "," getrennt - [param1, param2, param3]   

var result = data['_testMail'];

"_testMail" -> mit dieser Variablen wird das Resultat der DB-Abfrage aus der ipl Datei übergeben.

            if (result == 0){              
             document.getElementById("errortext").innerHTML = 'Sie haben bereits ein Kundenkonto unter dieser e-mail registriert!';
              re = false;
            }
            if (result == 1){
              re = true;
               document.getElementById('loginF').submit();
            }


hier wird definiert, was passieren soll, wenn das zurückgegebene Resultat 0 oder 1 ist

0 -> die e-mail Adresse steht bereits in der DB - also das Anmeldformular NICHT abschicken und Fehlermelding ausgeben (re = false;)
"errortext" -> die ID des div in dem der Meldungstext auf der Formularseite ausgegeben werden soll (inline-Fehlermeldung)

Anmerkung: wenn man die Meldung als alert ausgegeben will:
            if (result == 0){              
             alert('Sie haben bereits ein Kundenkonto unter dieser e-mail registriert!');
              re = false;
            }


1 -> e-mail noch nicht in DB - neuer Kunde - alsses OK - Anmeldeformular absenden (re = true;)
"loginF" -> ID des submit-Button


und jetzt die ipl Datei:

<!--spmacro:module()                    
push(@INC,'ajax');
require "JSON.pm";

print "Content-Type: text/plain;charset=ISO-8859-1\n\n";
#use utf8;
my $pCall = JSON::jsonToObj($main::input);
my %result;
$result{_call} = $pCall;

if ($pCall->{method} eq 'testMail') {
 $result{_testMail} = 1;
 
 my $mail =  $pCall->{params}[0];
 
 my $USRTBL = ssp::db_get_prefix() . "USR";
 my $sql = qq|SELECT EMAIL FROM $USRTBL WHERE EMAIL='$mail'|;
 
 my $read = ssp::readSQLData($sql, "count");
 if ($read){
   if(ssp::get_var_db("count", 0)){
     #e-mail bereits vorhanden
     $result{_testMail} = 0;
   }
}  
}

print JSON::objToJson(\%result);
exit 0;
-->

            
push(@INC,'ajax');
require "JSON.pm";

print "Content-Type: text/plain;charset=ISO-8859-1\n\n";
#use utf8;
my $pCall = JSON::jsonToObj($main::input);
my %result;
$result{_call} = $pCall;

Dieser Teil steht in allen Ajax-Funktions ipl und hier darf NICHTS verändert werden!!!

if ($pCall->{method} eq 'testMail') { -> dieses Script soll bei method : 'testMail' ausgeführt werden.
siehe
var postdata = {
      method : 'testMail',
in der js Datei
(mit dieser eindeutigen Definition können beliebig viele unterschiedliche Script auf dieser ipl Seite hinterlegt und je nach JS-Zuordnung einzeln ausgeführt werden)

 $result{_testMail} = 1;
das zurückgegebene Ergebnis ist hier mit "1" definiert (-> Antragsformular normal absenden)

my $mail =  $pCall->{params}[0];  -> Übergabe die eingetippte MailAdresse aus Formular

werden mehrere Parameter übergeben, können diese (in der Reihenfolge wie sie - mit "," getrennt - übergeben werden, mit
my $parameter2 =  $pCall->{params}[1];
my $parameter3 =  $pCall->{params}[2];
u.s.w.
ausgelesen werden.

 my $USRTBL = ssp::db_get_prefix() . "USR";
 my $sql = qq|SELECT EMAIL FROM $USRTBL WHERE EMAIL='$mail'|;
 
     my $read = ssp::readSQLData($sql, "count");
     if ($read){
       if(ssp::get_var_db("count", 0)){
         #e-mail bereits vorhanden
         $result{_testMail} = 0;
       }

-> die DB-Abfrage
wenn e-mail Adresees bereits eingetragen ist, zurückgegebenes Resultat auf "0" setzen.


So, jetzt fehlt nur noch die HTML-Vorlage (im Beispiel das Registrierungsformular)   

Wie oben schon beschrieben, muss hier mal die Ajax-Funktion eingebunden werden
      <script type="text/javascript">
       // Server-URL für die Ajax-Abfragen
       var mycheckmail = "__xxpath__?ajax1200001280,__xxsession__";
      </script>
      <script type="text/javascript" src="../ajax/checkmail.js"></script>

      
und - wenn noch nicht vorhanden - auch
      <script type="text/javascript" src="../ajax/json.js"></script>
      <script type="text/javascript" src="../ajax/http/Request.js"></script>


der Formtag muß dann eine ID bekommen und die bei Absenden (onsubmit) die js-Funktion aufgerufen werden
   <form id="loginF" method="post" action="__UDC__" onSubmit="return checkmail();">

Anmerkung: eine Ajax-Funktion kann mit jedem beliebigen Event-Handler (onclick, onload, onchange usw) oder auch per Link aufgerufen werden.

<input name="eMail" id="reg_mail" value="__eMail__"> -> ID "reg_mail" - siehe übergebene Variable var reg_mail = document.getElementById('reg_mail').value; in der js-Datei
<div id="errortext" class="inputerror"></div> -> id="errortext" - hier wird der Meldungstext ausgegeben, wenn Formular nicht abgesendet wird
siehe document.getElementById("errortext").innerHTML = 'Sie haben bereits ein Kundenkonto unter dieser e-mail registriert!';

Das ist jetzt nur mal ein ganz einfaches Beispiel zur Dokumentation - als "Einstiegsdroge" sozusagen ;)
Wenn Sie sich die ajaxsearch-Scripte anschauen, bekommen Sie einen kleinen Einblick, was da alles möglich ist.
Aber ich hoffe, mit dieser Anleitung mal die Grundfunktion einer Ajax-Anwendung verständlich gemacht zu haben.

Tipp:  wer Firebug noch nicht installiert, sollte das unbedingt tun!
(kostenloses Firefox Add-on - gibt's z.B. hier https://addons.mozilla.org/de/firefox/addon/1843)
Hier kann dann in der Konsole kontrolliert werden, welche POSTs gesendet und Antworten zurückgegeben werden.
mfG
dobra