1 // A plugin that wraps all ajax calls introducing a fixed callback function on ajax complete
2 if(!jQuery
.load_handlers
) {
3 jQuery
.load_handlers
= new Array();
5 // Add a function to the list of those to be executed on ajax load complete
7 function onAjaxLoad(f
) {
8 jQuery
.load_handlers
.push(f
);
12 // Call the functions that have been added to onAjaxLoad
14 function triggerAjaxLoad(root
) {
15 for ( var i
= 0; i
< jQuery
.load_handlers
.length
; i
++ )
16 jQuery
.load_handlers
[i
].apply( root
);
19 // jQuery uses _load, we use _ACBload
20 jQuery
.fn
._ACBload
= jQuery
.fn
.load
;
22 jQuery
.fn
.load = function( url
, params
, callback
) {
24 callback
= callback
|| function(){};
26 // If the second parameter was provided
29 if ( params
.constructor == Function
) {
30 // We assume that it's the callback
35 var callback2 = function(res
,status
) {triggerAjaxLoad(this);callback
.call(this,res
,status
);};
37 return this._ACBload( url
, params
, callback2
);
40 jQuery
._ACBajax
= jQuery
.ajax
;
42 jQuery
.ajax = function(type
) {
43 var s
= jQuery
.extend(true, {}, jQuery
.ajaxSettings
, type
);
44 var callbackContext
= s
.context
|| s
;
45 //If called by _load exit now because the callback has already been set
46 if (jQuery
.ajax
.caller
==jQuery
.fn
._load
) return jQuery
._ACBajax( type
);
47 var orig_complete
= s
.complete
|| function() {};
48 type
.complete = function(res
,status
) {
49 // Do not fire OnAjaxLoad if the dataType is not html
50 var dataType
= type
.dataType
;
51 var ct
= (res
&& (typeof res
.getResponseHeader
== 'function'))
52 ? res
.getResponseHeader("content-type"): '';
53 var xml
= !dataType
&& ct
&& ct
.indexOf("xml") >= 0;
54 orig_complete
.call( callbackContext
, res
, status
);
55 if(!dataType
&& !xml
|| dataType
== "html") triggerAjaxLoad(document
);
57 return jQuery
._ACBajax(type
);
62 // animation du bloc cible pour faire patienter
63 jQuery
.fn
.animeajax = function(end
) {
64 this.children().css('opacity', 0.5);
65 if (typeof ajax_image_searching
!= 'undefined'){
66 var i
= (this).find('.image_loading');
67 if (i
.length
) i
.eq(0).html(ajax_image_searching
);
68 else this.prepend('<span class="image_loading">'+ajax_image_searching
+'</span>');
70 return this; // don't break the chain
73 // s'il n'est pas totalement visible, scroller pour positionner
74 // le bloc cible en haut de l'ecran
75 // si force = true, scroller dans tous les cas
76 jQuery
.fn
.positionner = function(force
) {
77 var offset
= jQuery(this).offset();
78 var hauteur
= parseInt(jQuery(this).css('height'));
79 var scrolltop
= self
['pageYOffset'] ||
80 jQuery
.boxModel
&& document
.documentElement
[ 'scrollTop' ] ||
81 document
.body
[ 'scrollTop' ];
82 var h
= jQuery(window
).height();
85 if (force
|| offset
['top'] - 5 <= scrolltop
)
86 scroll
= offset
['top'] - 5;
87 else if (offset
['top'] + hauteur
- h
+ 5 > scrolltop
)
88 scroll
= Math
.min(offset
['top'] - 5, offset
['top'] + hauteur
- h
+ 15);
91 .animate({scrollTop
: scroll
}, 300);
93 // positionner le curseur dans la premiere zone de saisie
94 jQuery(jQuery('*', this).filter('input[type=text],textarea')[0]).focus();
95 return this; // don't break the chain
98 // deux fonctions pour rendre l'ajax compatible Jaws
99 var virtualbuffer_id
='spip_virtualbufferupdate';
100 function initReaderBuffer(){
101 if (jQuery('#'+virtualbuffer_id
).length
) return;
102 jQuery('body').append('<p style="float:left;width:0;height:0;position:absolute;left:-5000;top:-5000;"><input type="hidden" name="'+virtualbuffer_id
+'" id="'+virtualbuffer_id
+'" value="0" /></p>');
104 function updateReaderBuffer(){
105 var i
= jQuery('#'+virtualbuffer_id
);
106 if (!i
.length
) return;
107 // incrementons l'input hidden, ce qui a pour effet de forcer le rafraichissement du
108 // buffer du lecteur d'ecran (au moins dans Jaws)
109 i
.attr('value',parseInt(i
.attr('value'))+1);
112 // rechargement ajax d'un formulaire dynamique implemente par formulaires/xxx.html
113 jQuery
.fn
.formulaire_dyn_ajax = function(target
) {
116 return this.each(function() {
117 var cible
= target
|| this;
118 jQuery('form:not(.noajax,.bouton_action_post)', this).each(function(){
120 var leclk
,leclk_x
,leclk_y
;
121 jQuery(this).prepend("<input type='hidden' name='var_ajax' value='form' />")
123 beforeSubmit: function(){
124 // memoriser le bouton clique, en cas de repost non ajax
128 if (n
&& !leclk
.disabled
&& leclk
.type
== "image") {
129 leclk_x
= leform
.clk_x
;
130 leclk_y
= leform
.clk_y
;
133 jQuery(cible
).addClass('loading').animeajax();
135 success: function(c
){
137 // le serveur ne veut pas traiter ce formulaire en ajax
138 // on resubmit sans ajax
139 jQuery("input[name=var_ajax]",leform
).remove();
140 // si on a memorise le nom et la valeur du bouton clique
141 // les reinjecter dans le dom sous forme de input hidden
142 // pour que le serveur les recoive
145 if (n
&& !leclk
.disabled
) {
146 jQuery(leform
).prepend("<input type='hidden' name='"+n
+"' value='"+leclk
.value
+"' />");
147 if (leclk
.type
== "image") {
148 jQuery(leform
).prepend("<input type='hidden' name='"+n
+".x' value='"+leform
.clk_x
+"' />");
149 jQuery(leform
).prepend("<input type='hidden' name='"+n
+".y' value='"+leform
.clk_y
+"' />");
153 jQuery(leform
).ajaxFormUnbind().submit();
156 var recu
= jQuery('<div><\/div>').html(c
);
157 var d
= jQuery('div.ajax',recu
);
161 .removeClass('loading')
163 var a
= jQuery('a:first',recu
).eq(0);
165 && a
.is('a[name=ajax_ancre]')
166 && jQuery(a
.attr('href'),cible
).length
){
168 if (jQuery(a
,cible
).length
)
169 setTimeout(function(){
170 jQuery(a
,cible
).positionner(true);
172 //window.location.hash = a[1];
176 jQuery(cible
).positionner(false);
177 if (a
.length
&& a
.is('a[name=ajax_redirect]')){
179 jQuery(cible
).addClass('loading').animeajax();
180 setTimeout(function(){
181 document
.location
.replace(a
);
185 // on le refait a la main ici car onAjaxLoad intervient sur une iframe dans IE6 et non pas sur le document
186 triggerAjaxLoad(cible
);
187 // mettre a jour le buffer du navigateur pour aider jaws et autres readers
188 updateReaderBuffer();
191 iframe
: jQuery
.browser
.msie
193 .addClass('noajax') // previent qu'on n'ajaxera pas deux fois le meme formulaire en cas de ajaxload
199 // permettre d'utiliser onclick='return confirm('etes vous sur?');' sur un lien ajax
200 var ajax_confirm
=true;
201 var ajax_confirm_date
=0;
202 var spip_confirm
= window
.confirm
;
203 function _confirm(message
){
204 ajax_confirm
= spip_confirm(message
);
207 ajax_confirm_date
= d
.getTime();
211 window
.confirm
= _confirm
;
213 // rechargement ajax d'une noisette implementee par {ajax}
214 // avec mise en cache des url
215 var preloaded_urls
= {};
216 var ajaxbloc_selecteur
;
217 jQuery
.fn
.ajaxbloc = function() {
221 return this.each(function() {
222 jQuery('div.ajaxbloc',this).ajaxbloc(); // traiter les enfants d'abord
223 var blocfrag
= jQuery(this);
225 var on_pagination = function(c
) {
228 .removeClass('loading');
229 var a
= jQuery('a:first',jQuery(blocfrag
)).eq(0);
231 && a
.is('a[name=ajax_ancre]')
232 && jQuery(a
.attr('href'),blocfrag
).length
){
234 setTimeout(function(){
235 jQuery(a
,blocfrag
).positionner(true);
237 //window.location.hash = a[1];
241 jQuery(blocfrag
).positionner(false);
243 updateReaderBuffer();
246 var ajax_env
= (""+blocfrag
.attr('class')).match(/env-([^ ]+)/);
247 if (!ajax_env
|| ajax_env
==undefined) return;
248 ajax_env
= ajax_env
[1];
249 if (ajaxbloc_selecteur
==undefined)
250 ajaxbloc_selecteur
= '.pagination a,a.ajax';
252 jQuery(ajaxbloc_selecteur
,this).not('.noajax').each(function(){
253 var url
= this.href
.split('#');
254 url
[0] += (url
[0].indexOf("?")>0 ? '&':'?')+'var_ajax=1&var_ajax_env='+encodeURIComponent(ajax_env
);
256 url
[0] += "&var_ajax_ancre="+url
[1];
257 if (jQuery(this).is('.preload') && !preloaded_urls
[url
[0]]) {
258 jQuery
.ajax({"url":url
[0],"success":function(r
){preloaded_urls
[url
[0]]=r
;}});
260 jQuery(this).click(function(){
262 // on rearme pour le prochain clic
265 // seule une annulation par confirm() dans les 2 secondes precedentes est prise en compte
266 if ((d
.getTime()-ajax_confirm_date
)<=2)
271 .addClass('loading');
272 if (preloaded_urls
[url
[0]]) {
273 on_pagination(preloaded_urls
[url
[0]]);
274 triggerAjaxLoad(document
);
278 success: function(c
){
280 preloaded_urls
[url
[0]] = c
;
286 }).addClass('noajax'); // previent qu'on ajax pas deux fois le meme lien
287 jQuery('form.bouton_action_post.ajax:not(.noajax)', this).each(function(){
289 var url
= jQuery(this).attr('action').split('#');
291 .prepend("<input type='hidden' name='var_ajax' value='1' /><input type='hidden' name='var_ajax_env' value='"+(ajax_env
)+"' />"+(url
[1]?"<input type='hidden' name='var_ajax_ancre' value='"+url
[1]+"' />":""))
293 beforeSubmit: function(){
294 jQuery(blocfrag
).addClass('loading').animeajax();
296 success: function(c
){
298 preloaded_urls
= {}; // on vide le cache des urls car on a fait une action en bdd
299 // on le refait a la main ici car onAjaxLoad intervient sur une iframe dans IE6 et non pas sur le document
303 iframe
: jQuery
.browser
.msie
305 .addClass('noajax') // previent qu'on n'ajaxera pas deux fois le meme formulaire en cas de ajaxload
311 // Ajaxer les formulaires qui le demandent, au demarrage
314 jQuery('form:not(.bouton_action_post)').parents('div.ajax')
315 .formulaire_dyn_ajax();
316 jQuery('div.ajaxbloc').ajaxbloc();
319 // ... et a chaque fois que le DOM change
320 onAjaxLoad(function() {
322 jQuery('form:not(.bouton_action_post)', this).parents('div.ajax')
323 .formulaire_dyn_ajax();
324 jQuery('div.ajaxbloc', this)