[PLUGINS] +multilangue
[ptitvelo/web/www.git] / www / plugins / multilang / javascript / multilang.js
diff --git a/www/plugins/multilang/javascript/multilang.js b/www/plugins/multilang/javascript/multilang.js
new file mode 100644 (file)
index 0000000..72f0fb7
--- /dev/null
@@ -0,0 +1,646 @@
+/**\r
+ * multilang\r
+ *\r
+ * Copyright (c) 2006-2010 Renato Formato (rformato@gmail.com)\r
+ * Licensed under the GPL License:\r
+ *   http://www.gnu.org/licenses/gpl.html\r
+ *\r
+ * Modif Yffic mars 2010\r
+ * - Correction bug : Fonctionnement incoherent si plusieurs menu dans la meme page (ex : portfolio dans page de\r
+ *   presentation d'un article)\r
+ * - On ne rajoute pas le menu s'il existe deja (cas d'un retour Ajax)\r
+ * - On ne rajoute pas le menu dans forms d'upload (par ex vignette d'un doc)\r
+ */\r
+\r
+\r
+var multilang_containers={}, //menu containers\r
+    multilang_forms_fields={};\r
+\r
+/*\r
+(?:\[([a-z_]+)\]|^[\s\n]*)\r
+[lang] or white space\r
+\r
+((?:.|\n)*?)\r
+all chars not greedy\r
+\r
+(?=\[[a-z_]+\]|$)\r
+[lang] or end string\r
+*/\r
+\r
+/**\r
+ * Initialisation de différentes variables :\r
+ *\r
+ */\r
+var multilang_match_multi = /(?:\[([a-z_]+)\]|^[\s\n]*)((?:.|\n|\s)*?)(?=\[[a-z_]+\]|$)/ig;\r
+var multilang_jq_root, //root of the search (jQuery object)\r
+    multilang_root_opt,\r
+    multilang_fields_selector,\r
+    multilang_fields_selector_opt,\r
+    multilang_menu_selector,\r
+    multilang_containers,\r
+    multilang_forms_toadd,\r
+    multilang_forms, //forms to be processed (jQuery object)\r
+    multilang_menu_lang, //template of the menu (jQuery object)\r
+    multilang_forms_selector, //selector of the forms to be processed (string)\r
+    multilang_init = false;\r
+\r
+/**\r
+ * options is a hash having the following values:\r
+ * - fields (mandatory): a jQuery selector to set the fields that have to be internationalized.\r
+ * - page (optional): a string to be searched in the current url. if found the plugin is applied.\r
+ * - root (optional): the root element of all processing. Default value is 'document'. To speed up search\r
+ * - forms (optional): a jQuery selector to set the forms that have to be internationalized. Default value is 'form'.\r
+ * - main_menu (optional): a jQuery selector to set the container for the main menu to control all the selected forms.\r
+ * - form_menu (optional): a jQuery selector to set the container for the form menus.\r
+ */\r
+function multilang_init_lang(options) {\r
+       var init_done = options.init_done || multilang_init;\r
+       //Detect if we're on the right page and if multilinguism is activated. If not return.\r
+       if((options.page && window.location.search.indexOf(options.page)==-1) || multilang_avail_langs.length<=1) return;\r
+       \r
+       //set the root element of all processing\r
+\r
+       var root = options.root || document;\r
+       multilang_jq_root = $(root).add($(options.root_opt).parent());\r
+       multilang_root_opt = options.root_opt;\r
+\r
+       /**\r
+        * set the main menu element\r
+        * Plus utilisé pour l'instant\r
+        */\r
+       multilang_containers = options.main_menu ? $(options.main_menu,multilang_jq_root) : $([]);\r
+\r
+       multilang_forms_toadd = $([]);\r
+\r
+       /**\r
+        * On crée le modèle du menu de langue\r
+        * C'est ce modèle qui est cloné au début de chaque formulaire\r
+        */\r
+       multilang_menu_lang = $("<div class='langues'></div>");\r
+       $.each(multilang_avail_langs,function() {\r
+               var title = 'multilang_lang.title_lien_multi_'+this;\r
+               multilang_menu_lang.append($("<a class='change_lang "+this+"' title='"+eval(title)+"'></a>").html("["+this+"]"));\r
+       });\r
+       multilang_menu_lang.append($("<a class='recover_lang' href='#'></a>").html("["+multilang_lang.lien_desactiver+"]"));\r
+\r
+       //init fields\r
+       multilang_fields_selector = options.fields;\r
+       multilang_fields_selector_opt = options.fields_opt;\r
+\r
+       //store all the internationalized forms\r
+       multilang_forms_selector = options.forms || "form";\r
+\r
+       if(init_done){\r
+               multilang_forms_toadd = $(multilang_forms_selector,multilang_jq_root).not($(multilang_forms));\r
+       }\r
+       multilang_forms = $(multilang_forms_selector,multilang_jq_root);\r
+       if(!init_done)\r
+               multilang_forms_toadd = multilang_forms;\r
+\r
+       //create menu lang for the global form\r
+       if(multilang_containers.size())\r
+               multilang_make_menu_lang(multilang_containers);\r
+       multilang_menu_selector = options.form_menu;\r
+\r
+       multilang_init = true;\r
+\r
+       // Modif Yffic : On va pas plus loin s'il n'y a pas de form\r
+       if(multilang_forms_toadd.size()) multilang_init_multi();\r
+\r
+}\r
+\r
+/**\r
+ * Initialisation des champs multi sur les formulaires\r
+ *\r
+ * @param options\r
+ * @return\r
+ */\r
+function multilang_init_multi(options) {\r
+       var target = options ? options.target : null;\r
+       var init_forms;\r
+       //Update the list of form if this is an update\r
+       if(target) {\r
+               //Verify the target is really a form to be internationalized (in case of an ajax request fired by onAjaxLoad)\r
+               if(target==document) return;\r
+               init_forms = $(target).find('form').in_set($(multilang_forms_selector,multilang_jq_root));\r
+               if(!init_forms.length) return;\r
+               multilang_forms.add(init_forms.each(multilang_attach_submit).get());\r
+       } else {\r
+               //attach multi processing to submit event\r
+               init_forms = multilang_forms_toadd;\r
+               multilang_forms_toadd.each(multilang_attach_submit);\r
+       }\r
+\r
+       multilang_forms_fields = {};\r
+       multilang_forms_fields["undefined"] = $(multilang_fields_selector,multilang_forms);\r
+       //init the value of the field to current lang\r
+       //add a container for the language menu inside the form\r
+       init_forms.each(function() {\r
+               /*\r
+                * Je ne sais pas à quoi cela sert particulièrement, désactivé pour l'instant\r
+                */\r
+               //$(this).find('input[type=submit],button').click(function(){\r
+                       //multilang_multi_submit.apply($(this).parents('form').get(0));\r
+                       //$(this).parents('form').submit();\r
+                       //return false;\r
+               //});\r
+               this.isfull = false;\r
+               this.form_lang = multilang_def_lang;\r
+               var container = multilang_menu_selector ? $(multilang_menu_selector,this) : $(this);\r
+               // Pas de rajout s'il y en deja un\r
+               if(!container.find('.menu_multilang').size())\r
+                       container.prepend("<div class='menu_multilang'></div>");\r
+       });\r
+\r
+       /**\r
+        * Initialisation de chaque input ou textarea\r
+        * On vérifie si on est dans un formulaire optionnel (dans ce cas on ne prend que\r
+        * les éléments qui on la class optionnelle) sinon on prend tous les champs qui\r
+        * matchent\r
+        */\r
+       $(multilang_fields_selector,init_forms).each(function(){\r
+           var me = $(this);\r
+           if(me.closest(multilang_root_opt).length){\r
+               if(me.is(multilang_fields_selector_opt))\r
+                       multilang_init_field(this,this.form.form_lang);\r
+           }else{\r
+                       multilang_init_field(this,this.form.form_lang);\r
+               }\r
+       });\r
+       //create menu for each form. The menu is just before the form\r
+       $("div.menu_multilang",init_forms).empty().each(function() {\r
+               //store all form containers to allow menu lang update on each container\r
+               //when it is triggered by global menu\r
+               multilang_containers.add(this);\r
+               multilang_make_menu_lang($(this),$(this).parents("form"));\r
+       });\r
+}\r
+\r
+/**\r
+ * Création du menu de langue\r
+ * Liste les langues disponibles et ajoute un lien pour désactiver multilang\r
+ *\r
+ * @param container\r
+ * @param target\r
+ * @return\r
+ */\r
+function multilang_make_menu_lang(container,target) {\r
+       target = target || multilang_forms;\r
+       $(multilang_menu_lang).clone().find("a").click(function() {\r
+               if($(this).is('.change_lang') && !$(this).is('.on')){\r
+                       $(this).parents('form > .menu_multilang').find('a.on').removeClass('on');\r
+                       $(this).parents('form > .menu_multilang').find('.multilang_message').detach();\r
+                       $(this).parents('form').find('li.editer_titre_numero,div.editer_titre_numero').show();\r
+                       $(this).addClass('on');\r
+                       multilang_change_lang(this,container,target);\r
+               }else if(!$(this).is('.on') && $(this).is('.recover_lang')){\r
+                       $(this).parents('form > .menu_multilang').find('a.on').removeClass('on');\r
+                       $(this).parents('form > .menu_multilang').append('<div class="multilang_message"><p>'+multilang_lang.champs_readonly+'<\/p><\/div>');\r
+                       $(this).parents('form').find('li.editer_titre_numero,div.editer_titre_numero').hide();\r
+                       $(this).addClass('on');\r
+                       multilang_multi_recover(this,container,target,'submit');\r
+               }\r
+               return false;\r
+       }).end().appendTo(container);\r
+       $(target).find('.menu_multilang .langues a').eq(0).addClass('on');\r
+\r
+       var target_id = multilang_init_target_id(target);\r
+       multilang_forms_fields[target_id].each(function(){\r
+               multilang_save_lang(this,this.form.form_lang);\r
+       });\r
+       // Maj du menu de langues\r
+       multilang_mark_empty_langs(container,target);\r
+}\r
+\r
+/**\r
+ * Initialise target_id\r
+ *\r
+ * @param target Le formulaire\r
+ * @return\r
+ */\r
+function multilang_init_target_id(target){\r
+       var target_id = target != multilang_forms ? jQuery.data(target[0]) : "undefined";\r
+       multilang_forms_fields[target_id] = $(multilang_fields_selector,target);\r
+       return(target_id);\r
+}\r
+\r
+/**\r
+ * Affiche le contenu complet du champ\r
+ * Utilisé lors de la désactivation de multilang et de la validation des formulaires\r
+ *\r
+ * @param el Le lien de désactivation\r
+ * @param container Le container du formulaire\r
+ * @param target Le formulaire\r
+ * @return\r
+ */\r
+function multilang_multi_recover(el,container,target,event){\r
+       if(target[0].isfull){\r
+               return true;\r
+       }\r
+       if(event == 'submit'){\r
+               lang = 'full';\r
+               var target_id = multilang_init_target_id(target);\r
+               target[0].isfull = true;\r
+               multilang_forms_fields[target_id].each(function(){\r
+                       if(!this.totreat) return ;\r
+                       //save data before submit\r
+                       multilang_save_lang(this,this.form.form_lang);\r
+                       //build the string value\r
+                       multilang_field_set_background(this,lang);\r
+                       if(container && target){\r
+                               multilang_mark_empty_langs(container,target);\r
+                       }\r
+                       var def_value = this.field_lang[multilang_def_lang];\r
+                       if(!this.multi)\r
+                               this.value = (def_value==undefined?"":def_value);\r
+                       else {\r
+                               var value="",count=0;\r
+                               $.each(this.field_lang,function(name){\r
+                                       if((name != 'full') && (this.length > 0)){\r
+                                               //save default lang value and other lang values if different from the default one\r
+                                               if(name == multilang_def_lang){\r
+                                                       value = "["+name+"]"+this+value;\r
+                                                       count++;\r
+                                               }else if(this!=def_value) {\r
+                                                       value += "["+name+"]"+this;\r
+                                                       count++;\r
+                                               }\r
+                                       }\r
+                               });\r
+                               this.value = (count > 1 ? "<multi>"+value+"</multi>":value.replace(/^\[[a-z_]+\]/,''));\r
+                       }\r
+                       // Add the title number to the final value\r
+                       if(multilang_is_title(this) && ($('#'+this.id+'_numero').val() != ''))\r
+                               this.value= $('#'+this.id+'_numero').val().replace(/\.|\s+/,'') + ". " + this.value;\r
+               });\r
+               return true;\r
+       }\r
+}\r
+\r
+/**\r
+ * Défini si un id de champ correspond a un champ "numerotable"\r
+ *\r
+ * @param id chaine correspondant a l'id du champ\r
+ */\r
+function multilang_is_title(el) {\r
+       return (el.id=='titre' || el.id=='champ_titre' || (el.id=='nom_site' && ($(el).parents('#configurer-accueil,.formulaire_configurer_identite,.formulaire_editer_auteur').size() < 1)) || el.id.match(/^titre_document[0-9]+/)!=null || el.name.match(/^content_[a-z0-9_]+_titre/)!=null || el.name.match(/^content_[a-z0-9_-]+nom_/)!=null)\r
+}\r
+\r
+/**\r
+ * Initialisation du script sur un champ\r
+ *\r
+ * Récupère les données suivantes\r
+ * - Le contenu de l'élément du champ\r
+ * - Le booléen (true/false) multi (est ce un champs déjà multi)\r
+ * - Les différentes chaines de langue dans un objet :\r
+ * {fr="texte fr",en="texte en",full="<multi>[fr]texte fr[en]texte en</multi>"}\r
+ * Si le champ est déjà initialisé, fait un simple return\r
+ *\r
+ * @param el Le champ a initialiser\r
+ * @param lang La langue\r
+ *\r
+ */\r
+function multilang_init_field(el,lang,force) {\r
+       if(el.field_lang && !force) return;\r
+       var langs;\r
+       \r
+       // On enlève les espaces, retours à la ligne et tabulations de début et de fin de chaine\r
+       el.value.replace(/(?:^\s+|\s+$)/g, "");\r
+       \r
+       // Modif Yffic : ne pas considerer comme multi les champs qui contiennent du texte\r
+       // en dehors des multi sauf un numero (\d+\.\s+)\r
+       var m = el.value.match(/(\d+\.\s+)?<multi>((?:.|\n|\s)*?)<\/multi>(.|\n*)/);\r
+       el.field_lang = {};\r
+       el.field_pre_lang = ""; //this is the 01. part of the string, the will be put outside the <multi>\r
+       el.titre_el = $("#titre_"+el.id);\r
+       \r
+       // Init the elements to treat\r
+       if(m!=null) {\r
+               if( m.index || (m[3]!=undefined && m[3]!="")){\r
+                       $(el).addClass('multi_lang_broken');\r
+                       el.totreat=false;\r
+               }\r
+               else\r
+                       el.totreat=true;\r
+               if(el.totreat) {\r
+                       el.field_pre_lang = m[1] || "";\r
+                       // Suppress point and spaces\r
+                       el.field_pre_lang = el.field_pre_lang.replace(/\.|\s+/,'') ;\r
+                       el.multi = true;\r
+                       multilang_match_multi.lastIndex=0;\r
+                       el.field_lang['full'] = el.value;\r
+                       while((langs=multilang_match_multi.exec(m[2]))!=null) {\r
+                               var text = langs[2].match(/^(\d+\.\s+)((?:.|\n|\s)*)/), value;\r
+                               // Suppression du numero uniquement pour les titres\r
+                               if(multilang_is_title(el) && text!=null) {\r
+                                       value = text[2];\r
+                                       // Suppress point and spaces\r
+                                       el.field_pre_lang = text[1].replace(/\.|\s+/,'') || "";\r
+                               } else {\r
+                                       value = langs[2];\r
+                               }\r
+                               el.field_lang[langs[1]||multilang_def_lang] = value;\r
+                       }\r
+               }\r
+       } else {\r
+               el.multi = false;\r
+               el.totreat=true;\r
+\r
+               // Suppression du numero uniquement pour les titres\r
+               if(multilang_is_title(el)) {\r
+                       var n = el.value.match(/(\d+\.\s+)?(.*)/);\r
+                       el.field_pre_lang = n[1] || "";\r
+                       el.field_pre_lang = el.field_pre_lang.replace(/\.|\s+/,'') ;\r
+                       el.field_lang[multilang_def_lang] = n[2];\r
+               } else\r
+                       el.field_lang[multilang_def_lang] = el.value;\r
+       }\r
+\r
+       // Put the current lang string only in the field\r
+       multilang_set_lang(el,lang);\r
+\r
+       /**\r
+        * Si le champ est un titre, on ajoute un champ facultatif "numéro" au formulaire permettant\r
+        * de traiter le cas où l'on utilise les numéros pour trier les objets\r
+        * Ajout d'Yffic le 30/03/2010\r
+        */\r
+       if(!force && multilang_is_title(el)){\r
+               numid=el.id+'_numero';\r
+               /**\r
+                * Cas des crayons qui n'ont pas toujours de formalisme en ul > li\r
+                */\r
+               if(el.name.match(/^content_[a-z0-9_]+_titre/)){\r
+                       if($(el).parent().is('li'))\r
+                               $(el).parent()\r
+                                       .before('<li class="editer_'+numid+'"><label for="titre_numero">'+multilang_lang.numero+'</label><input id="'+numid+'" name="titre_numero" type="text" value="'+el.field_pre_lang+'" size="4" class="text nomulti" /></li>');\r
+                       else\r
+                               $(el)\r
+                                       .before('<div class="editer_titre_numero"><label for="titre_numero">'+multilang_lang.numero+'</label><input id="'+numid+'" name="titre_numero" type="text" value="'+el.field_pre_lang+'" size="4" class="text nomulti" /><br /><br /></div>');\r
+               }else\r
+                       $(el).parent()\r
+                               .before('<li class="editer_'+numid+'"><label for="titre_numero">'+multilang_lang.numero+'</label><input id="'+numid+'" name="titre_numero" type="text" value="'+el.field_pre_lang+'" size="4" class="text nomulti" /></li>');\r
+               $('#'+numid).totreat = false;\r
+       }\r
+}\r
+\r
+/**\r
+ * Action au click sur une langue du menu de langue\r
+ *\r
+ * @param el Le lien cliqué sur le menu\r
+ * @param container Le conteneur du formulaire\r
+ * @param target Le formulaire lui même\r
+ *\r
+ */\r
+function multilang_change_lang(el,container,target) {\r
+       var added_lang="";\r
+       var target_id = multilang_init_target_id(target);\r
+       var lang = el.innerHTML;\r
+\r
+       lang = lang.slice(1,-1);\r
+\r
+       if(target[0].isfull){\r
+               // Maj du menu de langues avant multilang_init_field\r
+               multilang_forms_fields[target_id].each(function(){\r
+                       var me = $(this);\r
+                       if(me.parents(multilang_root_opt).size()>0){\r
+                       if(me.is(multilang_fields_selector_opt))\r
+                               multilang_init_field(this,lang,true);\r
+                   }else\r
+                       multilang_init_field(this,lang,true);\r
+               });\r
+               target[0].isfull = false;\r
+       }else{\r
+               //store the fields inputs for later use (usefull for select)\r
+               //save the current values\r
+               multilang_forms_fields[target_id].each(function(){\r
+                       multilang_save_lang(this,this.form.form_lang);\r
+               });\r
+               // Maj du menu de langues apres multilang_save_lang\r
+       }\r
+\r
+       //change current lang\r
+       target.each(function(){this.form_lang = lang});\r
+\r
+       //reinit fields to current lang\r
+       multilang_forms_fields[target_id].each(function(){\r
+               multilang_set_lang(this,lang);\r
+       });\r
+       \r
+       multilang_mark_empty_langs(container,target);\r
+}\r
+\r
+/**\r
+ * Marquer dans le menu des langues, celles pour lesquelles\r
+ * au moins un champ multi du formulaire n'est pas renseigne\r
+ *\r
+ * @param container Le conteneur du formulaire\r
+ *\r
+ */\r
+function multilang_mark_empty_langs(container,target) {\r
+       var langs_empty = [];\r
+       var target_id = multilang_init_target_id(target);\r
+\r
+       multilang_forms_fields[target_id].each(function(){\r
+               var field_langs = [];\r
+               // Mise sous forme de tableau\r
+               if(typeof(this.field_lang) != 'undefined'){\r
+                       $.each(this.field_lang,function(name,value){\r
+                               if(value)\r
+                                       field_langs.push(name);\r
+                       });\r
+               }\r
+               // Trouver les elements non communs entre le tableau des langues availables et pour chaque champ,\r
+               // celui des langues renseignees, si ce champ est multi\r
+               // Si la langue d'origine n'est pas remplie (champ texte par exemple, on ne considère donc pas empty)\r
+               if(this.multi) {\r
+                       // Comparaison des tableaux\r
+                       $.each(multilang_avail_langs,function(i,name){\r
+                               if ((jQuery.inArray(name, field_langs) == -1) && (jQuery.inArray(name, langs_empty) == -1) && (jQuery.inArray(multilang_def_lang, field_langs) != -1))\r
+                                       langs_empty.push(name);\r
+                       });\r
+               }else{\r
+                       // Comparaison des tableaux\r
+                       $.each(multilang_avail_langs,function(i,name){\r
+                               if ((jQuery.inArray(name, field_langs) == -1) && (jQuery.inArray(name, langs_empty) == -1) && (jQuery.inArray(multilang_def_lang, field_langs) != -1))\r
+                                       langs_empty.push(name);\r
+                       });\r
+               }\r
+       });\r
+\r
+       // On indique dans le menu de langue, celles qui ont au moins un champ non renseigne\r
+       if(container!='') {\r
+               $.each(multilang_avail_langs,function(i,name){\r
+                       if((jQuery.inArray(name, langs_empty) == -1)){\r
+                               var title = 'multilang_lang.title_lien_multi_'+name;\r
+                               container.find('a[class~='+name+']').removeClass('empty').attr('title',eval(title));\r
+                       }else{\r
+                               var title = 'multilang_lang.title_lien_multi_sans_'+name;\r
+                               container.find('a[class~='+name+']').addClass('empty').attr('title',eval(title));\r
+                       }\r
+               });\r
+       }\r
+}\r
+\r
+/**\r
+ * Action au changement de la langue\r
+ * Lorsque l'on clique sur une le menu de langue\r
+ * On affiche pour le champ "el" son contenu dans la langue "lang"\r
+ *\r
+ * @param el Un champ du formulaire (input ou textarea)\r
+ * @param lang La langue correspondante souhaitée\r
+ * @return\r
+ */\r
+function multilang_set_lang(el,lang) {\r
+\r
+       if(!el.totreat) return;\r
+\r
+       //if current lang is not setted use default lang value\r
+       if(el.field_lang[lang]==undefined) {\r
+               el.field_lang[lang] = el.field_lang[multilang_def_lang];\r
+       }\r
+\r
+       el.value = (el.field_lang[lang] == undefined ? "" : el.field_lang[lang]);\r
+\r
+       el.titre_el.html(el.value);\r
+\r
+       multilang_field_set_background(el,lang);\r
+}\r
+\r
+/**\r
+ * Change la class multi_lang_* d'un champ pour indiquer la présence ou non de multis\r
+ * - multi_lang_(lang) si une langue particulière est disponible\r
+ * - multi_lang_no_multi si pas de multis pour le champ\r
+ *\r
+ * @param el\r
+ * @param lang\r
+ * @return\r
+ */\r
+function multilang_field_set_background(el,lang) {\r
+       if(lang != 'full'){\r
+               if(el.totreat){\r
+                       $(el).removeAttr('readonly').removeClass('multilang_readonly');\r
+                       if(typeof($(el).attr('class')) != 'undefined'){\r
+                               $($(el).attr('class').split(' ')).each(function(){\r
+                                       var m = this.match(/^multi_lang_*/);\r
+                                       if(m!=null)\r
+                                               $(el).removeClass(m.input).addClass('multi_lang_'+lang);\r
+                               });\r
+                       }\r
+                       $(el).addClass('multi_lang_'+(el.multi?lang:'no_multi'));\r
+               }\r
+               else{\r
+                       if(typeof($(el).attr('class')) != 'undefined'){\r
+                               $($(el).attr('class').split(' ')).each(function(){\r
+                                       var m = this.match(/^multi_lang_*/);\r
+                                       if(m!=null)\r
+                                               $(el).removeClass(m.input);\r
+                               });\r
+                       }\r
+                       $(el).css({"background":"url("+multilang_dir_plugin+"/images/multi_forbidden.png) no-repeat right top"});\r
+               }\r
+       }else{\r
+               $(el).attr('readonly','readonly').addClass('multilang_readonly');\r
+               if(typeof($(el).attr('class')) != 'undefined'){\r
+                       $($(el).attr('class').split(' ')).each(function(){\r
+                               var m = this.match(/^multi_lang_*/);\r
+                               if(m!=null)\r
+                                       $(el).removeClass(m.input);\r
+                       });\r
+               }\r
+       }\r
+}\r
+\r
+/**\r
+ * Garde en mémoire dans l'array de langues du champs la valeur de la langue\r
+ * sélectionnée\r
+ *\r
+ * @param el Le champ du formulaire concerné\r
+ * @param lang La langue actuelle\r
+ * @return\r
+ */\r
+function multilang_save_lang(el,lang) {\r
+\r
+       if(!el.totreat) return ;\r
+\r
+       // Suppression du numero uniquement pour les titres\r
+       if(multilang_is_title(el)) {\r
+               var m = el.value.match(/^(\d+\.\s+)((?:.|\n|\s)*)/);\r
+               if(m!=null) {\r
+                       // Suppress point and spaces\r
+                       el.field_pre_lang = m[1].replace(/\.|\s+/,'');\r
+                       el.value = m[2];\r
+               }\r
+       }\r
+\r
+       //if the lang value is equal to the def lang do nothing\r
+       //else save value but if the field is not empty, delete lang value\r
+       if(el.field_lang[multilang_def_lang]!= el.value) {\r
+               if(!el.value) {\r
+                       delete el.field_lang[lang];\r
+                       return;\r
+               }\r
+               el.multi = true;\r
+               el.field_lang[lang] = el.value;\r
+       }else{\r
+               el.field_lang[lang] = el.field_lang[multilang_def_lang];\r
+               $.each(el.field_lang,function(index, value){\r
+                       if((index != multilang_def_lang) && (value == el.field_lang[multilang_def_lang])){\r
+                               delete el.field_lang[index];\r
+                       }\r
+               });\r
+       }\r
+}\r
+\r
+//This func receives the form that is going to be submitted\r
+function multilang_multi_submit(params) {\r
+       if(multilang_avail_langs.length<=1) return;\r
+       var form = $(this);\r
+       //remove the current form from the list of forms\r
+       multilang_forms.not(this);\r
+       //remove the current menu lang container from the list\r
+       multilang_containers.not("div.menu_multilang",$(this));\r
+       //build the input values\r
+       multilang_multi_recover('','',form,'submit');\r
+       //save back the params\r
+       if(params) $.extend(params,$(form).formToArray(false));\r
+}\r
+\r
+/**\r
+ * On attache nos évènements pour la validation du formulaire\r
+ * - sur le submit pour tous les formulaires\r
+ * - sur l'évènement 'form-pre-serialize' d'ajaxForms au cas où nous sommes dans\r
+ * un formulaire ajax\r
+ *\r
+ * @return\r
+ */\r
+function multilang_attach_submit() {\r
+       if($(this).parents('.ajax').size() && $(this).find('input[name=var_ajax]')){\r
+               $(this).bind('form-pre-serialize',multilang_multi_submit);\r
+       }else if($(this).is('.formulaire_crayon')){\r
+               cQuery(this).bind('form-pre-serialize',function(){multilang_multi_submit.apply(this);});\r
+       }else{\r
+               var oldsubmit = this.onsubmit;\r
+               this.onsubmit = "";\r
+               if(oldsubmit && oldsubmit != ""){\r
+                       $(this).submit(function(){multilang_multi_submit.apply(this);return oldsubmit.apply(this);});\r
+               }\r
+               else if(oldsubmit != "")\r
+                       $(this).submit(multilang_multi_submit);\r
+       }\r
+}\r
+\r
+(function($) {\r
+       $.extend($.fn, {\r
+               in_set: function(set) {\r
+                       var elements = this.get();\r
+                       var result = $.grep(set,function(i){\r
+                               var found = false;\r
+                               $.each(elements,function(){\r
+                                       if(this==i) found=true;\r
+                               })\r
+                               return found;\r
+                       });\r
+                       return jQuery(result);\r
+               }\r
+       });\r
+})(jQuery);
\ No newline at end of file