Subversion Repositories eFlore/Applications.cel

Rev

Rev 3226 | Rev 3235 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3167 idir 1
"use strict";
3165 idir 2
 
3174 idir 3
/*************************************
4
 *  Fonctions de Style et Affichage  *
5
 *      des éléments "spéciaux"      *
6
 *************************************/
3168 idir 7
 
3174 idir 8
// Logique d'affichage pour le input type=file
9
function inputFile() {
10
  // Initialisation des variables
11
  var $fileInput  = $( '.input-file' ),
12
      $button     = $( '.label-file' ),
13
      thisId = '';
14
  // Action lorsque la "barre d'espace" ou "Entrée" est pressée
15
  $( '.label-file' ).keydown( function( event ) {
16
    if ( event.keyCode == 13 || event.keyCode == 32 ) {
17
      $( '#' + $( this ).attr( 'for' ) + '.input-file' ).focus();
18
    }
19
  });
20
  // Action lorsque le label est cliqué
21
  $( '.label-file' ).click( function(event) {
22
    $( '#' + $( this ).attr( 'for' ) + '.input-file' ).focus();
23
    return false;
24
  });
25
  // Affiche un retour visuel dès que input:file change
26
  $fileInput.change( function( event ) {
27
    // Il est possible de supprimer un fichier
3226 idir 28
    // donc on vérifie que le 'change' est un ajout ou modificationis-defaut-value
3174 idir 29
    if( !$.isEmptyObject( event.target.files[0] ) ) {
3233 idir 30
 
3174 idir 31
      var file = event.target.files[0],
3233 idir 32
          fileInputId = $( this ).attr( 'id' ),
33
          $theReturn = $( '.' + fileInputId );
3174 idir 34
      // Affichage du nom du fichier
3233 idir 35
      $theReturn.text( file.name ).removeClass( 'hidden') ;
36
 
37
      if( 5242880 < file.size ) {
38
        $theReturn.append(
39
          '<p class="message">'+
40
            '<i class="fa fa-exclamation-triangle" aria-hidden="true" style="color:#ff5d55"></i> '+
41
            'La taille du fichier ne doit pas dépasser 5Mo'+
42
          '</p>'
43
        )
44
        .addClass( 'invalid' );
45
        // lib : https://resources.tela-botanica.org/jquery/form/3.51/jquery.form.min.js
46
        $( this ).clearInputs();
47
        console.log(file);
48
 
49
      } else if( file.type.match( 'image/*' ) && 'especes' !== fileInputId ) {
50
      // Si le fichier est une image (et qu'on est pas sur "especes") on l'affiche
3174 idir 51
        // Chemin temporaire de l'image et affichage
52
        var tmppath = URL.createObjectURL( file );
3233 idir 53
        $theReturn.append( '<img src="' + tmppath + '" width="50%">' ).removeClass( 'invalid' );;
54
 
55
      } else if ( !( 'especes' === fileInputId && file.type.match( 'text/csv' ) ) ) {
56
        // on a pas un type image, ou on est sur une liste d'espèces mais on a pas un csv
57
 
58
        if( 'especes' === fileInputId ) {// cas où on demandait un csv
59
          $theReturn.append(
60
            '<p class="message">'+
61
              '<i class="fa fa-exclamation-triangle" aria-hidden="true" style="color:#ff5d55"></i> '+
62
              'Le fichier doit être au format csv'+
63
            '</p>'
64
          )
65
          .addClass( 'invalid' );
66
        } else { // cas où on demandait un format image
67
          $theReturn.append(
68
            '<p class="message">'+
69
              '<i class="fa fa-exclamation-triangle" aria-hidden="true" style="color:#ff5d55"></i> '+
70
              'Le fichier doit être au format image (jpg, png, etc.)'+
71
            '</p>'
72
          )
73
          .addClass( 'invalid' );
74
        }
3226 idir 75
        // lib : https://resources.tela-botanica.org/jquery/form/3.51/jquery.form.min.js
76
        $( this ).clearInputs();
77
        console.log(file);
3233 idir 78
      } else {// file "especes" csv ok
79
        $theReturn.append( ' <i class="fa fa-check-circle" aria-hidden="true" style="color:#B3C954;font-size:1.3rem"></i>' ).removeClass( 'invalid' );
3174 idir 80
      }
81
    }
82
  });
83
  // Annuler le téléchargement
84
  $( '.remove-file' ).click( function() {
85
    var $thisFileInput = $( this ).prev( '.input-file-container' ).find( '.input-file' );
3226 idir 86
    // lib : https://resources.tela-botanica.org/jquery/form/3.51/jquery.form.min.js
87
    $thisFileInput.clearInputs();
3174 idir 88
    $thisFileInput.triggerHandler( 'change' );
3226 idir 89
    // $thisFileInput.unwrap();
3174 idir 90
    $( this ).next( '.file-return' ).addClass( 'hidden' ).empty();
91
  });
92
}
3165 idir 93
 
3174 idir 94
// Style et affichage des list-checkboxes
95
function inputListCheckbox() {
96
  // On écoute le click sur une list-checkbox ('.selectBox')
97
  // à tout moment de son insertion dans le dom
3185 idir 98
  $( '#zone-appli' ).on( 'click' , '.selectBox' , function() {
3226 idir 99
    $( '.checkboxes[data-id="' + $(this).data( 'id' ) + '"]' ).toggleClass( 'hidden' );
3174 idir 100
  });
101
}
3165 idir 102
 
3186 idir 103
// Style et affichage des input type="range"
3185 idir 104
function inputRangeDisplayNumber() {
105
  $( '#zone-supp' ).on( 'input' , '.range input[type="range"]' , function () {
106
    $( this ).next( 'input[type="number"]' ).val ( $( this ).val() );
107
  });
108
  $( '#zone-supp' ).on( 'input' , '.range input[type="number"]' , function () {
109
    $( this ).prev( 'input[type="range"]' ).val ( $( this ).val() );
110
  });
3174 idir 111
}
3168 idir 112
 
3167 idir 113
/***********************************************************
114
 *  Fonctions pour la création des champs supplémentaires  *
115
 ***********************************************************/
116
 
117
// Logique globale pour l'ajout de nouveaux champs
3171 idir 118
function onClickAddNewFields( fieldIndex ) {
3174 idir 119
  // Bouton ajouter un champ
3167 idir 120
  $( '#add-fields' ).click( function() {
3174 idir 121
    // Affichage du formulaire pour un champ
3171 idir 122
    displayNewField( fieldIndex );
3174 idir 123
    // Affichage du nom du champ
3171 idir 124
    onChangeDisplayFieldLabel( fieldIndex );
3176 idir 125
    // Empêcher de créer plus d'une fois la même clé
126
    onChangeCheckKeyUnique();
3174 idir 127
    // Affichage des images/nom des documents importés dans les champs ajoutés
128
    inputFile();
129
    // Recueil des informations correspondantes au nouveau champ
3171 idir 130
    onChangeFieldTypeCollectDetails( fieldIndex );
3167 idir 131
    // Suppression d'un champ
132
    onClickRemoveField();
133
 
3171 idir 134
    fieldIndex++;
3167 idir 135
  });
3165 idir 136
}
137
 
3174 idir 138
// Création/affichage du formulaire d'un nouveau champ
3171 idir 139
function displayNewField( fieldIndex ) {
3174 idir 140
  // Html du formulaire du nouveaux champs inséré dans le dom
3168 idir 141
  $( '#new-fields' ).append(
3174 idir 142
    '<fieldset data-id="' + fieldIndex + '" class="new-field">'+
143
      '<h3>Nouveau champ :<br><strong class="field-title" data-id="' + fieldIndex + '"></strong></h3>'+
3167 idir 144
      // Nom du champ
3174 idir 145
      '<label for="field-name" title="Donnez un titre à votre champ">Nom du champ *</label>'+
3233 idir 146
      '<input type="text" name="field-name" data-id="' + fieldIndex + '" class="field-name" placeholder="Titre de votre champ" title="Le titre du champ" required>'+
3168 idir 147
      // Clé du champ
3174 idir 148
      '<label for="field-key" title="Nom du champ dans la base de données">'+
3178 idir 149
        'Clé du champ *'+
3168 idir 150
      '</label>'+
3233 idir 151
      '<input type="text" name="field-key" data-id="' + fieldIndex + '" class="field-key" placeholder="Clé du champ" pattern="^(?:[a-z]+(?:(?:[A-Z]+[a-z]+)+)?|[a-z]+(?:(?:-[a-z]+)+)?)$" title="Clé Unique en Camelcase ou minuscule séparés par tirets, pas d\'accents pas de caractères spéciaux." required>'+
3178 idir 152
      '<p class="message">' +
153
        '<i class="fa fa-exclamation-triangle" aria-hidden="true" style="color:#ff5d55"></i> '+
154
        'Une clé doit être unique<br>' +
3226 idir 155
        'En "camelCase" (ecriture chameau)<br>'+
156
        'Ou en minuscule avec tirets ("-") si nécessaire<br>'+
157
        'Pas d\'espaces, aucuns caractères spéciaux (accents, cédilles, etc.).' +
3178 idir 158
      '</p>' +
3167 idir 159
      // Type de champ
3174 idir 160
      '<label for="field-element" title="Quel type de champ">Type de champ *</label>'+
161
      '<div class="select-wrapper add-field-select" data-id="' + fieldIndex + '">'+
162
        '<select name="field-element" data-id="' + fieldIndex + '" class="field-element">'+
163
          '<option value="text">Champ texte</option>'+
3167 idir 164
          '<option value="email">Champ email</option>'+
165
          '<option value="textarea">Champ rédaction</option>'+
166
          '<option value="select">Menu déroulant</option>'+
167
          '<option value="checkbox">Cases à cocher</option>'+
3174 idir 168
          '<option value="list-checkbox">Liste de cases à cocher</option>'+
3167 idir 169
          '<option value="radio">Boutons radio</option>'+
170
          '<option value="date">Calendrier</option>'+
3174 idir 171
          '<option value="range">Curseur (entre 2 bornes)</option>'+
3167 idir 172
          '<option value="number">Nombre</option>'+
173
        '</select>'+
174
      '</div>'+
3168 idir 175
      // Checkbox "champ requis"
176
      '<label for="field-is_mandatory" title="Ce champ est obligatoire">Champ requis ?</label>'+
3174 idir 177
      '<input type="checkbox" name="field-is_mandatory" data-id="' + fieldIndex + '" class="field-is_mandatory">'+
3168 idir 178
      // Unité des valeurs
179
      '<label for="field-unit" title="Unité de mesure de vos valeurs">Unités ( cm, kg, ha, etc.)</label>'+
3174 idir 180
      '<input type="text" name="field-unit" data-id="' + fieldIndex + '" class="field-unit" placeholder="symbole de vos unités">'+
3167 idir 181
      // Tooltip
3168 idir 182
      '<label for="field-description" title="Ajoutez une info-bulle">Info-bulle</label>'+
3174 idir 183
      '<input type="text" name="field-description" data-id="' + fieldIndex + '" class="field-description" placeholder="Quelques mots">'+
3226 idir 184
      // Import d'une image d'aide à afficher en popup
3167 idir 185
      '<div class="input-file-container">'+
3226 idir 186
        '<input type="file" class="input-file field-help" name="field-help' + fieldIndex + '" data-id="' + fieldIndex + '" id="help-doc-' + fieldIndex + '" accept="image/*">'+
187
        '<label for="field-help' + fieldIndex + '" class="label-file"><i class="fas fa-download"></i> Popup aide image (.jpg)</label>'+
3167 idir 188
      '</div>'+
3174 idir 189
      '<div class="remove-file button" name="remove-file" data-id="' + fieldIndex + '" title="Supprimer le fichier"><i class="fas fa-times" aria-hidden="true"></i></div>'+
190
      '<div class="file-return help-doc-' + fieldIndex + ' hidden"></div>'+
191
      // Boutons supprimer
192
      '<label for="remove-field">Supprimer</label>'+
193
      '<div class="remove-field button" name="remove-field" data-id="' + fieldIndex + '" title="Supprimer un champ"><i class="fa fa-skull" aria-hidden="true"></i></div>'+
194
    '</fieldset>'
3168 idir 195
  );
196
  // Animation de l'affichage
3174 idir 197
  $( 'fieldset.new-field[data-id="' + fieldIndex + '"]').hide().show( 200 );
3168 idir 198
}
3167 idir 199
 
