var isProcessing;
//Permet aux composant de mutualiser leurs appels
var componentQueue = {};
$(document).ready(function(){
if($.urlParam('title')!=null){
window.parent.document.title = decodeURI($.urlParam('title'));
}
var page = $.page();
page = page == '' ? 'index' : page;
var init = 'init_'+page;
init = init.replace(/[^a-z_0-9]/g,'_');
init_components();
if($.urlParam('module')==null){
if(window[init]!=null) window[init]($.urlParam());
} else {
var mod = $.urlParam('module').replace(/[^a-z_0-9]/g,'_');
var init = 'init_plugin_'+mod;
if(window[init]!=null) window[init]($.urlParam());
}
//SHOW HTTP ERROR/NOTICE
if ($.urlParam('error') != null) {
$.message('error', decodeURIComponent($.urlParam('error')), 0);
$.urlParam('error', false);
}
if ($.urlParam('info') != null) {
$.message('info', decodeURIComponent($.urlParam('info')));
$.urlParam('info', false);
}
if ($.urlParam('success') != null) {
$.message('success', decodeURIComponent($.urlParam('success')));
$.urlParam('success', false);
}
//Icône menu mobile
$('#mainMenu > button').on('click', function(e){
$('.menu').toggleClass('open');
});
$('.navbar-toggler').on('click', function(e){
if($(e.target).closest('#mainMenu').length) return;
$('#navbarCollapse').collapse('hide');
$('.menu').removeClass('open');
});
//Positionnement du loginHeader
if($(document).width() <= 767) $('#mainMenu .navbar-brand').after($('#loginHeader').detach());
});
//Changement positionnement loginHeader
//au redimensionnement de la fenêtre
$(window).resize(function(event) {
if(is_phone()) return;
var width = $(document).width();
var loginForm = $('#loginHeader').detach();
if(width>767) $('#navbarCollapse').append(loginForm);
if(width<=767) $('#mainMenu .navbar-brand').after(loginForm);
});
/* COMPOSANT */
function init_components(selector){
var selected = selector ? $('[data-type]',selector) : '[data-type]';
$(selected).each(function(i,input){
var input = $(input);
switch($(input).attr('data-type')){
/**
* data-format : Supporte les formats dd/mm/yyyy ou yyyy/mm/dd avec séparateur "/" ou "-"
* data-begin : date de début de sélection par rapport à aujourd'hui(peut être en nb de jour, en objet Date ou en string de type dateFormat ou en date relative [+1m +7d]==>Début à 1 mois et 7 jours)
* data-end : date de début de sélection par rapport à aujourd'hui(peut être en nb de jour, en objet Date ou en string de type dateFormat ou en date relative [+1m +7d]==>Début à 1 mois et 7 jours)
* data-workdays : si attribut est présent, seuls les jours ouvrés sont sélectionnables
*/
case 'date':
//Les séparateurs doivent être similaires entre les éléments de la chaîne
var dateFormatRegex = /^(dd|yy)([\/|-])(mm)\2(dd|yy)$/;
var dateFormat = input.attr('data-format') != undefined && input.attr('data-format').match(dateFormatRegex) ? input.attr('data-format').match(dateFormatRegex)[0] : "dd/mm/yy";
var begin = input.attr('data-begin');
begin = (begin != undefined && (begin.match(/-?\d+/) || begin.match(/^(\d{2}(?:\d{2})?)\/(\d{2})\/(\d{2}(?:\d{2})?)$/))) ? begin : null ;
var end = input.attr('data-end');
end = (end != undefined && (end.match(/-?\d+/) || end.match(/^(\d{2}(?:\d{2})?)[-|\/](\d{2})[-|\/](\d{2}(?:\d{2})?)$/))) ? end : null ;
input.date({
placeholder: input.attr('placeholder') != undefined ? input.attr('placeholder') : "jj/mm/aaaa",
dateFormat: dateFormat,
beginDate: begin,
endDate: end,
workdays: input.attr('data-workdays') != null
});
break;
/**
* data-format : Supporte les formats dd/mm/yyyy ou yyyy/mm/dd avec séparateur "/" ou "-"
* data-step : L'intervalle entre 2 valeurs en minutes
*/
case 'hour':
var timeFormatRegex = /^(H):(i)$/;
var timeFormat = input.attr('data-format') != undefined && input.attr('data-format').match(timeFormatRegex) ? input.attr('data-format').match(timeFormatRegex)[0] : "H:i";
var step = input.attr('data-step');
input.hour({
placeholder: input.attr('placeholder') != undefined ? input.attr('placeholder') : "hh:mm",
timeFormat: timeFormat,
step: is_numeric(step) && step>0 ? step : 1
});
break;
case 'color':
$(input).colorInput();
break;
case 'image':
if(input.closest('.type-image-bloc').length!=0) break;
input.attr('type', 'file');
input.wrap( "
';
input.before(thumbnail);
if(thumbnail.attr('src').indexOf('default-') === -1) thumbnail.before(deleteBtn);
input.addClass('noPrint');
input.change(function(){
var reader = new FileReader();
reader.onload = function (e) {
thumbnail.attr('src', e.target.result);
thumbnail.before(deleteBtn);
}
reader.readAsDataURL(input.get(0).files[0]);
});
break;
//Selection de tag liés a un dictionnary
case 'tag-list':
var container;
var picker;
var pickerLi;
if(!input.data("data-component")){
var placeholder = input.attr("placeholder") != undefined ? input.attr("placeholder") : "";
container = $('
');
input.before(container);
input.data("data-component", container);
if(input.attr("required")) container.attr("required","");
if(input.attr("disabled")) container.attr("disabled","");
if(input.attr("readonly")) container.attr("readonly","");
} else {
container = input.data("data-component");
}
picker = container.find('input:eq(0)');
pickerLi = container.find('ul li.tag-picker-li');
if(container.attr('disabled') || container.attr('readonly'))
pickerLi.find('input').attr('readonly','');
container.find('.tag-picker-tag').remove();
pickerLi.removeClass('hidden');
var pickerFunctions = {
//Récuperation des valeurs sélectionnées (objet et id) en fonction des tags visuels présents
getValues : function( container){
var tags = container.find('ul .tag-picker-tag');
var values = {object:[],id:[]};
tags.each(function(i,element){
if($(element).attr('data-id') == '') return;
var object = $(element).data();
values['object'].push(object);
values['id'].push(object.id);
});
return values;
},
//Ajout d'un tag visuel et mise à jour de l'input brut en fonction de l'objet fournis
addTag : function( container,tag){
pickerLi = container.find('ul li.tag-picker-li');
if( container.find('li[data-id="'+tag.id+'"]').length>0) return;
var closeBtn = container.attr('disabled') || container.attr('readonly') ? '' : '';
var tag = $('
'+tag.name+closeBtn+'
');
pickerLi.before(tag);
var values = pickerFunctions.getValues( container);
input.val(values['id'].join(','));
input.data('values',values['object']);
if((values['id'].length) == 1 && input.attr('data-multiple') == null){
pickerLi.addClass('hidden');
}else{
pickerLi.removeClass('hidden');
}
tag.find('i').click(function(){
if(container.attr('disabled') || container.attr('readonly')) return;
$(this).closest('.tag-picker-tag').remove();
var values = pickerFunctions.getValues( container);
input.val(values['id'].join(','));
input.data('values',values['object']);
if((values['id'].length-1) ==1 && input.attr('data-multiple') == null){
pickerLi.addClass('hidden');
}else{
pickerLi.removeClass('hidden');
}
});
}
}
//Gestion des champs déja remplis au chargement de la page
if(input.val() !=''){
var id = input.val();
container.find('ul').append('
Chargement
');
picker.addClass('hidden');
$.action({
action : 'tag_list_by_id',
id : id
},function(r){
container.find('.tag-picker-loader').remove();
picker.removeClass('hidden');
for(var key in r.tags)
pickerFunctions.addTag( container,r.tags[key]);
});
}
//Sélectionne l'input d'auto-completion ou que l'on clique dans le composant
container.find('ul').click(function(e){
picker.focus();
e.stopPropagation();
});
//Selectionne l'item dropdown actif lors de l'appuis sur entré
picker.off('keyup').keyup(function(e){
//si appui sur Entrée, virgule ou espace on valide le tag
if((e.key!='Enter' && e.key!=' ' && e.key!=',') || input.is('[readonly]') || input.is('[disabled]')) return;
var active = $('.tag-picker-li .dropdown-menu .active');
if(active.length==0){
//Si aucun clic sur un tag existant et que la saisie libre est desactivée on quitte
if(input.data('force')){
picker.val('');
return;
}
//si la saisie libre est activée on ajoute le tag au dictionnaire
$.action({
action : 'tag_list_autocreate',
slug : input.attr('data-slug'),
label : picker.val()
},function(newTag){
picker.val('');
selected.label = picker.val();
pickerFunctions.addTag(container,newTag);
input.trigger('click').trigger('change');
});
}else{
active.trigger('click');
}
});
//aucompletion sur le nom des tags
picker.autocomplete({
action : 'tag_list_autocomplete',
suggest : !input.is('[readonly]') && !input.is('[disabled]'),
items : input.attr('data-items'),
data : {
parent : input.attr('data-slug')
},
skin : function(item){
var html = '';
var re = new RegExp(picker.val(),"gi");
name = item.name.replace(re, function (x) {
return ''+x+'';
});
html += '
'+name+'';
html += '';
return html;
},
highlight : function(item){
return item;
},
onClick : function(selected,element){
picker.val('');
selected.label = selected.name;
pickerFunctions.addTag(container,selected);
input.trigger('click').trigger('change');
},
onBlur : function(selected){
if(input.attr('data-force')!='false' && input.val() == '') picker.val('');
}
});
break;
//composant permettant les listes sous
//form de dropdown avec icones et couleurs
case 'dropdown-select':
if(!input.is(':visible')) return;
var container;
if(!input.data("data-component")){
container = $('
\
\
\
');
input.before(container);
input.data("data-component", container);
if(input.attr("required")) container.attr("required","");
var html = '';
input.find('option').each(function(i,element){
var option = $(element);
var classes = option.attr('class') ? option.attr('class') : '';
var icon = option.attr("data-icon") ? ' ': '';
var title = option.attr("data-title") ? 'title="'+option.attr("data-title")+'"': '';
html += ''+icon+option.html()+'';
});
container.find('.dropdown-menu').append(html);
$('.dropdown-menu a',container).click(function(){
if(input.attr("readonly") == 'readonly') return;
var item = $(this);
$('.dropdown-menu a',container).removeClass('active');
//Utilisation background-color pour fonctionner sous FF
container.find('.dropdown-toggle').html(item.html()).css('background-color',item.css('background-color'));
item.addClass('active');
input.val(item.attr('data-value')).trigger('change');
});
} else {
container = input.data("data-component");
}
input.addClass('hidden');
var state = input.attr('data-value') != null ? input.attr('data-value') : input.val();
if(state == '') return;
var item = $('.dropdown-menu a[data-value="'+state+'"]', container);
//Utilisation background-color pour fonctionner sous FF
container.find('.dropdown-toggle').html(item.html()).css('background-color',item.css('background-color'));
item.addClass('active');
input.val(item.attr('data-value')).trigger('change');
break;
case 'user':
var userContainer;
var userPicker;
var pickerLi;
if(!input.data("data-component")){
userContainer = $('
');
input.before(userContainer);
input.data("data-component", userContainer);
if(input.attr("required")) userContainer.attr("required","");
if(input.attr("disabled")) userContainer.attr("disabled","");
if(input.attr("readonly")) userContainer.attr("readonly","");
} else {
userContainer = input.data("data-component");
}
userPicker = userContainer.find('input:eq(0)');
pickerLi = userContainer.find('ul li.user-picker-li');
if(userContainer.attr('disabled') || userContainer.attr('readonly'))
pickerLi.find('input').attr('readonly','');
userContainer.find('.user-picker-tag').remove();
pickerLi.removeClass('hidden');
var pickerFunctions = {
//Récuperation des valeurs sélectionnées (objet et uid) en fonction des tags visuels présents
getValues : function(userContainer){
var tags = userContainer.find('ul .user-picker-tag');
var values = {object:[],uid:[]};
tags.each(function(i,element){
if($(element).attr('data-uid') == '') return;
var object = $(element).data();
values['object'].push(object);
values['uid'].push(object.uid);
});
return values;
},
//Ajout d'un tag visuel et mise à jour de l'input brut en fonction de l'objet user fournis
addTag : function(userContainer,user,input){
pickerLi = userContainer.find('ul li.user-picker-li');
if(userContainer.find('li[data-uid="'+user.uid+'"]').length>0) return;
var closeBtn = userContainer.attr('disabled') || userContainer.attr('readonly') ? '' : '';
var tag = $('
');
userPicker.addClass('hidden');
window.componentQueue.user.timeout = setTimeout(function(){
$.action({
action : 'user_by_uid',
uids : Object.keys(window.componentQueue.user.uids)
},function(r){
for(var key in window.componentQueue.user.components){
var component = window.componentQueue.user.components[key];
component.container.find('.user-picker-loader').remove();
component.picker.removeClass('hidden');
input = window.componentQueue.user.components[key].input;
for(var i in component.values){
var value = component.values[i];
if(!r.users[value]) continue;
pickerFunctions.addTag(component.container,r.users[value],input);
}
}
delete window.componentQueue.user;
});
},50);
/*var login = input.val();
userContainer.find('ul').append('
Chargement
');
userPicker.addClass('hidden');
$.action({
action : 'user_by_uid',
login : login
},function(r){
userContainer.find('.user-picker-loader').remove();
userPicker.removeClass('hidden');
for(var key in r.users)
pickerFunctions.addTag(userContainer,r.users[key]);
});*/
}
//Sélectionne l'input d'auto-completion ou que l'on clique dans le composant
userContainer.find('ul').click(function(e){
if(input.attr("readonly") == "readonly") return;
userPicker.focus();
e.stopPropagation();
});
//Selectionne l'item dropdown actif lors de l'appui sur entrée
userPicker.keyup(function(e){
if(e.keyCode!=13 || input.is('[readonly]') || input.is('[disabled]')) return;
if(input.attr("readonly") == "readonly") return;
var active = $('.user-picker-li .dropdown-menu .active');
if(active.length==0) return;
active.trigger('click').trigger('change');
});
var types = ['user'];
if(input.data('types') && input.data('types')!='')
types = input.data('types').split(',');
//aucompletion sur le nom des users / rangs
userPicker.autocomplete({
action : 'user_autocomplete',
data : {
types : types
},
skin : function(item){
var html = '';
var re = new RegExp(escape_regex_chars(userPicker.val()),"gi");
name = item.name.replace(re, function (x) {
return ''+x+'';
});
if(item.type=='user'){
if(item.avatar) html += '';
html += '
'+name+' - Utilisateur (@'+item.id+')';
html += item.function ? ' '+item.function+'
' : '
';
html += '';
}else{
html += '
';
html += '
'+name+' - Rang';
html += item.description ? ' '+item.description+'
' : '';
html += '';
}
return html;
},
highlight : function(item){
return item;
},
onClick : function(selected,element){
userPicker.val('');
pickerFunctions.addTag(userContainer,selected,input);
input.trigger('click').trigger('change');
},
onBlur : function(selected){
if(input.attr('data-force')!='false' && input.val() == '') userPicker.val('');
}
});
break;
/**
* data-labels : tableau des libellés entre double quotes eg : ["Libellé 1","Libellé 2"]
* data-values : taleau des valeurs eg : [12,13]
* data-colors : taleau des couleurs entre double quotes eg : ["#cecece","#222222"]
*/
case 'doughnut':
var data = input.data();
var myChart = new Chart(input.get(0).getContext('2d'), {
type: 'doughnut',
data: {
labels: data.labels,
datasets: [{
data: data.values,
backgroundColor: data.colors
}]
},
options: {
cutoutPercentage:80
}
});
break;
/**
* data-labels : tableau des libellés entre double quotes eg : ["Libellé1","Libellé 2"]
* data-values : taleau des valeurs eg : [12,13]
* data-colors : taleau des couleurs entre double quotes eg : ["#cecece","#222222"]
*/
case 'bar':
var data = input.data();
var myChart = new Chart(input.get(0).getContext('2d'), {
type: 'bar',
data: {
labels: data.labels,
datasets: [{
label : input.html(),
data: data.values,
backgroundColor: data.colors
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
},
legend: {
display: false
}
}
});
break;
/**
* data-labels : tableau des libellés entre double quotes eg : ["Libellé1","Libellé 2"]
* data-values : taleau des valeurs eg : [12,13]
* data-color : couleurs eg : #cecece
*/
case 'line':
var data = input.data();
var myChart = new Chart(input.get(0).getContext('2d'), {
type: 'line',
data: {
labels: data.labels,
datasets: [{
label : input.html(),
data: data.values,
borderColor: [data.color]
}]
},
options: {
scales: {
yAxes: [{
ticks: {
beginAtZero:true
}
}]
}
}
});
break;
/**
* data-filter-country : filtre par pays à rechercher séparés par virgule (format ISO 3 numériques, ex : FRA)
* data-filter-items : nb de résultats à retourner
* data-filter-language : langue dans laquelle retourner les résultats
*
* data-select-callback : fonction de callback appelée lors de la sélection d'un élément
*
* data-filter-geocode : retourne les infos complémentaires de l'élément sélectionné (latitude, longitude,etc...)
* data-geocode-callback : fonction de callback appelée pour traiter les infos retournées via geocode
*/
case 'location':
input.location({
items: input.attr('data-filter-items'),
language: input.attr('data-filter-language'),
country: input.attr('data-filter-country'),
geocode: input.attr('data-filter-geocode') != null ? true : false,
select: function(location){
if(input.attr('data-select-callback')!=null && input.attr('data-select-callback').length) {
var select = input.attr('data-select-callback').replace(/[^a-z0-9]/i,'_');
if(window[select] !=null) window[select](location);
}
},
geocode: function(location){
$.action({
action: 'location_detail_search',
locationId: location.locationId
}, function(r){
if(input.attr('data-geocode-callback')!=null && input.attr('data-geocode-callback').length) {
var geocode = input.attr('data-geocode-callback').replace(/[^a-z0-9]/i,'_');
if(window[geocode] !=null) window[geocode](r);
}
});
}
});
var data = input.data();
input.removeData();
input.data({
type : data.type,
country : data.country,
zip : data.zip,
city : data.city,
complement : data.complement,
street : data.street
});
break;
/**
* data-depth : nb de profondeur de liste (ex: 2, affichera 2 select au maximum), 1 par défaut
* data-slug : le slug de la liste mère à afficher, listes primaires par défaut
* data-value : la valeur de l'entité à récup en base
* data-disable-label : cache le label de sous-liste si mentionné
* data-hierarchy : si mentionné à false, ne récupère pas
* data-parent-id : l'id de la liste parente associée
*/
case 'dictionnary':
var slug = input.attr('data-slug') ? input.attr('data-slug') : "";
var parentId = input.attr('data-parent-id') && input.attr('data-parent-id').length ? input.attr('data-parent-id') : "";
if (!slug.match(/^[a-z\d\-_]+$/i) && parentId == '') return;
$.action({
action : 'load_dictionnary_component',
slug: slug,
parentId : parentId,
hierarchy : input.attr('data-hierarchy') == 'false' ? 0 : 1,
value: input.attr('data-value')
},function(r){
var children = r.content.childs ? r.content.childs : r.content;
input.attr('onchange', 'get_sub_dictionnary(this, "'+input.attr('name')+'",'+1+');');
input.html('');
input.append('');
$.each(children, function (index, value){
if (value.selected) {
input.append('');
get_selected_values(input, value);
}else{
input.append('');
}
});
});
break;
/**
* data-label : le label affiché dans la zone
* data-delete : méthode de suppression de doc de l'entité
* data-save : méthode de sauvegarde de doc de l'entité (si mentionné, save automatique)
* data-readonly: Empeche l'ajout/suppression de documents
* data-allowed : les extensions de fichier acceptées
*/
case 'dropzone':
if(input.find('form').length != 0 || input.find('ul>li').length) break;
if(!input.attr('data-action')) input.attr('data-action','action.php?action=upload_temporary_file');
var readonly = input.attr('data-readonly') == "true" ? true : false;
if(!input.get(0).hasAttribute('id')) input.attr('id',generate_uuid(10));
var customTpl = input.find('> *:not(:visible)');
var customActions = '';
if(customTpl && customTpl.length){
$.each(customTpl, function(i, action){
if(i>2) return;
var valCalc = readonly ? i*28+3 : i*28+25;
customActions += $(action).removeClass('hidden').css('right', valCalc).get(0).outerHTML;
});
}
var preview = '
');
input.append(files);
var filesValues = $('');
input.append(filesValues);
for(var i in valueFiles) {
files.append(Mustache.render(preview,valueFiles[i]));
if(readonly) files.find('li > i.fa-times').remove();
}
if(!valueFiles.length && readonly)
input.append('
Aucun document
');
break;
/**
* data-simple : Si "true" alors interface avec moins de boutons
* data-minimal: Si présent alors affichage simple en mode input inline
*/
case 'wysiwyg':
var buttons = [
['strong','em','underline','del'],
['foreColor', 'backColor'],
['fontfamily'],
['fontsize'],
['undo', 'redo'], // Only supported in Blink browsers
['formatting'],
['superscript', 'subscript'],
['link'],
['insertImage'],
['table'],
['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull'],
['unorderedList', 'orderedList'],
['horizontalRule'],
['removeformat'],
['fullscreen'],
['viewHTML']
]
if(input.attr('data-simple')!=null || input.attr('data-simple') == 'true'){
buttons = [
['strong','em','underline','del'],
['foreColor', 'backColor'],
['undo', 'redo'], // Only supported in Blink browsers
['formatting'],
['link'],
['unorderedList', 'orderedList'],
['insertImage']
]
}
if(input.attr('data-buttons')!=null && input.attr('data-buttons')!=''){
buttons = [ input.attr('data-buttons').split(',') ];
}
var defaultOptions = {
btns: buttons,
lang: 'fr',
autogrow: input.attr('data-minimal') == null,
semantic: false,
plugins : {}
};
var data = input.data();
defaultOptions.tagsToRemove= ['script', 'link'];
var scriptAllow = input.get(0).hasAttribute('data-script-allow');
if(scriptAllow){
defaultOptions.tagsToRemove= [];
}
// gestion des mentions
defaultOptions.plugins.mention = {keys : {}};
if(input.attr('data-mention-user') == 'true'){
//mention @
defaultOptions.plugins.mention.keys['@'] = {
load : function(data){
data.event.preventDefault();
document.execCommand('insertHTML', false, '@');
var inputContainer = $('.mention-user-picker-container');
init_components(inputContainer);
var picker = $('.mention-user-picker-container input');
picker.focus();
var timeout = null;
picker.click(function(){
clearTimeout(timeout);
var value = $(this).val();
inputContainer.remove();
data.editor.focus();
data.textarea.trumbowyg('restoreRange');
document.execCommand('insertHTML', false, '@'+value+' ');
data.editor.trigger('keyup');
}).blur(function(){
//on supprime le composant si blur sans valeur (attente de 200 ms car le blur est trigger avant le click)
timeout = setTimeout(function(){
inputContainer.remove();
data.editor.trigger('keyup');
},200);
});
picker.keydown(function(e){
var code = e.keyCode || e.which;
//Si appuis sur espace ça casse l'autocompletion
if(code == 32){
e.preventDefault();
var value = picker.val();
$('.mention-user-picker-container').remove();
data.editor.focus();
data.textarea.trumbowyg('restoreRange');
document.execCommand('insertHTML', false, '@'+value+' ');
data.editor.trigger('keyup');
}
});
}
};
}
if(input.attr('data-mention-object') && input.attr('data-mention-object') != ''){
//mention #
defaultOptions.plugins.mention.keys['#'] = {
load : function(data){
data.event.preventDefault();
document.execCommand('insertHTML', false, '#');
var picker = $('.mention-object-picker');
picker.focus();
picker.keydown(function(e){
var code = e.keyCode || e.which;
//Si appuis sur espace ça casse l'autocompletion
if(code == 32){
e.preventDefault();
var value = picker.val();
$('.mention-object-picker-container').remove();
data.editor.focus();
data.textarea.trumbowyg('restoreRange');
document.execCommand('insertHTML', false, '#'+value+' ');
data.editor.trigger('keyup');
}
});
var timeout = null;
picker.autocomplete({
action : input.attr('data-mention-object'),
skin : function(item){
var html = '';
var re = new RegExp(picker.val(),"gi");
name = item.name.replace(re, function (x) {
return ''+x+'';
});
html += '
'+name+'';
html += '';
return html;
},
highlight : function(item){
return item;
},
onClick : function(selected,element){
clearTimeout(timeout);
picker.val('');
$('.mention-object-picker-container').remove();
data.textarea.trumbowyg('restoreRange');
slug = selected.slug ? selected.slug : selected.name;
document.execCommand('insertHTML', false, '#'+slug+' ');
data.editor.trigger('keyup');
},
onBlur : function(selected){
if(input.val() == '') picker.val('');
timeout = setTimeout(function(){
$('.mention-object-picker-container').remove();
data.editor.trigger('keyup');
},200);
}
});
}
};
}
var options = $.extend(defaultOptions,data);
var obj = input.trumbowyg(options);
//fix pour accepter les tags non sémantiques dans la gestion du highlight de bouttons
trumb = input.data('trumbowyg');
trumb.tagToButton['b'] = 'strong';
trumb.tagToButton['i'] = 'em';
trumb.tagToButton['u'] = 'underline';
input.data('trumbowyg',trumb);
obj.data('trumbowyg',trumb);
obj.on('tbwblur', function(){ input.trigger('blur'); });
var trumbowygBox = $(input).closest('div.trumbowyg-box');
trumbowygBox.addClass(input.attr('class')).removeClass('trumbowyg-textarea');
if(input.attr('required')) trumbowygBox.attr('required', true);
if(input.val()!='')
input.trumbowyg('html', input.val());
if(input.attr('data-minimal') != null){
trumbowygBox.addClass('trumbowyg-minimal');
var btnPane = trumbowygBox.find('.trumbowyg-button-pane');
var editor = trumbowygBox.find('.trumbowyg-editor');
btnPane.addClass('hidden');
editor.removeAttr('style').keydown(function(e) {
$(this).find('*').removeProp('font-size');
switch (e.keyCode) {
case 13:
return false;
break;
default:
return true;
break;
}
}).on('paste',function(e){
e.preventDefault();
e.stopImmediatePropagation();
var text = (e.originalEvent || e).clipboardData.getData('text/plain');
document.execCommand("insertHTML", false, text);
});
}
break;
/**
* Permet la recherche combinatoire multi critères.
* Voir filter.component.js pour plus d'infos.
*/
case 'filter':
var box = new FilterBox(input,input.data());
break;
/**
* data-toggle-event : Pour le moment, que "hover", de base au click
* data-show-strength: Si indiqué, affiche la barre de force du mot de passe renseigné dans l'input
* data-generator : Si indiqué, affiche une icône pour géénrer un mdp sécurisé
*/
case 'password':
if(input.closest('.password-field').length) return;
input.attr('type', 'password');
input.wrap(function() {return '';});
var container = input.parent('.password-field');
container.append('');
container.find('i.password-toggler').attr((input.attr('data-toggle-event') == 'hover')?{
'onmouseover': 'toggle_password(this);',
'onmouseleave': 'toggle_password(this);'
}:{'onclick': 'toggle_password(this);'});
if(input.attr('data-generator') !== undefined) {
container.append('')
container.find('i.password-generator').on('click', function(){
if(input.val()!='' && !confirm('Attention, un mot de passe est déjà défini.\nVoulez-vous quand même en générer un nouveau ?')) return;
//regex norme ANSSI
var strong = new RegExp('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[=/\()%ยง!@#$%^&*])(?=.{12,})');
do {
password = generate_password();
} while(!strong.test(password))
input.val(password);
if(input.attr('data-show-strength') !== undefined)
check_password_strength(input);
});
function generate_password(){
var password = "";
var charset = get_characters_set();
var length = Math.ceil(parseFloat(78) * Math.log(2) / Math.log(charset.length));
for (var i=0; i
');
// check_password_strength($('input[data-type="password"][data-show-strength]'));
// Strength validation on keyup-event
input.on("keyup mouseup", function(e) {
check_password_strength($(this));
});
//Check password strength
function check_password_strength(input) {
var value = $(input).val();
var container = $(input).closest('.password-field');
$(".line", container).removeClass("strength-low strength-medium strength-hard").addClass("strength-transparent");
if(!value.length) return;
var strongRegex = new RegExp('^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[=/\()%ยง!@#$%^&*])(?=.{12,})'),
mediumRegex = new RegExp('^(((?=.*[a-z])(?=.*[A-Z]))|((?=.*[a-z])(?=.*[0-9]))|((?=.*[A-Z])(?=.*[0-9])))(?=.{6,})');
if(strongRegex.test(value)) {
$(".line", container).removeClass("strength-transparent").addClass("strength-hard");
} else if (mediumRegex.test(value)) {
$(".line:not(:last-of-type)", container).removeClass("strength-transparent").addClass("strength-medium");
} else {
$(".line:nth-child(1)", container).removeClass("strength-transparent").addClass("strength-low");
}
}
}
break;
case 'icon':
input.addClass('hidden');
input.next('.component-icon').remove();
var data = {
value : input.val(),
choices : []
};
var icons = $.fontAwesome();
var line = [];
for(var key in icons){
if(line.length==15){
data.choices.push(line);
line = [];
}
line.push(icons[key].icon);
}
var selector = $(Mustache.render($('.component-icon.hidden').get(0).outerHTML,data));
selector.addClass(input.attr('class'));
selector.removeClass('hidden form-control');
input.after(selector);
selector.on('show.bs.dropdown', function () {
setTimeout(function(){selector.find('input.form-control').focus();},0);
})
selector.find('.dropdown-icon-item').click(function(){
selector.find('.dropdown-icon-item').removeClass('hidden');
selector.find('input.form-control').val('');
var icon = $(this).attr('data-icon');
input.val(icon);
selector.find('.dropdown-toggle i').attr('class',icon);
input.trigger('change');
});
selector.find('input.form-control').keyup(function(){
var value = $(this).val();
$('.dropdown-icon-item i',selector).each(function(i,iconElement){
iconElement = $(iconElement);
parent = iconElement.parent();
iconElement.attr('class').indexOf(value)!=-1 ? parent.removeClass('hidden') : parent.addClass('hidden');
});
/*var icon = $(this).attr('data-icon');
input.val(icon);
selector.find('.dropdown-toggle i').attr('class',icon);*/
});
break;
/**
* data-title (*) : Le titre du modal
* data-loaded (*): fonction callback appelée auprès le chargement du modal (bien pour setter des actions custom sur les boutons dans le modal par exemple)
* data-params : Les paramètres utilisés pour l'appel du callback
* data-action (*) : Appel de la modal par action et non par ajax
* data-precall : fonction appelée avant le chargement du modal (méthode de check sur l'UI par exemple)
* Pour customiser l'icône du quickform, il suffit de placer le contenu que l'on veut dans la div de data-type="quickform"
*/
case 'quickform':
if(input.find('span').length) return;
if(input.attr('disabled')) return;
var cbLoaded = input.attr('data-loaded');
// var params = input.attr('data-params') ? input.attr('data-params').split(',') : [];
var params = input.attr('data-params') ? JSON.parse(input.attr('data-params')) : [];
var preCb = input.attr('data-precall') ? input.attr('data-precall') : '';
if(input.find('> *').length){
input.find('> *').wrap('');
} else {
input.append(' div:first-of-type', modal).nextAll().remove();
modal.clear();
$('form', modal).attr('data-id','');
if(cbLoaded) window[cbLoaded](params);
modal.modal('show');
init_components('#quickform-modal');
});
});
});
break;
/**
* data-class : Classe custom à ajouter au conteneur du l'input
*/
case 'checkbox':
//3 cas possibles :
// - input sans rien, data-type="checkbox" --> on fait tout
// - input avec coquille sans data-uuid, --> on génère simplement un data-uuid et maj valeur
// - input avec coquille et data-uuid --> on maj simplement sa valeur
if(input.get(0).hasAttribute('data-uuid')) return;
if(input.attr('type') != 'checkbox') input.attr('type', 'checkbox');
if(!input.closest('label.check-component').length) {
var labelBox = $('');
var checkbox = $('');
var id = input.attr('id');
var title = input.attr('title');
var customClass = input.attr('data-class');
if(id) labelBox.attr('for', id);
if(title) labelBox.attr('title', title);
if(customClass) labelBox.addClass(customClass);
if(input.prop('disabled') == true) labelBox.attr('disabled', true);
input.removeAttr('title data-class').wrap(labelBox);
input.after(checkbox);
}
var uuid = generate_uuid(15);
input.attr('data-uuid', uuid);
if(input.get(0).hasAttribute('id')) return;
input.closest('label.check-component').off('click','div.box').on('click','div.box',function(e){
var checkboxInput = $('input[data-uuid="'+uuid+'"]');
checkboxInput.prop('checked', checkboxInput.prop('checked'));
});
break;
/**
* data-label : Libellé affiché à côté de l'input radio
* name (*) : Le nom du groupe dont fait partie l'input radio
*/
case 'radio':
if(input.get(0).hasAttribute('data-uuid')) return;
if(input.attr('type') != 'radio') input.attr('type', 'radio');
var uuid = generate_uuid(15);
var id = input.get(0).hasAttribute('id')? input.attr('id') : '';
var title = input.get(0).hasAttribute('title') ? input.attr('title') : '';
var label = input.attr('data-label');
var labelBox = $('');
labelBox.attr({
'for': id,
'title': title
});
if(input.prop('disabled') == true) labelBox.attr('disabled', true);
input.addClass('radio-component').removeAttr('title data-label').attr('data-uuid', uuid);
input.after(labelBox);
if(label) labelBox.after('');
if(input.attr('id') && input.attr('id').length) return;
labelBox.click(function(e){
var radioInput = $('input[data-uuid="'+uuid+'"]');
if(radioInput.prop('disabled') != true) radioInput.prop('checked', true);
});
break;
/**
* data-action : l'action php pour récupérer l'UI de la card
* data-parameters : paramètres à passer avec l'action json encodés
*/
case 'card':
if(!input.is(':visible')) return;
var action = input.attr('data-action');
if(!action) {
console.warn('CARD COMPONENT: Need "data-action" to get card content');
return;
}
var showDelay = input.attr('data-show-delay') ? input.attr('data-show-delay') : 0;
var hideDelay = input.attr('data-hide-delay') ? input.attr('data-hide-delay') : 600;
var parameters = input.attr('data-parameters');
var data = parameters ? JSON.parse(parameters) : {};
data.action = action;
input.addClass('card-component-container');
$(document).ready(function(){
var timeout;
input.mouseenter(function(event){
var e = event.target || event.relatedTarget;
if (e.parentNode != this && e != this) return;
event.stopImmediatePropagation();
event.stopPropagation();
$('*[data-type="card"]').find('.card-component')
.addClass('card-component-hide')
.removeClass('card-component-hover')
.one('webkitAnimationEnd oanimationend msAnimationEnd animationend',
function(e) {
$(this).closest('.wrapper').remove();
});
timeout = setTimeout(function(){
var currInput = input;
if(!currInput.find('.card-component').length) {
$.action(data, function(r){
if(!r.content) return;
//On utilise un wrapper pour gérer les overflows "out of the box"
var card = $(r.content);
var topOffset = currInput.offset().top;
currInput.append(card);
var cardWidth = card.outerWidth();
var position = {};
card.wrap($(''));
card.addClass('card-component card-component-hover');
if($('body').width() < (currInput.offset().left + cardWidth))
position['right'] = cardWidth;
else
position['left'] = 0;
var cardHeight = card.outerHeight();
var htmlHeight = $('html').height();
if(htmlHeight-100 < (topOffset + cardHeight)){
var spaceBottom = htmlHeight-topOffset;
var height = 0;
if(spaceBottom > topOffset){
if(cardHeight > spaceBottom) height = (spaceBottom-100);
} else {
position['top'] = -cardHeight;
if(cardHeight > topOffset){
height = (topOffset-100);
position['top'] = -(topOffset-100);
}
}
if(height!=0){
card.css({
height: height+'px',
'overflow-y': 'auto',
'overflow-x': 'hidden'
});
}
}
currInput.find('.wrapper').css(position);
});
} else {
var card = $(currInput.find('.card-component'));
card.addClass('card-component-hover').removeClass('card-component-hide');
}
clearTimeout(currInput.data('tOutbox'));
}, showDelay);
});
input.add(input.find('.card-component')).mouseleave(function(e){
// e.stopImmediatePropagation();
// e.stopPropagation();
var input = $(this),
card = input.find('.card-component'),
tOutbox = setTimeout(function(){
if(!$('.card-component:hover').length) {
card.addClass('card-component-hide').removeClass('card-component-hover');
card.one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function(e) {
$(this).closest('.wrapper').remove();
});
}
}, hideDelay);
//Clear du timeout d'apparition
clearTimeout(timeout);
//Set du l'id de timeout, permet de clear ce trigger si la souris revient sur l'input
input.data('tOutbox', tOutbox);
});
});
break;
/**
* data-dictionnary : Le slug du dictionnary à utiliser
*/
case 'dictionnary-table':
if(input.hasClass('component-dictionnary-table')) return;
if(!input.attr('data-dictionnary') || !input.attr('data-dictionnary').length) return;
var tpl = $('.component-dictionnary-table').get(0).outerHTML;
var inputData = input.data();
$.action({
action: 'load_dictionnary_component',
slug : input.attr('data-dictionnary')
},function(r){
var list = $(Mustache.render(tpl,{label:'{{label}}', slug:'{{slug}}', id:'{{id}}',parent:r.content}));
input.append(list);
list.removeClass('hidden');
dictionnary_table_refresh(list);
//Save
$(input).on('click','thead .btn-success',function(){
var line = $(this).closest('tr');
var data = {
action: inputData.saveAction ? inputData.saveAction : 'dictionnary_table_save',
label: line.find('input.list-label').val(),
id: list.attr('data-id'),
list: list.attr('data-dictionnary')
};
if(list.find('input.list-slug')) data.slug = $('input.list-slug', list).val();
$.action(data, function(r){
list.attr('data-id', '');
line.find('input').val('');
$.message('success','Enregistré');
dictionnary_table_refresh(list);
});
});
//Suppression
$(input).on('click','tbody tr .btn-danger',function(){
if(!confirm('Êtes-vous sûr de vouloir supprimer cet élément de liste ?')) return;
var line = $(this).closest('tr');
$.action({
action: inputData.deleteAction ? inputData.deleteAction : 'delete_dictionnary',
id: line.attr('data-id')
},function(r){
line.remove();
line.closest('.edit-field').val('');
$.message('info', 'Élément de liste supprimé');
});
});
//Édition
$(input).on('click','tbody tr .btn-edit',function(){
var line = $(this).closest('tr');
$.action({
action: inputData.editAction ? inputData.editAction : 'edit_dictionnary',
id: line.attr('data-id')
},function(r){
list.find('input.list-label').val(r.label);
if(list.find('input.list-slug')) $('input.list-slug', list).val(r.slug);
list.attr('data-id',r.id);
});
});
});
break;
//Permet aux plugins d'ajouter leurs composants
//via la fonction init_components_nomcomposant(input);
default:
var type = input.attr('data-type').replace(/[^a-z0-9]/i,'_');
if(window['init_components_'+type] !=null) window['init_components_'+type](input);
break;
}
});
$('[data-tooltip]').each(function(){
var element = $(this);
var options = {html:true};
if(element.attr('data-placement')) options.placement = element.attr('data-placement');
element.tooltip(options);
});
}
/** PRELOADER **/
var detached;
function preloader(parent, mode){
var mode = mode!=null ? mode : 'add';
if(['toggle', 'add', 'delete'].indexOf(mode) === -1) return;
var parent = $(parent);
var loader = $('
');
switch (mode) {
case 'add':
parent.html(loader);
break;
case 'delete':
parent.find('div.loader-container').remove();
break;
case 'toggle':
if(parent.find('div.loader-container').length) {
parent.find('div.loader-container').remove();
parent.append(detached);
} else {
detached = parent.find('>*').detach();
parent.html(loader);
}
break;
default:
break;
}
}
/** BACK TO TOP **/
$('#scroll-top').click(function() {
scroll_top(150);
});
// Affichage du bouton dès lors où l'on a scrollé
$(window).on('scroll', function(){
scrollPos = $(document).scrollTop();
if (scrollPos >= 100) {
$('#scroll-top').addClass('active');
} else {
$('#scroll-top').removeClass('active');
}
});
//Permet de scroller en haut de page
function scroll_top(time){
$('html,body').animate({scrollTop:0},time);
}
/** CONTRÔLES DATE ET HEURE **/
function is_valid_date(string){
var format = /^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]|(?:Jan|Mar|May|Jul|Aug|Oct|Dec)))\1|(?:(?:29|30)(\/|-|\.)(?:0?[1,3-9]|1[0-2]|(?:Jan|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.)(?:0?2|(?:Feb))\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.)(?:(?:0?[1-9]|(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep))|(?:1[0-2]|(?:Oct|Nov|Dec)))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/;
return format.test(string);
}
function is_valid_hour(string){
var format = /^(?:\d|[01]\d|2[0-3]):[0-5]\d$/;
return format.test(string);
}
//SHOW/HIDE PASSWORD
function toggle_password(element){
if ($(element).hasClass('fa-eye-slash')) {
$(element).removeClass('fa-eye-slash').addClass('fa-eye');
$(element).prev('input').attr('type', 'text');
} else {
$(element).removeClass('fa-eye').addClass('fa-eye-slash');
$(element).prev('input').attr('type', 'password');
}
}
/** QUICKFORM **/
function reset_quickform_modal(){
$('.modal form').attr('data-id','');
$('input, textarea', '.modal').each(function(i, v){
if($(v).attr('type') == 'checkbox')
$(v).prop('checked', false);
else
$(v).val('');
});
}
/** CORE **/
//LOGIN
$(document).ready(function(){
$('.login-form').on('keyup', 'input', function(e){
if(e.keyCode == 13) core_login(this);
});
});
function core_login(element,parent){
if(isProcessing) return;
var parent = parent!=undefined ? parent : '#loginRequest';
var form = $(element).closest('form');
var data = form.toJson();
data.redirect = form.attr('data-redirect');
data.url = form.attr('data-url');
var loginBtn = $('#login-button', form);
prevLoginBtn = loginBtn.html();
loginBtn.html(' Connexion');
preloader(parent, 'toggle');
$('.loader-container').append('Connexion en cours');
isProcessing = true;
$.action(data, function(r){
isProcessing = false;
if(r.redirect) window.location = r.redirect;
}, function(r){
isProcessing = false;
$('#password',form).val('');
loginBtn.html(prevLoginBtn);
preloader(parent, 'toggle');
});
}
// INIT - INDEX
function init_index(){
$('#loginHeader #login-button').keypress(function(e){
var key = e.which;
if(key == 13){
$('#login-button').click();
return false;
}
});
}
function init_setting(parameter){
switch(parameter.section){
case 'plugin':
search_plugin();
$('.section-plugin').on('change', 'input.toggle', function(){
var input = $(this);
var button = input.closest('.activator');
var label = $('> label', button).detach();
var value = input.prop('checked');
if(!value) {
if(!confirm("Êtes-vous sûr de vouloir désactiver ce plugin ?\nCela entraînera la suppression de toutes les données associées.")) {
input.prop('checked',!value);
button.prepend(label);
return;
}
button.removeClass('btn-danger').addClass('btn-info').text('Activer').prepend(label);
} else {
button.addClass('btn-danger').removeClass('btn-info').text('Désactiver').prepend(label);
}
$.action({
action : 'change_plugin_state',
plugin : input.closest('li').attr('data-id'),
state: value ? 1 : 0
}, function(r){
}, function(r){
if(button.hasClass('btn-danger'))
button.removeClass('btn-danger').addClass('btn-info').text('Activer').prepend(label);
else if(button.hasClass('btn-info'))
button.removeClass('btn-info').addClass('btn-danger').text('Désactiver').prepend(label);
input.prop('checked',!value);
});
});
break;
case 'user':
search_user();
break;
case 'firm':
search_firm();
break;
case 'firmPlugin':
search_firm_plugin();
break;
case 'userfirmrank':
search_userfirmrank();
break;
case 'log':
$('#logs').sortable_table({
onSort : search_log
});
break;
case 'rank':
search_rank();
break;
case 'dictionnary':
search_dictionnary();
$('#label').blur(function(){
if($('#label').val() != '' && $('#slug').val() == ''){
$('#slug').off('click');
dictionnary_slug_proposal($('#label'), $('#parent'));
}
});
$('#slug').off('click');
$('#slug').on('click', function(){
if($('#label').val() != '' && $('#slug').val() == '')
dictionnary_slug_proposal($('#label'), $('#parent'));
});
break;
case 'right':
search_right();
break;
default:
if(parameter.section!= null){
var section = parameter.section.replace(/[^a-z_0-9]/g,'_');
var init = 'init_setting_'+section;
if(window[init]!=null) window[init]($.urlParam());
}
break;
}
}
/** RIGHT **/
function right_switch(element){
$(element).closest('tr').find('input').trigger('click');
}
/** FORM **/
function send_form(element){
var form = $(element).closest('[data-form]');
var data = $.getForm(form);
var data = {};
for(var key in form.data()){
if(key!="action" && key != "id") continue;
data[key] = form.attr('data-'+key);
}
$('input,select,textarea',form).each(function(i,element){
element = $(element);
if(element.attr('data-id')!=null && element.attr('data-id')!=""){
if(element.attr("type")=='checkbox' || element.attr("type")=='radio'){
data[element.attr('data-id')] = (element.is(':checked')?1:0);
}else{
data[element.attr('data-id')] = element.val();
}
}
});
data.action = 'send_form';
$.action(data,function(r){
});
}
/** LOG **/
// SEARCH
function search_log(callback){
var box = new FilterBox('#filters');
$('#logs').fill({
action:'search_log',
filters : box.filters(),
sort : $('#logs').sortable_table('get')
},function(){
if(callback!=null) callback();
});
}
/** USER FIRM RANK**/
// SEARCH
function search_userfirmrank(callback){
$('#userfirmranks').fill({firm : $('#firm').val(),action:'search_userfirmrank'},function(){
if(callback!=null) callback();
});
}
// SAVE
function save_userfirmrank(element){
if(isProcessing) return;
var button = $(element);
var data = $.getForm('#userfirmrankForm');
data.id = $('#userfirmrankForm').attr('data-id');
button.html(' Enregistrement en cours').addClass('disabled');
isProcessing = true;
$.action(data,function(r){
button.html(' Enregistrer').removeClass('disabled');
if(typeof r.success !== 'undefined'){
for(var i = 0; i').closest('form').get(0).reset();
imageComposer.unwrap();
$(element).next('img').attr('src', $(imageComposer).attr('data-default-src'));
$(element).remove();
});
}
/** USER **/
// SEARCH
function search_user(callback){
$('#users').fill({action:'search_user'},function(){
if(callback!=null) callback();
});
}
// SAVE
function save_user(){
var form = $('#userFormAdmin');
var data = $.getForm(form);
data.id = form.attr('data-id');
$.action(data,function(r){
$.message('success','Utilisateur enregistré');
$('#login').removeAttr('readonly');
$('input',form).val('');
form.attr('data-id','');
init_components(form);
search_user();
});
}
// EDIT
function edit_user(element){
var line = $(element).closest('tr');
$.action({
action:'edit_user',
login:line.attr('data-user')
},function(r){
$.setForm('#userFormAdmin',r);
$('#userFormAdmin').attr('data-id',r.id);
$('#login').attr('readonly', true);
init_components('#userFormAdmin');
scroll_top(150);
});
}
// DELETE
function delete_user(element){
if(!confirm('Êtes vous sûr de vouloir supprimer cet utilisateur ?')) return;
var line = $(element).closest('tr');
$.action({
action : 'delete_user',
login : line.attr('data-user')
},function(r){
$.message('info','Utilisateur supprimé');
$('#userFormAdmin').attr('data-id','');
reset_inputs($('#userFormAdmin'));
$('#login').removeAttr('readonly');
line.remove();
});
}
/* ACCOUNT **/
function account_lost_password(element){
if(isProcessing) return;
var btn = $(element);
btn.addClass('btn-preloader').attr('disabled', true);
isProcessing = true;
$.action({
action: 'account_lost_password',
mail : $('#mail').val()
}, function(r){
isProcessing = false;
$.message('success','Confirmation envoyée par e-mail');
btn.removeAttr('disabled');
}, function(r){
isProcessing = false;
btn.removeAttr('disabled');
});
}
function account_save(element){
var data = $('#user-form').toJson();
data.login = $('#login').val();
data.avatar = $('#avatar')[0].files[0];
data.action = 'account_save';
$.action(data, function(r){
$.message('success','Enregistré');
if(r.warning) $.message('warning',r.warning);
});
}
// SUPPRIME AVATAR USER
function account_avatar_delete(element){
if(!confirm('Êtes vous sûr de vouloir supprimer l\'image ?')) return;
var imageComposer = $(element).parent().find("input[data-type='image']");
$.action({
action: 'account_avatar_delete',
login: $('#login').val()
}, function(r){
imageComposer.wrap('