// Cette variable globale est utilisée par le mécanisme de cache de la PFW_Ajax_classe // Elle permet d'utiliser un système de cache global (non dépendant de l'objet PFW_AJAX instancié) à toute la page jusqu'à son rafraichissement var PFW_AjaxCache = new Array(); /** * Constructeur de la classe PFW_AJAX * @url : l'url du fichier php contenant la requete a executer **/ function PFW_AJAX(url) { //*************************** // Attributs de la classe //*************************** this.xmlhttp = false; this.url = url; this.parametres = false; this.id_champ = false; this.submitMethod = "post"; this.Mode = "asynchronous"; this.ResponseType = "text"; this.Response = false; this.isAjaxMessage = false; this.isIE = document.all; this.CacheMode = 'inactive'; this.isResponseInCache = false; //*************************** //*************************** // Instanciation des Attributs //*************************** /*@cc_on @*/ /*@if (@_jscript_version >= 5) // JScript gives us Conditional compilation, we can cope with old IE versions. // and security blocked creation of the objects. try { this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { this.xmlhttp = false; } } @end @*/ if (!this.xmlhttp && typeof XMLHttpRequest!='undefined') { this.xmlhttp = new XMLHttpRequest(); } //*************************** } /** * Definition des methodes de la classe PFW_AJAX **/ PFW_AJAX.prototype = { //*************************** // Définition des geters //*************************** getUrl : function() { return this.url; }, getParametres : function() { return this.parametres; }, getIdChamp : function() { return this.id_champ; }, getsubmitMethod : function() { return this.submitMethod; }, getMode : function() { return this.Mode; }, getResponseType : function() { return this.ResponseType; }, getResponse : function() { return this.Response; }, getCacheMode : function() { return this.CacheMode; }, getFromCache : function() { var index; var argv = this.getFromCache.arguments; if (argv.length > 0) { index = argv[0]; } else { index = (this.getsubmitMethod() == "post")? this.getUrl()+"?"+this.getParametres() : this.getUrl(); } return (PFW_AjaxCache[index]) ? PFW_AjaxCache[index] : false; }, //*************************** // Définition des seters //*************************** setUrl : function(url) { this.url = url; }, setParametres : function(parametres) { this.parametres = parametres; }, setIdChamp : function(id) { this.id_champ = id; }, setsubmitMethod : function(submitMethod) { this.submitMethod = submitMethod; }, setMode : function(Mode) { this.Mode = Mode; }, setResponseType : function(responseType) { this.ResponseType = responseType; }, setCacheMode : function(mode) { this.CacheMode = mode; }, addIntoCache : function() { var index; var argv = this.addIntoCache.arguments; if (argv.length > 0) { index = argv[0]; } else { index = (this.getsubmitMethod() == "post")? this.getUrl()+"?"+this.getParametres() : this.getUrl(); } PFW_AjaxCache[index] = (this.getResponse() instanceof PFW_AJAX_Message) ? this.getResponse().getResponseFromServer() : this.getResponse(); }, /** * Fonction qui recoit la reponse a une requete precedemment envoyée **/ setResponse : function() { // 1) Aucune requete n'a été soumise car la réponse se trouve dans le cache if ( this.isResponseInCache ) { this.Response = this.getFromCache(); } // 2) On obtient la réponse suite à une requette HTTP au serveur else { if (this.xmlhttp.readyState == 4) { if (this.xmlhttp.status == 200) { // Autodetection d'une réponse XML si le response_type a été laissé à sa valeur par défaut // ... alors que la reponse recue est bien de type XML if (this.isIE && this.getResponseType() == 'text' && this.xmlhttp.responseXML.firstChild != null) { this.setResponseType('xml'); } else { if (!this.isIE && this.getResponseType() == 'text' && this.xmlhttp.responseXML != null) { this.setResponseType('xml'); } } switch (this.getResponseType()) { case 'readyState': this.Response = this.xmlhttp.readyState; break; case 'text': //on effectue l'equivalent d'un trim() en JS pour supprimer tout caractere special en debut de chaine this.Response = this.xmlhttp.responseText.replace(/(^\s*)|(\s*$)/g, ""); // Si le cache est activé, on stocke le retour dans un tableau associatif if(this.getCacheMode()=='auto') { this.addIntoCache(); } break; case 'xml': /* test de sécurité firefox multi domaine */ try { this.xmlhttp.responseXML.firstChild.tagName; domdoc = this.xmlhttp.responseXML; } catch(e) { domdoc = (new DOMParser()).parseFromString(this.xmlhttp.responseText,"text/xml"); } // On vérifie la présence d'erreur dans la réponse xml if ( domdoc==null || (domdoc.parseError && domdoc.parseError.errorCode !=0) || domdoc.getElementsByTagName('*').length==0 || domdoc.firstChild.tagName== "parsererror" || this.xmlhttp.responseText.replace(/(^\s*)/, "").substr(0,5)!="<"+"?xml" ) // Si la réponse ne peut pas être interprétée comme du XML valide, on la traite comme une chaine de texte ... { this.setResponseType('text'); this.Response = this.xmlhttp.responseText; } // ... sinon else { //on effectue l'equivalent d'un trim() pour supprimer tout caractere special dans l'arbre xml this.Response = PFW_clean(domdoc); // Si le cache est activé, on stocke le retour dans un tableau associatif if(this.getCacheMode()=='auto') { this.addIntoCache(); } } break; case 'status': this.Response = this.xmlhttp.status; break; case 'onreadystate': this.Response = this.xmlhttp.onreadystate; break; case 'statusText ': this.Response = this.xmlhttp.onreadystate; break; } } else { return false; } } else { return false; } } // 3) Si j'ai bien obtenu ma reponse (du cache OU du serveur) if (this.getResponse()) { // 3.1) Autodetection d'une réponse XML si le response_type a été laissé à sa valeur par défaut // ... alors que la reponse recue est bien de type XML if (this.getResponseType() == 'text' && this.Response.firstChild != null) { this.setResponseType('xml'); } // 3.2) Auto détection d'une trame ajax message dans le cas ou la réponse est de type XML if (this.getResponseType() == 'xml') { if(this.getResponse().getElementsByTagName("message").length > 0 && this.getResponse().getElementsByTagName("message")[0].getAttribute("type") == "PFW_ajax_message") { this.isAjaxMessage = true; this.Response = new PFW_AJAX_Message(this.Response); } } } // 4) On execute le traitement post Réponse this.traitement(); }, /** * Fonction qui effectue une requete HTTP * @cache : active le cache lors de l'envoi de la requete [non obligatoire] **/ HTTPrequest : function() { // 1) On s'assure que la fonction pour l'attente lors du traitement n'a pas été désactivée if (this.action_debut_ATTENTE != false) { this.action_debut_ATTENTE(); } var cacheActif = false; // 2) On teste si le cache a été activé dans le mode manual if (this.getCacheMode()=='manual') { var argv = this.HTTPrequest.arguments; if (argv.length > 0) { cacheActif = (argv[0] == true)? true : false; } } // 3) Si le cache est activé et qu'on trouve l'url dans le cache if ( ( this.getCacheMode()=='auto' || (this.getCacheMode()=='manual' && cacheActif)) && this.getFromCache()) { this.isResponseInCache = true; this.setResponse(); } // 4) Sinon on realise une requete HTTP else { var mode = (this.Mode == "asynchronous")? true : false; if (this.submitMethod == 'post') { this.xmlhttp.open("POST", this.url, mode); if (this.parametres!='') { this.xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); this.xmlhttp.send(this.parametres); } else { this.xmlhttp.send(null); } var refToThis = this; this.xmlhttp.onreadystatechange = function () {refToThis.setResponse();} } } }, /** * Fonction Javascript de traitement de la réponse à une requete XMLHttpRequest **/ traitement : function() { // On s'assure que la fonction pour le traitement de la réponse n'a pas été désactivée if (this.action_OK != false) { switch (this.getResponseType()) { case 'text': this.action_OK(); break; case 'xml': // 1 - Si la réponse est de type "PFW_ajax_message" ... if(this.isAjaxMessage) { // ... on verifie que le traitement s'est bien déroulé sur le serveur et on appelle action_OK if (this.getResponse().getError_code() == "0") { this.action_OK(); } // ... sinon on appelle action_ERREUR else { this.action_ERREUR(); } // Si j'ai un noeud debug dans le message, j'affiche son contenu if (this.getResponse().getDebug() && this.getIdChamp()) { PFW_customInnerHTML(this.getIdChamp() , document.getElementById(this.getIdChamp()).innerHTML + '
DEBUG' +this.getResponse().getDebug() + '
'); } } // 2 - Sinon on appelle la fonction pour le traitement de la réponse else { this.action_OK(); } break; default : this.action_OK(); break; } } // On s'assure que la fonction pour l'attente lors du traitement n'a pas été désactivée if (this.action_fin_ATTENTE != false) { this.action_fin_ATTENTE(); } }, /** * Fonction Javascript appelée automatiquement lors du traitement de la réponse à une requete XMLHttpRequest si celle-ci est OK **/ action_OK : function() { //alert('actionok'); switch (this.getResponseType()) { case 'text': PFW_customInnerHTML(this.getIdChamp() , this.getResponse()); break; case 'xml': if (this.isAjaxMessage) { if (Number(this.getResponse().getVersion()) < 3) { PFW_customInnerHTML(this.getIdChamp() , this.getResponse().getHTML_content()); } else { var tab_HTML_content = this.getResponse().getHTML_content(); if (tab_HTML_content != false) { for (var i=0; i // pour firefox c'est la racine du xml, en l'occurence // on stocke dans xml_message le sous-arbre qui commence à la racine message en fonction du navigateur this.xml_message = xml; } /** * Definition des methodes de la classe PFW_AJAX_Message **/ PFW_AJAX_Message.prototype = { /** * getResponseFromServer **/ getResponseFromServer : function() { return this.xml_message; }, /** * getXMLMessage **/ getXMLMessage : function() { return (this.xml_message.childNodes[0].nodeName != 'message')? this.xml_message.childNodes[1] : this.xml_message.childNodes[0]; }, /** * getVersion **/ getVersion : function() { return (this.getXMLMessage().getAttribute("version") != null)? this.getXMLMessage().getAttribute("version") : false; }, /** * getError_code **/ getError_code : function() { var return_value; switch (this.getVersion()) { case "1": return_value = (this.getXMLMessage().getElementsByTagName("error_code")[0].firstChild != null)? this.getXMLMessage().getElementsByTagName("error_code")[0].firstChild.nodeValue : false; break; case "2" || "3": return_value = (this.getXMLMessage().firstChild.getElementsByTagName("error_code")[0].firstChild != null)? this.getXMLMessage().firstChild.getElementsByTagName("error_code")[0].firstChild.nodeValue : false; break; default: return_value = (this.getXMLMessage().getElementsByTagName("error_code")[0].firstChild != null)? this.getXMLMessage().getElementsByTagName("error_code")[0].firstChild.nodeValue : false; break; } return return_value; }, /** * getError_message **/ getError_message : function() { var noeud_ERRORMESSAGE_content; var return_value; switch (this.getVersion()) { case "1": noeud_ERRORMESSAGE_content = (this.getXMLMessage().getElementsByTagName("error_message")[0].firstChild != null)? this.getXMLMessage().getElementsByTagName("error_message")[0] : false; break; case "2" || "3": noeud_ERRORMESSAGE_content = (this.getXMLMessage().firstChild.getElementsByTagName("error_message").length > 0)? this.getXMLMessage().firstChild.getElementsByTagName("error_message")[0] : false; break; default: noeud_ERRORMESSAGE_content = (this.getXMLMessage().getElementsByTagName("error_message")[0].firstChild != null)? this.getXMLMessage().getElementsByTagName("error_message")[0] : false; break; } // On teste que le message contient bien un Debug_content if (noeud_ERRORMESSAGE_content) { return_value = this.getContentNodeAsString(noeud_ERRORMESSAGE_content); } else { return_value = false; } return return_value; }, /** * getHTML_content **/ getHTML_content : function() { var noeud_HTML_content; var return_value = ''; switch (this.getVersion()) { case "1": noeud_HTML_content = (this.getXMLMessage().getElementsByTagName("HTML_content").length > 0)? this.getXMLMessage().getElementsByTagName("HTML_content")[0] : false; break; case "2" : noeud_HTML_content = (this.getXMLMessage().childNodes[1].getElementsByTagName("HTML_content").length > 0)? this.getXMLMessage().childNodes[1].getElementsByTagName("HTML_content")[0] : false; break; case "3": noeud_HTML_content = (this.getXMLMessage().childNodes[1].getElementsByTagName("HTML_content").length > 0)? this.getXMLMessage().childNodes[1].getElementsByTagName("HTML_content") : false; break; default: noeud_HTML_content = (this.getXMLMessage().getElementsByTagName("HTML_content").length > 0)? this.getXMLMessage().getElementsByTagName("HTML_content")[0] : false; break; } // On teste que le message contient bien un HTML_content if (noeud_HTML_content) { if (Number(this.getVersion()) < 3) { return_value = this.getContentNodeAsString(noeud_HTML_content); } else { var tab_HTML_content = new Array(); for (var i=0; i 0)? this.getXMLMessage().getElementsByTagName("XML_content")[0] : false; break; case "2" || "3": noeud_XML_content = (this.getXMLMessage().childNodes[1].getElementsByTagName("XML_content").length > 0)? this.getXMLMessage().childNodes[1].getElementsByTagName("XML_content")[0] : false; break; default: noeud_XML_content = (this.getXMLMessage().getElementsByTagName("XML_content").length > 0)? this.getXMLMessage().getElementsByTagName("XML_content")[0] : false; break; } // On teste que le message contient bien un XML_content if (noeud_XML_content) { // 1) On detecte le format du XML : string ou XML // On récupère le premier fils du noeud XML_content, on teste son type (3 = text, 1 = xml) // Si c'est une string : on essaie de la transformer en objet XML document if (noeud_XML_content.firstChild.nodeType == 3) { var chaineXML = this.getContentNodeAsString(noeud_XML_content); // On transforme la chaineXML en objet XML Document // code for IE if (window.ActiveXObject) { var return_value = new ActiveXObject("Microsoft.XMLDOM"); return_value.async = "false"; // si le xml est mal formé, on retourne false if(!return_value.loadXML(chaineXML)) { return_value = false; } } // code for Mozilla, Firefox, Opera, etc. else { var parser=new DOMParser(); var return_value=parser.parseFromString(chaineXML,"text/xml"); } } // 2) Dans le cas XML on renvoie le sous arbre contenu dans XML_content else { return_value = noeud_XML_content; } } else { return_value = false; } return return_value; }, /** * getDebug **/ getDebug : function() { var noeud_DEBUG_content; var return_value; switch (this.getVersion()) { case "1": noeud_DEBUG_content = (this.getXMLMessage().getElementsByTagName("debug").length > 0)? this.getXMLMessage().getElementsByTagName("debug")[0] : false; break; case "2" || "3": noeud_DEBUG_content = (this.getXMLMessage().firstChild.getElementsByTagName("debug").length > 0)? this.getXMLMessage().firstChild.getElementsByTagName("debug")[0] : false; break; default: noeud_DEBUG_content = (this.getXMLMessage().getElementsByTagName("debug").length > 0)? this.getXMLMessage().getElementsByTagName("debug")[0] : false; break; } // On teste que le message contient bien un Debug_content if (noeud_DEBUG_content) { return_value = this.getContentNodeAsString(noeud_DEBUG_content); } else { return_value = false; } return return_value; }, /** * getContentNodeAsString **/ getContentNodeAsString : function(node) { var return_value = ''; // Pour parer au probleme de Firefox et Opera qui eclatent les contenus de plus de 4ko (ou 32ko pour Opera) dans une collection de noeuds ... // ... , on detecte le nombre des noeuds qui stockent les données retournées par le serveur ... // ... , si on est en présence d'une collection : on la parcourt en concaténant le contenu de chacun de ses éléments // ... , si on est en presence d'un seul noeud, on retourne le contenu de celui-ci // ... , si on est en presence d'un noeud vide, on retourne une chaine vide if (node.childNodes.length > 1) { for(i=0; i< node.childNodes.length; i++) { return_value += node.childNodes[i].nodeValue; } } else { if (node.childNodes.length == 1) { return_value = node.firstChild.nodeValue; } else { return_value = ""; } } return return_value; } } /***************************************************************************************************/ /***************************************************************************************************/ /** * Transforme un formulaire en un objet Javascript contenant le nom des champs * ainsi que pour chacun leur(s) valeur(s). Est prévu pour gérer les champs de type radio , * checkbox , listbox (avec choix multiples possibles) en les traitant uniquement * dans le cas ou au moins une valeur a été spécifiées pour un élément de formulaire. * Ne traite pas les éléments de type submit , reset ou button. * * @En entree : prend l'id du formulaire a traiter * * @Retourne un objet JavaScript avec une propriété pour chaque champ du formulaire à soumettre. * La valeur de chaque propriété de l'objet est un tableau contenant une ou plusieurs valeurs à soumettre */ function PFW_getFormValuesAsMap(id_form) { var params = new Object(); var inputs = document.getElementById(id_form).elements; for (var i=0; i