Subversion Repositories eFlore/Applications.cel

Rev

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