Subversion Repositories eFlore/Applications.cel

Rev

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