3168 idir 200
// Affichage du nom du champ dès qu'il est renseigné
3171 idir 201
function onChangeDisplayFieldLabel( fieldIndex ) {
3174 idir 202
  $('.field-name[data-id="' + fieldIndex + '"]').change( function() {
203
    $( '.field-title[data-id="' + fieldIndex + '"]' ).text( $( this ).val() );
3168 idir 204
  });
3167 idir 205
}
3166 idir 206
 
3174 idir 207
// Supprimer un nouveau champ
3226 idir 208
function onClickRemoveField () {
3174 idir 209
  $( '.remove-field' ).click( function() {
3226 idir 210
    $( this ).closest('fieldset').hide( 200 , function () {
211
      $( this ).remove();
3174 idir 212
    });
3167 idir 213
  });
214
}
3165 idir 215
 
3171 idir 216
 
3167 idir 217
/**** Recueil des informations et détails qui dépendent du type de champ choisi ****/
3166 idir 218
 
3167 idir 219
// Logique de recueil d'informations en fonction du type de champ choisi
3171 idir 220
function onChangeFieldTypeCollectDetails( fieldIndex ) {
3174 idir 221
  // On insère les champs par défaut de recueil d'informations
222
  displayFieldDetailsCollect(
223
    fieldIndex,
3168 idir 224
    // Placeholder (champ type text par défaut)
225
    '<label for="aide-saisie" title="Aidez les utilisateurs en deux ou 3 mots ou chiffres à comprendre ce que doit contenir le champ">Texte d\'aide à la saisie</label>'+
3174 idir 226
    '<input type="text" name="aide-saisie" data-id="' + fieldIndex + '" class="aide-saisie" placeholder="Ce que doit contenir le champ">'
227
  );
3171 idir 228
  // Sinon :
3174 idir 229
  $( '.field-element[data-id="' + fieldIndex + '"]' ).change( function() {
3171 idir 230
    // On intialise l'index pour les listes la variable qui contiendra un id pour chaque option
231
    var valueIndex = 0;
3167 idir 232
    // Si on hésite on qu'on se trompe dans la liste :
233
    // les champs de détails de l'option précédente doivent être supprimés
3174 idir 234
    $( '.field-details[data-id="' + fieldIndex + '"]' ).hide( 200 , function () {
3226 idir 235
      $( this ).remove();
3174 idir 236
    });
3167 idir 237
 
3174 idir 238
    // Html de recueil de données en fonction de l'élément choisi
3167 idir 239
    switch( $( this ).val() ) {
240
      case 'number':
241
      case 'range':
3174 idir 242
        displayFieldDetailsCollect(
243
          fieldIndex,
244
          '<p class="message"><i class="fa fa-exclamation-triangle" aria-hidden="true" style="color:#ff5d55"></i> Ne pas oublier de changer, si nécessaire, les valeurs step, min et max</p>' +
3167 idir 245
          // Placeholder
3168 idir 246
          '<label for="aide-saisie" title="Deux ou 3 mots ou chiffres pour comprendre ce que doit contenir le champ (ex: min 20, 10 par 10, etc.)">Texte d\'aide à la saisie</label>'+
3174 idir 247
          '<input type="text" name="aide-saisie" data-id="' + fieldIndex + '" class="aide-saisie" placeholder="Ce que doit contenir le champ">'+
3167 idir 248
          // Valeur par défaut
3168 idir 249
          '<label for="default" title="Valeur par défaut">Valeur par défaut</label>'+
3197 idir 250
          '<input type="number" name="default" data-id="' + fieldIndex + '" class="default" step="0.01" lang="en">'+
3167 idir 251
          // Incrémentation ( attribut step="" )
3174 idir 252
          '<label for="step" title="De 10 en 10, de 0.5 en 0.5, etc.">Incrémentation (step) :<br>defaut = +1</label>'+
3197 idir 253
          '<input type="number" name="step" data-id="' + fieldIndex + '" class="step" step="0.01" value="1" lang="en">'+
3167 idir 254
          // Min
255
          '<label for="min" title="valeur min">Valeur minimale</label>'+
3197 idir 256
          '<input type="number" name="min" data-id="' + fieldIndex + '" class="min" step="0.01" value="0" lang="en">'+
3167 idir 257
          // Max
258
          '<label for="max" title="valeur max">Valeur maximale</label>'+
3197 idir 259
          '<input type="number" name="max" data-id="' + fieldIndex + '" class="max" step="0.01" value="1" lang="en">'
3174 idir 260
        );
3167 idir 261
        break;
262
 
263
      case 'date':
3174 idir 264
        displayFieldDetailsCollect(
265
          fieldIndex,
3167 idir 266
          // Date min
3174 idir 267
          '<label for="min" title="date min">Date minimale</label>'+
3197 idir 268
          '<input type="date" name="min" data-id="' + fieldIndex + '" class="min" pattern="(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)" title="jj/mm/aaaa">'+
3167 idir 269
          // Date max
3174 idir 270
          '<label for="max" title="date max">Date maximale</label>'+
3197 idir 271
          '<input type="date" name="max" data-id="' + fieldIndex + '" class="max"  pattern="(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)" title="jj/mm/aaaa">'
3174 idir 272
        );
3167 idir 273
        break;
274
 
275
      case 'select':
276
      case 'checkbox':
277
      case 'list-checkbox':
278
      case 'radio':
3174 idir 279
        displayFieldDetailsCollect(
280
          fieldIndex,
3188 idir 281
          '<p class="message element-message">' +
282
            '<i class="fa fa-exclamation-triangle" aria-hidden="true" style="color:#ff5d55"></i> ' +
283
            'Entrez au moins une valeur de ' + $( this ).children( 'option:selected' ).text() +
284
          '</p>'+
285
          // Première option
286
          '<div class="new-value" data-list-value-id="' + valueIndex +'">'+
287
            // Recueil d'une valeur de la liste
288
            '<label for="list-value">Valeur *:</label>'+
289
            '<input type="text" name="list-value" data-id="' + fieldIndex + '" class="list-value" data-list-value-id="' + valueIndex +'" placeholder="Une des valeurs de la liste" required>'+
290
            // Checkbox valeur par défaut
291
            '<label for="is-defaut-value" title="Ceci est la valeur par défaut">Valeur par défaut</label>'+
292
            '<input type="checkbox" name="is-defaut-value" data-id="' + fieldIndex + '" class="is-defaut-value" title="entrez une valeur pour activer cette case" data-list-value-id="' + valueIndex +'" disabled >'+
293
          '</div>' +
3167 idir 294
          // Bouton ajout d'une valeur à la liste
3174 idir 295
          '<label for="add-value" class="add-value" data-id="' + fieldIndex + '" title="Ajouter une valeur à la liste">Ajouter une valeur</label>'+
296
          '<div class="button add-value-button" name="add-value" data-id="' + fieldIndex + '" title="Ajouter une valeur à la liste"><i class="fa fa-puzzle-piece" aria-hidden="true"></i></div>'+
3167 idir 297
          // checkbox ajouter une valeur "Autre:"
298
          '<label for="option-other-value" title="Ajouter une option \'Autre:\' à la fin">Valeur "Autre"</label>'+
3174 idir 299
          '<input type="checkbox" name="option-other-value" data-id="' + fieldIndex + '" class="option-other-value" title="Ajouter une option \'Autre\' à la fin">'
300
        );
3168 idir 301
        break;
302
 
303
      case 'email':
3167 idir 304
      case 'text':
305
      case 'textarea':
306
      default:
3174 idir 307
        displayFieldDetailsCollect(
308
          fieldIndex,
3167 idir 309
        // Placeholder
310
        '<label for="aide-saisie" title="Aidez les utilisateurs en deux ou 3 mots ou chiffres à comprendre ce que doit contenir le champ">Texte d\'aide à la saisie</label>'+
3174 idir 311
        '<input type="text" name="aide-saisie" data-id="' + fieldIndex + '" class="aide-saisie" placeholder="Ce que doit contenir le champ">'
312
      );
3167 idir 313
        break;
314
    }
315
    // Ajout des valeurs possibles
316
    // lorsque le champ est une liste ou case à cocher
3171 idir 317
    onClickAddNewValueToList( fieldIndex , valueIndex );
3167 idir 318
  });
3165 idir 319
}
320
 
3167 idir 321
// Insertion dans le dom des champs de recueil d'informations
3171 idir 322
function displayFieldDetailsCollect( fieldIndex , fieldDetails ) {
3174 idir 323
  $( '.add-field-select[data-id="' + fieldIndex + '"]' ).after(
324
    '<div class="field-details" data-id="' + fieldIndex + '">' +
325
      fieldDetails +
326
    '</div>'
327
  ).hide().show( 200);
3167 idir 328
}
3165 idir 329
 
3167 idir 330
/**** Ajout des valeurs (options) des "champs de listes" (select, checkbox, radio, etc.) ****/
3165 idir 331
 
