Rev 3877 | Blame | Compare with Previous | Last modification | View Log | RSS feed
import {WidgetsSaisiesCommun,utils} from './WidgetsSaisiesCommun.js';import {valOk,tryParseJson} from './Utils.js';/*** Constructeur WidgetSaisie par défaut*/function WidgetSaisie( ) {if ( valOk(widgetProp) ) {this.urlWidgets = widgetProp.urlWidgets;this.projet = widgetProp.projet;this.idProjet = widgetProp.idProjet;this.tagsMotsCles = widgetProp.tagsMotsCles;this.mode = widgetProp.mode;this.langue = widgetProp.langue;this.serviceAnnuaireIdUrl = widgetProp.serviceAnnuaireIdUrl;this.serviceNomCommuneUrl = widgetProp.serviceNomCommuneUrl;this.serviceNomCommuneUrlAlt = widgetProp.serviceNomCommuneUrlAlt;this.debug = widgetProp.debug;this.html5 = widgetProp.html5;this.serviceSaisieUrl = widgetProp.serviceSaisieUrl;this.serviceObsUrl = widgetProp.serviceObsUrl;this.chargementImageIconeUrl = widgetProp.chargementImageIconeUrl;this.pasDePhotoIconeUrl = widgetProp.pasDePhotoIconeUrl;this.autocompletionElementsNbre = widgetProp.autocompletionElementsNbre;this.serviceAutocompletionNomSciUrl = widgetProp.serviceAutocompletionNomSciUrl;this.serviceAutocompletionNomSciUrlTpl = widgetProp.serviceAutocompletionNomSciUrlTpl;this.dureeMessage = widgetProp.dureeMessage;this.obsMaxNbre = widgetProp.obsMaxNbre;this.tagImg = widgetProp.tagImg;this.tagObs = widgetProp.tagObs;this.obsId = widgetProp.obsId;this.nomSciReferentiel = widgetProp.nomSciReferentiel;this.especeImposee = widgetProp.especeImposee;this.infosEspeceImposee = widgetProp.infosEspeceImposee;this.referentielImpose = widgetProp.referentielImpose;this.isTaxonListe = widgetProp.isTaxonListe;this.photoObligatoire = widgetProp.photoObligatoire;}this.urlRacine = window.location.origin;this.obsNbre = 0;this.nbObsEnCours = 1;this.totalObsATransmettre = 0;this.nbObsTransmises = 0;this.observer = null;this.isASL = false;this.geoloc = {};}WidgetSaisie.prototype = new WidgetsSaisiesCommun();/*** Initialise le formulaire, les validateurs, les listes de complétion...*/WidgetSaisie.prototype.initForm = function() {this.initFormConnection();if ( valOk( this.obsId ) ) {this.chargerInfoObs();}if( this.isTaxonListe ) {this.initFormTaxonListe();} else {this.ajouterAutocompletionNoms();}// au rafraichissement de la page,// les input date semblent conserver la valeur entrée précedemment// c'est voulu après la création d'une obs mais pas quand la page est actualisée// Déjà tenté: onbeforeunload avec un location.reload(true) n'a pas permis de le faire$( 'input[type=date]' ).each( function () {( valOk( $( this ).data( 'default' ) ) ) ? $( this ).val( $( this ).data( 'default' ) ) : $( this ).val( '' );});this.configurerFormValidator();this.definirReglesFormValidator();if( this.especeImposee ) {$( '#taxon' ).attr( 'disabled', 'disabled' );$( '#taxon-input-groupe' ).attr( 'title', '' );// Bricolage cracra pour avoir le nom retenu avec auteur (nom_retenu.libelle ne le mentionne pas)const infosEspeceImposee = $.parseJSON( this.infosEspeceImposee );let nomRetenuComplet = infosEspeceImposee.nom_retenu_complet;const debutAnneRefBiblio = nomRetenuComplet.indexOf( ' [' );if ( -1 !== debutAnneRefBiblio ) {nomRetenuComplet = nomRetenuComplet.substr( 0, debutAnneRefBiblio );}// fin bricolage cracraconst infosAssociee = {label : infosEspeceImposee.nom_sci_complet,value : infosEspeceImposee.nom_sci_complet,nt : infosEspeceImposee.num_taxonomique,nomSel : infosEspeceImposee.nom_sci,nomSelComplet : infosEspeceImposee.nom_sci_complet,numNomSel : infosEspeceImposee.id,nomRet : nomRetenuComplet,numNomRet : infosEspeceImposee['nom_retenu.id'],famille : infosEspeceImposee.famille,retenu : ( 'false' === infosEspeceImposee.retenu ) ? false : true};$( '#taxon' ).data( infosAssociee );}};/*** Initialise les écouteurs d'événements*/WidgetSaisie.prototype.initEvts = function() {// identitéthis.initEvtsConnection();// on location, initialisation de la géolocthis.initEvtsGeoloc();// Sur téléchargement imagethis.initEvtsFichier();$( '#referentiel' ).on( 'change', this.surChangementReferentiel.bind( this ) );// Création / Suppression / Transmission des obs// Défilement des miniatures dans le résumé obsthis.initEvtsObs();// Alertes et aidesthis.initEvtsAlertes();// message avant de quitter le formulairethis.confirmerSortie();};// Identité Observateur par courrielWidgetSaisie.prototype.requeterIdentiteCourriel = function() {const lthis = this,courriel = $( '#courriel' ).val(),urlAnnuaire = this.serviceAnnuaireIdUrl + courriel;if ( valOk( courriel ) ) {$.ajax({url : urlAnnuaire,type : 'GET',success : function( data, textStatus, jqXHR ) {if ( lthis.debug ) {console.log( 'SUCCESS: ' + textStatus );}if ( valOk( data ) && valOk( data[courriel] ) ) {const infos = data[courriel];lthis.surSuccesCompletionCourriel( infos, courriel );} else {lthis.surErreurCompletionCourriel();}},error : function( jqXHR, textStatus, errorThrown ) {if ( lthis.debug ) {console.log( 'ERREUR: '+ textStatus );}lthis.surErreurCompletionCourriel();},complete : function( jqXHR, textStatus ) {if ( lthis.debug ) {console.log( 'COMPLETE: '+ textStatus );}}});}};// se déclanche quand on choisit "Observation sans inscription" mais que le mail entré est incrit à TelaWidgetSaisie.prototype.surSuccesCompletionCourriel = function( infos, courriel ) {if ( $( '#utilisateur-connecte' ).hasClass( 'hidden' ) ) {// si quelque chose a foiré après actualisationif ( !valOk( $( '#warning-identite' ) ) ) {$( '#zone-courriel' ).before( '<p id="warning-identite" class="warning"><i class="fas fa-exclamation-triangle"></i> ' + this.msgTraduction( 'courriel-connu' ) + '</p>' );}$( '#inscription, #zone-prenom-nom, #zone-courriel-confirmation' ).addClass( 'hidden' );$( '#prenom, #nom, #courriel_confirmation' ).attr( 'disabled', 'disabled' );$( '.nav.control-group' ).addClass( 'error' );}};// se déclanche quand on choisit "Observation sans inscription" et qu'effectivement le mail n'est pas connu de TelaWidgetSaisie.prototype.surErreurCompletionCourriel = function() {$( '#creation-compte, #zone-prenom-nom, #zone-courriel-confirmation' ).removeClass( 'hidden' );$( '#warning-identite' ).remove();$( '.nav.control-group' ).removeClass( 'error' );$( '#prenom, #nom, #courriel_confirmation' ).val( '' ).removeAttr( 'disabled' );};WidgetSaisie.prototype.testerLancementRequeteIdentite = function( event ) {if ( valOk( event.which, true, 13 ) ) {this.requeterIdentiteCourriel();event.preventDefault();event.stopPropagation();}};WidgetSaisie.prototype.reduireVoletIdentite = function() {if ( $( '#form-observateur' ).valid() && $( '#courriel' ).valid() && $( '#courriel_confirmation' ).valid() ) {$( '#bouton-connexion, #creation-compte' ).addClass( 'hidden' );$( '#bienvenue').removeClass( 'hidden' );$( '#inscription, #zone-courriel' ).addClass( 'hidden' );if ( valOk( $( '#nom' ).val() ) && valOk( $( '#prenom' ).val() ) ) {$( '#zone-prenom-nom' ).addClass( 'hidden' );$( '#bienvenue-prenom' ).text( ' ' + $( '#prenom' ).val() );$( '#bienvenue-nom' ).text( ' ' + $( '#nom' ).val() );} else {$( '#zone-prenom-nom' ).removeClass( 'hidden' );$( '#bienvenue-prenom,#bienvenue-nom' ).text( '' );}} else {$( '#bouton-connexion, #creation-compte' ).removeClass( 'hidden' );$( '#bienvenue').addClass( 'hidden' );}};WidgetSaisie.prototype.formaterNom = function() {$( '#nom' ).val( $( '#nom' ).val().toUpperCase() );};WidgetSaisie.prototype.formaterPrenom = function() {const prenom = [],mots = $( '#prenom' ).val().split( ' ' ),motsLength = mots.length;for ( let i = 0; i < motsLength; i++ ) {let mot = mots[i],motMajuscule = '';if ( 0 <= mot.indexOf( '-' ) ) {const prenomCompose = new Array(),motsComposes = mot.split( '-' ),motsComposesLength = motsComposes.length;for ( let j = 0; j < motsComposesLength; j++ ) {const motSimple = motsComposes[j];motMajuscule = motSimple.charAt(0).toUpperCase() + motSimple.slice(1);prenomCompose.push( motMajuscule );}prenom.push( prenomCompose.join( '-' ) );} else {motMajuscule = mot.charAt(0).toUpperCase() + mot.slice(1);prenom.push( motMajuscule );}}$( '#prenom' ).val( prenom.join( ' ' ) );};WidgetSaisie.prototype.bloquerCopierCollerCourriel = function() {this.afficherPanneau( '#dialogue-bloquer-copier-coller' );return false;};// Préchargement des infos-obs ************************************************/WidgetSaisie.prototype.chargerInfoObs = function() {const lthis = this,urlObs = this.serviceObsUrl + '/' + this.obsId;$.ajax({url: urlObs,type: 'GET',success: function( data, textStatus, jqXHR ) {if ( valOk( data ) ) {lthis.prechargerForm( data );} else {lthis.surErreurChargementInfosObs.bind( lthis );}},error: function( jqXHR, textStatus, errorThrown ) {lthis.surErreurChargementInfosObs();}});};// @TODO faire mieux que ça !WidgetSaisie.prototype.surErreurChargementInfosObs = function() {utils.activerModale( this.msgTraduction( 'erreur-chargement' ) );};WidgetSaisie.prototype.prechargerForm = function( data ) {$( '#milieu' ).val( data.milieu );$( '#commune-nom' ).text( data.zoneGeo );if( data.hasOwnProperty( 'codeZoneGeo' ) ) {// TODO: trouver un moyen qui fonctionne lorsqu'on aura d'autres référentiels que INSEE$( '#commune-insee' ).text( data.codeZoneGeo.replace( 'INSEE-C:', '' ) );}if( data.hasOwnProperty( 'latitude' ) && data.hasOwnProperty( 'longitude' ) ) {// $cartoRemplacee = $( '#tb-geolocation' ),// suffixe = '',// layer = 'osm',// zoomInit = 18const typeLocalisation = $( '#top' ).data( 'type-loc' ),donnesResetCarto = {latitude : data.latitude,longitude : data.longitude,typeLocalisation : typeLocalisation,zoom : 18};this.transfererCarto( donnesResetCarto );}};// Ajouter Obs ****************************************************************//*** Retourne un Array contenant les valeurs des champs étendus*/WidgetSaisie.prototype.getObsChpSpecifiques = function() {const lthis = this,champs = [],$thisForm = $( '#form-supp' ),elements ='input[type=text]:not(.collect-other),'+'input[type=checkbox]:checked,'+'input[type=radio]:checked,'+'input[type=email],'+'input[type=number],'+'input[type=range],'+'input[type=date],'+'textarea,'+'.select',retour = [];$( elements, $thisForm ).each( function() {if ( valOk( $( this ).val() ) && ( valOk( $( this ).attr( 'name' ) ) || valOk( $( this ).data( 'name' ) ) ) ) {const valeur = $( this ).val(),cle = ( valOk( $( this ).attr( 'name' ) ) ) ? $( this ).attr( 'name' ) : $( this ).data( 'name' );if ( cle in champs ) {champs[cle] += ';' + valeur;} else {champs[cle] = valeur;}}});for ( let key in champs ) {retour.push({ 'cle' : key , 'valeur' : champs[key] });}if ( valOk( $( '#coord-lineaire' ).val() ) ) {retour.push({ 'cle' : 'coordonnees-rue-ou-lineaire' , 'valeur' : $( '#coord-lineaire' ).val() });}return retour;};WidgetSaisie.prototype.reinitialiserForm = function() {this.supprimerMiniatures();if( !this.especeImposee ) {$( '#taxon' ).val( '' );$( '#taxon' ).data( 'numNomSel', '' ).data( 'nomRet','' ).data( 'numNomRet', '' ).data( 'nt', '' ).data( 'famille', '' );if( this.isTaxonListe ) {$( '#taxon-liste' ).find( 'option' ).each( function() {if ( $( this ).hasClass( 'choisir' ) ) {$( this ).attr( 'selected', true );} else {$( this ).attr( 'selected', false );}});$( '#taxon-input-groupe' ).addClass( 'hidden' );$('#taxon-autre').val('');}}if ( valOk( $( '#form-supp' ) ) ) {$( '#form-supp' ).validate().resetForm();}};WidgetSaisie.prototype.validateGeometry = function( geometry ) {const isLineString = !!geometry && 'LineString' === geometry.type,validateTypeOfCoordinates = coordinates => isLineString ? Array.isArray( coordinates ) : ['number','string'].includes( typeof coordinates );if ( !valOk( geometry.coordinates ) ) {return false;}let isValid = true;$.each(geometry.coordinates, (i, coordinates) => {if ( !validateTypeOfCoordinates( coordinates ) ) {isValid = false;}});const isValidLength = isLineString ? ( geometry.coordinates.length >= 2 ) : ( geometry.coordinates.length === 2 );return isValid && isValidLength;}// Géolocalisation *************************************************************//*** Fonction handler de l'évenement location du module tb-geoloc*/WidgetSaisie.prototype.locationHandler = function( location ) {const locDatas = location.originalEvent.detail,$geolocControlGroup = $( '#geoloc' ).closest( '.control-group' );if ( !valOk( locDatas ) ) {console.warn( 'Error location' );} else {if ( !this.validateGeometry( locDatas.geometry ) ) {$geolocControlGroup.addClass( 'error' );$( '#geometry' ).val( '' );} else {console.log( locDatas );const geometry = JSON.stringify( locDatas.geometry ),altitude = ( valOk( locDatas.elevation ) ) ? locDatas.elevation : '',pays = ( valOk( locDatas.osmCountryCode ) ) ? locDatas.osmCountryCode.toUpperCase() : 'FR',rue = ( valOk( locDatas.osmRoad ) ) ? locDatas.osmRoad : '';let latitude = '',longitude = '',coordLineaire = '',nomCommune = '',communeInsee = '';if ( valOk( locDatas.geometry.coordinates ) &&valOk( locDatas.centroid.coordinates ) &&valOk( locDatas.centroid.coordinates[0] ) &&valOk( locDatas.centroid.coordinates[1] )) {longitude = locDatas.centroid.coordinates[0];latitude = locDatas.centroid.coordinates[1];}if ( valOk( locDatas.inseeData ) ) {nomCommune = locDatas.inseeData.nom;communeInsee = ( valOk( locDatas.inseeData.code ) ) ? locDatas.inseeData.code : '';} else if ( valOk( locDatas.locality ) ) {nomCommune = locDatas.locality;} else if ( valOk( locDatas.locality ) ) {nomCommune = locDatas.osmCounty;}$( '#geometry' ).val( geometry );$( '#coord-lineaire' ).val( coordLineaire );$( '#latitude' ).val( latitude );$( '#longitude' ).val( longitude );$( '#commune-nom' ).val( nomCommune );$( '#commune-insee' ).val( communeInsee );$( '#altitude' ).val( altitude );$( '#pays' ).val( pays );$( '#station' ).val( rue );$( '#latitude, #longitude' ).valid();$geolocControlGroup.toggleClass('error',!valOk( $( '#latitude' ).val() ) || !valOk( $( '#longitude' ).val() ));}}}// Form Validator *************************************************************/WidgetSaisie.prototype.chpEtendusValidation = function() {const lthis = this,$thisForm = $( '#form-supp' ),elements ='.checkbox,'+'.radio,'+'.checkboxes,'+'.select,'+'textarea,'+'input[type=text]:not(.collect-other),'+'input[type=email],'+'input[type=number],'+'input[type=range],'+'input[type=date]',speFields = ['checkbox','radio','checkboxes','select'],spefieldsCount = speFields.length,chpSuppValidation = {rules : {},messages : {},minmax : []},errors = {},namesListFields = [];let picked = '';$( elements, $thisForm ).each( function() {for( let fieldsClass = 0; spefieldsCount > fieldsClass; fieldsClass++ ) {const dataName = $( this ).data( 'name' );if ( valOk( $( this ).attr( 'required' ) ) && $( this ).hasClass( speFields[fieldsClass] ) && !valOk( chpSuppValidation.rules[ dataName ] ) ) {namesListFields.push( dataName );chpSuppValidation.rules[ dataName ] = { required : true };if ( valOk( $( '.other', $( this ) ) ) ) {picked = ( 'select' === speFields[fieldsClass] ) ? ':selected' : ':checked';chpSuppValidation.rules[ 'collect-other-' + dataName.replace( '[]', '' ) ] = {required : '#other-' + dataName.replace( '[]', '' ) + picked,minlength: 1};chpSuppValidation.messages[ 'collect-other-' + dataName.replace( '[]', '' ) ] = false;}chpSuppValidation.rules[ dataName ]['listFields'] = true;chpSuppValidation.messages[ dataName ] = 'Ce champ est requis :\nVeuillez choisir une option, ou entrer une valeur autre valide.';errors[dataName] = '.' + speFields[fieldsClass];}}if ( valOk( $( this ).attr( 'name' ) ) && valOk ( $( this ).attr( 'required' ) ) && 0 > $.inArray( $( this ).attr( 'name' ) , namesListFields ) ) {chpSuppValidation.rules[ $( this ).attr( 'name' ) ] = { required : true, minlength: 1 };if(( valOk( $( this ).attr( 'type' ), true, 'number' ) || valOk( $( this ).attr( 'type' ), true, 'range' ) ) &&( valOk( $( this )[0].min ) || valOk( $( this )[0].max ) )) {chpSuppValidation.rules[ $( this ).attr('name') ]['minMaxOk'] = true;chpSuppValidation.messages[ $( this ).attr('name') ] = lthis.validerMinMax( $( this )[0] ).message;}}});if ( valOk( chpSuppValidation.rules ) ) {$.each( chpSuppValidation.rules, function( key ) {if ( !valOk( chpSuppValidation.messages[key] ) ) {chpSuppValidation.messages[key] = 'Ce champ est requis :\nVeuillez entrer une valeur valide.';}});if ( 0 < Object.keys( errors ).length ) {chpSuppValidation['errors'] = errors;}}return chpSuppValidation;};WidgetSaisie.prototype.validerMinMax = function( element ) {const minCond = parseFloat( element.value ) >= parseFloat( element.min ),maxCond = parseFloat( element.value ) <= parseFloat( element.max ),returnMnMx = { cond : true , message : '' };let mnMxCond = new Boolean(),messageMnMx = 'La valeur entrée doit être';if(( valOk( element.type, true, 'number' ) || valOk( element.type, true, 'range' ) ) &&( valOk( element.min ) || valOk( element.max ) )) {if ( element.min && element.max ) {messageMnMx += ' comprise entre ' + element.min + ' et ' + element.max;mnMxCond = ( minCond && maxCond );} else if ( element.min ) {messageMnMx += ' supérieure à ' + element.min;mnMxCond = minCond;} else {messageMnMx += ' inférieure à ' + element.max;mnMxCond = maxCond;}returnMnMx.cond = mnMxCond;returnMnMx.message = messageMnMx;}return returnMnMx;};WidgetSaisie.prototype.definirReglesFormValidator = function() {const lthis = this,formSuppValidation = this.chpEtendusValidation();$( '#form-supp' ).validate({onclick : function( element ) {if ((valOk( element.type, true, 'checkbox' ) ||valOk( element.type, true, 'radio' )) &&(!valOk( $( '.' + $( element ).attr( 'name' ).replace( '[]', '' ) + ':checked' ) ) ||valOk( $( '.' + $( element ).attr( 'name' ).replace( '[]', '' ) + ':not(.other):checked' ) ) ||!valOk( $( '#other-' + $( element ).attr( 'name' ).replace( '[]', '' ) ) ) ||$( '#other-' + $( element ).attr( 'name' ).replace( '[]', '' ) ).is( ':checked' ) ||($( '#other-' + $( element ).attr( 'name' ).replace( '[]', '' ) ).is( ':checked' ) &&$( element ).closest( '.control-group' ).hasClass('error')))) {$( element ).valid();if ( $( element ).valid() ) {$( element ).closest( '.control-group' ).removeClass( 'error' );$( element ).next( $( 'span.error' ) ).remove();} else {$( element ).closest( '.control-group' ).addClass( 'error' );}}return false;},rules : formSuppValidation.rules,messages : formSuppValidation.messages,errorPlacement : function( error , element ) {if ( 0 < Object.keys( formSuppValidation.errors ).length ) {const errorsKeys = Object.keys( formSuppValidation.errors );let thisKey = '',errorsFlag = true;for ( let i = 0 ; i < errorsKeys.length ; i++ ) {thisKey = errorsKeys[i];if( $( element ).attr( 'name' ) === thisKey ) {$( formSuppValidation.errors[thisKey] ).append( error );errorsFlag = false;}}if ( errorsFlag ) {error.insertAfter( element );}} else {error.insertAfter( element );}}});$( '#form-supp .select' ).change( function() {$( this ).valid();});$( 'input[type=date]' ).on( 'input', function() {$( this ).valid();});// Validation taxon// et gestion des messages d'erreur taxon et images en fonction de la certitude$( '#taxon, #certitude' ).on( 'change', function() {lthis.validerTaxonRequis( valOk( $( '#taxon' ).val() ) );});// Validation miniatures avec MutationObserverthis.surPresenceAbsenceMiniature();$( '#form-observation' ).validate({rules : {date_releve : {required : true,'dateCel' : true},latitude : {required : true,minlength : 1,range : [-90, 90]},longitude : {required : true,minlength : 1,range : [-180, 180]}}});$( '#form-observateur' ).validate({rules : {courriel : {required : true,email : true,'userEmailOk' : true},courriel_confirmation : {required : true,equalTo : '#courriel'}}});$( '#connexion,#inscription,#bouton-anonyme' ).on( 'click', function( event ) {$( '.nav.control-group' ).removeClass( 'error' );});};WidgetSaisie.prototype.validerCertitudeTaxonImage = function( hasTaxon = false, hasImages = false ) {const isCertain = 'certain' === $( '#certitude' ).val();let isvalid = true ;if ( this.photoObligatoire || !isCertain ) {isvalid = this.validerImageRequise( hasImages );}if ( isCertain ) {isvalid &= this.validerTaxonRequis( hasTaxon );}return isvalid;};WidgetSaisie.prototype.validerTaxonRequis = function( hasTaxon = false ) {const taxonEstRequis = 'certain' === $( '#certitude' ).val();if ( !this.photoObligatoire ) {$( '#photos-conteneur').removeClass( 'error' ).find( 'span.error' ).hide();}if ( !hasTaxon && taxonEstRequis ) {this.afficherPanneau( '#dialogue-taxon-or-image' );$( '#bloc-taxon' ).addClass( 'error' ).find( 'span.error' ).show();} else {this.masquerPanneau( '#dialogue-taxon-or-image' );$( '#bloc-taxon' ).removeClass( 'error' ).find( 'span.error' ).hide();}if ( taxonEstRequis ) {return hasTaxon;}};WidgetSaisie.prototype.validerImageRequise = function( hasImages = false ) {$( '#bloc-taxon' ).removeClass( 'error' ).find( 'span.error' ).hide();if ( hasImages ) {this.masquerPanneau( '#dialogue-taxon-or-image' );this.masquerPanneau( '#dialogue-image-requise' );$( '#fichier' ).parent( 'label.label-file' ).removeClass( 'error' );$( '#photos-conteneur').removeClass( 'error' ).find( 'span.error' ).hide();} else {if ( this.photoObligatoire ) {this.afficherPanneau( '#dialogue-image-requise' );} else {this.afficherPanneau( '#dialogue-taxon-or-image' );}$( '#fichier' ).parent( 'label.label-file' ).addClass( 'error' );$( '#photos-conteneur').addClass( 'error' ).find( 'span.error' ).show();}return hasImages;};WidgetSaisie.prototype.surPresenceAbsenceMiniature = function() {const lthis = this;// voir : https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/disconnect// Selectionne le noeud dont les mutations seront observéesconst targetNode = document.getElementById( 'miniatures' );// Fonction callback à éxécuter quand une mutation est observéeconst callback = mutationsList => {for( let mutation of mutationsList ) {lthis.validerCertitudeTaxonImage(valOk( $( '#taxon' ).val() ),0 < mutation.target.childElementCount);}};// Créé une instance de l'observateur lié à la fonction de callbackthis.observer = new MutationObserver( callback );// Commence à observer le noeud cible pour les mutations précédemment configuréesthis.observer.observe( targetNode, { childList: true } );};WidgetSaisie.prototype.validerForm = function() {const observateur = ( $( '#form-observateur' ).valid() && $( '#courriel' ).valid() && $( '#courriel_confirmation' ).valid() ),obs = $( '#form-observation' ).valid(),parsedGeometry = tryParseJson( $( '#geometry' ).val() ),geoloc = this.validateGeometry( parsedGeometry ) && ( valOk( $( '#latitude' ).val() ) && valOk( $( '#longitude' ).val() ) ) ,// validation et panneau taxon/imagescertitudeTaxonImage = this.validerCertitudeTaxonImage(valOk( $( '#taxon' ).val() ),valOk( $( '#miniatures .miniature' ) ));let chpsSupp = true;if ( valOk( $( '#form-supp' ) ) ) {chpsSupp = ( function () {let otherFlag = $( '#form-supp' ).valid();if( valOk( $( '.other', $( '#form-supp' ) ) ) ) {$( '.other', $( '#form-supp' ) ).each( function() {const picked = ( $( this ).data( 'element' ) !== 'select' ) ? ':checked' : ':selected';if ( $( this ).is( picked ) && valOk( $( this ).val(), true, 'other' ) ) {otherFlag = false;}});}return otherFlag;})();}// panneau geolocif ( geoloc ) {this.masquerPanneau( '#dialogue-geoloc-ko' );$( '#geoloc-datas' ).closest( '.control-group' ).removeClass( 'error' );} else{this.afficherPanneau( '#dialogue-geoloc-ko' );$( '#geoloc-datas' ).closest( '.control-group' ).addClass( 'error' );}// panneau observateurif ( observateur ) {this.masquerPanneau( '#dialogue-utilisateur-non-identifie' );$( '.nav.control-group' ).removeClass( 'error' );} else {this.afficherPanneau( '#dialogue-utilisateur-non-identifie' );$( '.nav.control-group' ).addClass( 'error' );}return ( observateur && obs && geoloc && certitudeTaxonImage && chpsSupp );};// Referentiel ****************************************************************/// N'est pas utilisé en cas de taxon-listeWidgetSaisie.prototype.surChangementReferentiel = function() {this.nomSciReferentiel = $( '#referentiel' ).val();//réinitialise taxon.val$( '#taxon' ).val( '' );$( '#taxon' ).data( 'numNomSel', '' );};$( document ).ready( function() {const widget = new WidgetSaisie();widget.init();// Fonctions de Style et Affichage des éléments "spéciaux"utils.init();});