// 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 + '
');
}
}
// 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 (, ,
,
) sous IE
* (le innerHTML sur un
ne fonctionne pas correctement sous IE6)
*/
function PFW_customInnerHTML(id_dest, html)
{
is_table_content= false;
var dest= document.getElementById(id_dest);
// Si l'element dont on doit rafraichir le contenu n'est pas present dans la page, on retourne false
if(!dest)
{
return false;
}
// On detecte le type de balise de l'element dont on doit rafraichir le contenu
// On recherche une balise de type table pour adapter le comportement de la fonction
destTagName= dest.tagName.toLowerCase();
if(destTagName=='table' || destTagName=='tr' || destTagName=='tbody' || destTagName=='thead' || destTagName=='tfoot')
{
is_table_content= true;
}
// L'element dont on doit rafraichir le contenu est effectivement de type table ...
if(is_table_content)
{
// On récupère le type de la première balise du contenu HTML a insérer
var res= html.match(/<([a-z]+)/i);
if(res && res[1])
{
balise= res[1];
}
// S'il n'y a aucune balise on assimile le cas à celui de la balise TD
else
{
balise= 'td';
}
var content;
// On recréée une table complète à partir du code HTML a insérer
if(balise== 'td')
{
content='
'+ html +'
';
}
else if(balise== 'tr')
{
content='
'+ html +'
';
}
else
{
content='
'+ html +'
';
}
// On crée un élément temporaire qui autorise l'usage de innerHTML pour lui insérer via cette méthode, la table recréée précedemment
// Le but de cette manipulation est d'obtenir une table qui soit parsable en DOM
var container= document.createElement("div");
container.innerHTML= content;
// On parcourt desormais en DOM le sous arbre DOM ainsi obtenu à la recherche du contenu que l'on doit insérer
// (l'équivalent DOM en fait du code html passé à la fonction PFW_customInnerHTML)
var to_see=container;
var found= null;
while(to_see!=null)
{
var elem= to_see;
to_see= null;
for (var i=0;i0)
{
dest.removeChild(dest.childNodes[0]);
}
// On ajoute dans l'element que l'on doit rafraichir les noeuds DOM du contenu HTML passés à la fonction
while(src.childNodes.length>0)
{
dest.appendChild(src.childNodes[0]);
}
}
// On n'a pas trouvé le noeud qui contient notre code html à ajouter, on poursuit la recherche ...
else if(elem.childNodes[i].getAttribute("way_to_container")=="yes")
{
to_see= elem.childNodes[i];
}
}
}
}
// Si le contenu HTML a insérer n'est pas de type table, on utilise la méthode innerHTML classique
else
{
dest.innerHTML= html;
}
}