3174 idir 332
// Ajout des options des listes (deroulantes, cases à cocher etc.)
3171 idir 333
function onClickAddNewValueToList( fieldIndex , valueIndex ) {
3174 idir 334
  $( '.add-value-button[data-id="' + fieldIndex + '"]' ).click( function() {
3188 idir 335
    valueIndex++;
3174 idir 336
    $( '.add-value[data-id="' + fieldIndex + '"]' ).before(
3171 idir 337
      '<div class="new-value" data-list-value-id="' + valueIndex +'">'+
3167 idir 338
        // Recueil d'une valeur de la liste
3174 idir 339
        '<label for="list-value">Valeur  *:</label>'+
340
        '<input type="text" name="list-value" data-id="' + fieldIndex + '" class="list-value" data-list-value-id="' + valueIndex +'" placeholder="Une des valeurs de la liste" required>'+
341
        // Checkbox valeur par défaut+bouton supprimer
3167 idir 342
        '<div class="row">'+
343
          '<div class="col-md-5">'+
3174 idir 344
            // Valeur par défaut
3167 idir 345
            '<label for="is-defaut-value" title="Ceci est la valeur par défaut">Valeur par défaut</label>'+
3174 idir 346
            '<input type="checkbox" name="is-defaut-value" data-id="' + fieldIndex + '" class="is-defaut-value" title="entrez une valeur pour activer cette case" data-list-value-id="' + valueIndex +'" disabled >'+
3167 idir 347
          '</div>'+
348
          '<div class="col-md-5">'+
3174 idir 349
            // Bouton supprimer une option
350
            '<label for="remove-value">supprimer valeur</label>'+
351
            '<div class="remove-value button" name="remove-value" data-id="' + fieldIndex + '" data-list-value-id="' + valueIndex + '" title="Supprimer une valeur"><i class="fa fa-trash" aria-hidden="true"></i></div>'+
3167 idir 352
          '</div>'+
353
        '</div>'+
3168 idir 354
      '</div>'
3174 idir 355
    ).hide().show( 200);
356
    // Une seule valeur par défaut pour select et radio
3171 idir 357
    onClickDefaultValueRemoveOthers( fieldIndex );
3174 idir 358
    // Supprimer une valeur
3171 idir 359
    onClickRemoveListValue( fieldIndex );
360
  });
361
}
3167 idir 362
 
3171 idir 363
// Activer la checkbox de valeur par default uniquement si une valeur est entrée
3226 idir 364
function onInputListValueLabelEnableDefaultCheckbox() {
365
  $( '#new-fields' ).on( 'input' , '.list-value' , function() {
366
    var thisValue = $( this ).parent( '.new-value' );
367
    if( '' !== $( this ).val() ) {
368
      $( '.is-defaut-value', thisValue ).removeAttr( 'disabled' );
3174 idir 369
    } else {
3233 idir 370
      $( '.is-defaut-value', thisValue ).attr( 'disabled', true ).attr( 'checked' , false );
3174 idir 371
    }
3167 idir 372
  });
373
}
374
 
3174 idir 375
// Pour les éléments "select" et "radio" il ne peut y avoir qu'une valeur par défaut cochée
3171 idir 376
function onClickDefaultValueRemoveOthers( fieldIndex ) {
3174 idir 377
  var selectedFieldElement = $( '.field-element[data-id="' + fieldIndex + '"]' ).val();
3167 idir 378
 
3174 idir 379
  if( selectedFieldElement === 'select' || selectedFieldElement === 'radio' ) {
380
    $( '.is-defaut-value[data-id="' + fieldIndex + '"]' ).click( function() {
3233 idir 381
     if( $( this ).is( ':checked' ) ) {
3174 idir 382
        // Décocher tous les autres
3233 idir 383
        $( '.is-defaut-value[data-id="' + fieldIndex + '"]:checked' ).not( $( this) ).attr( 'checked' , false );
3174 idir 384
      }
385
    });
386
  }
3167 idir 387
}
388
 
3174 idir 389
// Bouton supprimer une valeur
3171 idir 390
function onClickRemoveListValue( fieldIndex ) {
3174 idir 391
  $( '.remove-value.button[data-id="' + fieldIndex + '"]' ).click( function() {
3226 idir 392
    $( '.new-value[data-list-value-id="' + $( this ).data( 'list-value-id' ) + '"]' ).hide( 200 , function () {
393
      $( this ).remove();
3174 idir 394
    });
3167 idir 395
  });
396
}
397
 
3171 idir 398
/*********************************************
399
 *  Validation et envoi des nouveaux champs  *
400
 *********************************************/
3168 idir 401
 
3176 idir 402
// Empêcher de créer plus d'une fois la même clé
403
function onChangeCheckKeyUnique() {
404
 if( 1 < $( '.field-key' ).length ) {
3177 idir 405
    // Marqueur de valeur dupliquée
3183 idir 406
    var notUnique = false;
3176 idir 407
 
408
    $( '.field-key' ).change( function () {
3177 idir 409
      let count = $( '.field-key' ).length;
3176 idir 410
 
411
      for(var index = 0 ; index < count ; index++) {
3177 idir 412
        let thisFieldKey = $( '.field-key[data-id="' + index + '"]' );
413
        // Le champ avec cet index paourrait avoir été supprimé
414
        if( 0 < thisFieldKey.length ) {
415
          for( var otherIndex = 0 ; otherIndex < count ; otherIndex++ ) {
416
            let otherFieldKey = $( '.field-key[data-id="' + otherIndex + '"]' );
417
            // Le champ avec cet index pourrait avoir été supprimé
418
            // On vérifie qu'on ne compare pas un champ avec lui-même
419
            // Que les champs ne sont pas vides
420
            // Les champs dupliqués déclanchent le marqueur et les alertes
421
            if(
422
 
423
              index !== otherIndex &&
424
              '' !== otherFieldKey.val() &&
425
              '' !== thisFieldKey.val() &&
426
              thisFieldKey.val() === otherFieldKey.val()
427
            ) {
428
              // Le marqueur de valeur dupliquée passe à true
429
              notUnique = true;
430
              if( 0 === $( '.invalid-field-key[data-id="' + index + '"]' ).length ) {
431
                // Le champ est signalé en rouge
432
                // Un message d'alerte apparait sous le champ
3188 idir 433
                thisFieldKey.addClass( 'invalid-key' );
3177 idir 434
                thisFieldKey.after(
435
                  '<p class="message invalid-field-key" data-id="' + index + '">' +
436
                    '<i class="fa fa-exclamation-triangle" aria-hidden="true" style="color:#ff5d55"></i>' +
437
                    ' Vérifiez qu\'aucune clé n\'ait été utilisée plus d\'une fois'  +
438
                  '</p>'
439
                );
440
              }
441
            }
442
          }
3176 idir 443
        }
444
      }
445
      if( notUnique ) {
446
        // Un message d'alerte apparait au dessus des boutons prévisualiser/valider
447
        if( 0 === $( '.invalid-field-key-bottom' ).length ) {
3177 idir 448
          $( '#new-fields' ).after(
3176 idir 449
            '<p class="message invalid-field-key-bottom">' +
450
              '<i class="fa fa-exclamation-triangle" aria-hidden="true" style="color:#ff5d55"></i>' +
451
              ' Une clé a été utilisée plusieurs fois' +
452
            '</p>'
453
          );
454
        }
455
        // Les boutons prévisualiser/valider sont désactivés et signalés en rouge
3188 idir 456
        $( '#preview-field , #validate-new-fields' ).addClass( 'invalid-key' ).css( 'pointer-events', 'none' );
3177 idir 457
      } else {// Si on est ok on retire toutes les alertes
458
        // signalements rouges
459
        $( '.field-key' ).each( function() {
3188 idir 460
          $( this ).removeClass( 'invalid-key' );
3177 idir 461
        });
3188 idir 462
        $( '#preview-field , #validate-new-fields' ).removeClass( 'invalid-key' );
3177 idir 463
        // messages d'alerte
464
        $( '.invalid-field-key' ).each( function() {
465
          $( this ).hide( 200 , function () {
466
            $( this ).remove();
467
          });
3176 idir 468
        });
469
        $( '.invalid-field-key-bottom' ).hide( 200 , function () {
470
          $( this ).remove();
471
        });
3177 idir 472
        //réactivation des boutons prévisualiser/valider
3176 idir 473
        $( '#preview-field' )[0].style.removeProperty( 'pointer-events' );
474
        $( '#validate-new-fields' )[0].style.removeProperty( 'pointer-events' )
475
      }
476
      // Réinitialisation
477
      notUnique = false;
478
    });
479
  }
480
}
481
 
3188 idir 482
// Activation/desactivation des champs valider/previsualiser
483
function onClickButtonsTagMissingValues() {
484
  $( '#preview-field , #validate-new-fields' ).on( 'click' , function() {
485
    var $button = $( this );
486
    //S'il n'y a pas (plus) de bloc nouveau champ
3174 idir 487
    if( 0 === $( 'fieldset' ).length ) {
488
      return;
489
    }
3188 idir 490
    // Classe "invalid"
491
    missingValuesClass();
492
    if( !$( this ).hasClass( 'invalid' ) ) {
493
      if( $( this ).is( '#validate-new-fields') ) {
494
        // Lancement de l'enregistrement des valeurs à transmettre
495
        onClickStoreNewFields();
496
      } else if( $( this ).is( '#preview-field') ) {
497
        // Lancement de la prévisualisation
498
        newFieldsPreview();
3171 idir 499
      }
3174 idir 500
    }
3188 idir 501
  });
502
  // Si un champ manquant est renseigné
503
  // ou on choisit nouvel élément liste (au moins une option)
504
  // Cette action doit être prise en compte dans la validation
505
  $( '#new-fields' ).on( 'change' , '.invalid[type="text"] , .field-element' , function() {
506
    // S'il on a pas encore cliqué sur prévisualiser/valider
507
    // changer l'élément ne doit pas déclancher le signalement en rouge
508
    if( $( this ).is( '.field-element' ) && !$( '#preview-field , #validate-new-fields' ).hasClass( 'invalid' ) ) {
509
      return;
510
    } else {
511
      // Classe "invalid"
512
      missingValuesClass();
513
    }
514
  });
515
}
516
 
