Rev 3434 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
"use strict";function Utils(){this.cheminFichiers = $( '#zone-appli' ).data( 'url-fichiers' );// système de traduction minimalistethis.msgs = {fr: {'arbre' : 'Arbre','dupliquer' : 'Dupliquer','saisir-plantes' : 'Saisir les plantes','saisir-lichens' : 'Saisir les lichens','upload-non-suppote' : 'Votre navigateur ne permet pas le téléchargement de fichiers.','format-non-supporte' : 'Le format de fichier n\'est pas supporté, les formats acceptés sont','image-deja-chargee' : 'Cette image a déjà été utilisée','date-incomplete' : 'Format : jj/mm/aaaa.','observations-transmises' : 'observations transmises','supprimer-observation-liste' : 'Supprimer cette observation de la liste à transmettre','confirmation-suppression' : 'Êtes-vous sûr de vouloir supprimer cette observation','milieu' : 'Milieu','commentaires' : 'Commentaires','non-lie-au-ref' : 'non lié au référentiel','obs-le' : 'le','non-connexion' : 'Veuillez entrer votre login et votre mot de passe','obs-numero' : 'Observation n°','erreur' : 'Erreur','erreur-inconnue' : 'Erreur inconnue','erreur-image' : 'Erreur lors du chargement des images','erreur-ajax' : 'Erreur Ajax','erreur-chargement' : 'Erreur lors du chargement de l\'observation','erreur-chargement-obs-utilisateur' : 'Erreur lors du chargement des observations de cet utilisateur','erreur-formulaire' : 'Erreur: impossible de charger le formulaire','lieu-obs' : 'observé à','lieu-dit' : 'Lieu-dit','taxon-ou-image' : 'Veuillez transmettre au moins, soit une image, soit une espèce','station' : 'Station','date-rue' : 'Un releve existe dejà à cette date pour cette rue.','rechargement-page' : 'Êtes vous sûr de vouloir quiter la page?\nLes observations saisies mais non transmises seront perdues.','courriel-connu' : 'Un compte existe pour ce courriel, connectez-vous pour saisir votre observation'},en: {'arbre' : 'Tree','dupliquer' : 'Duplicate','saisir-plantes' : 'Enter the plants','saisir-lichens' : 'Enter the lichens','upload-non-suppote' : 'Your browser does not support file upload.','format-non-supporte' : 'The file format is not supported, the accepted formats are','image-deja-chargee' : 'This image has already been used','date-incomplete' : 'Format: dd/mm/yyyy.','observations-transmises' : 'observations transmitted','supprimer-observation-liste' : 'Delete this observation from the list to be transmitted','confirmation-suppression' : 'Are you sure you want to delete this observation','milieu' : 'Environment','commentaires' : 'Comments','non-lie-au-ref' : 'unrelated to the referencial ','obs-le' : 'the','non-connexion' : 'Please enter your login and password','obs-numero' : 'Observation number ','erreur' : 'Error','erreur-inconnue' : 'Unknown error','erreur-image' : 'Error loading the images','erreur-ajax' : 'Ajax Error','erreur-chargement' : 'Error loading the observation','erreur-chargement-obs-utilisateur' : 'Error loading this user\'s observations','erreur-formulaire' : 'Error: couldn\'t load form','lieu-obs' : 'observed at','lieu-dit' : 'Locality','taxon-ou-image' : 'Please transmit at least one image or one species','station' : 'Place','date-rue' : 'A record already exists on this date for this street','rechargement-page' : 'Are you sure you want to leave the page?\nAll untransmitted observations will be lost.','courriel-connu' : 'An account exists for this email, log in to enter your observation'}};};var lthis = Utils.prototype;Utils.prototype.init = function() {// Modale "aide" du projetthis.projetHelpModale();// Affichage input filethis.inputFile();// Affichage des List-checkboxthis.inputListCheckbox();// Affichage des Rangethis.inputRangeDisplayNumber()// Modale "aide"this.newFieldsHelpModal();// Ajout/suppression d'un champ texte "Autre"this.onOtherOption();// Récupérer les données entrées dans "Autre"this.collectOtherOption();};/*** Permet à la fois de vérifier qu'une valeur ou objet existe et n'est pas vide* et de comparer à une autre valeur :* Vérifie qu'une variable ou objet n'est pas : vide, null, undefined, NaN* Si comparer est défini on le compare à valeur en fonction de sensComparaison* Un booléen est une variable valide : on retourne true* @param { string || number || object || undefined } valeur* @param { boolean } sensComparaison : true = rechercher, false = refuser* @param { string || number || object || undefined || boolean } comparer :valeur à comparer* @returns {boolean}*/Utils.prototype.valOk = function (valeur, sensComparaison = true, comparer = undefined ) {var retour = true;if ( 'boolean' !== typeof valeur ) {switch( typeof valeur ) {case 'string' :retour = ( '' !== valeur );break;case 'number' :retour = ( NaN !== valeur );break;case 'object' :retour = ( null !== valeur && undefined !== valeur && !$.isEmptyObject( valeur ) );if ( null !== valeur && undefined !== valeur.length ) {retour = ( retour && 0 < valeur.length );}break;case 'undefined' :default :retour = false;}if ( retour && comparer !== undefined ) {var resultComparaison = ( comparer === valeur );retour = ( sensComparaison ) ? resultComparaison : !resultComparaison ;}return retour;} else {// Un booléen est une valeur valablereturn true;}};/************************************** Fonctions de Style et Affichage ** des éléments "spéciaux" **************************************/// Logique d'affichage pour le input type=fileUtils.prototype.inputFile = function() {// Initialisation des variablesvar $fileInput = $( '.input-file' ),$button = $( '.label-file' );// Action lorsque la "barre d'espace" ou "Entrée" est pressée$( '#formulaire' ).on( 'keydown', '.label-file', function( event ) {if ( event.keyCode == 13 || event.keyCode == 32 ) {$( '#' + $( this ).attr( 'for' ) + '.input-file' ).click();}});};// Style et affichage des list-checkboxesUtils.prototype.inputListCheckbox = function() {// On écoute le click sur une list-checkbox ('.selectBox')// à tout moment de son insertion dans le dom// _ S'assurer de bien viser la bonne list-checkbox// _ Au click sur un autre champ remballer la list-checkbox$( document ).click( function( event ) {var target = event.target;if ( !$( target ).is( '.overSelect' ) && 0 === $( target ).closest( '.checkboxes' ).length ) {$( '.checkboxes' ).each( function () {$( this ).addClass( 'hidden' );});$( '.selectBox select.focus', '#zone-appli' ).each( function() {$( this ).removeClass( 'focus' );});}});$( '#zone-appli' ).on( 'click' , '.selectBox' , function() {// afficher/cacher le volet des checkboxes et focus$( this ).next().toggleClass( 'hidden' );$( this ).find( 'select' ).toggleClass( 'focus' );// Cacher le volet des autres checkboxes et retirer leur focusvar $checkboxes = $( this ).next(),count = $( '.checkboxes' ).length;for ( var i = 0; i < count; i++ ) {if ( $( '.checkboxes' )[i] !== $checkboxes[0] && !$checkboxes.hasClass( 'hidden' ) ) {var $otherListCheckboxes = $( '.checkboxes' )[i];if ( !$otherListCheckboxes.classList.contains( 'hidden' ) ) {$otherListCheckboxes.classList.add( 'hidden' );}if( $otherListCheckboxes.previousElementSibling.firstElementChild.classList.contains( 'focus' ) ) {$otherListCheckboxes.previousElementSibling.firstElementChild.classList.remove( 'focus' );}}}});};// Style et affichage des input type="range"Utils.prototype.inputRangeDisplayNumber = function() {$( 'input[type="range"]' ).each( function() {$( this ).siblings( '.range-live-value' ).text( $( this ).val() );});$( '#top' ).on( 'input' , 'input[type="range"]' , function () {$( this ).siblings( '.range-live-value' ).text( $( this ).val() );});$( '#top' ).on( 'click', '#ajouter-obs', function() {$( '.range-live-value' ).each( function() {var $this = $( this );$this.text( '' );});});};// Activation/Desactivation et contenu de la modale Bootstrap// https://getbootstrap.com/docs/3.3/javascript/#modalsUtils.prototype.newFieldsHelpModal = function() {const lthis = this;$( '#zone-appli' ).on( 'click' , '.help-button' , function ( event ) {var thisFieldKey = $( this ).data( 'key' ),fileMimeType = $( this ).data( 'mime-type' ),label = 'Aide pour : ' + $( this ).data( 'name' );if( fileMimeType.match( 'image' ) ) {var extention = fileMimeType.replace( /(?:imag)?e\/?/g , '' ),content = '<img id="modale-aide-img" src="' + lthis.cheminFichiers + thisFieldKey + '.' + extention + '" style="" alt="' + thisFieldKey + '" />';}lthis.activerModale( label, content );});};// aide dans le titre du projetUtils.prototype.projetHelpModale = function() {const lthis = this;$( '#top' ).on ( 'click', '#info-button', function ( event ) {var fileMimeType = $( this ).data( 'mime-info' ),label = 'Aide du projet : ' + $( '#titre-projet' ).text();if( fileMimeType.match( 'image' ) ) {var extention = fileMimeType.replace( /(?:imag)?e\/?/g , '' ),content = '<img id="modale-aide-img" src="' + lthis.cheminFichiers + 'info.' + extention + '" style="" alt="info projet" />';}lthis.activerModale( label, content );});};// Activation/Desactivation et contenu de la modale Bootstrap// https://getbootstrap.com/docs/3.3/javascript/#modalsUtils.prototype.activerModale = function( label, content = '', buttons = [] ) {var dismiss = '',buttonsHtmlBase = '<button type="button" class="btn btn-secondary" data-dismiss="modal">Fermer</button>',buttonsHtml = buttonsHtmlBase;// Titre$( '#fenetre-modal-label' ).text( label );if ( '' !== content ) {$( '#print_content' ).append( content );}// Sortie avec la touche escape$( '#fenetre-modal' ).modal( { keyboard : true } );// Affichage$( '#fenetre-modal' ).modal({ show: true });// Remplacer l'autofocus qui ne fonctionne plus en HTML5// Message dans la doc de bootstrap :// Due to how HTML5 defines its semantics,// the autofocus HTML attribute has no effect in Bootstrap modals.// To achieve the same effect, use some custom JavaScript$( '#fenetre-modal' ).off( 'shown.bs.modal' ).on( 'shown.bs.modal' , function () {$( '#myInput' ).trigger( 'focus' );if( lthis.valOk( $( '#modale-aide-img' ) ) ) {lthis.redimentionnerImgAide();$( window ).on( 'resize', lthis.redimentionnerImgAide.bind( lthis ) );}});if ( this.valOk( buttons ) ) {buttonsHtml = '';$.each( buttons, function( i, button ) {dismiss = button.dismiss ? 'data-dismiss="modal"' : '';buttonsHtml += '<button type="button" class="btn ' + button.class + '" ' + dismiss + '>' + button.label + '</button>';});}$( '.modal-footer' ).html( buttonsHtml );// Réinitialisation$( '#fenetre-modal' ).on( 'hidden.bs.modal' , function () {$( '#confirm-modal-label' ).text();$( '#print_content' ).empty();$( '.modal-footer' ).html( buttonsHtmlBase );});};Utils.prototype.redimentionnerImgAide = function() {var espHorizDisp = $( '.modal-dialog' ).innerWidth() <= 768 ? $( '.modal-dialog' ).innerWidth() - 30 : 768,cssImg = {'width': espHorizDisp,'height' : 'auto'};$( '#modale-aide-img' ).css(cssImg).show(50);};// Faire apparaitre un champ text "Autre"Utils.prototype.onOtherOption = function() {const PREFIX = 'collect-other-';// Ajouter un champ texte pour "Autre"function optionAdd( otherId, $target, element, dataName, dataLabel ) {$target.after('<div class="control-group">'+'<label'+' for="' + otherId + '"'+' class="' + otherId + '"'+'>'+'Autre option "' + dataLabel.toLowerCase() + '" :'+'</label>'+'<input'+' type="text"'+' id="' + otherId + '"'+' name="' + otherId + '"'+' class="collect-other form-control"'+' data-name="' + dataName + '"'+' data-element="' + element + '"'+'>'+'</div>');$( '#' + otherId ).focus();}// Supprimer un champ texte pour "Autre"function optionRemove( otherId ) {$( '#' + otherId ).closest('.control-group').remove();}$( '.other', '#formulaire' ).each( function() {if( $( this ).hasClass( 'is-select' ) ) {var dataName = $( this ).data( 'name' ),otherId = PREFIX + dataName,dataLabel = $( '.select' ).data( 'label' );// Insertion du champ "Autre" après les boutonsif ( !lthis.valOk( $( '#'+otherId ) ) ) {optionAdd( otherId, $( this ).parent( '.add-field-select' ), 'select', dataName, dataLabel );}} else if ( $( this ).is( ':checked' ) ) {var dataName = $( this ).data( 'name' ),otherId = PREFIX + dataName,element = $( this ).data( 'element' ),dataLabel = $( this ).data( 'label' );// Insertion du champ "Autre" après les boutonsif ( !lthis.valOk( $( '#'+ otherId ) ) ) {optionAdd( otherId, $( this ).parent( 'label' ), element, dataName, dataLabel );}}});$( '#formulaire' ).on( 'change', '.select', function () {var dataName = $( this ).data( 'name' ),otherId = PREFIX + dataName,dataLabel = $( this ).data( 'label' );if( 'other' === $( this ).val() ) {// Insertion du champ "Autre" après les boutonsif ( !lthis.valOk( $( '#'+otherId ) ) ) {optionAdd( otherId, $( this ).parent( '.add-field-select' ), 'select', dataName, dataLabel );}} else {// Suppression du champ autreoptionRemove( otherId );$( this ).find( '.other' ).val( 'other' );}});$( '#formulaire' ).on( 'change', 'input[type=radio]', function () {var dataName = $( this ).data( 'name' ),otherId = PREFIX + dataName,dataLabel = $( this ).data( 'label' );if( 'other' === $( this ).val() ) {// Insertion du champ "Autre" après les boutonsif ( !lthis.valOk( $( '#'+otherId ) ) ) {optionAdd( otherId, $( this ).parent( 'label' ), 'radio', dataName, dataLabel );}} else {// Suppression du champ autreoptionRemove( otherId );$( this ).closest( '.radio' ).find( '.other' ).val( 'other' );}});$( '#formulaire' ).on( 'click', '.list-checkbox .other,.checkbox .other', function () {var dataName = $( this ).data( 'name' ),otherId = PREFIX + dataName,element = $( this ).data( 'element' ),dataLabel = $( this ).data( 'label' );if( $( this ).is( ':checked' ) ) {// Insertion du champ "Autre" après les boutonsif ( !lthis.valOk( $( '#'+otherId ) ) ) {optionAdd( otherId, $( this ).parent( 'label' ), element, dataName, dataLabel );}} else {// Suppression du champ autreoptionRemove( otherId );$( this ).val( 'other' );}});};Utils.prototype.collectOtherOption = function() {$( '#formulaire' ).on( 'change', '.collect-other', function () {var otherIdSuffix = $( this ).data( 'name' ).replace( '[]', '' );var element = $( this ).data( 'element' );if ( '' === $( this ).val() ){if ( 'select' === element ) {$( '#' + otherIdSuffix ).find( '.other' ).prop( 'selected', false ).val( 'other' );} else {$( '#other-' + otherIdSuffix ).prop( 'checked', false ).val( 'other' );}$( 'label.collect-other-' + otherIdSuffix ).remove();$( this ).remove();} else {if ( 'select' === element ) {$( '#' + otherIdSuffix ).find( '.other' ).val( $( this ).val() );$( '#' + otherIdSuffix ).val( $( this ).val() );$( '#' + otherIdSuffix + ' option').not( '.other' ).prop( 'selected', false );$( '#' + otherIdSuffix ).find( '.other' ).prop( 'selected', true );} else {if ( 'radio' === element ) {$( 'input[name=' + otherIdSuffix + ']' ).not( '#other-' + otherIdSuffix ).prop( 'checked', false );}$( '#other-' + otherIdSuffix ).val( $( this ).val() );$( '#other-' + otherIdSuffix ).prop( 'checked', true );}}});};