517
// Classe "invalid"
518
function missingValuesClass() {
519
  // Si au moins un champ "required" n'est pas rempli
520
  $( '#new-fields input[required]' ).each( function() {
521
    if( 0 === $( this ).val().length ) {
522
      // Le champ est signalé en rouge
523
      $( this ).addClass( 'invalid' );
524
      // Un message d'alerte apparait après le champ
3226 idir 525
      if( 0 === $( this ).next( '.validation-warning' ).length ) {
526
        $( this ).after(
3174 idir 527
          '<p class="validation-warning message">' +
528
            '<i class="fa fa-exclamation-triangle" aria-hidden="true" style="color:#ff5d55"></i>' +
3188 idir 529
             '&nbsp;Ce champ est requis' +
3174 idir 530
          '</p>'
531
        );
532
      }
533
    } else {
3188 idir 534
      // Le champ est signalé en rouge
535
      $( this ).removeClass( 'invalid' );
536
      // Le message d'alerte du champ est supprimé
3226 idir 537
      if( 0 < $( this ).next( '.validation-warning' ).length ) {
3188 idir 538
        $( this ).next( '.validation-warning' ).hide( 200 , function () {
539
          $( this ).remove();
540
        });
3174 idir 541
      }
542
    }
543
  });
3188 idir 544
  // Si on a des champs à compléter
545
  if( 0 < $( '.invalid[type="text"]' ).length ) {
546
    // Les boutons sont signalés en rouge
547
    $( '#preview-field , #validate-new-fields' ).addClass( 'invalid' );
548
    // Un message d'alerte apparait avant les boutons
549
    if( 0 === $( '#new-fields' ).next( '.validation-warning' ).length ) {
550
      $( '#new-fields' ).after(
551
        '<p class="validation-warning message">' +
552
          '<i class="fa fa-exclamation-triangle" aria-hidden="true" style="color:#ff5d55"></i>' +
553
           '&nbsp;Des informations sont manquantes pour certains champs,' +
554
           ' vérifiez ceux signalés en rouge' +
555
        '</p>'
556
      );
557
    }
558
  } else {
559
    // Les signalements et messages sont supprimés
560
    $( '#preview-field , #validate-new-fields' ).removeClass( 'invalid' );
561
    $( '#new-fields' ).next( '.validation-warning' ).hide( 200 , function () {
562
        $( this ).remove();
563
    });
564
  }
3174 idir 565
}
3168 idir 566
 
3189 idir 567
/**** Envoi des nouveaux champs ****/
568
 
3174 idir 569
// Enregistrement des valeurs à transmettre
570
function onClickStoreNewFields() {
571
  // Lorsqu'on valide
572
  var resultArrayIndex = 0;
3226 idir 573
  var count = $( 'fieldset' ).last().data( 'id' );
3174 idir 574
  var helpFileExists = false;
575
  // Savoir si au moins un fichier "aide" est enregistré
576
  $( '.field-help' ).each( function () {
577
    if( '' !== $( this ).val() ){
578
      helpFileExists = true;
579
    }
580
  })
581
  // dans ce cas intégrer dans le formulaire à soumettre un bloc
582
  // qui contiendra une copie de chacun de ces input[type="file"]
583
  if( helpFileExists ){
3226 idir 584
    $( '#submit-button' ).before( '<div id="help-doc-submit" style="position:fixed;visibility:hidden;"></div>' );
3174 idir 585
  }
586
  // On déroule les blocs de champs supplémentaires
3226 idir 587
  for( var index = $( 'fieldset' ).first().data( 'id' ) ; index <= count ; index++ ) {
3174 idir 588
    var thisFieldset = $( 'fieldset[data-id="' + index + '"]');
589
    // Certains indices peuvent correspondre à un champ supprimé
590
    if( 0 < $( thisFieldset ).length ) {
591
      // initialisation du tableau de résultats
3185 idir 592
      datasToSubmit[ resultArrayIndex ]             = { fieldValues:{} };
3174 idir 593
      // Ajout de la clé au tableau de resultats
3185 idir 594
      datasToSubmit[ resultArrayIndex ].key         = $( '.field-key' , thisFieldset ).val();
3174 idir 595
      // Ajout de le nom au tableau de resultats
3185 idir 596
      datasToSubmit[ resultArrayIndex ].name        = $( '.field-name' , thisFieldset ).val();
3174 idir 597
      // Recueil de l'élément choisi pour le tableau de resultats
3185 idir 598
      datasToSubmit[ resultArrayIndex ].element     = $( '.field-element' , thisFieldset ).val();
3174 idir 599
      // Ajout de la valeur 'requis' ou non au tableau de resultats
3185 idir 600
      datasToSubmit[ resultArrayIndex ].mandatory   = $( '.field-is_mandatory' , thisFieldset ).is( ':checked' );
3174 idir 601
      // Ajout de l'unité au tableau de resultats
3185 idir 602
      datasToSubmit[ resultArrayIndex ].unit        = $( '.field-unit' , thisFieldset ).val() || null;
3174 idir 603
      // Ajout du tooltip au tableau de resultats
3176 idir 604
      datasToSubmit[ resultArrayIndex ].description = $( '.field-description' , thisFieldset ).val() || null;
3174 idir 605
      // Collecte les des données dépendantes de l'élément choisi
606
      // sous forme d'un tableau de resultats
607
      onSelectCollectDataValuesToSubmit( datasToSubmit[ resultArrayIndex ] , thisFieldset );
3226 idir 608
 
609
      if( $.isEmptyObject( datasToSubmit[ resultArrayIndex ].fieldValues ) ){
3174 idir 610
        delete datasToSubmit[ resultArrayIndex ].fieldValues;
611
      }
612
      // Copie d'un champ de fichier d'aide dans le bloc d'envoi
3233 idir 613
      if( 0 < $( '.field-help' , thisFieldset ).get(0).files.length ) {
614
        console.log( $( '.field-help' , thisFieldset ).get(0).files[0].type );
615
        // Présence d'un document d'aide
616
        datasToSubmit[ resultArrayIndex ].help = $( '.field-help' , thisFieldset ).get(0).files[0].type;
3174 idir 617
        $( '.field-help' , thisFieldset ).clone()
3226 idir 618
          .attr( 'name' , 'help-' + datasToSubmit[ resultArrayIndex ].key )// l'attribut name prend la valeur de la clé
3174 idir 619
          .appendTo( '#help-doc-submit' );
3233 idir 620
      } else {
621
        datasToSubmit[ resultArrayIndex ].help = null;
3174 idir 622
      }
623
      resultArrayIndex++;
3171 idir 624
    }
3174 idir 625
  }
3233 idir 626
 
627
  var resultsArrayJson = JSON.stringify( datasToSubmit , replacer );
628
 
629
  // JSON.strigify : Gestion des apostrophes dans les valeurs :
630
  function replacer( key , value ) {
631
    if ( 'fieldValues' === key && 'object' === typeof value ) {
632
      for ( var i in value ) {
633
        if ( typeof value[i] === 'string' ) {
634
          value[i] = value[i].replace( /\u0027/g, "&apos;&apos;" );
635
        }
636
      }
637
    } else if ( typeof value === 'string' ) {
638
      value = value.replace( /\u0027/g, "&apos;&apos;" );
639
    }
640
    return value;
641
  }
642
 
643
  console.log( resultsArrayJson );
644
 
3174 idir 645
  // Désactivation de tous les champs et boutons (nouveaux champs)
646
  $( '#new-fields, #new-fields .button , #add-fields , #preview-field' ).addClass( 'disabled' );
647
  $( '#validate-new-fields' ).addClass( 'validated' );
648
  $( '.validate-new-fields' ).text( 'Champs validés' );
649
  // Mise à disposition des données pour le bouron submit
3226 idir 650
  $( '#submit-button' ).before(
3233 idir 651
    //la value est passée avec des apostrophes pour que les guillemets de la string json passent bien en string de l'attribut
652
    '<input type="hidden" name="champs-supp" id="champs-supp" value=\'' + resultsArrayJson + '\'>'
3174 idir 653
  );
3171 idir 654
}
655
 
656
// Renseigne le tableau de resultat
657
// pour les données dépendant de l'élément choisi
3174 idir 658
function onSelectCollectDataValuesToSubmit( datasToSubmitObject , thisFieldset ) {
3171 idir 659
    switch( datasToSubmitObject.element ) {
660
      case 'select':
661
      case 'checkbox':
662
      case 'list-checkbox':
663
      case 'radio':
3173 idir 664
        datasToSubmitObject.fieldValues.listValue = [];
3171 idir 665
        // Ajout des valeurs de liste
3174 idir 666
        onChangeStoreListValueLabel( datasToSubmitObject , thisFieldset );
3171 idir 667
        // S'il y a une valeur 'autre' on l'indique à la fin de la liste
3233 idir 668
        if( $( '.option-other-value' , thisFieldset ).is( ':checked' ) && -1 === datasToSubmitObject.fieldValues.listValue.indexOf( 'other' ) ) {
3171 idir 669
          datasToSubmitObject.fieldValues.listValue.push( 'other' );
670
        }
671
        break;
672
 
673
      case 'number':
674
      case 'range':
675
        // Placeholder
3176 idir 676
        datasToSubmitObject.fieldValues.placeholder = $( '.aide-saisie' , thisFieldset ).val() || null;
3171 idir 677
        // Valeur par défaut
3176 idir 678
        datasToSubmitObject.fieldValues.default = $( '.default' , thisFieldset ).val() || null;
3171 idir 679
        // Incrémentation ( attribut step="" )
3176 idir 680
         datasToSubmitObject.fieldValues.step = $( '.step' , thisFieldset ).val() || null;
3171 idir 681
        // Min
3176 idir 682
        datasToSubmitObject.fieldValues.min = $( '.min' , thisFieldset ).val() || null;
3171 idir 683
        // Max
3176 idir 684
        datasToSubmitObject.fieldValues.max = $( '.max' , thisFieldset ).val() || null;
3171 idir 685
        break;
686
 
687
      case 'date':
688
        // Min
3176 idir 689
        datasToSubmitObject.fieldValues.min = $( '.min' , thisFieldset ).val() || null;
3171 idir 690
        // Max
3176 idir 691
        datasToSubmitObject.fieldValues.max = $( '.max' , thisFieldset ).val() || null;
3171 idir 692
        break;
693
 
694
      case 'email':
695
      case 'text':
696
      case 'textarea':
697
      default:
698
        // Placeholder
3176 idir 699
        datasToSubmitObject.fieldValues.placeholder = $( '.aide-saisie' , thisFieldset ).val() || null;
3171 idir 700
        break;
701
    }
3173 idir 702
    return datasToSubmitObject;
3171 idir 703
}
704
 
705
// Ajout d'une valeur d'un élément liste (select, checkbox etc.)
706
// dans le tableau de resultats
3174 idir 707
function onChangeStoreListValueLabel( datasToSubmitObject , thisFieldset ) {
708
  $( '.list-value' , thisFieldset ).each( function() {
709
    var selectedFieldElement = $( '.field-element' , thisFieldset ).val();
3176 idir 710
 
3171 idir 711
     if( $( this ).val() ){
3176 idir 712
      // Is-default-value non cochée
3233 idir 713
      if( !$( '.is-defaut-value[data-list-value-id="' + $( this ).data( 'list-value-id' ) + '"]' , thisFieldset ).is( ':checked' ) ) {
3174 idir 714
        datasToSubmitObject.fieldValues.listValue.push( $( this ).val() );
3176 idir 715
      // Is-default-value cochée pour select/radio
3174 idir 716
      } else if( 'select' ===  selectedFieldElement || 'radio' === selectedFieldElement ) {
3176 idir 717
        // Une seule valeur par defaut, devient la première valeur du tableau + '#'
3174 idir 718
        datasToSubmitObject.fieldValues.listValue.unshift( $( this ).val() + '#' );
3176 idir 719
      // Is-default-value cochée pour checkbox/list-checkbox
3171 idir 720
      } else {
3176 idir 721
        // On ajoute simplement la valeur au tableau + '#'
3174 idir 722
        datasToSubmitObject.fieldValues.listValue.push( $( this ).val() + '#' );
3171 idir 723
      }
724
    }
725
  });
726
}
727
 
3174 idir 728
/************************************************
729
 *  Fonction d'affichage des champs classiques  *
730
 ************************************************/
3171 idir 731
 
3176 idir 732
// Prévisualisation
3174 idir 733
function DisplayClassicFields() {
734
  // Affichage du titre du widget
3226 idir 735
  renderFields( $( '#titre' ) , $( '.widget-renderer h1' ) );
3174 idir 736
  // Affichage du nom du projet
3226 idir 737
  renderFields( $( '#projet' ) , $( '.projet-description' ));
3174 idir 738
  // Affichage de la description
3226 idir 739
  renderFields( $( '#description' ) , $( '.preview-description' ) );
3174 idir 740
  // Affichage du logo s'il existe déjà
3226 idir 741
  if( 0 !== $( '#logo' ).val().length || $( '#logo' )[0].defaultValue ) {
3189 idir 742
    $( '#preview-logo' ).append(
743
      '<img src="' +
3226 idir 744
        $( '#group-settings-form .logo img' ).prop( 'src' ) +
3189 idir 745
        '" width="75%"' +
746
      '>'
747
    );
3174 idir 748
  }
749
  // Affichage du logo chargé
750
  $( '#logo.input-file' ).change( function( event ) {
3189 idir 751
    // Si le 'change' n'était pas une suppression
3176 idir 752
    if( $.isEmptyObject( event.target.files[0] ) ) {
3190 idir 753
      $( '#preview-logo img' ).remove();
3176 idir 754
    // Si on a chargé un logo ou changé le fichier
755
    } else {
3189 idir 756
      $( '#preview-logo' ).append(
757
        '<img src="' +
758
          URL.createObjectURL( event.target.files[0] ) +
759
          '" width="75%"' +
760
        '>'
761
      );
3167 idir 762
    }
763
  });
3174 idir 764
  // Affichage de l'image de fond
765
  $('#fond.input-file').change( function ( event ) {
766
    if( !$.isEmptyObject( event.target.files[0] ) ) {
767
      $( '.widget-renderer' ).css('background' ,'url(' + URL.createObjectURL( event.target.files[0] ) + ') no-repeat center');
768
    } else {
769
      $( '.widget-renderer' )[0].style.removeProperty( 'background' );
770
    }
771
  });
772
}
3167 idir 773
 
3176 idir 774
// Affichage des infos dès que disponibles
775
// pour les champs classiques
776
function renderFields( $source , $taget ) {
3226 idir 777
  if( $source.val() ) {
3176 idir 778
    $taget.text( $source.val() );
779
  }
780
  $source.change( function () {
781
    $taget.text( $( this ).val() );
782
  });
783
}
3174 idir 784
 
785
 
3176 idir 786
/*****************************************************
787
 *  Fonction d'affichage des champs supplémentaires  *
788
 *****************************************************/
789
 
3174 idir 790
// Construction des éléments à visualiser
791
function onClickPreviewField( thisFieldset , index ) {
3176 idir 792
  // Récupération des données
793
      // Tous les champs
3185 idir 794
  var fieldLabel       = $( '.field-name'            , thisFieldset ).val() || '',//nom
795
      fieldKey         = $( '.field-key'             , thisFieldset ).val() || '',//clé
796
      fieldElement     = $( '.field-element'         , thisFieldset ).val() || '',//élément
3176 idir 797
      fieldIsMandatory = $( '.field-is_mandatory'    , thisFieldset ).is( ':checked' ),//champ requis
3185 idir 798
      fieldUnit        = $( '.field-unit'            , thisFieldset ).val() || '',//unités
799
      fieldTooltip     = $( '.field-description'     , thisFieldset ).val() || '',//info-bulle
800
      fieldHelp        = $( '.file-return.help-doc-' + index ).text()       || '',//nom du fichier d'aide
3176 idir 801
      fieldPlaceholder = $( '.aide-saisie'           , thisFieldset ).val() || '',//placeholder
802
      // Champs à valeur numérique ou date
3185 idir 803
      fieldStep        = $( '.step'                  , thisFieldset ).val() || '',
804
      fieldMin         = $( '.min'                   , thisFieldset ).val() || '',
805
      fieldMax         = $( '.max'                   , thisFieldset ).val() || '',
3176 idir 806
      // Champs "listes"
3185 idir 807
      fieldDefaultNum  = $( '.default'               , thisFieldset ).val() || '',// value range/number par default
3176 idir 808
      fieldOtherValue  = $( '.option-other-value'    , thisFieldset ).is( ':checked' ),//option autre
809
      fieldOptions     = collectListOptions( thisFieldset );//Array: toutes les options
810
  // Variables d'affichage
811
  var fieldHtml               = '',//variable contenant tout le html à afficher
812
      commonFieldsHtml        = {},//Éléments simples ou chaînes communes aux "listes"
813
      listFieldsHtml = {},//chaînes & html pour les listes mais non spécifiques
814
      listFieldsHtml          = {},//chaînes & html spécifiques aux listes
815
      count                   = fieldOptions.length;//nombre d'options, pour les boucles for
3233 idir 816
  fieldLabel = fieldLabel.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' );
817
  fieldTooltip = fieldTooltip.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' );
818
  fieldPlaceholder = fieldPlaceholder.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' );
819
 
3176 idir 820
  //valeurs initiales des chaînes de caractères
821
  //Éléments simples ou chaînes communes aux "listes"
822
  commonFieldsHtml = {
823
    dataIdAttr : ' data-id="' + index + '"',
824
    helpButton : '',//bouton aide
825
    helpClass  : '',//classe de l'élément associé au bouton aide
826
    titleAttr  : '',//info-bulle
827
    fieldInput : {//attributs de l'élément
828
      typeAttr        : ' type="' + fieldElement + '"',
829
      nameAttr        : ' name="' + fieldKey + '"',
830
      classAttr       : ' class="' +  fieldKey + '"',
831
      placeholderAttr : '',
832
      mandatoryAttr   : '',//required
833
      otherAttr       : ''
3174 idir 834
    },
3176 idir 835
    fieldLabel : {//attributs et contenu du label
836
      labelContent    : fieldLabel,//label
837
      forAttr         : ' for="' + fieldKey + '"',//attribut for
838
      classAttr       : '',//classe du label
839
      otherAttr       : ''//tous autres attributs
3174 idir 840
    }
841
  }
842
  // Pour les éléments de listes (select, checkbox, etc.)
3176 idir 843
  listFieldsHtml = {
844
    containerContent : fieldLabel,//les options peuvent avoir chacune un label
845
    containerClass   : '',//une classe pour le conteneur
846
    forAttr          : '',//correspond à l'id d'une checkbox/radio/list-checkbox
847
    optionIdAttr     : '',//value-id
848
    defaultAttr      : ''//default
3174 idir 849
  };
850
  // Changement d'un élément existant:
851
  // supprimer le précédent pour ajouter le nouveau
852
  if( 0 < $( '.preview-fields' , thisFieldset ).length ) {
853
    $( '.preview-fields' , thisFieldset ).remove();
854
  }
3176 idir 855
  // Élément requis
3174 idir 856
  if( fieldIsMandatory ) {
3176 idir 857
    // Attribut required pour le listes
858
    commonFieldsHtml.fieldInput.mandatoryAttr = ' required="required"';
3174 idir 859
    // Nom du champ (éléments listes)
3185 idir 860
    listFieldsHtml.containerContent += ' *';
3174 idir 861
    // Nom du champ (éléments simples)
3176 idir 862
    commonFieldsHtml.fieldLabel.labelContent += ' *';
3174 idir 863
  }
3176 idir 864
  // Infobulle
3174 idir 865
  if( '' !== fieldTooltip ) {
3176 idir 866
    commonFieldsHtml.titleAttr = ' title="' +  fieldTooltip + '"';
3174 idir 867
  }
3176 idir 868
  // Placeholder
3174 idir 869
  if( '' !== fieldPlaceholder ) {
3176 idir 870
    commonFieldsHtml.fieldInput.placeholderAttr = ' placeholder="' +  fieldPlaceholder + '"';
3174 idir 871
  }
3176 idir 872
  // Fichier d'aide
3174 idir 873
  if( '' !== fieldHelp ) {
3176 idir 874
    // Bouton 'aide'
875
    commonFieldsHtml.helpButton = '<div class="button help-button"><i class="fas fa-info-circle"></i></div>';
876
    // classe 'aide'
877
    commonFieldsHtml.helpClass = ' and-help';
3174 idir 878
  }
879
  // html à ajouter en fonction de l'élément choisi
880
  switch( fieldElement ) {
881
    case 'checkbox' :
882
    case 'radio' :
3176 idir 883
      listFieldsHtml.containerClass = ' class="' + fieldElement +'"';
3174 idir 884
      fieldHtml =
885
        // Conteneur
886
        '<div' +
887
          // Class="L'élément choisi"
3176 idir 888
          listFieldsHtml.containerClass +
3174 idir 889
          // DataId
3176 idir 890
          commonFieldsHtml.dataIdAttr +
3174 idir 891
          // Required
3176 idir 892
          commonFieldsHtml.fieldInput.mandatoryAttr +
3174 idir 893
          // Info bulle
3176 idir 894
          commonFieldsHtml.titleAttr +
3174 idir 895
        ' >'+
896
          // Nom du champ
3176 idir 897
          // Classe 'and-help'
898
          '<div class="list-label' + commonFieldsHtml.helpClass + '">' +
899
            // Label
900
            listFieldsHtml.containerContent +
3174 idir 901
          '</div>' +
3176 idir 902
          // Bouton 'help'
903
          commonFieldsHtml.helpButton;
3174 idir 904
      // On déroule les différentes valeurs
3176 idir 905
      for( let i = 0; i < count; i++ ) {
3174 idir 906
        let fieldOption = fieldOptions[i];
3176 idir 907
        // L'id de input
908
        listFieldsHtml.inputIdAttr = ' id="' + fieldOption.optionValue + '"';
909
        listFieldsHtml.forAttr = ' for="' + fieldOption.optionValue + '"';
910
        // Default
911
        listFieldsHtml.defaultAttr = '';//réinitialisation
912
        if( fieldOption.isDefault ) {//affectation
913
          listFieldsHtml.defaultAttr = ' checked';
3174 idir 914
        }
915
        // L'indice de chaque option
916
        // L'option "autre" n'en a pas
917
        if( '' !== fieldOption.optionIndex ) {
3176 idir 918
          listFieldsHtml.optionIdAttr = ' value-id="' + fieldOption.optionIndex + '"';
3174 idir 919
        }
920
 
921
        fieldHtml +=
922
          '<label' +
923
            // For
3176 idir 924
            listFieldsHtml.forAttr +
3174 idir 925
            // value-id
3176 idir 926
            listFieldsHtml.optionIdAttr +
3174 idir 927
            // Class="nom du champ"
3176 idir 928
            commonFieldsHtml.fieldInput.classAttr +
3174 idir 929
          '>' +
930
            '<input' +
931
              // Type
3176 idir 932
              commonFieldsHtml.fieldInput.typeAttr +
933
              // Id
934
              listFieldsHtml.inputIdAttr +
3174 idir 935
              // DataId
3176 idir 936
              commonFieldsHtml.dataIdAttr +
3174 idir 937
              // value-id
3176 idir 938
              listFieldsHtml.optionIdAttr +
3174 idir 939
              // Name
3176 idir 940
              commonFieldsHtml.fieldInput.nameAttr +
3174 idir 941
              // Value
3233 idir 942
              ' value="' + fieldOption.optionValue.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' ) + '"' +
3174 idir 943
              // Checked
3176 idir 944
              listFieldsHtml.defaultAttr +
3174 idir 945
              // Class="nom du champ"
3176 idir 946
              commonFieldsHtml.fieldInput.classAttr +
3174 idir 947
            '>' +
948
            // Label de l'option
3233 idir 949
            fieldOption.optionText.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' ) +
3174 idir 950
          '</label>';
3187 idir 951
      }
952
      // Si valeur "autre" est cochée
953
      if( fieldOtherValue ) {
954
        fieldHtml +=
955
          '<label for="other"' +
956
            commonFieldsHtml.dataIdAttr +
957
          '>' +
958
            '<input' +
959
              commonFieldsHtml.fieldInput.typeAttr +
960
              ' id="other"' +
961
              commonFieldsHtml.fieldInput.nameAttr +
962
              ' value="other"' +
963
              commonFieldsHtml.fieldInput.classAttr +
3176 idir 964
              commonFieldsHtml.dataIdAttr +
3174 idir 965
            '>' +
3187 idir 966
          'Autre</label>';
3174 idir 967
        }
968
      // Fin du conteneur
969
      fieldHtml += '</div>';
970
      break;
971
 
972
    case 'list-checkbox':
973
      fieldHtml =
3176 idir 974
        // Classe 'and-help'
975
        '<div class="multiselect ' + fieldElement + commonFieldsHtml.helpClass + '"' +
3174 idir 976
          // DataId
3176 idir 977
          commonFieldsHtml.dataIdAttr +
3174 idir 978
        '>' +
979
          '<label>' +
980
            // Nom du champ
3176 idir 981
            listFieldsHtml.containerContent +
3174 idir 982
          '</label>' +
983
          '<div class="selectBox"' +
984
            // DataId
3176 idir 985
            commonFieldsHtml.dataIdAttr +
3174 idir 986
          '>' +
987
            '<select' +
988
              // DataId
3176 idir 989
              commonFieldsHtml.dataIdAttr +
3174 idir 990
              // Required
3176 idir 991
              commonFieldsHtml.fieldInput.mandatoryAttr +
3174 idir 992
              // Info bulle
3176 idir 993
              commonFieldsHtml.titleAttr +
3174 idir 994
            '>' +
995
              // Apparait dans la barre de sélection
996
              '<option>Plusieurs choix possibles</option>' +
997
            '</select>' +
998
            '<div class="overSelect"></div>' +
999
          '</div>' +
1000
          '<div class="checkboxes hidden"' +
1001
            // DataId
3176 idir 1002
            commonFieldsHtml.dataIdAttr +
3174 idir 1003
          '>';
1004
      // On déroule les différentes valeurs
3176 idir 1005
      for( let i = 0; i < count; i++ ) {
3174 idir 1006
        let fieldOption = fieldOptions[i];
3176 idir 1007
        // Type="checkbox"
1008
        commonFieldsHtml.fieldInput.typeAttr = ' type="checkbox"';
1009
        // Id
3233 idir 1010
        listFieldsHtml.inputIdAttr = ' id="' + fieldOption.optionValue.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' ).toLowerCase() + '"';
3176 idir 1011
        // For
3233 idir 1012
        listFieldsHtml.forAttr = ' for="' + fieldOption.optionValue.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' ).toLowerCase() + '"';
3176 idir 1013
        // Default
1014
        listFieldsHtml.defaultAttr = '';//réinitialisation
3174 idir 1015
        if( fieldOption.isDefault ) {
3176 idir 1016
          listFieldsHtml.defaultAttr = ' checked';//affectation
3174 idir 1017
        }
3176 idir 1018
        // value-id
3174 idir 1019
        if( '' !== fieldOption.optionIndex ) {
3176 idir 1020
          listFieldsHtml.optionIdAttr = ' value-id="' + fieldOption.optionIndex + '"';
3174 idir 1021
        }
1022
 
1023
        fieldHtml +=
1024
          '<label' +
3176 idir 1025
            // For
1026
            listFieldsHtml.forAttr +
3174 idir 1027
            // value-id
3176 idir 1028
            listFieldsHtml.optionIdAttr +
3174 idir 1029
          '>' +
1030
            '<input type="checkbox"' +
3176 idir 1031
              // Id
1032
              listFieldsHtml.inputIdAttr +
3174 idir 1033
              // value-id
3176 idir 1034
              listFieldsHtml.optionIdAttr +
3174 idir 1035
              // Name
3176 idir 1036
              commonFieldsHtml.fieldInput.nameAttr +
3174 idir 1037
              // Value
3233 idir 1038
              ' value="' + fieldOption.optionValue.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' ) + '"' +
3174 idir 1039
              // Checked
3176 idir 1040
              listFieldsHtml.defaultAttr +
3174 idir 1041
              // Class="nom du champ"
3176 idir 1042
              commonFieldsHtml.fieldInput.classAttr +
3174 idir 1043
              // DataId
3176 idir 1044
              commonFieldsHtml.dataIdAttr +
3174 idir 1045
            '>' +
1046
            // Label de l'option
3233 idir 1047
            fieldOption.optionText.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' ) +
3174 idir 1048
          '</label>';
1049
      }
1050
      // Si valeur "autre" est cochée
1051
      if( fieldOtherValue ) {
1052
        fieldHtml +=
1053
          '<label for="other"' +
1054
            // DataId
3176 idir 1055
            commonFieldsHtml.dataIdAttr +
3174 idir 1056
          '>' +
1057
            '<input type="checkbox"' +
1058
              ' id="other"' +
3176 idir 1059
              commonFieldsHtml.fieldInput.nameAttr +
3174 idir 1060
              ' value="other"' +
3176 idir 1061
              commonFieldsHtml.fieldInput.classAttr +
3174 idir 1062
              // DataId
3176 idir 1063
              commonFieldsHtml.dataIdAttr +
3174 idir 1064
            '>' +
1065
          'Autre</label>';
1066
      }
1067
      // Fermeture des conteneurs .multiselect .checkboxes
1068
      fieldHtml +=
1069
        '</div>'+
1070
      '</div>' +
3176 idir 1071
      // Bouton 'help'
1072
      commonFieldsHtml.helpButton;
3174 idir 1073
      break;
1074
 
1075
    case 'select':
1076
      fieldHtml =
1077
        '<label' +
3176 idir 1078
          commonFieldsHtml.fieldLabel.forAttr +
3174 idir 1079
          // Info bulle
3176 idir 1080
          commonFieldsHtml.titleAttr +
3174 idir 1081
        '>' +
1082
          // Nom du champ
3176 idir 1083
          listFieldsHtml.containerContent +
3174 idir 1084
        '</label>' +
1085
        // Conteneur/Wrapper
3176 idir 1086
        // +Classe 'and-help'
1087
        '<div class="select-wrapper add-field-select ' + fieldElement + commonFieldsHtml.helpClass + '"' +
1088
          // DataID
1089
          commonFieldsHtml.dataIdAttr +
3174 idir 1090
        '>' +
1091
          '<select' +
3176 idir 1092
            commonFieldsHtml.fieldInput.nameAttr +
3174 idir 1093
            ' id="' + fieldKey + '"' +
3176 idir 1094
            // Class
1095
            commonFieldsHtml.fieldInput.classAttr +
3174 idir 1096
            // Required
3176 idir 1097
            commonFieldsHtml.fieldInput.mandatoryAttr +
3174 idir 1098
            // DataId
3176 idir 1099
            commonFieldsHtml.dataIdAttr +
3174 idir 1100
          '>';
1101
 
1102
      // On déroule les différentes valeurs
3176 idir 1103
      for( let i = 0; i < count; i++ ) {
3174 idir 1104
        let fieldOption = fieldOptions[i];
3176 idir 1105
        // Default
1106
        listFieldsHtml.defaultAttr = '';//réinitialisation
1107
        if( fieldOption.isDefault ) {//affectation
1108
          listFieldsHtml.defaultAttr = ' selected="selected"';
3174 idir 1109
        }
3176 idir 1110
        // value-id
3174 idir 1111
        if( '' !== fieldOption.optionIndex ) {
3176 idir 1112
          listFieldsHtml.optionIdAttr = ' value-id="' + fieldOption.optionIndex + '"';
3174 idir 1113
        }
1114
 
1115
        fieldHtml +=
1116
          '<option' +
1117
            // Value
3233 idir 1118
            ' value="' + fieldOption.optionValue.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' ) + '"' +
3174 idir 1119
            // Value-id
3176 idir 1120
            listFieldsHtml.optionIdAttr +
3174 idir 1121
            // Selected
3176 idir 1122
            listFieldsHtml.defaultAttr +
3174 idir 1123
          '>' +
1124
            // Option
3233 idir 1125
            fieldOption.optionText.replace( /(')/gm, '&apos;&apos;' ).replace( /(")/gm, '&quot;&quot;' ) +
3174 idir 1126
          '</option>';
1127
      }
1128
      // Si valeur "autre" est cochée
1129
      if( fieldOtherValue ) {
1130
        fieldHtml +=
3176 idir 1131
          '<option class="other" value="other"' + commonFieldsHtml.dataIdAttr + '>' +
3174 idir 1132
            'Autre' +
1133
          '</option>';
1134
      }
3176 idir 1135
      // Fermeture des conteneurs
3174 idir 1136
      fieldHtml +=
1137
          '</select>' +
1138
        // Fin du conteneur/wrapper
1139
        '</div>' +
3176 idir 1140
        // Bouton 'help'
1141
        commonFieldsHtml.helpButton;
3174 idir 1142
      break;
1143
 
1144
    case 'textarea':
3176 idir 1145
      // Classe 'and-help'
1146
      commonFieldsHtml.fieldLabel.classAttr = ' class="' + commonFieldsHtml.helpClass + '"';
3174 idir 1147
      // Autres attributs
3176 idir 1148
      commonFieldsHtml.fieldInput.otherAttr += ' id="' + fieldKey + '"';
3174 idir 1149
 
1150
      fieldHtml =
1151
        '<label' +
1152
          // For
3176 idir 1153
          commonFieldsHtml.fieldLabel.forAttr +
3174 idir 1154
          // Class
3176 idir 1155
          commonFieldsHtml.fieldLabel.classAttr +
3174 idir 1156
          // Info-bulle
3176 idir 1157
          commonFieldsHtml.titleAttr +
3174 idir 1158
          // Autres attributs
3176 idir 1159
          commonFieldsHtml.fieldLabel.otherAttr +
3174 idir 1160
        '>' +
1161
          // Nom du champ
3176 idir 1162
          commonFieldsHtml.fieldLabel.labelContent +
3174 idir 1163
        '</label>' +
3176 idir 1164
        // Bouton 'help'
1165
        commonFieldsHtml.helpButton +
3174 idir 1166
        '<textarea' +
1167
          // Name
3176 idir 1168
          commonFieldsHtml.fieldInput.nameAttr +
3174 idir 1169
          // DataId
3176 idir 1170
          commonFieldsHtml.dataIdAttr +
3174 idir 1171
          // Class
3176 idir 1172
          commonFieldsHtml.fieldInput.classAttr +
3174 idir 1173
          // Info-bulle
3176 idir 1174
          commonFieldsHtml.titleAttr +
3174 idir 1175
          // Info-bulle
3176 idir 1176
          commonFieldsHtml.fieldInput.placeholderAttr +
1177
          // Required
1178
          commonFieldsHtml.fieldInput.mandatoryAttr +
3174 idir 1179
          // Autres attributs
3176 idir 1180
          commonFieldsHtml.fieldInput.otherAttr +
3174 idir 1181
        '></textarea>';
1182
        break;
1183
 
1184
    case 'range':
3176 idir 1185
      // Classe 'and-help'
1186
      commonFieldsHtml.fieldLabel.classAttr = ' class="' + commonFieldsHtml.helpClass + '"';
1187
      // Step
3174 idir 1188
      if( '' !== fieldStep ) {
3176 idir 1189
        commonFieldsHtml.fieldInput.otherAttr += ' step="' +  fieldStep + '"';
3174 idir 1190
      }
3176 idir 1191
      // Min
3174 idir 1192
      if( '' !== fieldMin ) {
3176 idir 1193
        commonFieldsHtml.fieldInput.otherAttr += ' min="' +  fieldMin + '"';
3174 idir 1194
      }
3176 idir 1195
      //Max
3174 idir 1196
      if( '' !== fieldMax ) {
3176 idir 1197
        commonFieldsHtml.fieldInput.otherAttr += ' max="' +  fieldMax + '"';
3174 idir 1198
      }
1199
 
1200
      fieldHtml =
3185 idir 1201
        '<div' +
1202
          ' class="range"' +
1203
          ' id="' + fieldKey + '"' +
1204
        '>' +
3174 idir 1205
          '<label' +
1206
            // For
3176 idir 1207
            commonFieldsHtml.fieldLabel.forAttr +
3174 idir 1208
            // Class
3176 idir 1209
            commonFieldsHtml.fieldLabel.classAttr +
3174 idir 1210
            // Info-bulle
3176 idir 1211
            commonFieldsHtml.titleAttr +
3174 idir 1212
            // Autres attributs
3176 idir 1213
            commonFieldsHtml.fieldLabel.otherAttr +
3174 idir 1214
          '>' +
1215
            // Nom du champ
3176 idir 1216
            commonFieldsHtml.fieldLabel.labelContent +
3174 idir 1217
          '</label>' +
3176 idir 1218
          // Bouton 'help'
1219
          commonFieldsHtml.helpButton +
3174 idir 1220
          '<input' +
1221
            // Type
3176 idir 1222
            commonFieldsHtml.fieldInput.typeAttr +
3174 idir 1223
            // Name
3176 idir 1224
            commonFieldsHtml.fieldInput.nameAttr +
3174 idir 1225
            // DataId
3176 idir 1226
            commonFieldsHtml.dataIdAttr +
3174 idir 1227
            // Class
3176 idir 1228
            commonFieldsHtml.fieldInput.classAttr +
3174 idir 1229
            // Info-bulle
3176 idir 1230
            commonFieldsHtml.titleAttr +
1231
            // Required
1232
            commonFieldsHtml.fieldInput.mandatoryAttr +
3185 idir 1233
            // Default
1234
            ' value="' + fieldDefaultNum + '"' +
3174 idir 1235
            // Autres attributs
3176 idir 1236
            commonFieldsHtml.fieldInput.otherAttr +
3174 idir 1237
          '>' +
3185 idir 1238
          '<input' +
1239
            ' type="number"' +
1240
            ' name="' + fieldKey + 'Output"' +
1241
            // Info-bulle
1242
            commonFieldsHtml.titleAttr +
1243
            // Placeholder
1244
            commonFieldsHtml.fieldInput.placeholderAttr +
1245
            ' value="' + fieldDefaultNum + '"' +
1246
            // Autres attributs
1247
            commonFieldsHtml.fieldInput.otherAttr +
1248
            // DataId
1249
            commonFieldsHtml.dataIdAttr +
1250
          '>' +
3174 idir 1251
        '</div>';
1252
        break;
1253
 
3185 idir 1254
    case 'number':
1255
      // Step
1256
      if( '' !== fieldStep ) {
1257
        commonFieldsHtml.fieldInput.otherAttr += ' step="' +  fieldStep + '"';
1258
      }
3174 idir 1259
    case 'date':
3176 idir 1260
      // Ouvrir l'attribut class (suppression de '"')
1261
      commonFieldsHtml.fieldInput.classAttr = commonFieldsHtml.fieldInput.classAttr.slice(0, -1);
1262
      // Classe 'and-help'
1263
      commonFieldsHtml.fieldInput.classAttr += commonFieldsHtml.helpClass + '"';
1264
      // Min
3174 idir 1265
      if( '' !== fieldMin ) {
3176 idir 1266
        commonFieldsHtml.fieldInput.otherAttr += ' min="' +  fieldMin + '"';
3174 idir 1267
      }
3176 idir 1268
      // Max
3174 idir 1269
      if( '' !== fieldMax ) {
3176 idir 1270
        commonFieldsHtml.fieldInput.otherAttr += ' max="' +  fieldMax + '"';
3174 idir 1271
      }
1272
      fieldHtml =
1273
        '<div class="number">' +
1274
          '<label' +
1275
            // For
3176 idir 1276
            commonFieldsHtml.fieldLabel.forAttr +
3174 idir 1277
            // Class
3176 idir 1278
            commonFieldsHtml.fieldLabel.classAttr +
3174 idir 1279
            // Info-bulle
3176 idir 1280
            commonFieldsHtml.titleAttr +
3174 idir 1281
            // Autres attributs
3176 idir 1282
            commonFieldsHtml.fieldLabel.otherAttr +
3174 idir 1283
          '>' +
1284
            // Nom du champ
3176 idir 1285
            commonFieldsHtml.fieldLabel.labelContent +
3174 idir 1286
          '</label>' +
1287
          '<input' +
1288
            // Type
3176 idir 1289
            commonFieldsHtml.fieldInput.typeAttr +
3174 idir 1290
            // Name
3176 idir 1291
            commonFieldsHtml.fieldInput.nameAttr +
3174 idir 1292
            // DataId
3176 idir 1293
            commonFieldsHtml.dataIdAttr +
3174 idir 1294
            // Class
3176 idir 1295
            commonFieldsHtml.fieldInput.classAttr +
3174 idir 1296
            // Info-bulle
3176 idir 1297
            commonFieldsHtml.titleAttr +
3185 idir 1298
            // Placeholder
3176 idir 1299
            commonFieldsHtml.fieldInput.placeholderAttr +
1300
            // Required
1301
            commonFieldsHtml.fieldInput.mandatoryAttr +
3185 idir 1302
            // Default
1303
            ' value="' + fieldDefaultNum + '"' +
3174 idir 1304
            // Autres attributs
3176 idir 1305
            commonFieldsHtml.fieldInput.otherAttr +
3174 idir 1306
          '>' +
3176 idir 1307
          // Bouton 'help'
1308
          commonFieldsHtml.helpButton +
3174 idir 1309
        '</div>';
1310
        break;
1311
 
1312
    case 'text' :
1313
    case 'email':
1314
    default:
3176 idir 1315
      // Ouvrir l'attribut class (suppression de '"')
1316
      commonFieldsHtml.fieldInput.classAttr = commonFieldsHtml.fieldInput.classAttr.slice(0, -1);
1317
      // Classe 'and-help'
1318
      commonFieldsHtml.fieldInput.classAttr += commonFieldsHtml.helpClass + '"';
3174 idir 1319
 
1320
      fieldHtml =
1321
        '<label' +
1322
          // For
3176 idir 1323
          commonFieldsHtml.fieldLabel.forAttr +
3174 idir 1324
          // Class
3176 idir 1325
          commonFieldsHtml.fieldLabel.classAttr +
3174 idir 1326
          // Info-bulle
3176 idir 1327
          commonFieldsHtml.titleAttr +
3174 idir 1328
          // Autres attributs
3176 idir 1329
          commonFieldsHtml.fieldLabel.otherAttr +
3174 idir 1330
        '>' +
1331
          // Nom du champ
3176 idir 1332
          commonFieldsHtml.fieldLabel.labelContent +
3174 idir 1333
        '</label>' +
1334
        '<input' +
1335
          // Type
3176 idir 1336
          commonFieldsHtml.fieldInput.typeAttr +
3174 idir 1337
          // Name
3176 idir 1338
          commonFieldsHtml.fieldInput.nameAttr +
3174 idir 1339
          // DataId
3176 idir 1340
          commonFieldsHtml.dataIdAttr +
3174 idir 1341
          // Class
3176 idir 1342
          commonFieldsHtml.fieldInput.classAttr +
3174 idir 1343
          // Info-bulle
3176 idir 1344
          commonFieldsHtml.titleAttr +
3233 idir 1345
          // Placeholder
3176 idir 1346
          commonFieldsHtml.fieldInput.placeholderAttr +
1347
          // Required
1348
          commonFieldsHtml.fieldInput.mandatoryAttr +
3174 idir 1349
          // Autres attributs
3176 idir 1350
          commonFieldsHtml.fieldInput.otherAttr +
3174 idir 1351
        '>' +
3176 idir 1352
        // Bouton 'help'
1353
        commonFieldsHtml.helpButton;
3174 idir 1354
      break;
1355
  }
1356
  return fieldHtml;
1357
}
1358
 
1359
// Construire un tableau des options pour chaque élément de listes
1360
function collectListOptions( thisFieldset ) {
1361
  var $details = $( '.field-details' , thisFieldset ),
1362
      options = [];
1363
 
1364
  $details.find( '.new-value' ).each( function() {
1365
    options.push({
1366
      // Valeur transmise (value)
1367
      optionValue : $( this ).find('.list-value').val().toLowerCase(),
1368
      // Valeur Visible
3185 idir 1369
      optionText  : $( this ).find('.list-value').val(),
3174 idir 1370
      // Booléen "default"
1371
      isDefault   : $( this ).find( '.is-defaut-value').is( ':checked' ),
1372
      // Indice de l'option
3226 idir 1373
      optionIndex : $( this ).data( 'list-value-id')
3174 idir 1374
    });
3167 idir 1375
  });
3174 idir 1376
  return options;
1377
}
3167 idir 1378
 
3174 idir 1379
// Faire apparaitre un champ text "Autre"
1380
function onOtherOption( thisFieldset , index ) {
3176 idir 1381
  // Ce champ (dans la prévisualisation)
1382
  var thisPreviewFieldset = $( '.preview-fields[data-id="' + index + '"]'),
1383
      //L'élément choisi
1384
      element             = $('.field-element' , thisFieldset ).val(),
3174 idir 1385
      // Où insérer le champ "Autre"
3176 idir 1386
      $element            = $( '.' + element , thisPreviewFieldset ),
3174 idir 1387
      // html du champ "Autre"
3176 idir 1388
      collectOther        =
3174 idir 1389
        '<label data-id="' + index + '" for="collect-other">Autre option :</label>' +
1390
        '<input type="text" name="collect-other" data-id="' + index + '" class="collect-other" >';
1391
  // Pouvoir supprimer le champ "Autre"
3176 idir 1392
  function optionRemove( thisPreviewFieldset ) {
1393
    $( 'label[for="collect-other"]' , thisPreviewFieldset ).remove();
1394
    $( 'input.collect-other' , thisPreviewFieldset ).remove();
3174 idir 1395
  }
3167 idir 1396
 
3174 idir 1397
  switch( element ) {
1398
    case 'radio' :
1399
      // Lorsqu'un nouveau bouton est coché
3176 idir 1400
      $( 'input' , thisPreviewFieldset ).on( 'change' , function () {
3174 idir 1401
        if( 'other' === $( this ).val() ) {
1402
          // Insertion du champ "Autre" après les boutons
1403
          $element.after( collectOther );
1404
        } else {
1405
          // Suppression du champ autre
3176 idir 1406
          optionRemove( thisPreviewFieldset );
3174 idir 1407
        }
1408
      });
1409
      break;
1410
 
1411
    case 'select' :
1412
      // Lorsque l'option "Autre" est selectionnée
3176 idir 1413
      $( 'select' , thisPreviewFieldset ).on( 'change' , function () {
3174 idir 1414
        if( 'other' === $( this).val() ) {
1415
          // Insertion du champ "Autre" après les boutons
1416
          $element.after( collectOther );
1417
          // Suppression du champ autre
1418
        } else {
3176 idir 1419
          optionRemove( thisPreviewFieldset );
3174 idir 1420
        }
1421
      });
1422
      break;
1423
 
1424
    case 'checkbox' :
1425
    case 'list-checkbox' :
1426
      // Lorsque "Autre" est coché
3176 idir 1427
      $( 'input#other' , thisPreviewFieldset ).on( 'click' , function () {
3174 idir 1428
        // Insertion du champ "Autre" après les boutons
1429
        if( $( this ).is( ':checked' ) ) {
1430
          $element.after( collectOther );
1431
        } else {
1432
          // Suppression du champ autre
3176 idir 1433
          optionRemove( thisPreviewFieldset );
3174 idir 1434
        }
1435
      });
1436
      break;
1437
 
1438
    default :
1439
      break;
1440
  }
1441
}
1442
 
1443
// Prévisualisation des nouveaux champs
1444
function newFieldsPreview() {
3226 idir 1445
  var count = $( 'fieldset' ).last().data( 'id' );
3174 idir 1446
  // Si on a déjà prévisualisé on efface tout pour recommencer
1447
  if( 0 < $( '.preview-fields' ).length ) {
1448
    $( '.preview-fields' ).each( function () {
1449
      $( this ).remove();
1450
    });
1451
  }
1452
  // Au premier ajout d'un champ dans la prévisualisation on ajoute un titre et un message
1453
  if( true === firstClick ) {
1454
    $( '#zone-supp' ).prepend(
3182 idir 1455
      '<h2>Informations propres au projet</h2>' +
1456
      '<div class="message">L\'objectif principal de cet aperçu est de vérifier les contenus et repérer d\'éventuelles erreurs</div>'
3174 idir 1457
    );
1458
  }
1459
  // Parcourir tous les blocs d'infos de champs supplémentaires
3226 idir 1460
  for( var index = $( 'fieldset' ).first().data( 'id' ) ; index <= count ; index++ ) {
3174 idir 1461
    var thisFieldset = $( 'fieldset[data-id="' + index + '"]');
1462
    // Certains indices peuvent correspondre à un champ supprimé
1463
    if( 0 < $( thisFieldset ).length ) {
1464
      // Prévisualisation d'un champ
1465
      $( '#zone-supp .preview-container' ).append(
1466
        '<div class="preview-fields" data-id="' + index + '">'+
1467
          onClickPreviewField( thisFieldset , index ) +
1468
        '</div>'
1469
      );
1470
      // Ajout/suppression d'un champ texte "Autre"
1471
      if( $( '.option-other-value' , thisFieldset ).is( ':checked' ) ) {
1472
        onOtherOption( thisFieldset , index);
1473
      }
1474
    }
1475
  }
1476
  // Le titre + message de la section prévisualisation ne sont ajoutés qu'une fois
1477
  firstClick = false;
1478
}
1479
 
3176 idir 1480
// Activation/Desactivation et contenu de la modale Bootstrap
1481
// https://getbootstrap.com/docs/3.3/javascript/#modals
3174 idir 1482
function previewFieldHelpModal() {
1483
  $( '#zone-supp' ).on( 'click' , '.help-button' , function ( event ) {
3226 idir 1484
    var index = $( this ).closest( '.preview-fields' ).data( 'id' ),
3174 idir 1485
        thisFieldset = $( '.new-field[data-id="' + index + '"]' ),
1486
        file = $( '.field-help' , thisFieldset )[0].files[0],
3176 idir 1487
        tmppath = URL.createObjectURL( file );
1488
    // Titre
3174 idir 1489
    $( '#help-modal-label' ).text( 'Aide pour : ' +  $( '.field-name' , thisFieldset ).val() );
3176 idir 1490
    // Contenu
3226 idir 1491
    if( file.type.match( 'image/*' ) ) {
3174 idir 1492
        $( '#print_content' ).append( '<img src="' + tmppath + '" style="max-width:100%">' );
3226 idir 1493
    } else {
1494
      $( '#print_content' ).append( '<p>Erreur : le fichier n\'est pas une image</p>' );
3167 idir 1495
    }
3176 idir 1496
    // Sortie avec la touche escape
3174 idir 1497
    $( '#help-modal' ).modal( { keyboard : true } );
3176 idir 1498
    // Affichage
3174 idir 1499
    $( '#help-modal' ).modal( 'show' );
3176 idir 1500
    // Remplacer l'autofocus qui ne fonctionne plus en HTML5
1501
    // Message dans la doc de bootstrap :
1502
    // Due to how HTML5 defines its semantics,
1503
    // the autofocus HTML attribute has no effect in Bootstrap modals.
1504
    // To achieve the same effect, use some custom JavaScript
3174 idir 1505
    $( '#help-modal' ).on( 'shown.bs.modal' , function () {
1506
      $( '#myInput' ).trigger( 'focus' );
1507
    })
3176 idir 1508
    // Réinitialisation
3174 idir 1509
    $( '#help-modal' ).on( 'hidden.bs.modal' , function () {
1510
      $( '#help-modal-label' ).text();
1511
      $( '#print_content' ).empty();
1512
    })
3167 idir 1513
  });
1514
}
3174 idir 1515
 
1516
/***************************
1517
 *  Lancement des scripts  *
1518
 ***************************/
1519
 
1520
// Tableau d'envoi des données
3176 idir 1521
var datasToSubmit = new Array();
3182 idir 1522
// Variable permettant un seul affichage du titre
1523
// de la prévisualisation pour les nouveaux champs
3176 idir 1524
var firstClick = true;
3174 idir 1525
 
1526
jQuery( document ).ready( function() {
1527
  // Identifiant de champ
1528
  var fieldIndex = 0;
1529
  // Ajout de nouveaux champs
1530
  onClickAddNewFields( fieldIndex );
1531
  // Activation/Desactivation des boutons valider et prévisualiser
3188 idir 1532
  onClickButtonsTagMissingValues();
3174 idir 1533
  // Prévisualisation des champs classiques
3176 idir 1534
  DisplayClassicFields();
3174 idir 1535
  // Affichage des images ou nom des documents importés
1536
  inputFile();
1537
  // Affichage des List-checkbox
1538
  inputListCheckbox();
3226 idir 1539
  // Activer la checkbox de valeur par default uniquement si une valeur est entrée
1540
  onInputListValueLabelEnableDefaultCheckbox();
3185 idir 1541
  // Affichage des Range
3226 idir 1542
  inputRangeDisplayNumber();
3176 idir 1543
  // Modale "aide"
3174 idir 1544
  previewFieldHelpModal();
1545
});