Subversion Repositories eFlore/Applications.cel

Compare Revisions

Ignore whitespace Rev 3207 → Rev 3208

/trunk/widget/modules/saisie2/Saisie2.php
14,366 → 14,490
* ===> vignette = [0-9]+,[0-9]+ [par défaut : 4,3]
* Indique le nombre de vignette par ligne et le nombre de ligne.
*
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
* @version $Id$
* @copyright Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
* @version $Id$
* @copyright Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
*/
class Saisie2 extends WidgetCommun {
const DS = DIRECTORY_SEPARATOR;
const SERVICE_DEFAUT = 'saisie';
const LANGUE_DEFAUT = 'fr';
const PROJET_DEFAUT = 'base';
const WS_NOM = 'noms';
const EFLORE_API_VERSION = '0.1';
private $cel_url_tpl = null;
/** Si spécifié, on ajoute une barre de navigation inter-applications */
private $bar;
//private $parametres_autorises = array('projet', 'type', 'langue', 'order');
private $parametres_autorises = array(
'projet' => 'projet',
'type' => 'type',
'langue' => 'langue',
'order' => 'order'
);
/**
* Méthode appelée par défaut pour charger ce widget.
*/
public function executer() {
$retour = null;
// Pour la création de l'id du cache nous ne tenons pas compte du paramètre de l'url callback
unset($this->parametres['callback']);
extract($this->parametres);
$this->bar = (isset($bar)) ? $bar : false;
/* Le fichier Framework.php du Framework de Tela Botanica doit être appelé avant tout autre chose dans l'application.
Sinon, rien ne sera chargé.
L'emplacement du Framework peut varier en fonction de l'environnement (test, prod...). Afin de faciliter la configuration
de l'emplacement du Framework, un fichier framework.defaut.php doit être renommé en framework.php et configuré pour chaque installation de
l'application.
Chemin du fichier chargeant le framework requis */
$framework = dirname(__FILE__).'/framework.php';
if (!file_exists($framework)) {
$e = "Veuillez paramêtrer l'emplacement et la version du Framework dans le fichier $framework";
trigger_error($e, E_USER_ERROR);
} else {
// Inclusion du Framework
require_once $framework;
// Ajout d'information concernant cette application
Framework::setCheminAppli(__FILE__);// Obligatoire
Framework::setInfoAppli(Config::get('info'));// Optionnel
}
$langue = (isset($langue)) ? $langue : self::LANGUE_DEFAUT;
$this->langue = I18n::setLangue($langue);
$this->parametres['langue'] = $langue;
 
if (!isset($mode)) {
$mode = self::SERVICE_DEFAUT;
}
if (!isset($projet)) {
$this->parametres['projet'] = self::PROJET_DEFAUT;
}
$methode = $this->traiterNomMethodeExecuter($mode);
if (method_exists($this, $methode)) {
$retour = $this->$methode();
} else {
$this->messages[] = "Ce type de service '$methode' n'est pas disponible.";
}
$contenu = '';
if (is_null($retour)) {
$this->messages[] = 'La ressource demandée a retourné une valeur nulle.';
} else {
if (isset($retour['donnees'])) {
$retour['donnees']['prod'] = ($this->config['parametres']['modeServeur'] == "prod");
$retour['donnees']['bar'] = $this->bar;
$retour['donnees']['url_base'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], '');
$retour['donnees']['url_ws_annuaire'] = sprintf($this->config['chemins']['baseURLServicesAnnuaireTpl'], 'utilisateur/identite-par-courriel/');
$retour['donnees']['authTpl'] = $this->config['manager']['authTpl'].'?projet='.$this->parametres['projet'].'&langue='.$this->parametres['langue'];
$retour['donnees']['mode'] = $mode;
$squelette = dirname(__FILE__).self::DS.'squelettes'.self::DS.$retour['squelette'].'.tpl.html';
$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']);
} else {
$this->messages[] = 'Les données à transmettre au squelette sont nulles.';
}
}
$this->envoyer($contenu);
}
const DS = DIRECTORY_SEPARATOR;
const SERVICE_DEFAUT = 'saisie';
const LANGUE_DEFAUT = 'fr';
const PROJET_DEFAUT = 'base';
const WS_NOM = 'noms';
const EFLORE_API_VERSION = '0.1';
private $cel_url_tpl = null;
/** Si spécifié, on ajoute une barre de navigation inter-applications */
private $bar;
//private $parametres_autorises = array('projet', 'type', 'langue', 'order');
private $parametres_autorises = array(
'projet' => 'projet',
'type' => 'type',
'langue' => 'langue',
'order' => 'order'
);
/**
* Méthode appelée par défaut pour charger ce widget.
*/
public function executer() {
$retour = null;
// Pour la création de l'id du cache nous ne tenons pas compte du paramètre de l'url callback
unset($this->parametres['callback']);
extract($this->parametres);
$this->bar = (isset($bar)) ? $bar : false;
/* Le fichier Framework.php du Framework de Tela Botanica doit être appelé avant tout autre chose dans l'application.
Sinon, rien ne sera chargé.
L'emplacement du Framework peut varier en fonction de l'environnement (test, prod...). Afin de faciliter la configuration
de l'emplacement du Framework, un fichier framework.defaut.php doit être renommé en framework.php et configuré pour chaque installation de
l'application.
Chemin du fichier chargeant le framework requis */
$framework = dirname(__FILE__).'/framework.php';
if (!file_exists($framework)) {
$e = "Veuillez paramêtrer l'emplacement et la version du Framework dans le fichier $framework";
trigger_error($e, E_USER_ERROR);
} else {
// Inclusion du Framework
require_once $framework;
// Ajout d'information concernant cette application
Framework::setCheminAppli(__FILE__);// Obligatoire
Framework::setInfoAppli(Config::get('info'));// Optionnel
 
private function executerSaisie() {
$retour = array();
$retour['squelette'] = 'saisie';
$retour['donnees']['general'] = I18n::get('General');
$retour['donnees']['aide'] = I18n::get('Aide');
$retour['donnees']['observateur'] = I18n::get('Observateur');
$retour['donnees']['observation'] = I18n::get('Observation');
$retour['donnees']['widget'] = $this->rechercherProjet();
return $retour;
}
/* Recherche si le projet existe sinon va chercher les infos de base */
private function rechercherProjet() {
// projet avec un squelette défini (et non juste un mot-clé d'observation)
$estProjetDefini = true; $tab = array();
$url = $this->config['manager']['celUrlTpl'].'?projet='.$this->parametres['projet'].'&langue='.$this->parametres['langue'];
$json = $this->getDao()->consulter($url);
if ($json == false) {
$url = $this->config['manager']['celUrlTpl'].'?projet=base&langue='.$this->parametres['langue'];
$json = $this->getDao()->consulter($url);
$estProjetDefini = false;
} else {
$tab = $this->rechercherChampsSupp();
}
$tableau = json_decode($json, true);
$tableau = $this->traiterParametres($estProjetDefini, $tableau[0]);
$tableau['especes'] = $this->rechercherInfosEspeces($tableau);
if ($tableau['milieux'] != "") {
$tableau['milieux']= explode(";", $tableau['milieux']);
} else {
$tableau['milieux'] = array();
}
$tableau['chpSupp'] = $tab;
return $tableau;
}
/* Recherche si un projet a des champs de saisie supplémentaire */
private function rechercherChampsSupp() {
$retour = array();
$url = $this->config['manager']['celChpSupTpl'].'?projet='.$this->parametres['projet'].'&langue='.$this->parametres['langue'];
$json = $this->getDao()->consulter($url);
$retour = (array) json_decode($json, true);
return $retour;
}
// remplace certains parametres définis en bd par les parametres définis dans l'url
private function traiterParametres($estProjetDefini, $tableau) {
$criteres = array('tag', 'motcle', 'projet', 'titre', 'logo');
$criteresProjetNonDefini = array('commune', 'num_nom', 'referentiel');
foreach($this->parametres as $nom_critere => $valeur_critere) {
if (($estProjetDefini == false || $tableau['projet'] == "base") && in_array($nom_critere, $criteresProjetNonDefini)) {
$tableau[$nom_critere] = $valeur_critere;
} else if (in_array($nom_critere, $criteres)) {
$tableau[$nom_critere] = $valeur_critere;
}
}
return $tableau;
}
private function rechercherInfosEspeces($infos_projets) { //print_r($infos_projets);exit;
$retour = ""; $referentiel = $infos_projets['referentiel'];
$urlWsNsTpl = $this->config['chemins']['baseURLServicesEfloreTpl'];
$urlWsNs = sprintf($urlWsNsTpl, self::EFLORE_API_VERSION, $referentiel, self::WS_NOM);
$urlWsNsSansRef = sprintf($urlWsNsTpl, self::EFLORE_API_VERSION, '{referentiel}', self::WS_NOM);
$retour['url_ws_autocompletion_ns'] = $urlWsNs;
$retour['url_ws_autocompletion_ns_tpl'] = $urlWsNsSansRef;
$retour['ns_referentiel'] = $referentiel;
if (isset($infos_projets['type_especes'])) {
switch ($infos_projets['type_especes']) {
case "referentiel" : $referentiel = $infos_projets['referentiel']; break;
case "liste" : $referentiel = $infos_projets['referentiel']; break;
case "fixe" :
$retour['especes'] = $this->chargerInfosTaxon($infos_projets['referentiel'], $infos_projets['especes']);
break;
}
} else if (isset($infos_projets['referentiel'])) {
$referentiel = $infos_projets['referentiel'];
if (isset($infos_projets['num_nom'])) {
$retour['especes'] = $this->chargerInfosTaxon($infos_projets['referentiel'], $infos_projets['num_nom']);
}
}
$projetsAListeDeNoms = $this->transformerEnTableau($this->config['projets']['liste_noms']);
if (in_array($this->projet, $projetsAListeDeNoms) && !$this->especeEstImposee()) {
$projetsAListeDeNomsSciEtVerna = $this->transformerEnTableau($this->config['projets']['liste_noms_sci_et_verna']);
if (in_array($this->projet, $projetsAListeDeNomsSciEtVerna)) {
$retour['taxons'] = $this->recupererListeNoms();
} else {
$retour['taxons'] = $this->recupererListeNomsSci();
}
}
return $retour;
}
/**
* Consulte un webservice pour obtenir des informations sur le taxon dont le
* numéro nomenclatural est $num_nom (ce sont donc plutôt des infos sur le nom
* et non le taxon?)
* @param string|int $num_nom
* @return array
*/
protected function chargerInfosTaxon($referentiel, $num_nom) {
$url_service_infos = sprintf($this->config['chemins']['infosTaxonUrl'], $referentiel, $num_nom);
$infos = json_decode(file_get_contents($url_service_infos));
// trop de champs injectés dans les infos espèces peuvent
// faire planter javascript
$champs_a_garder = array('id', 'nom_sci','nom_sci_complet', 'nom_complet',
'famille','nom_retenu.id', 'nom_retenu_complet', 'num_taxonomique');
$resultat = array();
$retour = array();
if (isset($infos) && !empty($infos)) {
$infos = (array)$infos;
if (isset($infos['nom_sci']) && $infos['nom_sci'] != '') {
$resultat = array_intersect_key($infos, array_flip($champs_a_garder));
$resultat['retenu'] = ($infos['id'] == $infos['nom_retenu.id']) ? "true" : "false";
$retour['espece_imposee'] = true;
$retour['nn_espece_defaut'] = $nnEspeceImposee;
$retour['nom_sci_espece_defaut'] = $resultat['nom_complet'];
$retour['infos_espece'] = $this->array2js($resultat, true);
}
}
return $retour;
}
protected function getReferentielImpose() {
$referentiel_impose = true;
if (!empty($_GET['referentiel']) && $_GET['referentiel'] != "autre") {
$this->ns_referentiel = $_GET['referentiel'];
} else if (isset($this->configProjet['referentiel'])) {
$this->ns_referentiel = $this->configProjet['referentiel'];
} else if (isset($this->configMission['referentiel'])) {
$this->ns_referentiel = $this->configMission['referentiel'];
} else {
$referentiel_impose = false;
}
return $referentiel_impose;
}
}
$langue = (isset($langue)) ? $langue : self::LANGUE_DEFAUT;
$this->langue = I18n::setLangue($langue);
$this->parametres['langue'] = $langue;
 
/**
* Trie par nom français les taxons lus dans le fichier tsv
*/
protected function recupererListeNomsSci() {
$taxons = $this->recupererListeTaxon();
if (is_array($taxons)) {
$taxons = self::trierTableauMd($taxons, array('nom_fr' => SORT_ASC));
}
return $taxons;
}
/**
* @TODO documenter
* @return array
*/
protected function recupererListeNoms() {
$taxons = $this->recupererListeTaxon();
$nomsAAfficher = array();
$nomsSpeciaux = array();
if (is_array($taxons)) {
foreach ($taxons as $taxon) {
$nomSciTitle = $taxon['nom_ret'].
($taxon['nom_fr'] != '' ? ' - '.$taxon['nom_fr'] : '' ).
($taxon['nom_fr_autre'] != '' ? ' - '.$taxon['nom_fr_autre'] : '' );
$nomFrTitle = $taxon['nom_sel'].
($taxon['nom_ret'] != $taxon['nom_sel']? ' - '.$taxon['nom_ret'] : '' ).
($taxon['nom_fr_autre'] != '' ? ' - '.$taxon['nom_fr_autre'] : '' );
if ($taxon['groupe'] == 'special') {
$nomsSpeciaux[] = array(
'num_nom' => $taxon['num_nom_sel'],
'nom_a_afficher' => $taxon['nom_fr'],
'nom_a_sauver' => $taxon['nom_sel'],
'nom_title' => $nomSciTitle,
'nom_type' => 'nom-special');
} else {
$nomsAAfficher[] = array(
'num_nom' => $taxon['num_nom_sel'],
'nom_a_afficher' => $taxon['nom_sel'],
'nom_a_sauver' => $taxon['nom_sel'],
'nom_title' => $nomSciTitle,
'nom_type' => 'nom-sci');
$nomsAAfficher[] = array(
'num_nom' => $taxon['num_nom_sel'],
'nom_a_afficher' => $taxon['nom_fr'],
'nom_a_sauver' => $taxon['nom_fr'],
'nom_title' => $nomFrTitle,
'nom_type' => 'nom-fr');
}
}
$nomsAAfficher = self::trierTableauMd($nomsAAfficher, array('nom_a_afficher' => SORT_ASC));
$nomsSpeciaux = self::trierTableauMd($nomsSpeciaux, array('nom_a_afficher' => SORT_ASC));
}
return array('speciaux' => $nomsSpeciaux, 'sci-et-fr' => $nomsAAfficher);
}
/**
* Lit une liste de taxons depuis un fichier tsv fourni
*/
protected function recupererListeTaxon() {
$taxons = array();
if ($this->projet == 'missions-flore') {
$fichier_tsv = dirname(__FILE__).self::DS.'configurations'.self::DS.$this->projet.'_'.$this->mission.'_taxons.tsv';
} else {
$fichier_tsv = dirname(__FILE__).self::DS.'configurations'.self::DS.$this->projet.'_taxons.tsv';
}
if (file_exists($fichier_tsv) && is_readable($fichier_tsv)) {
$taxons = $this->decomposerFichierTsv($fichier_tsv);
} else {
$this->debug[] = "Impossible d'ouvrir le fichier '$fichier_tsv'.";
}
return $taxons;
}
/**
* Découpe un fihcier tsv
*/
protected function decomposerFichierTsv($fichier, $delimiter = "\t"){
$header = null;
$data = array();
if (($handle = fopen($fichier, 'r')) !== FALSE) {
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
if (!$header) {
$header = $row;
} else {
$data[] = array_combine($header, $row);
}
}
fclose($handle);
}
return $data;
}
/**
* Convertit un tableau PHP en Javascript - @WTF pourquoi ne pas faire un json_encode ?
* @param array $array
* @param boolean $show_keys
* @return une portion de JSON représentant le tableau
*/
protected function array2js($array,$show_keys) {
$tableauJs = '{}';
if (!empty($array)) {
$total = count($array) - 1;
$i = 0;
$dimensions = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$dimensions[$i] = array2js($value,$show_keys);
if ($show_keys) {
$dimensions[$i] = '"'.$key.'":'.$dimensions[$i];
}
} else {
$dimensions[$i] = '"'.addslashes($value).'"';
if ($show_keys) {
$dimensions[$i] = '"'.$key.'":'.$dimensions[$i];
}
}
if ($i == 0) {
$dimensions[$i] = '{'.$dimensions[$i];
}
if ($i == $total) {
$dimensions[$i].= '}';
}
$i++;
}
$tableauJs = implode(',', $dimensions);
}
return $tableauJs;
}
if (!isset($mode)) {
$mode = self::SERVICE_DEFAUT;
}
if (!isset($projet)) {
$this->parametres['projet'] = self::PROJET_DEFAUT;
}
 
$methode = $this->traiterNomMethodeExecuter($mode);
if (method_exists($this, $methode)) {
$retour = $this->$methode();
} else {
$this->messages[] = "Ce type de service '$methode' n'est pas disponible.";
}
 
$contenu = '';
if (is_null($retour)) {
$this->messages[] = 'La ressource demandée a retourné une valeur nulle.';
} else {
if (isset($retour['donnees'])) {
$retour['donnees']['prod'] = ($this->config['parametres']['modeServeur'] == "prod");
$retour['donnees']['bar'] = $this->bar;
$retour['donnees']['url_base'] = sprintf($this->config['chemins']['baseURLAbsoluDyn'], '');
$retour['donnees']['url_ws_annuaire'] = sprintf($this->config['chemins']['baseURLServicesAnnuaireTpl'], 'utilisateur/identite-par-courriel/');
$retour['donnees']['url_ws_upload'] = $this->config['manager']['uploadUrl'];
$retour['donnees']['authTpl'] = $this->config['manager']['authTpl'].'?projet='.$this->parametres['projet'].'&langue='.$this->parametres['langue'];
$retour['donnees']['mode'] = $mode;
$squelette = dirname(__FILE__).self::DS.'squelettes'.self::DS.$retour['squelette'].'.tpl.html';
$contenu = $this->traiterSquelettePhp($squelette, $retour['donnees']);
} else {
$this->messages[] = 'Les données à transmettre au squelette sont nulles.';
}
}
$this->envoyer($contenu);
}
 
 
private function executerSaisie() {
$retour = array();
$retour['squelette'] = 'saisie';
$retour['donnees']['general'] = I18n::get('General');
$retour['donnees']['aide'] = I18n::get('Aide');
$retour['donnees']['observateur'] = I18n::get('Observateur');
$retour['donnees']['observation'] = I18n::get('Observation');
$retour['donnees']['widget'] = $this->rechercherProjet();
return $retour;
}
 
/* Recherche si le projet existe sinon va chercher les infos de base */
private function rechercherProjet() {
// projet avec un squelette défini (et non juste un mot-clé d'observation)
$estProjetDefini = true;
$tab = array();
$url = $this->config['manager']['celUrlTpl'].'?projet='.$this->parametres['projet'].'&langue='.$this->parametres['langue'];
$json = $this->getDao()->consulter($url);
if ($json == false) {
$url = $this->config['manager']['celUrlTpl'].'?projet=base&langue='.$this->parametres['langue'];
$json = $this->getDao()->consulter($url);
$estProjetDefini = false;
} else {
$tab = $this->rechercherChampsSupp();
}
$tableau = json_decode($json, true);
$tableau = $this->traiterParametres($estProjetDefini, $tableau[0]);
$tableau['especes'] = $this->rechercherInfosEspeces($tableau);
if ($tableau['milieux'] != "") {
$tableau['milieux']= explode(";", $tableau['milieux']);
} else {
$tableau['milieux'] = array();
}
$tableau['chpSupp'] = $tab;
return $tableau;
}
 
/* Recherche si un projet a des champs de saisie supplémentaire */
private function rechercherChampsSupp() {
$retour = array();
$url = $this->config['manager']['celChpSupTpl'].'?projet='.$this->parametres['projet'].'&langue='.$this->parametres['langue'];
$json = $this->getDao()->consulter($url);
$retour = (array) json_decode($json, true);
foreach ($retour['sauvagessupp']['champs-supp'] as $key => $chsup) {
if (isset($chsup['fieldValues'])) {
$retour['sauvagessupp']['champs-supp'][$key]['fieldValues'] = json_decode($chsup['fieldValues'], true);
if (isset($retour['sauvagessupp']['champs-supp'][$key]['fieldValues']["listValue"])) {
foreach($retour['sauvagessupp']['champs-supp'][$key]['fieldValues']["listValue"] as $list_value) {
// Obtenir une liste de valeurs utilisables dans les attributs for id ou name par exemple
$retour['sauvagessupp']['champs-supp'][$key]['fieldValues']['cleanListValue'][] = 'val-' . preg_replace('/[^A-Za-z0-9_\-]/', '',$this->remove_accents($list_value));
}
}
}
$retour['sauvagessupp']['champs-supp'][$key]['mandatory'] = intval($chsup['mandatory']);
}
return $retour;
}
 
private function remove_accents($string) {
if ( !preg_match('/[\x80-\xff]/', $string) )
return $string;
 
$chars = array(
// Decompositions for Latin-1 Supplement
chr(195).chr(128) => 'A', chr(195).chr(129) => 'A',
chr(195).chr(130) => 'A', chr(195).chr(131) => 'A',
chr(195).chr(132) => 'A', chr(195).chr(133) => 'A',
chr(195).chr(135) => 'C', chr(195).chr(136) => 'E',
chr(195).chr(137) => 'E', chr(195).chr(138) => 'E',
chr(195).chr(139) => 'E', chr(195).chr(140) => 'I',
chr(195).chr(141) => 'I', chr(195).chr(142) => 'I',
chr(195).chr(143) => 'I', chr(195).chr(145) => 'N',
chr(195).chr(146) => 'O', chr(195).chr(147) => 'O',
chr(195).chr(148) => 'O', chr(195).chr(149) => 'O',
chr(195).chr(150) => 'O', chr(195).chr(153) => 'U',
chr(195).chr(154) => 'U', chr(195).chr(155) => 'U',
chr(195).chr(156) => 'U', chr(195).chr(157) => 'Y',
chr(195).chr(159) => 's', chr(195).chr(160) => 'a',
chr(195).chr(161) => 'a', chr(195).chr(162) => 'a',
chr(195).chr(163) => 'a', chr(195).chr(164) => 'a',
chr(195).chr(165) => 'a', chr(195).chr(167) => 'c',
chr(195).chr(168) => 'e', chr(195).chr(169) => 'e',
chr(195).chr(170) => 'e', chr(195).chr(171) => 'e',
chr(195).chr(172) => 'i', chr(195).chr(173) => 'i',
chr(195).chr(174) => 'i', chr(195).chr(175) => 'i',
chr(195).chr(177) => 'n', chr(195).chr(178) => 'o',
chr(195).chr(179) => 'o', chr(195).chr(180) => 'o',
chr(195).chr(181) => 'o', chr(195).chr(182) => 'o',
chr(195).chr(182) => 'o', chr(195).chr(185) => 'u',
chr(195).chr(186) => 'u', chr(195).chr(187) => 'u',
chr(195).chr(188) => 'u', chr(195).chr(189) => 'y',
chr(195).chr(191) => 'y',
// Decompositions for Latin Extended-A
chr(196).chr(128) => 'A', chr(196).chr(129) => 'a',
chr(196).chr(130) => 'A', chr(196).chr(131) => 'a',
chr(196).chr(132) => 'A', chr(196).chr(133) => 'a',
chr(196).chr(134) => 'C', chr(196).chr(135) => 'c',
chr(196).chr(136) => 'C', chr(196).chr(137) => 'c',
chr(196).chr(138) => 'C', chr(196).chr(139) => 'c',
chr(196).chr(140) => 'C', chr(196).chr(141) => 'c',
chr(196).chr(142) => 'D', chr(196).chr(143) => 'd',
chr(196).chr(144) => 'D', chr(196).chr(145) => 'd',
chr(196).chr(146) => 'E', chr(196).chr(147) => 'e',
chr(196).chr(148) => 'E', chr(196).chr(149) => 'e',
chr(196).chr(150) => 'E', chr(196).chr(151) => 'e',
chr(196).chr(152) => 'E', chr(196).chr(153) => 'e',
chr(196).chr(154) => 'E', chr(196).chr(155) => 'e',
chr(196).chr(156) => 'G', chr(196).chr(157) => 'g',
chr(196).chr(158) => 'G', chr(196).chr(159) => 'g',
chr(196).chr(160) => 'G', chr(196).chr(161) => 'g',
chr(196).chr(162) => 'G', chr(196).chr(163) => 'g',
chr(196).chr(164) => 'H', chr(196).chr(165) => 'h',
chr(196).chr(166) => 'H', chr(196).chr(167) => 'h',
chr(196).chr(168) => 'I', chr(196).chr(169) => 'i',
chr(196).chr(170) => 'I', chr(196).chr(171) => 'i',
chr(196).chr(172) => 'I', chr(196).chr(173) => 'i',
chr(196).chr(174) => 'I', chr(196).chr(175) => 'i',
chr(196).chr(176) => 'I', chr(196).chr(177) => 'i',
chr(196).chr(178) => 'IJ',chr(196).chr(179) => 'ij',
chr(196).chr(180) => 'J', chr(196).chr(181) => 'j',
chr(196).chr(182) => 'K', chr(196).chr(183) => 'k',
chr(196).chr(184) => 'k', chr(196).chr(185) => 'L',
chr(196).chr(186) => 'l', chr(196).chr(187) => 'L',
chr(196).chr(188) => 'l', chr(196).chr(189) => 'L',
chr(196).chr(190) => 'l', chr(196).chr(191) => 'L',
chr(197).chr(128) => 'l', chr(197).chr(129) => 'L',
chr(197).chr(130) => 'l', chr(197).chr(131) => 'N',
chr(197).chr(132) => 'n', chr(197).chr(133) => 'N',
chr(197).chr(134) => 'n', chr(197).chr(135) => 'N',
chr(197).chr(136) => 'n', chr(197).chr(137) => 'N',
chr(197).chr(138) => 'n', chr(197).chr(139) => 'N',
chr(197).chr(140) => 'O', chr(197).chr(141) => 'o',
chr(197).chr(142) => 'O', chr(197).chr(143) => 'o',
chr(197).chr(144) => 'O', chr(197).chr(145) => 'o',
chr(197).chr(146) => 'OE',chr(197).chr(147) => 'oe',
chr(197).chr(148) => 'R',chr(197).chr(149) => 'r',
chr(197).chr(150) => 'R',chr(197).chr(151) => 'r',
chr(197).chr(152) => 'R',chr(197).chr(153) => 'r',
chr(197).chr(154) => 'S',chr(197).chr(155) => 's',
chr(197).chr(156) => 'S',chr(197).chr(157) => 's',
chr(197).chr(158) => 'S',chr(197).chr(159) => 's',
chr(197).chr(160) => 'S', chr(197).chr(161) => 's',
chr(197).chr(162) => 'T', chr(197).chr(163) => 't',
chr(197).chr(164) => 'T', chr(197).chr(165) => 't',
chr(197).chr(166) => 'T', chr(197).chr(167) => 't',
chr(197).chr(168) => 'U', chr(197).chr(169) => 'u',
chr(197).chr(170) => 'U', chr(197).chr(171) => 'u',
chr(197).chr(172) => 'U', chr(197).chr(173) => 'u',
chr(197).chr(174) => 'U', chr(197).chr(175) => 'u',
chr(197).chr(176) => 'U', chr(197).chr(177) => 'u',
chr(197).chr(178) => 'U', chr(197).chr(179) => 'u',
chr(197).chr(180) => 'W', chr(197).chr(181) => 'w',
chr(197).chr(182) => 'Y', chr(197).chr(183) => 'y',
chr(197).chr(184) => 'Y', chr(197).chr(185) => 'Z',
chr(197).chr(186) => 'z', chr(197).chr(187) => 'Z',
chr(197).chr(188) => 'z', chr(197).chr(189) => 'Z',
chr(197).chr(190) => 'z', chr(197).chr(191) => 's'
);
 
$string = strtr($string, $chars);
 
return $string;
}
 
// remplace certains parametres définis en bd par les parametres définis dans l'url
private function traiterParametres($estProjetDefini, $tableau) {
$criteres = array('tag', 'motcle', 'projet', 'titre', 'logo');
$criteresProjetNonDefini = array('commune', 'num_nom', 'referentiel');
foreach($this->parametres as $nom_critere => $valeur_critere) {
if (($estProjetDefini == false || $tableau['projet'] == "base") && in_array($nom_critere, $criteresProjetNonDefini)) {
$tableau[$nom_critere] = $valeur_critere;
} else if (in_array($nom_critere, $criteres)) {
$tableau[$nom_critere] = $valeur_critere;
}
}
return $tableau;
}
 
 
private function rechercherInfosEspeces( $infos_projets ) { //print_r($infos_projets);exit;
$retour = array();
$referentiel = $infos_projets['referentiel'];
$urlWsNsTpl = $this->config['chemins']['baseURLServicesEfloreTpl'];
$urlWsNs = sprintf( $urlWsNsTpl, self::EFLORE_API_VERSION, $referentiel, self::WS_NOM );
$urlWsNsSansRef = sprintf( $urlWsNsTpl, self::EFLORE_API_VERSION, '{referentiel}', self::WS_NOM );
$retour['url_ws_autocompletion_ns'] = $urlWsNs;
$retour['url_ws_autocompletion_ns_tpl'] = $urlWsNsSansRef;
$retour['ns_referentiel'] = $referentiel;
 
if ( isset( $infos_projets['type_especes'] ) && 'fixe' === $infos_projets['type_especes']) {
 
switch ( $infos_projets['type_especes'] ) {
case "fixe" :
$retour['especes'] = $this->chargerInfosTaxon( $infos_projets['referentiel'], $infos_projets['especes'] );
break;
case "referentiel" :
case "liste" :
$referentiel = $infos_projets['referentiel'];
break;
}
} else if ( isset( $infos_projets['referentiel'] ) ) {
$referentiel = $infos_projets['referentiel'];
if ( isset($infos_projets['num_nom'] ) ) {
$retour['especes'] = $this->chargerInfosTaxon( $infos_projets['referentiel'], $infos_projets['num_nom'] );
}
}
 
$projetsAListeDeNoms = $this->transformerEnTableau( $this->config['projets']['liste_noms'] ) ;
if ( in_array( $this->projet, $projetsAListeDeNoms ) && !$this->especeEstImposee() ) {
$projetsAListeDeNomsSciEtVerna = $this->transformerEnTableau( $this->config['projets']['liste_noms_sci_et_verna'] );
if ( in_array( $this->projet, $projetsAListeDeNomsSciEtVerna ) ) {
$retour['taxons'] = $this->recupererListeNoms();
} else {
$retour['taxons'] = $this->recupererListeNomsSci();
}
}
return $retour;
}
 
/**
* Consulte un webservice pour obtenir des informations sur le taxon dont le
* numéro nomenclatural est $num_nom (ce sont donc plutôt des infos sur le nom
* et non le taxon?)
* @param string|int $num_nom
* @return array
*/
protected function chargerInfosTaxon( $referentiel, $num_nom ) {
$url_service_infos = sprintf( $this->config['chemins']['infosTaxonUrl'], $referentiel, $num_nom );
$infos = json_decode( file_get_contents( $url_service_infos ) );
// trop de champs injectés dans les infos espèces peuvent
// faire planter javascript
$champs_a_garder = array( 'id', 'nom_sci','nom_sci_complet', 'nom_complet',
'famille','nom_retenu.id', 'nom_retenu_complet', 'num_taxonomique' );
$resultat = array();
$retour = array();
if ( isset( $infos ) && !empty( $infos ) ) {
$infos = (array) $infos;
if ( isset( $infos['nom_sci'] ) && $infos['nom_sci'] != '' ) {
$resultat = array_intersect_key( $infos, array_flip($champs_a_garder ) );
$resultat['retenu'] = ( $infos['id'] == $infos['nom_retenu.id'] ) ? "true" : "false";
$retour['espece_imposee'] = true;
$retour['nn_espece_defaut'] = $nnEspeceImposee;
$retour['nom_sci_espece_defaut'] = $resultat['nom_complet'];
$retour['infos_espece'] = $this->array2js( $resultat, true );
}
}
return $retour;
}
 
protected function getReferentielImpose() {
$referentiel_impose = true;
if (!empty($_GET['referentiel']) && $_GET['referentiel'] != "autre") {
$this->ns_referentiel = $_GET['referentiel'];
} else if (isset($this->configProjet['referentiel'])) {
$this->ns_referentiel = $this->configProjet['referentiel'];
} else if (isset($this->configMission['referentiel'])) {
$this->ns_referentiel = $this->configMission['referentiel'];
} else {
$referentiel_impose = false;
}
return $referentiel_impose;
}
 
/**
* Trie par nom français les taxons lus dans le fichier tsv
*/
protected function recupererListeNomsSci() {
$taxons = $this->recupererListeTaxon();
if (is_array($taxons)) {
$taxons = self::trierTableauMd($taxons, array('nom_fr' => SORT_ASC));
}
return $taxons;
}
 
/**
* @TODO documenter
* @return array
*/
protected function recupererListeNoms() {
$taxons = $this->recupererListeTaxon();
$nomsAAfficher = array();
$nomsSpeciaux = array();
if (is_array($taxons)) {
foreach ($taxons as $taxon) {
$nomSciTitle = $taxon['nom_ret'].
($taxon['nom_fr'] != '' ? ' - '.$taxon['nom_fr'] : '' ).
($taxon['nom_fr_autre'] != '' ? ' - '.$taxon['nom_fr_autre'] : '' );
$nomFrTitle = $taxon['nom_sel'].
($taxon['nom_ret'] != $taxon['nom_sel']? ' - '.$taxon['nom_ret'] : '' ).
($taxon['nom_fr_autre'] != '' ? ' - '.$taxon['nom_fr_autre'] : '' );
 
if ($taxon['groupe'] == 'special') {
$nomsSpeciaux[] = array(
'num_nom' => $taxon['num_nom_sel'],
'nom_a_afficher' => $taxon['nom_fr'],
'nom_a_sauver' => $taxon['nom_sel'],
'nom_title' => $nomSciTitle,
'nom_type' => 'nom-special');
} else {
$nomsAAfficher[] = array(
'num_nom' => $taxon['num_nom_sel'],
'nom_a_afficher' => $taxon['nom_sel'],
'nom_a_sauver' => $taxon['nom_sel'],
'nom_title' => $nomSciTitle,
'nom_type' => 'nom-sci');
$nomsAAfficher[] = array(
'num_nom' => $taxon['num_nom_sel'],
'nom_a_afficher' => $taxon['nom_fr'],
'nom_a_sauver' => $taxon['nom_fr'],
'nom_title' => $nomFrTitle,
'nom_type' => 'nom-fr');
}
}
$nomsAAfficher = self::trierTableauMd($nomsAAfficher, array('nom_a_afficher' => SORT_ASC));
$nomsSpeciaux = self::trierTableauMd($nomsSpeciaux, array('nom_a_afficher' => SORT_ASC));
}
return array('speciaux' => $nomsSpeciaux, 'sci-et-fr' => $nomsAAfficher);
}
 
/**
* Lit une liste de taxons depuis un fichier tsv fourni
*/
protected function recupererListeTaxon() {
$taxons = array();
if ($this->projet == 'missions-flore') {
$fichier_tsv = dirname(__FILE__).self::DS.'configurations'.self::DS.$this->projet.'_'.$this->mission.'_taxons.tsv';
} else {
$fichier_tsv = dirname(__FILE__).self::DS.'configurations'.self::DS.$this->projet.'_taxons.tsv';
}
if (file_exists($fichier_tsv) && is_readable($fichier_tsv)) {
$taxons = $this->decomposerFichierTsv($fichier_tsv);
} else {
$this->debug[] = "Impossible d'ouvrir le fichier '$fichier_tsv'.";
}
return $taxons;
}
 
/**
* Découpe un fihcier tsv
*/
protected function decomposerFichierTsv($fichier, $delimiter = "\t"){
$header = null;
$data = array();
if (($handle = fopen($fichier, 'r')) !== FALSE) {
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE) {
if (!$header) {
$header = $row;
} else {
$data[] = array_combine($header, $row);
}
}
fclose($handle);
}
return $data;
}
 
/**
* Convertit un tableau PHP en Javascript - @WTF pourquoi ne pas faire un json_encode ?
* @param array $array
* @param boolean $show_keys
* @return une portion de JSON représentant le tableau
*/
protected function array2js($array,$show_keys) {
$tableauJs = '{}';
if (!empty($array)) {
$total = count($array) - 1;
$i = 0;
$dimensions = array();
foreach ($array as $key => $value) {
if (is_array($value)) {
$dimensions[$i] = array2js($value,$show_keys);
if ($show_keys) {
$dimensions[$i] = '"'.$key.'":'.$dimensions[$i];
}
} else {
$dimensions[$i] = '"'.addslashes($value).'"';
if ($show_keys) {
$dimensions[$i] = '"'.$key.'":'.$dimensions[$i];
}
}
if ($i == 0) {
$dimensions[$i] = '{'.$dimensions[$i];
}
if ($i == $total) {
$dimensions[$i].= '}';
}
$i++;
}
$tableauJs = implode(',', $dimensions);
}
return $tableauJs;
}
 
 
}
?>
?>
/trunk/widget/modules/saisie2/squelettes/js/champs-supp.js
New file
0,0 → 1,269
"use strict";
 
/*************************************
* Fonctions de Style et Affichage *
* des éléments "spéciaux" *
*************************************/
 
// Logique d'affichage pour le input type=file
function inputFile( countFiles ) {
// Initialisation des variables
var $fileInput = $( '.input-file' ),
$button = $( '.label-file' );
// Action lorsque la "barre d'espace" ou "Entrée" est pressée
$( '.label-file' ).keydown( function( event ) {
if ( event.keyCode == 13 || event.keyCode == 32 ) {
$( '#' + $( this ).attr( 'for' ) + '.input-file' ).click();
}
});
// // Affiche un retour visuel dès que input:file change
// $('#form-supp').on( 'change', '.input-file', function( event ) {
// // Il est possible de supprimer un fichier
// // donc on vérifie que le 'change' est un ajout ou modification
// if( !$.isEmptyObject( event.target.files[0] ) ) {
// var file = event.target.files[0],
// fileId = $( this ).attr( 'id' ),
// $thisFile = $( this ).parent('.label-file.' + fileId ),
// $imageContainer = $( '#miniatures' ),
// $theReturn = $( '.' + fileId + 'Img') || false,
// fileImgHtml = '';
 
 
// if( file.type.match( 'image' ) ) {
// fileImgHtml =
// '<div class="' + fileId + 'Img mb-1">'+
// '<p> ' + file.name + '</p>'+
// '<img src="' + URL.createObjectURL( file ) + '">'+
// '</div>';
// }
// // Permettre d'enregistrer une nouvelle image
// if( 0 < $theReturn.length ) {
// // Changement du fichier
// $theReturn.html( fileImgHtml );
// } else {
// $imageContainer.append( fileImgHtml );
// $imageContainer.append( $thisFile );
 
// $( '#photos-conteneur' ).html(
// '<label for="fichier' + countFiles + '" class="label-file btn btn-default fichier' + countFiles + '">'+
// '<i class="fas fa-download"></i> Ajouter une image'+
// '<input type="file" id="fichier' + countFiles + '" name="fichier' + countFiles + '" class="input-file" accept="image/jpeg">'+
// '<input type="hidden" name="MAX_FILE_SIZE" value="5242880">'+
// '</label>'+
// '<hr>'
// );
// countFiles++;
// }
// // Changer le text
// $thisFile.find( '.label-text').html( '<i class="fas fa-exchange-alt"></i> Changer cette image');
// $thisFile.css( 'background-color', '#ea9973' );
// $thisFile.hover( function() {
// $( this ).css( 'background-color', 'rgba(234, 153, 115, 0.7)' );
// });
// $( '.' + fileId + 'Img img').attr( 'width', $thisFile.outerWidth() );
 
// }
// });
// // Annuler le téléchargement
// $( '.remove-file' ).click( function() {
// var $thisFileInput = $( this ).prev( '.input-file-container' ).find( '.input-file' );
// $thisFileInput.wrap( '<form>' ).closest( 'form' ).get(0).reset();
// $thisFileInput.triggerHandler( 'change' );
// $thisFileInput.unwrap();
// $( this ).next( '.file-return' ).addClass( 'hidden' ).empty();
// });
}
 
// Style et affichage des list-checkboxes
function inputListCheckbox() {
// On écoute le click sur une list-checkbox ('.selectBox')
// à tout moment de son insertion dans le dom
// Todo :
// _ 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' ).each( function() {
$( this ).removeClass( 'focus' );
});
}
});
 
$( '#zone-appli' ).on( 'click' , '.selectBox' , function() {
// $( '.checkboxes[data-id="' + $(this).attr( 'data-id' ) + '"]' ).toggleClass( 'hidden' );
$( this ).next().toggleClass( 'hidden' );
$( this ).find( 'select' ).toggleClass( 'focus' );
 
});
}
 
// Style et affichage des input type="range"
function inputRangeDisplayNumber() {
$( '#zone-supp' ).on( 'input' , '.range input[type="range"]' , function () {
$( this ).next( 'input[type="number"]' ).val ( $( this ).val() );
});
$( '#zone-supp' ).on( 'input' , '.range input[type="number"]' , function () {
$( this ).prev( 'input[type="range"]' ).val ( $( this ).val() );
});
}
 
// Activation/Desactivation et contenu de la modale Bootstrap
// https://getbootstrap.com/docs/3.3/javascript/#modals
function previewFieldHelpModal() {
$( '#zone-supp' ).on( 'click' , '.help-button' , function ( event ) {
var index = $( this ).closest( '.preview-fields' ).attr( 'data-id' ),
thisFieldset = $( '.new-field[data-id="' + index + '"]' ),
file = $( '.field-help' , thisFieldset )[0].files[0],
tmppath = URL.createObjectURL( file );
// Titre
$( '#help-modal-label' ).text( 'Aide pour : ' + $( '.field-name' , thisFieldset ).val() );
// Contenu
if( file.type.match( 'image' ) ) {
$( '#print_content' ).append( '<img src="' + tmppath + '" style="max-width:100%">' );
} else if( file.type.match( 'pdf' ) ) {
$( '#print_content' ).append( '<iframe src="' + tmppath + '" width="100%" height="650" align="middle" scrolling="no" frameborder="0"></iframe>' );
}
// Sortie avec la touche escape
$( '#help-modal' ).modal( { keyboard : true } );
// Affichage
$( '#help-modal' ).modal( 'show' );
// 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
$( '#help-modal' ).on( 'shown.bs.modal' , function () {
$( '#myInput' ).trigger( 'focus' );
})
// Réinitialisation
$( '#help-modal' ).on( 'hidden.bs.modal' , function () {
$( '#help-modal-label' ).text();
$( '#print_content' ).empty();
})
});
}
 
// Faire apparaitre un champ text "Autre"
function onOtherOption() {
 
const PREFIX = 'collect-other-';
 
// Ajouter un champ texte pour "Autre"
function optionAdd( otherId, $target, element ) {
$target.after(
'<label for="' + otherId + '" class="' + otherId + '">Autre option :</label>' +
'<input type="text" id="' + otherId + '" name="' + otherId + '" class="collect-other" data-element="' + element + '">'
);
}
 
// Supprimer un champ texte pour "Autre"
function optionRemove( otherId, $this ) {
$( '.' + otherId + ', #' + otherId ).remove();
}
 
$( '#form-supp .other' ).each( function() {
if( $( this ).hasClass( 'is-select' ) ) {
var otherId = PREFIX + $( this ).parent( 'select' ).attr( 'name' );
// Insertion du champ "Autre" après les boutons
optionAdd( otherId, $( this ).parent( '.select' ) , 'select' );
} else if ( $( this ).is( ':checked' ) ) {
var otherId = PREFIX + $( this ).attr( 'name' ),
element = $( this ).attr( 'data-element' );
// Insertion du champ "Autre" après les boutons
optionAdd( otherId, $( this ).parent( 'label' ) , element );
}
});
 
$( '#form-supp select' ).change( function () {
var otherId = PREFIX + $( this ).attr( 'name' );
 
if( 'other' === $( this ).val() ) {
// Insertion du champ "Autre" après les boutons
optionAdd( otherId, $( this ).parent( '.select' ), 'select' );
} else {
// Suppression du champ autre
optionRemove( otherId, $( this ) );
$( this ).find( '.other' ).val( 'other' );
}
});
 
$( '#form-supp input[type=radio]' ).change( function () {
var otherId = PREFIX + $( this ).attr( 'name' );
 
if( 'other' === $( this ).val() ) {
// Insertion du champ "Autre" après les boutons
optionAdd( otherId, $( this ).parent( 'label' ), 'radio' );
} else {
// Suppression du champ autre
optionRemove( otherId, $( this ) );
$( this ).closest( 'div.control-group.radio' ).find( '.other' ).val( 'other' );
}
});
 
$( '#form-supp .list-checkbox .other, #form-supp .checkbox .other' ).click( function () {
var otherId = PREFIX + $( this ).attr( 'name' ),
element = $( this ).attr( 'data-element' );
// console.log(element);
if( $( this ).is( ':checked' ) ) {
// Insertion du champ "Autre" après les boutons
optionAdd( otherId, $( this ).parent( 'label' ), element );
} else {
// Suppression du champ autre
optionRemove( otherId, $( this ) );
$( this ).val( 'other' );
}
});
}
 
function collectOtherOption() {
$( '#form-supp' ).on( 'change', '.collect-other', function () {
var otherIdSuffix = $( this ).attr( 'name' ).replace( 'collect-other-', '' ),
element = $( this ).attr( 'data-element' );
if ( '' === $( this ).val() ){
if ( 'select' === element ) {
$( '#' + otherIdSuffix ).find( '.other' ).prop( 'selected', false );
} else {
$( '#other-' + otherIdSuffix ).prop( 'checked', false );
}
} else {
if ( 'select' === element ) {
$( '#' + otherIdSuffix ).find( '.other' ).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 );
}
// console.log( otherIdSuffix );
$( '#other-' + otherIdSuffix ).val( $( this ).val() );
$( '#other-' + otherIdSuffix ).prop( 'checked', true );
}
 
}
});
}
 
/***************************
* Lancement des scripts *
***************************/
jQuery( document ).ready( function() {
// var countFiles = 2;
// // Affichage des images ou nom des documents importés
// inputFile( countFiles );
// // Affichage des List-checkbox
inputListCheckbox();
// // Affichage des Range
// inputRangeDisplayNumber()
// // Modale "aide"
// previewFieldHelpModal();
// // Ajout/suppression d'un champ texte "Autre"
// if( $( '.option-other-value' , thisFieldset ).is( ':checked' ) ) {
onOtherOption();
collectOtherOption();
// }
});
/trunk/widget/modules/saisie2/squelettes/js/WidgetSaisie.js
2,37 → 2,37
* Constructeur WidgetSaisie par défaut
*/
function WidgetSaisie() {
this.langue = 'fr';
this.obsNbre = 0;
this.nbObsEnCours = 1;
this.totalObsATransmettre = 0;
this.nbObsTransmises = 0;
this.debug = null;
this.html5 = null;
this.tagProjet = null;
this.tagImg = null;
this.tagObs = null;
this.separationTagImg = null;
this.separationTagObs = null;
this.obsId = null;
this.serviceSaisieUrl = null;
this.serviceObsUrl = null;
this.nomSciReferentiel = null;
this.especeImposee = false;
this.infosEspeceImposee = null;
this.autocompletionElementsNbre = null;
this.referentielImpose = null;
this.serviceAutocompletionNomSciUrl = null;
this.serviceAutocompletionNomSciUrlTpl = null;
this.obsMaxNbre = null;
this.dureeMessage = null;
this.serviceAnnuaireIdUrl = null;
this.serviceNomCommuneUrl = null;
this.serviceNomCommuneUrlAlt = null;
this.chargementIconeUrl = null;
this.chargementImageIconeUrl = null;
this.calendrierIconeUrl = null;
this.pasDePhotoIconeUrl = null;
this.langue = 'fr';
this.obsNbre = 0;
this.nbObsEnCours = 1;
this.totalObsATransmettre = 0;
this.nbObsTransmises = 0;
this.debug = null;
this.html5 = null;
this.tagProjet = null;
this.tagImg = null;
this.tagObs = null;
this.separationTagImg = null;
this.separationTagObs = null;
this.obsId = null;
this.serviceSaisieUrl = null;
this.serviceObsUrl = null;
this.nomSciReferentiel = null;
this.especeImposee = false;
this.infosEspeceImposee = null;
this.autocompletionElementsNbre = null;
this.referentielImpose = null;
this.serviceAutocompletionNomSciUrl = null;
this.serviceAutocompletionNomSciUrlTpl = null;
this.obsMaxNbre = null;
this.dureeMessage = null;
this.serviceAnnuaireIdUrl = null;
this.serviceNomCommuneUrl = null;
this.serviceNomCommuneUrlAlt = null;
this.chargementIconeUrl = null;
this.chargementImageIconeUrl = null;
this.calendrierIconeUrl = null;
this.pasDePhotoIconeUrl = null;
}
 
/**
39,9 → 39,11
* Initialisation du widget
*/
WidgetSaisie.prototype.init = function() {
this.initForm();
this.initEvts();
this.requeterIdentite();
this.initForm();
this.initEvts();
if ( '' === $( '#nom-complet').val() && '' !== $( '#courriel' ).val() ) {
this.requeterIdentite();
}
};
 
/**
48,39 → 50,39
* Initialise le formulaire, les validateurs, les listes de complétion...
*/
WidgetSaisie.prototype.initForm = function() {
if (this.obsId != '') {
//this.chargerInfoObs();
}
if ( '' !== this.obsId ) {
this.chargerInfoObs();
}
 
this.configurerDatePicker('#date');
this.ajouterAutocompletionNoms();
//this.configurerFormValidator();
//this.definirReglesFormValidator();
this.configurerDatePicker( '.date' );
this.ajouterAutocompletionNoms();
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)
var nomRetenuComplet = this.infosEspeceImposee["nom_retenu_complet"],
debutAnneRefBiblio = nomRetenuComplet.indexOf(" [");
if (debutAnneRefBiblio != -1) {
nomRetenuComplet = nomRetenuComplet.substr(0, debutAnneRefBiblio);
}
// fin bricolage cracra
var infosAssociee = {
label : this.infosEspeceImposee.nom_sci_complet,
value : this.infosEspeceImposee.nom_sci_complet,
nt : this.infosEspeceImposee.num_taxonomique,
nomSel : this.infosEspeceImposee.nom_sci,
nomSelComplet : this.infosEspeceImposee.nom_sci_complet,
numNomSel : this.infosEspeceImposee.id,
nomRet : nomRetenuComplet,
numNomRet : this.infosEspeceImposee["nom_retenu.id"],
famille : this.infosEspeceImposee.famille,
retenu : (this.infosEspeceImposee.retenu == 'false') ? false : true
};
$("#taxon").data(infosAssociee);
}
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)
var nomRetenuComplet = this.infosEspeceImposee['nom_retenu_complet'],
debutAnneRefBiblio = nomRetenuComplet.indexOf( ' [' );
if ( -1 !== debutAnneRefBiblio ) {
nomRetenuComplet = nomRetenuComplet.substr( 0, debutAnneRefBiblio );
}
// fin bricolage cracra
var infosAssociee = {
label : this.infosEspeceImposee.nom_sci_complet,
value : this.infosEspeceImposee.nom_sci_complet,
nt : this.infosEspeceImposee.num_taxonomique,
nomSel : this.infosEspeceImposee.nom_sci,
nomSelComplet : this.infosEspeceImposee.nom_sci_complet,
numNomSel : this.infosEspeceImposee.id,
nomRet : nomRetenuComplet,
numNomRet : this.infosEspeceImposee['nom_retenu.id'],
famille : this.infosEspeceImposee.famille,
retenu : ( 'false' === this.infosEspeceImposee.retenu ) ? false : true
};
$( '#taxon' ).data( infosAssociee );
}
};
 
/**
87,111 → 89,128
* Initialise les écouteurs d'événements
*/
WidgetSaisie.prototype.initEvts = function() {
var lthis = this;
$('body').on('click', '.effacer-miniature', function() {
$(this).parent().remove();
});
$("#fichier").bind('change', function (e) {
arreter(e);
var options = {
success: lthis.afficherMiniature.bind(lthis), // post-submit callback
dataType: 'xml', // 'xml', 'script', or 'json' (expected server response type)
resetForm: true // reset the form after successful submit
};
$("#miniature").append('<img id="miniature-chargement" class="miniature" alt="chargement" src="'+this.chargementImageIconeUrl+'"/>');
$("#ajouter-obs").attr('disabled', 'disabled');
if(lthis.verifierFormat($("#fichier").val())) {
$("#form-upload").ajaxSubmit(options);
} else {
$('#form-upload')[0].reset();
window.alert("Le format de fichier n'est pas supporté, les formats acceptés sont "+ $("#fichier").attr("accept"));
}
return false;
});
// identité
$("#courriel").on('blur', this.requeterIdentite.bind(this));
$("#courriel").on('keypress', this.testerLancementRequeteIdentite.bind(this));
$(".alert .close").on('click', this.fermerPanneauAlert);
$(".has-tooltip").tooltip('enable');
$("#btn-aide").on('click', this.basculerAffichageAide);
$("#prenom").on("change", this.formaterPrenom.bind(this));
$("#nom").on("change", this.formaterNom.bind(this));
var lthis = this;
 
$("#courriel_confirmation").on('paste', this.bloquerCopierCollerCourriel.bind(this));
/*$("#ajouter-obs").on('click', this.ajouterObs.bind(this));
$(".obs-nbre").on('changement', this.surChangementNbreObs.bind(this));
$("body").on('click', ".supprimer-obs", function() {
var that = this,
suppObs = lthis.supprimerObs.bind(lthis);
// bricolage pour avoir les deux contextes en même temps (objet et elt. du DOM)
suppObs(that);
});
$("#transmettre-obs").on('click', this.transmettreObs.bind(this));
$("#referentiel").on('change', this.surChangementReferentiel.bind(this));
// console.log($( '#taxon' ).data('label') );
 
$("body").on('click', ".defilement-miniatures-gauche", function(event) {
event.preventDefault();
lthis.defilerMiniatures($(this));
});
$("body").on('click', ".defilement-miniatures-droite", function(event) {
event.preventDefault();
lthis.defilerMiniatures($(this));
});
*/
// fermeture fenêtre
if (this.debug == false) {
$(window).on('beforeunload', function(event) {
return 'Êtes vous sûr de vouloir quiter la page?\nLes observations saisies mais non transmises seront perdues.';
});
}
$( 'body' ).on( 'click', '.effacer-miniature', function() {
$( this ).parent().remove();
});
 
$( '#bouton-anonyme' ).on( 'click', function() {
$( this ).css({
'background-color': 'rgba(0, 159, 184, 0.7)',
'color': '#fff'
});
$( '#anonyme' ).removeClass( 'hidden' );
$( '#courriel' ).focus();
});
 
$( '#fichier' ).bind( 'change', function ( e ) {
arreter( e );
var options = {
success: lthis.afficherMiniature.bind( lthis ), // post-submit callback
dataType: 'xml', // 'xml', 'script', or 'json' (expected server response type)
resetForm: true // reset the form after successful submit
};
$( '#miniature' ).append( '<img id="miniature-chargement" class="miniature" alt="chargement" src="' + this.chargementImageIconeUrl + '">' );
$( '#ajouter-obs' ).attr( 'disabled', 'disabled' );
if( lthis.verifierFormat( $( '#fichier' ).val() ) ) {
$( '#form-upload' ).ajaxSubmit( options );
} else {
$( '#form-upload' )[0].reset();
window.alert( 'Le format de fichier n\'est pas supporté, les formats acceptés sont ' + $( '#fichier' ).attr( 'accept' ) );
}
return false;
});
 
// identité
if ( '' === $( '#nom-complet').val() ) {
$( '#courriel' ).on( 'blur', this.requeterIdentite.bind( this ) );
$( '#courriel' ).on( 'keypress', this.testerLancementRequeteIdentite.bind( this ) );
}
$( '.alert .close' ).on( 'click', this.fermerPanneauAlert );
$( '.has-tooltip' ).tooltip( 'enable' );
$( '#btn-aide' ).on( 'click', this.basculerAffichageAide);
$( '#prenom' ).on( 'change', this.formaterPrenom );
$( '#nom' ).on( 'change', this.formaterNom );
 
$( '#courriel_confirmation' ).on( 'paste', this.bloquerCopierCollerCourriel.bind( this ) );
$( '#ajouter-obs' ).on( 'click', this.ajouterObs.bind( this ) );
$( '.obs-nbre' ).on( 'changement', this.surChangementNbreObs.bind( this ) );
$( 'body' ).on( 'click', '.supprimer-obs', function() {
var that = this,
suppObs = lthis.supprimerObs.bind( lthis );
// bricolage pour avoir les deux contextes en même temps (objet et elt. du DOM)
suppObs( that );
});
 
$( '#transmettre-obs' ).on( 'click', this.transmettreObs.bind( this ) );
$( '#referentiel' ).on( 'change', this.surChangementReferentiel.bind( this ) );
 
$( 'body' ).on( 'click', '.defilement-miniatures-gauche', function( event ) {
event.preventDefault();
lthis.defilerMiniatures( $( this ) );
});
$( 'body' ).on( 'click', '.defilement-miniatures-droite', function( event ) {
event.preventDefault();
lthis.defilerMiniatures( $( this ) );
});
 
// fermeture fenêtre
if ( !this.debug ) {
$( window ).on( 'beforeunload', function( event ) {
return 'Êtes vous sûr de vouloir quiter la page?\nLes observations saisies mais non transmises seront perdues.';
});
}
 
};
 
/**
* Retourne true si l'extension de l'image "nom" est .jpg ou .jpeg
* Retourne true si l'extension de l'image 'nom' est .jpg ou .jpeg
*/
WidgetSaisie.prototype.verifierFormat = function(nom) {
var parts = nom.split('.');
extension = parts[parts.length - 1];
return (extension.toLowerCase() == 'jpeg' || extension.toLowerCase() == 'jpg');
WidgetSaisie.prototype.verifierFormat = function( nom ) {
var parts = nom.split( '.' );
extension = parts[ parts.length - 1 ];
return ( 'jpeg' === extension.toLowerCase() || 'jpg' === extension.toLowerCase() );
};
 
/**
* Affiche la miniature d'une image temporaire (formulaire) qu'on a ajoutée à l'obs
*/
WidgetSaisie.prototype.afficherMiniature = function(reponse) {
if (this.debug) {
var debogage = $("debogage", reponse).text();
//console.log("Débogage upload : "+debogage);
}
var message = $("message", reponse).text();
if (message != '') {
$("#miniature-msg").append(message);
} else {
$("#miniatures").append(this.creerWidgetMiniature(reponse));
}
$('#ajouter-obs').removeAttr('disabled');
WidgetSaisie.prototype.afficherMiniature = function( reponse ) {
if ( this.debug ) {
var debogage = $( 'debogage', reponse ).text();
//console.log( 'Débogage upload : '+debogage);
}
var message = $( 'message', reponse ).text();
if ( '' !== message ) {
$( '#miniature-msg' ).append( message );
} else {
$( '#miniatures' ).append( this.creerWidgetMiniature( reponse ) );
}
$( '#ajouter-obs' ).removeAttr( 'disabled' );
};
 
/**
* Crée la miniature d'une image temporaire (formulaire), avec le bouton pour l'effacer
*/
WidgetSaisie.prototype.creerWidgetMiniature = function(reponse) {
var miniatureUrl = $("miniature-url", reponse).text();
var imgNom = $("image-nom", reponse).text();
var html =
'<div class="miniature">'+
'<img class="miniature-img" class="miniature" alt="'+imgNom+'" src="'+miniatureUrl+'"/>'+
'<button class="effacer-miniature" type="button">Effacer</button>'+
'</div>'
return html;
WidgetSaisie.prototype.creerWidgetMiniature = function( reponse ) {
var miniatureUrl = $( 'miniature-url', reponse ).text();
var imgNom = $( 'image-nom', reponse ).text();
var html =
'<div class="miniature mb-3 mr-3">'+
'<img class="miniature-img" class="miniature img-rounded" alt="' + imgNom + '" src="' + miniatureUrl + '">'+
'<a class="effacer-miniature"><i class="far fa-trash-alt"></i></a>'+
'</div>'
return html;
};
 
/**
* Efface une miniature (formulaire)
*/
WidgetSaisie.prototype.supprimerMiniature = function(miniature) {
miniature.parents('.miniature').remove();
WidgetSaisie.prototype.supprimerMiniature = function( miniature ) {
miniature.parents( '.miniature' ).remove();
};
 
/**
198,197 → 217,960
* Efface toutes les miniatures (formulaire)
*/
WidgetSaisie.prototype.supprimerMiniatures = function() {
$("#miniatures").empty();
$("#miniature-msg").empty();
$( '#miniatures' ).empty();
$( '#miniature-msg' ).empty();
};
 
/* Observateur */
WidgetSaisie.prototype.testerLancementRequeteIdentite = function(event) {
if (event.which == 13) {
this.requeterIdentite();
this.event.preventDefault();
this.event.stopPropagation();
}
WidgetSaisie.prototype.testerLancementRequeteIdentite = function( event ) {
if ( 13 == event.which ) {
this.requeterIdentite();
event.preventDefault();
event.stopPropagation();
}
};
 
WidgetSaisie.prototype.requeterIdentite = function() {
var lthis = this;
var courriel = $("#courriel").val();
var urlAnnuaire = this.serviceAnnuaireIdUrl + courriel;
if (courriel != '') {
$.ajax({
url : urlAnnuaire,
type : "GET",
success : function(data, textStatus, jqXHR) {
if (lthis.debug) {
console.log('SUCCESS: '+textStatus);
}
if (data != undefined && data[courriel] != undefined) {
var 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);
}
// @TODO harmoniser class="hidden" VS style="display:none;"
$("#zone-prenom-nom").removeClass("hidden").show();
$("#zone-courriel-confirmation").removeClass("hidden").show();
}
});
}
var lthis = this;
var courriel = $( '#courriel' ).val();
var urlAnnuaire = this.serviceAnnuaireIdUrl + courriel;
// console.log(urlAnnuaire);
if ( '' !== courriel ) {
$.ajax({
url : urlAnnuaire,
type : 'GET',
success : function( data, textStatus, jqXHR ) {
if ( lthis.debug ) {
console.log( 'SUCCESS: ' + textStatus );
}
if ( undefined != data && undefined != data[courriel] ) {
var 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 );
}
}
});
}
};
 
WidgetSaisie.prototype.surSuccesCompletionCourriel = function(infos, courriel) {
$("#id_utilisateur").val(infos.id);
$("#prenom").val(infos.prenom);
$("#nom").val(infos.nom);
$("#courriel_confirmation").val(courriel);
$("#prenom, #nom, #courriel_confirmation").attr('disabled', 'disabled');
this.focusChampFormulaire();
this.masquerPanneau("#dialogue-courriel-introuvable");
WidgetSaisie.prototype.surSuccesCompletionCourriel = function( infos, courriel ) {
$( '#zone-courriel' ).before( '<p class="warning"><i class="fas fa-exclamation-triangle"></i> Un compte existe pour ce courriel, connectez-vous pour saisir votre observation</p>' );
$( '#creation-compte, #zone-prenom-nom, #zone-courriel-confirmation' ).addClass( 'hidden' );
$( '#bouton-connexion a' ).css( 'box-shadow', '0 0 1.5px 1px red' );
// // Traité par auth.js :
// $( '#id_utilisateur' ).val(infos.id);
// // console.log(infos);
// $( '#prenom' ).val(infos.prenom);
// $( '#nom' ).val(infos.nom);
// $( '#courriel_confirmation' ).val(courriel);
// $( '#prenom, #nom, #courriel_confirmation' ).attr( 'disabled', 'disabled' );
// this.focusChampFormulaire();
// // todo function masquerPanneau
// this.masquerPanneau( '#dialogue-courriel-introuvable' );
};
 
WidgetSaisie.prototype.surErreurCompletionCourriel = function() {
$("#prenom, #nom, #courriel_confirmation").val('');
$("#prenom, #nom, #courriel_confirmation").removeAttr('disabled');
this.afficherPanneau("#dialogue-courriel-introuvable");
$( '#creation-compte, #zone-prenom-nom, #zone-courriel-confirmation' ).removeClass( 'hidden' );
$( '.warning' ).remove();
$( '#bouton-connexion a' ).css( 'box-shadow', '' );
 
$( '#prenom, #nom, #courriel_confirmation' ).val( '' );
$( '#prenom, #nom, #courriel_confirmation' ).removeAttr( 'disabled' );
// // Traité par auth.js :
// // todo function afficherPanneau
// this.afficherPanneau( '#dialogue-courriel-introuvable' );
};
 
WidgetSaisie.prototype.fermerPanneauAlert = function() {
$( this ).parentsUntil( '.zone-alerte', '.alert' ).addClass( 'hidden' );
};
 
WidgetSaisie.prototype.formaterNom = function() {
$(this).val($(this).val().toUpperCase());
$( this ).val( $( this ).val().toUpperCase() );
};
 
WidgetSaisie.prototype.formaterPrenom = function() {
var prenom = new Array();
var mots = $(this).val().split(' ');
for (var i = 0; i < mots.length; i++) {
var mot = mots[i];
if (mot.indexOf('-') >= 0) {
var prenomCompose = new Array();
var motsComposes = mot.split('-');
for (var j = 0; j < motsComposes.length; j++) {
var motSimple = motsComposes[j];
var motMajuscule = motSimple.charAt(0).toUpperCase() + motSimple.slice(1);
prenomCompose.push(motMajuscule);
}
prenom.push(prenomCompose.join('-'));
} else {
var motMajuscule = mot.charAt(0).toUpperCase() + mot.slice(1);
prenom.push(motMajuscule);
}
}
$(this).val(prenom.join(' '));
var prenom = new Array(),
mots = $( this ).val().split( ' ' ),
motsLength = mots.length;
 
 
for ( var i = 0; i < motsLength; i++ ) {
var mot = mots[i];
 
if ( 0 <= mot.indexOf( '-' ) ) {
var prenomCompose = new Array(),
motsComposes = mot.split( '-' )
motsComposesLength = motsComposes.length;
 
for ( var j = 0; j < motsComposesLength; j++ ) {
var motSimple = motsComposes[j],
motMajuscule = motSimple.charAt(0).toUpperCase() + motSimple.slice(1);
 
prenomCompose.push( motMajuscule );
}
prenom.push( prenomCompose.join( '-' ) );
} else {
var motMajuscule = mot.charAt(0).toUpperCase() + mot.slice(1);
 
prenom.push( motMajuscule );
}
}
$( this ).val( prenom.join( ' ' ) );
};
 
WidgetSaisie.prototype.bloquerCopierCollerCourriel = function() {
this.afficherPanneau("#dialogue-bloquer-copier-coller");
return false;
this.afficherPanneau( '#dialogue-bloquer-copier-coller' );
return false;
};
 
WidgetSaisie.prototype.focusChampFormulaire = function() {
$("#date").focus();
/**
* Ajoute une observation saisie dans le formulaire à la liste des observations à transmettre
*/
WidgetSaisie.prototype.ajouterObs = function() {
// Fermeture automatique des dialogue de transmission de données
// @WARNING TEST
$( '#dialogue-obs-transaction-ko' ).addClass( 'hidden' );
$( '#dialogue-obs-transaction-ok' ).addClass( 'hidden' );
 
if ( this.validerFormulaire() ) {
this.masquerPanneau( '#dialogue-form-invalide' );
this.obsNbre = this.obsNbre + 1;
$( '.obs-nbre' ).text( this.obsNbre );
$( '.obs-nbre' ).triggerHandler( 'changement' );
this.afficherObs();
this.stockerObsData();
this.supprimerMiniatures();
if( !this.especeImposee ) {
$( '#taxon' ).val( '' );
$( '#taxon' ).data( 'numNomSel', undefined );
}
$( '#barre-progression-upload' ).attr( 'aria-valuemax', this.obsNbre );
$( '#barre-progression-upload .sr-only' ).text( '0/' + this.obsNbre + ' observations transmises' );
} else {
this.afficherPanneau( '#dialogue-form-invalide' );
}
};
 
/**
* Affiche une observation dans la liste des observations à transmettre
*/
WidgetSaisie.prototype.afficherObs = function() {
 
// var commune = $( '#commune-nom' ).text();
// commune = ( '' !== commune.trim() ) ? commune : $( '#carte-recherche' ).val();
 
// var code_insee = $('#commune-code-insee').text();
// code_insee = ( '' !== code_insee.trim() ) ? '(' + code_insee + ')' : '';
 
// if ( this.debug ) {
// console.log( commune + ' - ' + code_insee );
// }
 
$( '#liste-obs' ).prepend(
'<div id="obs' + this.obsNbre + '" class="obs obs' + this.obsNbre + ' mb-2">'+
 
'<div '+
'class="obs-action droite" '+
'title="Supprimer cette observation de la liste à transmettre"'+
'>'+
'<button class="btn btn-danger supprimer-obs" value="'+ this.obsNbre + '" title="Observation n°' + this.obsNbre + '">'+
'<i class="far fa-trash-alt"></i>'+
'</button>'+
'</div> '+
 
'<div class="row">'+
'<div class="thumbnail col-md-2">'+
this.ajouterImgMiniatureAuTransfert()+
'</div>'+
'<div class="col-md-9">'+
'<ul class="unstyled">'+
'<li>'+
'<span class="nom-sci">' + $( '#taxon' ).val() + '</span> '+
this.ajouterNumNomSel() + '<span class="referentiel-obs">'+
( ( undefined == $('#taxon').data( 'numNomSel' ) ) ? '' : '[' + this.nomSciReferentiel + ']' ) + '</span>'+
// ' observé à '+
// '<span class="commune">' + commune + '</span> '+
// code_insee + ' [' + $( '#latitude' ).val() + ' / ' + $( '#longitude' ).val() + ']'+
// ' le '+
// '<span class="date">' + $( '#date' ).val() + '</span>'+
'</li>'+
'<li>'+
// '<span>Lieu-dit :</span> ' + $( '#lieudit' ).val() + ' '+
// '<span>Station :</span> ' + $( '#station' ).val() + ' '+
'<span>Milieu :</span> '+ $ ( '#milieu' ).val() + ' '+
'</li>'+
// '<li>'+
// 'Commentaires : <span class="discretion">' + $( '#notes' ).val() + '</span>'+
// '</li>'+
'</ul>'+
'</div>'+
'</div>'+
 
'</div>'
);
 
$( '#zone-liste-obs' ).removeClass( 'hidden' );
};
 
WidgetSaisie.prototype.stockerObsData = function() {
var lthis = this;
 
// var commune = $( '#commune-nom' ).text();
// commune = ( '' === commune.trim() ) ? commune : $( '#carte-recherche' ).val();
 
$( '#liste-obs' ).data( 'obsId' + this.obsNbre, {
'date' : $( '#date' ).val(),
// 'notes' : $( '#notes' ).val().trim(),
'nom_sel' : $( '#taxon' ).val(),
'num_nom_sel' : $( '#taxon' ).data( 'numNomSel' ),
'nom_ret' : $( '#taxon' ).data( 'nomRet' ),
'num_nom_ret' : $( '#taxon' ).data( 'numNomRet' ),
'num_taxon' : $( '#taxon' ).data( 'nt' ),
'famille' : $( '#taxon' ).data( 'famille' ),
'referentiel' : ( ( undefined === $( '#taxon' ).data( 'numNomSel' ) ) ? '' : lthis.nomSciReferentiel ),
// 'latitude' : $( '#latitude' ).val(),
// 'longitude' : $( '#longitude' ).val(),
// 'commune_nom' : commune,
// 'commune_code_insee' : $( '#commune-code-insee' ).text(),
// 'lieudit' : $( '#lieudit' ).val(),
// 'station' : $( '#station' ).val(),
'milieu' : $( '#milieu' ).val(),
 
//Ajout des champs images
'image_nom' : lthis.getNomsImgsOriginales(),
'image_b64' : lthis.getB64ImgsOriginales(),
 
// Ajout des champs étendus de l'obs
'obs_etendue': lthis.getObsChpEtendus()
});
};
 
/**
* Retourne un Array contenant les valeurs des champs étendus
*/
WidgetSaisie.prototype.getObsChpEtendus = function() {
var 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';
 
$( elements, $thisForm ).each( function() {
var valeur = $( this ).val(),
cle = $( this ).attr( 'name' ),
label = $( this ).data( 'label' );
if ( '' !== valeur ) {
var chpEtendu = {
cle: cle,
label: label,
valeur: valeur
};
champs.push( chpEtendu );
}
});
return champs;
};
 
WidgetSaisie.prototype.surChangementReferentiel = function() {
this.nomSciReferentiel = $( '#referentiel' ).val();
$( '#taxon' ).val( '' );
this.initialiserAutocompleteCommune();
this.initialiserGoogleMap( false );
};
 
WidgetSaisie.prototype.surChangementNbreObs = function() {
if ( 0 === this.obsNbre ) {
$( '#transmettre-obs' ).attr( 'disabled', 'disabled' );
$( '#ajouter-obs' ).removeAttr( 'disabled' );
} else if ( 0 < this.obsNbre && this.obsNbre < this.obsMaxNbre ) {
$( '#transmettre-obs' ).removeAttr( 'disabled' );
$( '#ajouter-obs' ).removeAttr( 'disabled' );
} else if ( this.obsNbre >= this.obsMaxNbre ) {
$( '#ajouter-obs' ).attr( 'disabled', 'disabled' );
this.afficherPanneau( '#dialogue-bloquer-creer-obs' );
}
};
 
WidgetSaisie.prototype.transmettreObs = function() {
var observations = $( '#liste-obs' ).data();
if ( this.debug ) {
console.log( observations );
}
if ( undefined == observations || jQuery.isEmptyObject( observations ) ) {
this.afficherPanneau( '#dialogue-zero-obs' );
} else {
this.nbObsEnCours = 1;
this.nbObsTransmises = 0;
this.totalObsATransmettre = $.map( observations, function( n, i ) {
return i;
}).length;
this.depilerObsPourEnvoi();
}
return false;
};
 
WidgetSaisie.prototype.depilerObsPourEnvoi = function() {
var observations = $( '#liste-obs' ).data();
// la boucle est factice car on utilise un tableau
// dont on a besoin de n'extraire que le premier élément
// or javascript n'a pas de méthode cross browsers pour extraire les clés
// TODO: utiliser var.keys quand ça sera plus répandu
// ou bien utiliser un vrai tableau et pas un objet
for ( var obsNum in observations ) {
var obsATransmettre = {
'projet' : this.tagProjet,
'tag-obs' : this.tagObs,
'tag-img' : this.tagImg
};
var utilisateur = {
id_utilisateur : $( '#id_utilisateur' ).val(),
prenom : $( '#prenom' ).val(),
nom : $( '#nom' ).val(),
courriel : $( '#courriel' ).val()
};
obsATransmettre['utilisateur'] = utilisateur;
obsATransmettre[obsNum] = observations[obsNum];
var idObsNumerique = obsNum.replace( 'obsId', '' );
if( '' !== idObsNumerique ) {
this.envoyerObsAuCel( idObsNumerique, obsATransmettre );
}
break;
}
};
 
WidgetSaisie.prototype.envoyerObsAuCel = function( idObs, observation ) {
var lthis = this;
var erreurMsg = '';
$.ajax({
url : lthis.serviceSaisieUrl,
type : 'POST',
data : observation,
dataType : 'json',
beforeSend : function() {
$( '#dialogue-obs-transaction-ko' ).addClass( 'hidden' );
$( '#dialogue-obs-transaction-ok' ).addClass( 'hidden' );
$( '.alert-txt' ).empty();
$( '.alert-txt .msg-erreur' ).remove();
$( '.alert-txt .msg-debug' ).remove();
$( '#chargement' ).removeClass( 'hidden' );
},
success : function( data, textStatus, jqXHR ) {
// mise à jour du nombre d'obs à transmettre
// et suppression de l'obs
lthis.supprimerObsParId( idObs );
lthis.nbObsEnCours++;
// mise à jour du statut
lthis.mettreAJourProgression();
if( 0 < lthis.obsNbre ) {
// dépilement de la suivante
lthis.depilerObsPourEnvoi();
}
},
statusCode : {
500 : function( jqXHR, textStatus, errorThrown ) {
erreurMsg += 'Erreur 500 :\ntype : ' + textStatus + ' ' + errorThrown + '\n';
}
},
error : function( jqXHR, textStatus, errorThrown ) {
erreurMsg += 'Erreur Ajax :\ntype : ' + textStatus + ' ' + errorThrown + '\n';
try {
reponse = jQuery.parseJSON( jqXHR.responseText );
if ( null !== reponse ) {
$.each( reponse, function( cle, valeur ) {
erreurMsg += valeur + '\n';
});
}
} catch( e ) {
erreurMsg += 'Erreur inconnue: ' + jqXHR.responseText;
}
},
complete : function( jqXHR, textStatus ) {
var debugMsg = extraireEnteteDebug( jqXHR );
 
if ( '' !== erreurMsg ) {
if ( this.debug ) {
$( '#dialogue-obs-transaction-ko .alert-txt' ).append( '<pre class="msg-erreur">' + erreurMsg + '</pre>' );
$( '#dialogue-obs-transaction-ko .alert-txt' ).append( '<pre class="msg-debug">Débogage : ' + debugMsg + '</pre>' );
}
var hrefCourriel = 'mailto:cel_remarques@tela-botanica.org?'+
'subject=Dysfonctionnement du widget de saisie ' + this.tagProjet+
'&body=' + erreurMsg + '%0D%0ADébogage :%0D%0A' + debugMsg;
 
// mise en valeur de l'obs en erreur + scroll vers celle ci en changeant le hash
$( '#obs' + idObs + ' div div' ).addClass( 'obs-erreur' );
window.location.hash = 'obs' + idObs;
 
$( '#dialogue-obs-transaction-ko .alert-txt' ).append( $( '#tpl-transmission-ko' ).clone()
.find( '.courriel-erreur' )
.attr( 'href', hrefCourriel )
.end()
.html()
);
$( '#dialogue-obs-transaction-ko' ).removeClass( 'hidden' );
$( '#chargement' ).addClass( 'hidden' );
lthis.initialiserBarreProgression();
} else {
if ( lthis.debug ) {
$( '#dialogue-obs-transaction-ok .alert-txt' ).append( '<pre class="msg-debug">Débogage : ' + debugMsg + '</pre>' );
}
if( 0 === lthis.obsNbre ) {
setTimeout( function() {
$( '#chargement' ).addClass( 'hidden' );
$( '#dialogue-obs-transaction-ok .alert-txt' ).append( $( '#tpl-transmission-ok' ).clone().html());
$( '#dialogue-obs-transaction-ok' ).removeClass( 'hidden' );
window.location.hash = 'dialogue-obs-transaction-ok';
lthis.initialiserObs();
}, 1500 );
 
}
}
}
});
};
 
WidgetSaisie.prototype.mettreAJourProgression = function() {
this.nbObsTransmises++;
var pct = ( this.nbObsTransmises / this.totalObsATransmettre ) * 100;
$( '#barre-progression-upload' ).attr( 'aria-valuenow', this.nbObsTransmises );
$( '#barre-progression-upload' ).attr( 'style', 'width: ' + pct + '%' );
$( '#barre-progression-upload .sr-only' ).text( this.nbObsTransmises + '/' + this.totalObsATransmettre + ' observations transmises' );
 
if( 0 === this.obsNbre ) {
$( '.progress' ).removeClass( 'active' );
$( '.progress' ).removeClass( 'progress-striped' );
}
};
 
WidgetSaisie.prototype.validerFormulaire = function() {
observateur = $( '#form-observateur' ).valid();
// station = $( '#form-station' ).valid();
obs = ( '' !== $( '#nom-complet' ).text() || ( $( '#form-observation' ).valid() && !$( '#anonyme' ).hasClass( 'hidden' ) ) ) ? true : false;
( obs ) ? this.masquerPanneau( '#dialogue-utilisateur-non-identifie' ) : this.afficherPanneau( '#dialogue-utilisateur-non-identifie' );
 
return ( observateur /*&& station */&& obs ) ? true : false;
};
 
WidgetSaisie.prototype.getNomsImgsOriginales = function() {
var noms = new Array();
$( '.miniature-img' ).each( function() {
noms.push( $( this ).attr( 'alt' ) );
});
return noms;
};
 
WidgetSaisie.prototype.getB64ImgsOriginales = function() {
var b64 = new Array();
$( '.miniature-img' ).each( function() {
if ( $( this ).hasClass( 'b64' ) ) {
b64.push( $( this ).attr( 'src' ) );
} else if ( $( this ).hasClass( 'b64-canvas' ) ) {
b64.push( $( this ).data( 'b64' ) );
}
});
return b64;
};
 
WidgetSaisie.prototype.supprimerObs = function( selector ) {
var obsId = $( selector ).val();
// Problème avec IE 6 et 7
if ( 'Supprimer' === obsId ) {
obsId = $( selector ).attr( 'title' );
}
this.supprimerObsParId( obsId );
};
 
WidgetSaisie.prototype.supprimerObsParId = function( obsId ) {
this.obsNbre = this.obsNbre - 1;
$( '.obs-nbre' ).text( this.obsNbre );
$( '.obs-nbre' ).triggerHandler( 'changement' );
$( '.obs' + obsId ).remove();
$( '#liste-obs' ).removeData( 'obsId' + obsId );
};
 
WidgetSaisie.prototype.initialiserBarreProgression = function() {
$( '#barre-progression-upload' ).attr( 'aria-valuenow', 0 );
$( '#barre-progression-upload' ).attr( 'style', 'width: 0%' );
$( '#barre-progression-upload .sr-only' ).text( '0/0 observations transmises' );
$( '.progress' ).addClass( 'active' );
$( '.progress' ).addClass( 'progress-striped' );
};
 
WidgetSaisie.prototype.initialiserObs = function() {
this.obsNbre = 0;
this.nbObsTransmises = 0;
this.nbObsEnCours = 0;
this.totalObsATransmettre = 0;
this.initialiserBarreProgression();
$( '.obs-nbre' ).text( this.obsNbre );
$( '.obs-nbre' ).triggerHandler( 'changement' );
$( '#liste-obs' ).removeData();
$( '.obs' ).remove();
$( '#dialogue-bloquer-creer-obs' ).addClass( 'hidden' );
};
 
/**
* Ajoute une boîte de miniatures avec défilement des images,
* pour une obs de la liste des obs à transmettre
*/
WidgetSaisie.prototype.ajouterImgMiniatureAuTransfert = function() {
var html =
'<div class="defilement-miniatures">'+
'<figure class="centre">'+
'<img class="miniature align-middle" alt="Aucune photo" src="' + this.pasDePhotoIconeUrl + '" width="80%" />'+
'</figure>'+
'</div>',
miniatures = '',
premiere = true,
centre = '';
defilVisible = '';
 
if ( 0 < $( '#miniatures img' ).length ) {
$( '#miniatures img' ).each( function() {
var imgVisible = ( premiere ) ? 'miniature-selectionnee' : 'miniature-cachee';
premiere = false;
 
var css = ( $( this ).hasClass( 'b64' ) ) ? 'miniature b64' : 'miniature',
src = $( this ).attr( 'src' ),
alt = $( this ).attr( 'alt' ),
miniature = '<img class="' + css + ' ' + imgVisible + ' align-middle" alt="' + alt + '"src="' + src + '" width="80%" />';
// miniature = '<div class="' + css + ' ' + imgVisible + '" alt="' + alt + '" style="background-image: url(' + src + ')" ></div>';
 
miniatures += miniature;
});
 
 
if ( 1 === $( '#miniatures img' ).length ) {
centre = 'centre';
defilVisible = ' defilement-miniatures-cache';
}
 
html =
'<div class="defilement-miniatures">'+
'<a href="#" class="defilement-miniatures-gauche mr-1' + defilVisible + '"><i class="fas fa-chevron-circle-left"></i></a>'+
'<figure class="' + centre + '">'+
miniatures+
'</figure>'+
'<a href="#" class="defilement-miniatures-droite ml-1' + defilVisible + '"><i class="fas fa-chevron-circle-right"></i></a>'+
'</div>';
}
return html;
};
 
WidgetSaisie.prototype.defilerMiniatures = function( element ) {
 
 
var miniatureSelectionne = element.siblings( 'figure' ).find( 'img.miniature-selectionnee' );
miniatureSelectionne.removeClass( 'miniature-selectionnee' );
miniatureSelectionne.addClass( 'miniature-cachee' );
 
var miniatureAffichee = miniatureSelectionne;
 
if( element.hasClass( 'defilement-miniatures-gauche' ) ) {
if( 0 !== miniatureSelectionne.prev( '.miniature' ).length ) {
miniatureAffichee = miniatureSelectionne.prev( '.miniature' );
} else {
miniatureAffichee = miniatureSelectionne.siblings( '.miniature' ).last();
}
} else {
if( 0 !== miniatureSelectionne.next('.miniature').length ) {
miniatureAffichee = miniatureSelectionne.next( '.miniature' );
} else {
miniatureAffichee = miniatureSelectionne.siblings( '.miniature' ).first();
}
}
miniatureAffichee.addClass( 'miniature-selectionnee' );
miniatureAffichee.removeClass( 'miniature-cachee' );
};
 
WidgetSaisie.prototype.ajouterNumNomSel = function() {
var nn = '<span class="nn">[nn' + $( '#taxon' ).data( 'numNomSel' ) + ']</span>';
if ( undefined == $( '#taxon' ).data( 'numNomSel' ) ) {
nn = '<span class="alert-error">[non lié au référentiel]</span>';
}
return nn;
};
 
WidgetSaisie.prototype.ajouterAutocompletionNoms = function() {
var lthis = this;
$( '#taxon' ).autocomplete({
source: function( requete, add ) {
// la variable de requête doit être vidée car sinon le parametre "term" est ajouté
requete = '';
if( 'autre' !== $( '#referentiel' ).val() ) {
var url = lthis.getUrlAutocompletionNomsSci();
$.getJSON( url, requete, function( data ) {
var suggestions = lthis.traiterRetourNomsSci( data );
add( suggestions );
});
}
},
html: true
});
 
$( '#taxon' ).bind( 'autocompleteselect', this.surAutocompletionTaxon );
};
 
// WidgetSaisie.prototype.focusChampFormulaire = function() {
// $( '#date_releve' ).focus();
// };
 
WidgetSaisie.prototype.chargerInfoObs = function() {
var urlObs = this.serviceObsUrl + '/' + this.obsId;
var lthis = this;
$.ajax({
url: urlObs,
type: 'GET',
success: function( data, textStatus, jqXHR ) {
if ( undefined != data && '' !== data ) {
lthis.prechargerForm( data );
} else {
lthis.surErreurChargementInfosObs();
}
},
error: function( jqXHR, textStatus, errorThrown ) {
lthis.surErreurChargementInfosObs();
}
});
};
 
// @TODO faire mieux que ça !
WidgetSaisie.prototype.surErreurChargementInfosObs = function() {
alert( 'Erreur lors du chargement de l\'observation' );
};
 
WidgetSaisie.prototype.prechargerForm = function( data ) {
 
$( '#milieu' ).val( data.milieu );
 
// $( '#carte-recherche' ).val( data.zoneGeo );
// $( '#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-code-insee' ).text( data.codeZoneGeo.replace( 'INSEE-C:', '' ) );
// }
 
// if( data.hasOwnProperty( 'latitude' ) && data.hasOwnProperty( 'longitude' ) ) {
// var latLng = new google.maps.LatLng( data.latitude, data.longitude );
// this.mettreAJourMarkerPosition( latLng );
// this.marker.setPosition( latLng );
// this.map.setCenter( latLng );
// this.map.setZoom( 16 );
// }
};
 
WidgetSaisie.prototype.configurerFormValidator = function() {
var lthis = this;
$.validator.addMethod(
'dateCel',
function ( value, element ) {
return ( '' === value || ( /(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)/.test( value ) ) );
},
'Format : jj/mm/aaaa. Date incomplète, utiliser 0, exemple : 00/12/2011.'
);
 
$.validator.addMethod(
'userEmailOk',
function ( value, element ) {
return ( '' !== value );
},
''
);
 
$.extend( $.validator.defaults, {
errorElement: 'span',
 
onfocusout: function( element ){
if ( $( element ).valid() ) {
$( element ).closest( '.control-group' ).removeClass( 'error' );
} else {
$( element ).closest( '.control-group' ).addClass( 'error' );
}
},
onkeyup : function( element ){
if ( $( element ).valid() ) {
$( element ).closest( '.control-group' ).removeClass( 'error' );
} else {
$( element ).closest( '.control-group' ).addClass( 'error' );
}
},
onclick : function( element ){
if ( $( element ).valid() ) {
$( element ).closest( '.control-group' ).removeClass( 'error' );
} else {
$( element ).closest( '.control-group' ).addClass( 'error' );
}
},
 
highlight: function( element ) {
$( element ).closest( '.control-group' ).addClass( 'error' );
},
 
unhighlight: function( element ) {
if ( 'taxon' === $( element ).attr( 'id' ) ) {
if ( '' !== $( '#taxon' ).val() ) {
// Si le taxon n'est pas lié au référentiel, on vide le data associé
if ( $( '#taxon' ).data( 'value' ) != $( '#taxon' ).val() ) {
$( '#taxon' ).data( 'numNomSel', '' );
$( '#taxon' ).data( 'nomRet','' );
$( '#taxon' ).data( 'numNomRet', '' );
$( '#taxon' ).data( 'nt', '' );
$( '#taxon' ).data( 'famille', '' );
}
$( '#taxon-input-groupe' ).removeClass( 'error' );
$( element ).next( 'span.help-inline' ).remove();
}
} else {
$( element ).closest( '.control-group' ).removeClass( 'error' );
$( element ).next( 'span.help-inline' ).remove();
}
}
 
});
};
 
WidgetSaisie.prototype.definirReglesFormValidator = function() {
 
$( '#form-observateur' ).validate({
rules : {
courriel : {
required : true,
email : true,
'userEmailOk' : true
},
courriel_confirmation : {
required : true,
equalTo : '#courriel'
}
}
});
// $( '#form-station' ).validate({
// rules: {
// latitude : {
// range: [-90, 90]
// },
// longitude : {
// range: [-180, 180]
// }
// }
// });
$( '#form-observation' ).validate({
rules : {
date_releve : {
required : true,
'dateCel' : true
},
taxon : 'required'
}
});
};
 
/* calendrier */
WidgetSaisie.prototype.configurerDatePicker = function(selector) {
$.datepicker.setDefaults($.datepicker.regional[this.langue]);
$(selector).datepicker({
dateFormat: "dd/mm/yy",
maxDate: new Date,
onSelect: function(date) {
$(this).valid();
}
});
$(selector + ' + img.ui-datepicker-trigger').appendTo(selector + '-icone.add-on');
WidgetSaisie.prototype.configurerDatePicker = function( selector ) {
$.datepicker.setDefaults( $.datepicker.regional[ this.langue ] );
$( selector ).datepicker({
dateFormat: 'dd/mm/yy',
maxDate: new Date,
onSelect: function( date ) {
$( this ).valid();
}
});
$( selector + ' + img.ui-datepicker-trigger' ).appendTo( selector + '-icone.add-on' );
};
 
/* auto completion nom sci */
WidgetSaisie.prototype.ajouterAutocompletionNoms = function() {
var lthis = this;
$('#taxon').autocomplete({
source: function(requete, add){
// la variable de requête doit être vidée car sinon le parametre "term" est ajouté
requete = "";
if($("#referentiel").val() != "autre") {
var url = lthis.getUrlAutocompletionNomsSci();console.log(url);
$.getJSON(url, requete, function(data) {
var suggestions = lthis.traiterRetourNomsSci(data);
add(suggestions);
});
}
},
html: true,
position : {
my : 'top',
at : 'top'
}
});
var lthis = this;
$( '#taxon' ).autocomplete({
source: function( requete, add ) {
// la variable de requête doit être vidée car sinon le parametre 'term' est ajouté
requete = '';
if( 'autre' !== $( '#referentiel' ).val() ) {
var url = lthis.getUrlAutocompletionNomsSci();
// console.log( url );
$.getJSON( url, requete, function( data ) {
var suggestions = lthis.traiterRetourNomsSci( data );
add( suggestions );
});
}
},
html: true,
position : {
my : 'top',
at : 'top'
}
});
 
$("#taxon").bind("autocompleteselect", this.surAutocompletionTaxon);
$( '#taxon' ).bind( 'autocompleteselect', this.surAutocompletionTaxon );
};
 
WidgetSaisie.prototype.surAutocompletionTaxon = function(event, ui) {
$("#taxon").data(ui.item);
if (ui.item.retenu == true) {
$("#taxon").addClass('ns-retenu');
} else {
$("#taxon").removeClass('ns-retenu');
}
WidgetSaisie.prototype.surAutocompletionTaxon = function( event, ui ) {
$( '#taxon' ).data( ui.item );
if ( ui.item.retenu ) {
$( '#taxon' ).addClass( 'ns-retenu' );
} else {
$( '#taxon' ).removeClass( 'ns-retenu' );
}
};
 
WidgetSaisie.prototype.getUrlAutocompletionNomsSci = function() {
var mots = $('#taxon').val();
var url = this.serviceAutocompletionNomSciUrlTpl.replace('{referentiel}', this.nomSciReferentiel);
url = url.replace('{masque}', mots);
return url;
var mots = $( '#taxon' ).val();
var url = this.serviceAutocompletionNomSciUrlTpl.replace( '{referentiel}', this.nomSciReferentiel );
url = url.replace( '{masque}', mots );
return url;
};
 
WidgetSaisie.prototype.traiterRetourNomsSci = function(data) {
var suggestions = [];
if (data.resultat != undefined) {
$.each(data.resultat, function(i, val) {
val.nn = i;
var nom = {label : '', value : '', nt : '', nomSel : '', nomSelComplet : '', numNomSel : '',
nomRet : '', numNomRet : '', famille : '', retenu : false
};
if (suggestions.length >= this.autocompletionElementsNbre) {
nom.label = "...";
nom.value = $('#taxon').val();
suggestions.push(nom);
return false;
} else {
nom.label = val.nom_sci_complet;
nom.value = val.nom_sci_complet;
nom.nt = val.num_taxonomique;
nom.nomSel = val.nom_sci;
nom.nomSelComplet = val.nom_sci_complet;
nom.numNomSel = val.nn;
nom.nomRet = val.nom_retenu_complet;
nom.numNomRet = val["nom_retenu.id"];
nom.famille = val.famille;
// Tester dans ce sens, permet de considérer "absent" comme "false" => est-ce opportun ?
// en tout cas c'est harmonisé avec le CeL
nom.retenu = (val.retenu == 'true') ? true : false;
WidgetSaisie.prototype.traiterRetourNomsSci = function( data ) {
var suggestions = [];
if ( undefined != data.resultat ) {
$.each( data.resultat, function( i, val ) {
val.nn = i;
var nom = {
label : '',
value : '',
nt : '',
nomSel : '',
nomSelComplet : '',
numNomSel : '',
nomRet : '',
numNomRet : '',
famille : '',
retenu : false
};
if ( suggestions.length >= this.autocompletionElementsNbre ) {
nom.label = '...';
nom.value = $( '#taxon' ).val();
suggestions.push( nom );
return false;
} else {
nom.label = val.nom_sci_complet;
nom.value = val.nom_sci_complet;
nom.nt = val.num_taxonomique;
nom.nomSel = val.nom_sci;
nom.nomSelComplet = val.nom_sci_complet;
nom.numNomSel = val.nn;
nom.nomRet = val.nom_retenu_complet;
nom.numNomRet = val['nom_retenu.id'];
nom.famille = val.famille;
// Tester dans ce sens, permet de considérer 'absent' comme 'false' => est-ce opportun ?
// en tout cas c'est harmonisé avec le CeL
nom.retenu = ( 'true' == val.retenu ) ? true : false;
 
suggestions.push(nom);
}
});
}
suggestions.push( nom );
}
});
}
 
return suggestions;
return suggestions;
};
 
WidgetSaisie.prototype.afficherPanneau = function(selecteur) {
$(selecteur).fadeIn("slow").delay(this.dureeMessage).fadeOut("slow");
WidgetSaisie.prototype.afficherPanneau = function( selecteur ) {
$( selecteur )
.removeClass( 'hidden')
.hide()
.show( 600 )
.delay( this.dureeMessage )
.hide( 600 );
};
 
WidgetSaisie.prototype.masquerPanneau = function( selecteur ) {
$( selecteur ).addClass( 'hidden' );
};
 
// lib hors objet --
 
/**
* Stope l'évènement courant quand on clique sur un lien.
* Utile pour Chrome, Safari...
*/
function arreter( evenement ) {
if ( evenement.stopPropagation ) {
evenement.stopPropagation();
}
if ( evenement.preventDefault ) {
evenement.preventDefault();
}
return false;
}
 
/**
* Extrait les données de désinsectisation d'une requête AJAX de jQuery
* @param jqXHR
* @returns {String}
*/
function extraireEnteteDebug( jqXHR ) {
var msgDebug = '';
if ( '' !== jqXHR.getResponseHeader( 'X-DebugJrest-Data' ) ) {
var debugInfos = jQuery.parseJSON( jqXHR.getResponseHeader( 'X-DebugJrest-Data' ) );
if ( null !== debugInfos ) {
$.each( debugInfos, function( cle, valeur ) {
msgDebug += valeur + '\n';
});
}
}
return msgDebug;
}
 
/*
* jQuery UI Autocomplete HTML Extension
*
* Copyright 2010, Scott González (http://scottgonzalez.com)
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* http://github.com/scottgonzalez/jquery-ui-extensions
*
* Adaptation par Aurélien Peronnet pour la mise en gras des noms de taxons valides
*/
( function( $ ) {
var proto = $.ui.autocomplete.prototype,
initSource = proto._initSource;
 
WidgetSaisie.prototype.filter = function( array, term ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), 'i' );
return $.grep( array, function( value ) {
return matcher.test( $( '<div>' ).html( value.label || value.value || value ).text() );
});
}
 
$.extend( proto, {
_initSource: function() {
if ( this.options.html && $.isArray( this.options.source ) ) {
this.source = function( request, response ) {
response( filter( this.options.source, request.term ) );
};
} else {
initSource.call( this );
}
},
_renderItem: function( ul, item) {
if ( item.retenu ) {
item.label = '<strong>' + item.label + '</strong>';
}
 
return $( '<li></li>' )
.data( 'item.autocomplete', item )
.append( $( '<a></a>' )[ ( this.options.html ) ? 'html' : 'text' ]( item.label ) )
.appendTo( ul );
}
});
})( jQuery );
/trunk/widget/modules/saisie2/squelettes/js/auth.js
1,19 → 1,35
// configuration
var urlRacine = 'https://www.tela-botanica.org',
config = {
prod: {
urlWidgetNavigation : urlRacine + '/widget:cel:saisie2',
urlBaseAuth : 'https://www.tela-botanica.org/service:annuaire:auth'
},
test: {
urlWidgetNavigation : urlRacine + '/widget-test:cel:saisie2',
urlBaseAuth : 'https://www.tela-botanica.org/service:annuaire-test:auth'
},
local: {
urlWidgetNavigation : 'https://localhost/widget:cel:saisie2',
urlBaseAuth : 'https://localhost/service:annuaire:auth'
}
}
config = {
prod: {
urlWidgetNavigation : urlRacine + '/widget:cel:saisie2',
urlBaseAuth : 'https://www.tela-botanica.org/service:annuaire:auth'
},
test: {
urlWidgetNavigation : urlRacine + '/widget-test:cel:saisie2',
urlBaseAuth : 'https://www.tela-botanica.org/service:annuaire-test:auth'
},
local: {
urlWidgetNavigation : 'https://localhost/widget:cel:saisie2',
urlBaseAuth : 'https://localhost/service:annuaire:auth'
}
}
// // Prod: décommenter ci-dessus et commenter ou supprimer ci-dessous
// var urlRacine = 'http://localhost',
// config = {
// prod: {
// urlWidgetNavigation : urlRacine + '/widget:cel:saisie2',
// urlBaseAuth : 'https://www.tela-botanica.org/service:annuaire:auth'
// },
// test: {
// urlWidgetNavigation : urlRacine + '/widget:cel:saisie2',
// urlBaseAuth : 'https://api.tela-botanica.test/service:annuaire:auth'
// },
// local: {
// urlWidgetNavigation : 'https://localhost/widget:cel:saisie2',
// urlBaseAuth : 'https://localhost/service:annuaire:auth'
// }
// }
 
/**
* Charge la barre de navigation depuis le widget:reseau:navigation dans un <div id="tb-navigation"> , s'il existe
31,37 → 47,39
* "?squelette=contenu-de-data-squelette"; se reporter à la documentation du widget:reseau:navigation
*/
 
$(document).ready(function() {
var div = $('#tb-navigation');
if (div) {
var squelette = div.data('squelette'),
courant = div.data('courant'),
mode = div.data('mode') || 'prod',
contenu = div.html();
$( document ).ready( function() {
var $div = $( '#tb-navigation' );
if ( $div ) {
var squelette = $div.data( 'squelette' ),
courant = $div.data( 'courant' ),
mode = $div.data( 'mode' ) || 'prod',
contenu = $div.html();
 
// chargement de la barre
var urlBarreNavigation = config[mode]['urlWidgetNavigation'];
if (squelette) {
urlBarreNavigation += '?squelette=' + squelette;
}
htmlBarre = $.ajax({
url: urlBarreNavigation,
type: 'get',
success: function(data) {
// remplacement de la zone contenu-source
var zoneSource = div.find('#contenu-source');
if (zoneSource) {
zoneSource.replaceWith(contenu);
// Chargement de sinformations de connexion SSO
var urlBaseAuth = config[mode]['urlBaseAuth'];
chargerStatutSSO(urlBaseAuth);
}
},
error: function() {
div.html('Erreur: impossible de charger la barre de navigation');
}
});
// chargement de la barre
var urlBarreNavigation = config[mode]['urlWidgetNavigation'];
 
if ( squelette ) {
urlBarreNavigation += '?squelette=' + squelette;
}
 
htmlBarre = $.ajax({
url: urlBarreNavigation,
type: 'get',
success: function( data ) {
// remplacement de la zone contenu-source
var $zoneSource = $div.find( '#contenu-source' );
if ( $zoneSource ) {
$zoneSource.replaceWith( contenu );
// Chargement des informations de connexion SSO
var urlBaseAuth = config[mode]['urlBaseAuth'];
chargerStatutSSO( urlBaseAuth );
}
},
error: function() {
$div.html( 'Erreur: impossible de charger la barre de navigation' );
}
});
}
});
 
/**
70,9 → 88,9
* widget de barre de navigation et pas de la page appelante)
*/
function definirPageOrigineDansLiens() {
var page = window.location.href;
$('#bouton-connexion a').attr('href', $('#bouton-connexion a').attr('href') + page);
$('#deconnexion a').attr('href', $('#deconnexion a').attr('href') + page);
var page = window.location.href;
$( '#bouton-connexion a' ).attr( 'href', $( '#bouton-connexion a' ).attr( 'href' ) + page );
$( '#deconnexion a' ).attr( 'href', $( '#deconnexion a' ).attr( 'href' ) + page );
}
 
/**
79,32 → 97,48
* Interroge le SSO pour connaître le statut de l'utilisateur, et change le menu
* à droite de la barre en fonction
*/
function chargerStatutSSO(urlBaseAuth) {
var urlAuth = urlBaseAuth + '/identite';
$.ajax({
url: urlAuth,
type: "GET",
dataType: 'json',
xhrFields: {
withCredentials: true
}
}).done(function(data) {
// connecté
definirUtilisateur(data.token);
});
function chargerStatutSSO( urlBaseAuth ) {
var urlAuth = urlBaseAuth + '/identite';
// definirUtilisateur( 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwczpcL1wvd3d3LnRlbGEtYm90YW5pY2Eub3JnIiwidG9rZW5faWQiOiJ0Yl9hdXRoIiwic3ViIjoiaWRpckB0ZWxhLWJvdGFuaWNhLm9yZyIsImlhdCI6MTU0Mjk3MjIxNiwiZXhwIjoxNTQyOTg0NDQ1LCJzY29wZXMiOlsidGVsYS1ib3RhbmljYS5vcmciXSwiaWQiOiI0NDA4NCIsInByZW5vbSI6IklkaXIiLCJub20iOiJBbGxpY2hlIiwicHNldWRvIjoiSWRpciBBbGxpY2hlIiwicHNldWRvVXRpbGlzZSI6dHJ1ZSwiaW50aXR1bGUiOiJJZGlyIEFsbGljaGUiLCJhdmF0YXIiOiJcL1wvd3d3LmdyYXZhdGFyLmNvbVwvYXZhdGFyXC83ODU3ZmY2MWE5Yjk5NWE4NjIyMzdkMmEyYzYxODAyMT9zPTUwJnI9ZyZkPW1tIiwiZ3JvdXBlcyI6W10sInBlcm1pc3Npb25zIjpbImVkaXRvciJdLCJub21XaWtpIjoiSWRpckFsbGljaGUiLCJkYXRlRGVybmllcmVNb2RpZiI6MTQ5NTIwNjM3Nn0.D3rySwuCDsSl6JAmjncwgwg4gUJijZjeaYeDYHsw3uI' );
// Prod: décommenter $.ajax ci-dessous et supprimer la ligne ci-dessus
$.ajax({
url: urlAuth,
type: "GET",
dataType: 'json',
xhrFields: {
withCredentials: true
}
}).done( function( data ) {
// connecté
definirUtilisateur( data.token );
});
}
 
function definirUtilisateur(jeton) {
var nomComplet = '';
if (jeton != undefined) {
// décodage jeton
var jetonDecode = decoderJeton(jeton);
nomComplet = jetonDecode.intitule;
}
// affichage
$('#bouton-connexion').hide();
$('#utilisateur-connecte').show();
$('#nom-complet').html(nomComplet);
function definirUtilisateur( jeton ) {
var nomComplet = '',
idUtilisateur = '',
courriel = '',
nom = '',
prenom = '';
if ( undefined !== jeton ) {
// décodage jeton
var jetonDecode = decoderJeton( jeton );
nomComplet = jetonDecode.intitule;
idUtilisateur = jetonDecode.id;
courriel = jetonDecode.sub;
nom = jetonDecode.nom;
prenom = jetonDecode.prenom;
// console.log(jetonDecode);
}
// affichage
$( '#bouton-connexion, #creation-compte' ).addClass( 'hidden' );
$( '#utilisateur-connecte, #anonyme, #zone-courriel-confirmation, #zone-prenom-nom' ).removeClass( 'hidden' );
$( '#nom-complet' ).html( nomComplet );
$( '#courriel, #courriel_confirmation' ).val( courriel ).attr( 'disabled', 'disabled' );
$( '#id_utilisateur' ).val( idUtilisateur );
$( '#prenom' ).val( prenom ).attr( 'disabled', 'disabled' );
$( '#nom' ).val( nom ).attr( 'disabled', 'disabled' );
$( '#date-releve' ).focus();
}
 
/**
113,11 → 147,11
* Si pb de cross-browser, tenter ceci : https://code.google.com/p/javascriptbase64/
* ou ceci : https://code.google.com/p/crypto-js
*/
function decoderJeton(jeton) {
parts = jeton.split('.');
payload = parts[1];
payload = atob(payload);
payload = JSON.parse(payload, true);
function decoderJeton( jeton ) {
parts = jeton.split( '.' );
payload = parts[1];
payload = atob( payload );
payload = JSON.parse( payload, true );
 
return payload;
}
return payload;
}
/trunk/widget/modules/saisie2/squelettes/saisie.tpl.html
1,358 → 1,811
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<html xmlns="https://www.w3.org/1999/xhtml">
<head>
<title><?= $widget['titre']; ?></title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
<meta name="revisit-after" content="15 days" />
<title><?= $widget['titre']; ?></title>
 
<meta charset="utf-8" />
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-style-type" content="text/css" />
<meta http-equiv="Content-script-type" content="text/javascript" />
<meta http-equiv="Content-language" content="fr" />
 
<meta name="revisit-after" content="15 days" />
<meta name="robots" content="index,follow" />
<meta name="author" content="Tela Botanica" />
<meta name="keywords" content="Tela Botanica, CEL" />
<meta name="description" content="Gestion des widgets de saisie du carnet en ligne" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no, user-scalable=no" />
 
<!-- OpenGraph pour Facebook, Pinterest, Google+ -->
<meta property="og:type" content="website" />
<meta property="og:title" content="Widgets de saisie du CeL" />
<meta property="og:site_name" content="Tela Botanica" />
<meta property="og:description" content="Widgets de saisie du Carnet en Ligne" />
<meta property="og:image" content="http://resources.tela-botanica.org/tb/img/256x256/carre_englobant.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="256" />
<meta property="og:image:height" content="256" />
<meta property="og:locale" content="fr_FR" />
<!-- OpenGraph pour Facebook, Pinterest, Google+ -->
<meta property="og:type" content="website" />
<meta property="og:title" content="Widgets de saisie du CeL" />
<meta property="og:site_name" content="Tela Botanica" />
<meta property="og:description" content="Widgets de saisie du Carnet en Ligne" />
<meta property="og:image" content="https://resources.tela-botanica.org/tb/img/256x256/carre_englobant.png" />
<meta property="og:image:type" content="image/png" />
<meta property="og:image:width" content="256" />
<meta property="og:image:height" content="256" />
<meta property="og:locale" content="fr_FR" />
 
<!-- Favicones -->
<link rel="shortcut icon" type="image/x-icon" href="http://resources.tela-botanica.org/tb/img/16x16/favicon.ico" />
<!-- Jquery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.1.js"></script>
<!-- Jquery UI : nécessaire pour le minicalendrier et l'auto-complétion -->
<script type="text/javascript" src="http://resources.tela-botanica.org/jquery/jquery-ui/1.11.0/js/jquery-ui.min.js"></script>
<script type="text/javascript" src="http://resources.tela-botanica.org/jquery/jquery-ui/1.11.0/js/datepicker-fr.js"></script>
<!-- Jquery Plugins -->
<!-- Jquery Validate : nécessaire pour la validation des formulaires -->
<script type="text/javascript" src="http://resources.tela-botanica.org/jquery/validate/1.11.1/jquery.validate.min.js"></script>
<script type="text/javascript" src="http://resources.tela-botanica.org/jquery/validate/1.11.1/additional-methods.min.js"></script>
<script type="text/javascript" src="http://resources.tela-botanica.org/jquery/validate/1.11.1/messages_fr.js"></script>
<!-- Jquery Form :nécessaire pour l'upload des images -->
<script type="text/javascript" src="http://resources.tela-botanica.org/jquery/form/3.51/jquery.form.min.js"></script>
<!-- Bootstrap -->
<script type="text/javascript" src="http://resources.tela-botanica.org/bootstrap/2.3.2/js/bootstrap.min.js"></script>
<!-- Favicones -->
<link rel="shortcut icon" type="image/x-icon" href="https://resources.tela-botanica.org/tb/img/16x16/favicon.ico" />
 
<script type="text/javascript" src="<?=$url_base?>modules/saisie2/squelettes/js/WidgetSaisie.js"></script>
<script type="text/javascript" src="<?=$url_base?>modules/saisie2/squelettes/js/auth.js"></script>
<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
// OMG un modèle objet !!
var widget = new WidgetSaisie();
// langue
widget.langue = "<?= $widget['langue']; ?>";
// Squelette d'URL du web service de l'annuaire.
widget.serviceAnnuaireIdUrl = "<?=$url_ws_annuaire?>";
// URL de l'icône du chargement en cours
widget.chargementIconeUrl = "<?=$url_base?>modules/saisie/squelettes/defaut/img/icones/chargement.gif";
// URL de l'icône du chargement en cours d'une image
widget.chargementImageIconeUrl = "<?=$url_base?>modules/saisie/squelettes/defaut/img/icones/chargement-image.gif";
// URL de l'icône du calendrier
widget.calendrierIconeUrl = "<?=$url_base?>modules/saisie/squelettes/defaut/img/icones/calendrier.png";
// URL de l'icône pour une photo manquante
widget.pasDePhotoIconeUrl = "<?=$url_base?>modules/saisie/squelettes/defaut/img/icones/pasdephoto.png";
// Code du référentiel utilisé pour les nom scientifiques.
widget.nomSciReferentiel = "<?= strtolower($widget['referentiel']); ?>";
// Indication de la présence d'une espèce imposée
widget.especeImposee = "<?=$espece_imposee; ?>";
// Tableau d'informations sur l'espèce imposée
widget.infosEspeceImposee = "<?=$infos_espece; ?>";
// Nombre d'élément dans les listes d'auto-complétion
widget.autocompletionElementsNbre = 20;
// Indication de la présence d'un référentiel imposé
widget.referentielImpose = "<?=$referentiel_impose; ?>";
// URL du web service permettant l'auto-complétion des noms scientifiques
widget.serviceAutocompletionNomSciUrl = "<?= $widget['especes']['url_ws_autocompletion_ns']; ?>?"+
"masque={masque}&"+
"recherche=etendue&"+
"retour.champs=famille,nom_retenu,nom_retenu_complet,num_taxonomique,nom_retenu.id&"+
"ns.structure=au"+"&"+
"navigation.limite=" + widget.autocompletionElementsNbre;
// Squelette d'URL du web service permettant l'auto-complétion des noms scientifiques
widget.serviceAutocompletionNomSciUrlTpl = "<?= $widget['especes']['url_ws_autocompletion_ns_tpl']; ?>?"+
"masque={masque}&"+
"recherche=etendue&"+
"retour.champs=famille,nom_retenu,nom_retenu_complet,num_taxonomique,nom_retenu.id&"+
"retour.tri=alpharet&"+ // tri "à la CeL"
"ns.structure=au"+"&"+
"navigation.limite=" + widget.autocompletionElementsNbre;
<!-- CSS -->
<link href="https://www.tela-botanica.org/commun/jquery/jquery-ui/1.8.18/css/smoothness/jquery-ui-1.8.18.custom.css" rel="stylesheet" type="text/css" media="screen" />
<!-- <link href="https://www.tela-botanica.org/commun/jquery/jquery-ui/1.8.18/css/smoothness/jquery-ui-1.8.18.custom.css" rel="stylesheet" type="text/css" media="screen" /> -->
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous" />
<!-- <link href="https://www.tela-botanica.org/commun/bootstrap/2.0.2/css/bootstrap.min.css" rel="stylesheet" type="text/css" media="screen"> -->
<link rel="stylesheet" type="text/css" href="<?= $url_base; ?>modules/saisie2/squelettes/css/bootstrap-4/css/bootstrap.min.css" />
<!-- <link rel="stylesheet" type="text/css" href="https://resources.tela-botanica.org/bootstrap/3.1.0/css/bootstrap.min.css"> -->
<!-- <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"> -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.1.1/css/all.css" integrity="sha384-O8whS3fhG2OnA5Kas0Y9l3cfpmYjapjI0E4theH4iuMD+pLhbf6JI0jIMfYcK3yZ" crossorigin="anonymous" />
<!-- <link id="telabotanica-style-css" rel="stylesheet" href="https://beta.tela-botanica.org/preprod/wp-content/themes/telabotanica/dist/bundle.css?ver=4.9.7" type="text/css" media="all"> -->
<link href="<?= $url_base; ?>modules/saisie2/squelettes/css/saisie.css" rel="stylesheet" type="text/css" media="screen" />
 
// Initialisation du bousin
widget.init();
});
//]]>
</script>
<!-- Barre de navigation -->
<?php if ($bar !== false): ?>
<script src="<?=$url_script_navigation?>"></script>
<?php endif; ?>
<!-- CSS -->
<link href="http://www.tela-botanica.org/commun/jquery/jquery-ui/1.8.18/css/smoothness/jquery-ui-1.8.18.custom.css" rel="stylesheet" type="text/css" media="screen" />
<!-- <link href="http://www.tela-botanica.org/commun/bootstrap/2.0.2/css/bootstrap.min.css" rel="stylesheet" type="text/css" media="screen" /> -->
<link rel="stylesheet" type="text/css" href="<?=$url_base?>modules/saisie2/squelettes/css/bootstrap-4/css/bootstrap.min.css" />
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
<!-- <link id="telabotanica-style-css" rel="stylesheet" href="https://beta.tela-botanica.org/preprod/wp-content/themes/telabotanica/dist/bundle.css?ver=4.7.5" type="text/css" media="all">
--><link href="<?= $url_base; ?>modules/saisie2/squelettes/css/saisie.css" rel="stylesheet" type="text/css" media="screen" />
<!-- Google Analytics -->
<?php if($prod): ?>
<?php include "analytics.html"; ?>
<?php endif; ?>
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<!-- Google Analytics -->
<?php if( $prod ): ?>
<?php include "analytics.html"; ?>
<?php endif; ?>
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet" />
</head>
 
<body>
<div id="zone-appli" class="container">
<?php if ($bar !== false): ?>
<div id="tb-navigation" data-courant="widget-cel-saisie" data-squelette="bootstrap4" data-mode="prod">
</div>
<br/>
<?php endif; ?>
<div class="layout-wrapper page">
<div class="media">
<?= '<img class="d-flex mr-3" src="'.$widget['logo'].'" alt="'.$widget['projet'].'" >';?>
<div class="media-body">
<h1 class="mt-0">
<?= $widget['titre']; ?>
</h1>
</div>
</div>
<div class="row align-items-center">
<div class="col-md-6">
<div id="description"><?= $widget['description']; ?></div>
</div>
<div class="col-md-6">
<div id="aide" class="well well-lg hidden-sm-down">
<h3><?= $aide['titre']; ?></h3>
<div id="aide-txt" class="hiden-sm-down">
<p>
<?= $aide['description']; ?>
</p>
<p class="discretion">
<?= $aide['contact']; ?>
<a href="<?= $url_remarques ?>?service=cel&pageSource=<?php echo urlencode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING']); ?>"
target="_blank"
onclick="javascript:window.open(this.getAttribute('href'), 'Tela Botanica - Remarques', config='height=700, width=640, scrollbars=yes, resizable=yes'); return false;">
<?= $aide['contact2']; ?></a>
</p>
</div>
</div>
</div>
</div>
<div id="formulaire">
<form id="form-observateur" role="form" autocomplete="on">
<h2><?= $observateur['titre']; ?>
<!--la partie tb-navigation vient du widget stats http://svn.tela-botanica.net/websvn/filedetails.php?repname=eFlore%2FApplications.cel&path=%2Ftrunk%2Fwidget%2Fmodules%2Fstats%2Fsquelettes%2Fstats_utilisateur.tpl.html
la partie contenu-souce vient de http://svn.tela-botanica.net/websvn/filedetails.php?repname=Applications.reseau&path=%2Ftrunk%2Fwidget%2Fmodules%2Fnavigation%2Fsquelettes%2Fbootstrap3.tpl.php
le javascript auth.js vient de http://svn.tela-botanica.net/websvn/filedetails.php?repname=Applications.reseau&path=%2Ftrunk%2Fresources%2Fjs%2Fnavigation.js
de l'aide dans la partie Intégration dans l'interface (applications AJAX) de https://www.tela-botanica.org/wikini/DevInformatiques/wakka.php?wiki=MemoIntegrationSSO
<div id="tb-navigation" data-courant="widget-cel-stats" data-squelette="bootstrap3" data-mode="prod">
<form class="navbar-form navbar-left">
<?php if ($utilisateur_authentifie): ?>
<button class="btn btn-default" disabled><?=$utilisateur?></button>
<a id="mode-stats" class="btn btn-success" href="?mode=defaut" data-mode-courant="utilisateur">Statistiques globales</a>
<?php else: ?>
<a id="mode-stats" class="btn btn-success" href="?mode=utilisateur" data-mode-courant="defaut">Statistiques personnelles</a>
<?php endif; ?>
</form>
</div>
<div id="contenu-source">
<!-- ici le contenu du div #tb-navigation de la page appelante -->
<!--</div>-->
<ul class="nav navbar-nav navbar-right">
<li id="bouton-connexion" class="dropdown">
<a href="<?= $authTpl; ?>">Connexion</a>
</li>
<li class="dropdown" id="utilisateur-connecte" style="display: none;">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span id="nom-complet"></span> <b class="caret"></b></a>
<ul class="dropdown-menu">
<li id="profil-utilisateur"><a href="http://www.tela-botanica.org/inscription">Mon profil</a></li>
<li id="deconnexion"><a href="http://www.tela-botanica.org/widget:reseau:auth?action=deconnexion&origine=">Déconnexion</a></li>
</ul>
</li>
</ul>
</h2>
<div id="zone-courriel" class="row align-items-center">
<div class="col-md-6 form-inline">
<label for="courriel" class="col-sm-3" title="<?= $observateur['courriel-title']; ?>">
<strong class="obligatoire">* </strong>
<?= $observateur['courriel']; ?>
</label>
<div class="col-sm-8 mb-2 input-group">
<span class="input-group-addon hidden-xs-down"><span class="fa fa-envelope"></span></span>
<input id="courriel" name="courriel" class="form-control" type="email" title="<?= $observateur['courriel-title']; ?> "/>
<input id="id_utilisateur" name="id_utilisateur" type="hidden"/>
</div>
</div>
<div id="zone-courriel-confirmation" class="col-md-6 form-inline" style="display:none;">
<label for="courriel_confirmation" class="col-sm-3" title="Veuillez confirmer le courriel.">
<strong class="obligatoire">*</strong> Courriel (confirmation)
</label>
<div class="col-sm-8 input-group">
<span class="input-group-addon hidden-xs-down"><span class="fa fa-envelope"></span></span>
<input id="courriel_confirmation" name="courriel_confirmation" class="form-control" type="email"/>
</div>
</div>
</div>
<div id="zone-prenom-nom" class="row align-items-center" style="display:none;">
<div class="col-md-6 form-inline">
<label for="prenom" class="col-sm-3"><?= $observateur['prenom']; ?></label>
<div class="input-group col-sm-8">
<span class="input-group-addon hidden-xs-down"><span class="fa fa-user"></span></span>
<input id="prenom" name="prenom" class="form-control" type="text"/>
</div>
</div>
<div class="col-md-6 form-inline">
<label for="nom" class="col-sm-3"><?= $observateur['nom']; ?></label>
<div class="input-group col-sm-8">
<span class="input-group-addon hidden-xs-down"><span class="fa fa-user"></span></span>
<input id="nom" name="nom" class="form-control" type="text"/>
</div>
</div>
</div>
</form>
<form id="form-observation" role="form" autocomplete="on">
<h2><?= $observation['titre']; ?></h2>
<div id="zone-observation" class="row align-items-center">
<div class="col-md-6 form-inline">
<label for="geolocalisation" class="col-sm-3" title="<?= $observateur['courriel-title']; ?>">
<strong class="obligatoire">* </strong>
<?= $observation['geolocalisation']; ?>
</label>
<div class="col-sm-8 mb-2 input-group">
<input id="geolocalisation" name="geolocalisation" type="hidden"/>
<!-- code à décommenter pour avoir un aperçu de la carte qui fonctionne sous chrome,
à remplacer quand Stéphane aura fait une release sur https://github.com/steph-del/tb-geoloc-lib/releases -->
<!-- <app-root></app-root>
<script type="text/javascript" src="modules/saisie2/squelettes/js/runtime.js"></script>
<script type="text/javascript" src="modules/saisie2/squelettes/js/polyfills.js"></script>
<script type="text/javascript" src="modules/saisie2/squelettes/js/styles.js"></script>
<script type="text/javascript" src="modules/saisie2/squelettes/js/vendor.js"></script>
<script type="text/javascript" src="modules/saisie2/squelettes/js/main.js"></script> -->
</div>
<label for="milieu" class="col-sm-3">
<?= $observation['milieu']; ?>
</label>
<div class="col-sm-8 mb-2 input-group">
<span class="input-group-addon hidden-xs-down"><span class="fa fa-street-view"></span></span>
<?php if ($widget['milieux'] != array()) {?>
<select id="milieu" class="form-control" >
<?php foreach ($widget['milieux'] as $milieu) {?>
<option value="<?= $milieu; ?>"><?= $milieu; ?></option>
<?php } ?>
</select>
<?php } else { ?>
<input id="milieu" name="milieu" class="form-control" type="text" placeholder="bois, champ, falaise, ..."/>
<?php } ?>
</div>
</div>
<div class="col-md-6 form-inline">
<label for="date" class="col-sm-3" title="">
<strong class="obligatoire">* </strong><?= $observation['date']; ?>
</label>
<div class="col-sm-8 input-group date" id="datetimepicker">
<span id="date-icone" class="input-group-addon hidden-xs-down"><span class="fa fa-calendar"></span></span>
<input id="date" name="date" class="form-control" type="date"/>
</div>
<?php if($widget['type_especes'] == "referentiel" && $widget['referentiel'] == "") { ?>
<label for="referentiel" class="col-sm-3" title="">
<strong class="obligatoire">* </strong><?= $observation['referentiel']; ?>
</label>
<div class="col-sm-8 input-group">
<span class="input-group-addon hidden-xs-down"><span class="fa fa-book"></span></span>
<select id="referentiel" class="form-control" >
<option value="bdtfxr" selected="selected" title="Trachéophytes de France métropolitaine">Métropole (index réduit)</option>
<option value="bdtfx" title="Trachéophytes de France métropolitaine">Métropole (BDTFX)</option>
<option value="bdtxa" title="Trachéophytes des Antilles">Antilles françaises (BDTXA)</option>
<option value="bdtre" title="Trachéophytes de La Réunion">Réunion (BDTRE)</option>
<option value="aublet" title="Guyane">Guyane (AUBLET2)</option>
<option value="florical" title="Nouvelle-Calédonie">Nouvelle-Calédonie (FLORICAL)</option>
<option value="isfan" title="Afrique du Nord">Afrique du Nord (ISFAN)</option>
<option value="apd" title="Afrique de l'Ouest et du Centre">Afrique de l'Ouest et du Centre (APD)</option>
<option value="lbf" title="Liban">Liban (LBF)</option>
<option value="autre" title="Autre/Inconnu">Autre/Inconnu</option>
</select>
</div>
<?php } else { ?><input id="referentiel" name="referentiel" value="<?= $widget['referentiel']; ?>" type="hidden" /><?php } ?>
<label for="taxon" class="col-sm-3" title="">
<?= $observation['espece']; ?>
</label>
<div class="col-sm-8 input-group date">
<span class="input-group-addon hidden-xs-down"><span class="fa fa-leaf"></span></span>
<input id="taxon" name="taxon" class="form-control" type="text"/>
</div>
<label for="certitude" class="col-sm-3" title="">
<strong class="obligatoire">* </strong><?= $observation['certitude']; ?>
</label>
<div class="col-sm-8 input-group date" id="datetimepicker">
<span class="input-group-addon hidden-xs-down"><span class="fa fa-question"></span></span>
<select id="certitude" name="certitude" class="form-control">
<option value="aDeterminer" ><?= $observation['certADet']; ?></option>
<option value="douteuse" ><?= $observation['certDout']; ?></option>
<option value="certaine" selected="selected" ><?= $observation['certCert']; ?></option>
</select>
</div>
</div>
</div>
</form>
<?php if (isset($widget['chpSupp']) && $widget['chpSupp'] != array()) { ?>
<form id="form-supp" role="form" autocomplete="on">
<div id="zone-supp" class="row align-items-center">
<div class="col-md-6 form-inline">
<?php print_r(implode($widget['chpSupp']));?>
</div>
</div>
</form>
<?php } ?>
<div id="image" class="row align-items-center">
</div>
</div>
<div class="row align-items-end component-tools-item-link">
<a href="http://www.tela-botanica.org/appli:cel" target="" style="color: #e16e37">
<span>Gestion</span>
</a>
<a href="http://www.tela-botanica.org/widget:cel:cartoPoint?projet=<?= $widget['projet']; ?>" target="" style="color: #918a6f">
<span>Carto</span>
</a>
<a href="http://www.tela-botanica.org/widget:cel:photo?projet=<?= $widget['projet']; ?>" target="" style="color: #964e75">
<span>Photo</span>
</a>
<a href="http://www.tela-botanica.org/widget:cel:observation?projet=<?= $widget['projet']; ?>" target="" style="color: #b2cb43">
<span>Observation</span>
</a>
<a href="http://www.tela-botanica.org/widget:cel:export?projet=<?= $widget['projet']; ?>" target="" style="color: #009fb8">
<span>Export</span>
</a>
<a href="http://www.tela-botanica.org/appli:pictoflora?projet=<?= $widget['projet']; ?>" target="" style="color: #927fa2">
<span>PictoFlora</span>
</a>
<a href="http://www.tela-botanica.org/appli:identiplante?projet=<?= $widget['projet']; ?>" target="" style="color: #f25a52">
<span>IdentiPlante</span>
</a>
</div>
</div>
</div>
<!-- <?php //var_dump($widget['especes']['url_ws_autocompletion_ns']); ?> -->
<div id="zone-appli" class="container">
<!-- la barre de navigation est plus bas -->
<!-- <?php //if ( $bar ): ?>
<div id="tb-navigation" data-courant="widget-cel-saisie2" data-squelette="saisie" data-mode="test"></div>
<br/>
<?php //endif; ?> -->
<div class="layout-wrapper page">
 
<div class="media">
<img class="d-flex mr-3" src="<?= $widget['logo']; ?>" alt="<?= $widget['projet']; ?>" />
<div class="media-body">
<h1 class="mt-0"><?= $widget['titre']; ?></h1>
</div>
</div>
 
<div class="row">
<div class="col-md-6">
<div id="description"><?= $widget['description']; ?></div>
</div>
<div class="col-md-6">
<div id="aide" class="well well-lg hidden-sm-down">
<h3><?= $aide['titre']; ?></h3>
<div id="aide-txt" class="hiden-sm-down">
<p>
<?= $aide['description']; ?>
</p>
<p class="discretion">
<?= $aide['contact']; ?>
<a href="<?= $url_remarques; ?>?service=cel&pageSource=<?php echo urlencode( 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'] ); ?>"
target="_blank"
onclick="
javascript:window.open(
this.getAttribute( 'href' ),
'Tela Botanica - Remarques',
config = 'height=700, width=640, scrollbars=yes, resizable=yes'
);
return false;
">
<?= $aide['contact2']; ?></a>
</p>
</div>
</div>
</div>
</div>
 
<div id="formulaire" class="row mb-3 bloc-top">
<form id="form-observateur" role="form" autocomplete="on">
<h2><?= $observateur['titre']; ?></h2>
<!--la partie tb-navigation vient du widget stats http://svn.tela-botanica.net/websvn/filedetails.php?repname=eFlore%2FApplications.cel&path=%2Ftrunk%2Fwidget%2Fmodules%2Fstats%2Fsquelettes%2Fstats_utilisateur.tpl.html
la partie contenu-souce vient de http://svn.tela-botanica.net/websvn/filedetails.php?repname=Applications.reseau&path=%2Ftrunk%2Fwidget%2Fmodules%2Fnavigation%2Fsquelettes%2Fbootstrap3.tpl.php
le javascript auth.js vient de http://svn.tela-botanica.net/websvn/filedetails.php?repname=Applications.reseau&path=%2Ftrunk%2Fresources%2Fjs%2Fnavigation.js
de l'aide dans la partie Intégration dans l'interface (applications AJAX) de https://www.tela-botanica.org/wikini/DevInformatiques/wakka.php?wiki=MemoIntegrationSSO-->
<!-- <div id="tb-navigation" data-courant="widget-cel-saisie2" data-squelette="navigation" data-mode="test"> -->
<!-- En prod décommenter la div ci-dessous et commenter celle ci-dessus" -->
<div id="tb-navigation" data-courant="widget-cel-saisie2" data-squelette="navigation" data-mode="prod">
<div class="navbar-default mb-3" id="tb-navbar">
<div class="nav navbar-nav navbar-right row">
<div id="bouton-connexion" class="dropdown col-md-6 col-sm-12">
<label for="bouton-connexion">Je me connecte à mon compte : </label>
<a id="connexion" href="<?= $authTpl; ?>" class="btn btn-success mr-1 mb-1">Connexion</a>
<a id="bouton-inscription" href="https://www.tela-botanica.org/inscription" class="btn btn-primary mr-1 mb-1" taget="_blank">Inscription</a>
</div>
<div id="creation-compte" class="dropdown col-md-6 col-sm-12">
<label for="creation-compte">Je ne souhaite pas m'inscrire : </label>
<a id="bouton-anonyme" href="#" class="btn btn-info mr-1 mb-1">Observation sans inscription</a>
</div>
<div id="utilisateur-connecte" class="dropdown hidden">
<label for="utilisateur-connecte">Bienvenue : </label>
<a href="#" class="list-tool btn btn-largee btn-primary dropdown-toggle" data-toggle="dropdown">
<span id="nom-complet"></span>
</a>
<div class="dropdown-menu">
<div id="profil-utilisateur"><a href="https://www.tela-botanica.org/inscription">Mon profil</a></div>
<div id="deconnexion"><a href="https://www.tela-botanica.org/widget:reseau:auth?action=deconnexion&origine=">Déconnexion</a></div>
</div>
</div>
</div>
</div>
</div>
 
<div id="anonyme" class="mb-3 hidden">
<label for="anonyme">Informations sur l'observateur : </label>
<div id="zone-courriel" class="row">
<div class="control-group col-md-6">
 
<label for="courriel" class="col-sm-12 obligatoire" title="<?= $observateur['courriel-title']; ?>">
<i class="fa fa-envelope" aria-hidden="true"></i>
<?= $observateur['courriel']; ?>
</label>
<div class="col-sm-8 mb-3">
<input id="courriel" name="courriel" class="form-control" type="email" title="<?= $observateur['courriel-title']; ?> ">
<input id="id_utilisateur" name="id_utilisateur" type="hidden">
</div>
 
</div>
<div id="zone-courriel-confirmation" class="control-group col-md-6 hidden">
 
<label for="courriel_confirmation" class="col-sm-12 obligatoire" title="Veuillez confirmer le courriel.">
<i class="fa fa-envelope" aria-hidden="true"></i>
Courriel (confirmation)
</label>
<div class="col-sm-8">
<input id="courriel_confirmation" name="courriel_confirmation" class="form-control" type="email">
</div>
 
</div>
</div>
<div id="zone-prenom-nom" class="row hidden">
<div class="control-group col-md-6">
 
<label for="prenom" class="col-sm-12">
<i class="fa fa-user" aria-hidden="true"></i>
<?= $observateur['prenom']; ?>
</label>
<div class="input-group col-sm-8">
<input id="prenom" name="prenom" class="form-control" type="text">
</div>
 
</div>
<div class="control-group col-md-6">
 
<label for="nom" class="col-sm-12">
<i class="fa fa-user" aria-hidden="true"></i>
<?= $observateur['nom']; ?>
</label>
<div class="input-group col-sm-8">
<input id="nom" name="nom" class="form-control" type="text">
</div>
 
</div>
</div>
</div>
</form>
<!-- Messages d'erreur du formulaire-->
<div class="row">
<div class="zone-alerte">
<div id="dialogue-bloquer-copier-coller" class="alert alert-info alert-block hidden"">
<a class="close">×</a>
<h4 class="alert-heading">Information : copier/coller</h4>
<p>
Merci de ne pas copier/coller votre courriel.<br/>
La double saisie permet de vérifier l'absence d'erreurs.
</p>
</div>
<div id="dialogue-utilisateur-non-identifie" class="alert alert-warning alert-block hidden">
<a class="close">×</a>
<h4 class="alert-heading">Information : observateur non identifié</h4>
<p>
Votre observation doit être liée soit à un compte, soit à un email.<br/>
Veuillez choisir, soit de vous connecter, soit de vous inscrire, soit communiquer une adresse email afin de vous identifier comme auteur de l'observation.<br/>
Pour retrouver vos observations dans le <a href="http://www.tela-botanica.org/appli:cel">Carnet en ligne</a>,
il est nécesaire de <a href="http://www.tela-botanica.org/page:inscription">vous inscrire à Tela Botanica</a>.
</p>
</div>
<!-- <div id="dialogue-google-map" class="alert alert-info alert-block hidden">
<a class="close">×</a>
<h4 class="alert-heading">Information sur Google Maps</h4>
<div class="contenu"></div>
</div> -->
</div>
</div>
 
<form id="form-observation" role="form" autocomplete="on">
<h2><?= $observation['titre']; ?></h2>
<div id="zone-observation" class="row">
<div class="col-md-6">
<div class="control-group">
<label for="geolocalisation" class="col-sm-12 obligatoire" title="<?= $observateur['courriel-title']; ?>">
<i class="fa fa-street-view" aria-hidden="true"></i>
<?= $observation['geolocalisation']; ?>
</label>
<div class="col-sm-12 mb-3">
<input id="geolocalisation" name="geolocalisation" type="hidden">
<!-- code à décommenter pour avoir un aperçu de la carte qui fonctionne sous chrome,
à remplacer quand Stéphane aura fait une release sur https://github.com/steph-del/tb-geoloc-lib/releases -->
<!-- <app-root></app-root>
<script type="text/javascript" src="modules/saisie2/squelettes/js/runtime.js"></script>
<script type="text/javascript" src="modules/saisie2/squelettes/js/polyfills.js"></script>
<script type="text/javascript" src="modules/saisie2/squelettes/js/styles.js"></script>
<script type="text/javascript" src="modules/saisie2/squelettes/js/vendor.js"></script>
<script type="text/javascript" src="modules/saisie2/squelettes/js/main.js"></script> -->
</div>
</div>
<div class="control-group">
<label for="milieu" class="col-sm-12">
<i class="fa fa-street-view" aria-hidden="true"></i>
<?= $observation['milieu']; ?>
</label>
<div class="col-sm-8 mb-3">
<?php if ( 0 < count( (array) $widget['milieux'] ) ) :?>
<select id="milieu" class="form-control" >
<?php foreach ( $widget['milieux'] as $milieu ) :?>
<option value="<?= $milieu; ?>"><?= $milieu; ?></option>
<?php endforeach; ?>
</select>
<?php else : ?>
<input id="milieu" name="milieu" class="form-control" type="text" placeholder="bois, champ, falaise, ...">
<?php endif; ?>
</div>
</div>
</div>
<div class="col-md-6">
 
<div class="control-group">
<label for="date_releve" class="col-sm-12 obligatoire" title="">
<i class="fa fa-calendar" aria-hidden="true"></i>
<?= $observation['date']; ?>
</label>
<div class="col-sm-8 mb-3" id="datetimepicker">
<input type="text" id="date_releve" name="date_releve" class="form-control date" placeholder="jj/mm/aaaa" pattern="(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)" title="jj/mm/aaaa">
</div>
</div>
 
<?php if( 'referentiel' === $widget['type_especes'] && '' === $widget['referentiel'] ) : ?>
<div class="control-group">
<label for="referentiel" class="col-sm-12 obligatoire" title="">
<i class="fa fa-book" aria-hidden="true"></i>
<?= $observation['referentiel']; ?>
</label>
<div class="col-sm-8 mb-3">
<select id="referentiel" class="form-control" >
<option value="bdtfxr" selected="selected" title="Trachéophytes de France métropolitaine">Métropole (index réduit)</option>
<option value="bdtfx" title="Trachéophytes de France métropolitaine">Métropole (BDTFX)</option>
<option value="bdtxa" title="Trachéophytes des Antilles">Antilles françaises (BDTXA)</option>
<option value="bdtre" title="Trachéophytes de La Réunion">Réunion (BDTRE)</option>
<option value="aublet" title="Guyane">Guyane (AUBLET2)</option>
<option value="florical" title="Nouvelle-Calédonie">Nouvelle-Calédonie (FLORICAL)</option>
<option value="isfan" title="Afrique du Nord">Afrique du Nord (ISFAN)</option>
<option value="apd" title="Afrique de l'Ouest et du Centre">Afrique de l'Ouest et du Centre (APD)</option>
<option value="lbf" title="Liban">Liban (LBF)</option>
<option value="autre" title="Autre/Inconnu">Autre/Inconnu</option>
</select>
</div>
</div>
<?php else : ?>
<input id="referentiel" name="referentiel" value="<?= $widget['referentiel']; ?>" type="hidden">
<?php endif; ?>
 
<div class="control-group">
<label for="taxon" class="col-sm-12 obligatoire" title="">
<i class="fa fa-leaf" aria-hidden="true"></i>
<?= $observation['espece']; ?>
</label>
<div class="col-sm-8 mb-3">
<input id="taxon" name="taxon" class="form-control" type="text">
</div>
</div>
 
<div class="control-group">
<label for="certitude" class="col-sm-12 obligatoire" title="">
<i class="fa fa-question" aria-hidden="true"></i>
<?= $observation['certitude']; ?>
</label>
<div class="col-sm-8 mb-3">
<select id="certitude" name="certitude" class="form-control">
<option value="aDeterminer" ><?= $observation['certADet']; ?></option>
<option value="douteuse" ><?= $observation['certDout']; ?></option>
<option value="certaine" selected="selected" ><?= $observation['certCert']; ?></option>
</select>
</div>
</div>
 
</div>
</div>
</form>
 
<form id="form-upload" class="form-horizontal" action="<?= $url_ws_upload ?>" method="post" enctype="multipart/form-data">
<h2>Image(s) de cette plante</h2>
<p class="miniature-info" class="discretion help-inline">
Les photos doivent être au format JPEG et ne doivent pas excéder 5Mo chacunes.
</p>
<div id ="photos-conteneur" class="control-group">
<div>
<label for="fichier" class="label-file btn btn-large btn-info mb-3">
<span class="label-text"><i class="fas fa-download"></i> Ajouter une image</span>
<input type="file" id="fichier" name="fichier" class="input-file" accept="image/jpeg" multiple>
<input type="hidden" name="MAX_FILE_SIZE" value="5242880">
</label>
</div>
 
<div id="miniatures"></div>
<p class="miniature-msg" class="span12">&nbsp;</p>
</div>
</form>
 
<!-- Champs supplémentaires -->
<?php if ( isset($widget['chpSupp'] ) && 0 < count( (array) $widget['chpSupp'] ) ) : ?>
<form id="form-supp" role="form" autocomplete="on">
<h2>Informations propres au projet</h2>
<div id="zone-supp" class="row">
<div class="col-md-6">
 
<?php foreach( $widget['chpSupp']['sauvagessupp']['champs-supp'] as $champ ) :?>
<?php
$min = ( $champ['fieldValues']['min'] )? ' min="' . $champ['fieldValues']['min'] . '"':'';
$max = ( $champ['fieldValues']['max'] )? ' max="' . $champ['fieldValues']['max'] . '"':'';
$step = ( $champ['fieldValues']['step'] )? ' step="' . $champ['fieldValues']['step'] . '"':'';
$default = ( $champ['fieldValues']['default'] )? ' value="' . $champ['fieldValues']['default'] . '"':'';
$description = ( $champ['description'] )? ' title="' . $champ['description'] . '"':'';
$placeholder = ( $champ['fieldValues']['placeholder'] )? ' placeholder="' . $champ['fieldValues']['placeholder'] . '"':'';
$help = ( $champ['help'] )? ' and-help':'';
$required = '';
$mandatory = '';
$datepicker = '';
$pattern = '';
$obs_radio = '';
 
if( $champ['mandatory'] ) {
// Attr required
$required = ' required';
// class="obligatoire"
$mandatory = ' obligatoire';
}
 
if( 'date' === $champ['element'] ) {
$datepicker = ' date';
$pattern = ' pattern="(^(((0[1-9]|1[0-9]|2[0-8])[\/](0[1-9]|1[012]))|((29|30|31)[\/](0[13578]|1[02]))|((29|30)[\/](0[4,6,9]|11)))[\/](19|[2-9][0-9])\d\d$)|(^29[\/]02[\/](19|[2-9][0-9])(00|04|08|12|16|20|24|28|32|36|40|44|48|52|56|60|64|68|72|76|80|84|88|92|96)$)"';
}
 
switch( $champ['element'] ) {
case 'radio':
case 'checkbox': ?>
<div class="control-group <?= $champ['element']; ?> mb-3"<?php echo $description . $required; ?>>
<div class="col-sm-12 list-label<?php echo $help . $mandatory; ?>">
<?= $champ['name']; ?>
</div>
<div class="col-sm-8">
 
<?php foreach ( $champ['fieldValues']['listValue'] as $i => $list_value ) : ?>
 
<?php
$checked = '';
if ( '#' === substr( $list_value, -1 ) ) :
$checked = ' checked';
$list_value = substr( $list_value, 0, -1 );
endif;
?>
 
<?php if( 'other' !== $list_value ) : ?>
<label for="<?php echo $champ['fieldValues']['cleanListValue'][$i]; ?>" class="<?php echo $champ['fieldValues']['cleanListValue'][$i]; ?>">
<input type="<?= $champ['element']; ?>" id="<?php echo $champ['fieldValues']['cleanListValue'][$i]; ?>" name="<?= $champ['key']; ?>" value="<?= $list_value; ?>"<?= $checked; ?> class="<?php echo $champ['fieldValues']['cleanListValue'][$i]; ?>" data-label="<?= $champ['name']; ?>">
<?= $list_value; ?>
</label>
<?php else : ?>
<label for="other-<?= $champ['key']; ?>">
<input type="<?= $champ['element']; ?>" id="other-<?= $champ['key']; ?>"'name="<?= $champ['key']; ?>" value="other" class="other" data-label="<?= $champ['name']; ?>" data-element="<?= $champ['element']; ?>">
Autre
</label>
<?php endif; ?>
 
<?php endforeach; ?>
 
</div>
</div>
<?php break;
 
case 'list-checkbox': ?>
<div class="multiselect <?php echo $champ['element'] . $help; ?>">
<label class="col-sm-12<?= $mandatory; ?>"><?= $champ['name']; ?></label>
<div class="control-group col-sm-8 mb-3">
<div class="selectBox">
<select class="form-control" id="list-checkbox-<?= $champ['key']; ?>"<?php echo $description . $required; ?> class="form-control">
<option>Plusieurs choix possibles</option>
</select>
<div class="overSelect"></div>
</div>
<div class="checkboxes hidden">
<?php foreach ( $champ['fieldValues']['listValue'] as $i => $list_value ) : ?>
 
<?php
$checked = '';
if ( '#' === substr( $list_value, -1 ) ) :
$checked = ' checked';
$list_value = substr( $list_value, 0, -1 );
endif;
?>
 
<?php if( 'other' !== $list_value ) : ?>
<label for="<?php echo $champ['fieldValues']['cleanListValue'][$i]; ?>">
<input type="checkbox" id="<?php echo $champ['fieldValues']['cleanListValue'][$i]; ?>" name="<?= $champ['key']; ?>" value="<?= $list_value; ?>"<?= $checked; ?> class="<?php echo $champ['fieldValues']['cleanListValue'][$i]; ?>" data-label="<?= $champ['name']; ?>">
<?= $list_value; ?>
</label>
<?php else : ?>
<label for="other-<?= $champ['key']; ?>">
<input type="checkbox" id="other-<?= $champ['key']; ?>" name="<?= $champ['key']; ?>" value="other" class="other" data-label="<?= $champ['name']; ?>" data-element="<?= $champ['element']; ?>">
Autre
</label>
<?php endif; ?>
 
<?php endforeach; ?>
 
</div>
</div>
</div>
<?php break;
 
case 'select': ?>
<label for="<?= $champ['key']; ?>" class="col-sm-12<?= $mandatory; ?>"<?= $description; ?>><?= $champ['name']; ?></label>
<div class="champ col-sm-8 mb-3">
<div class="select-wrapper add-field-select <?php echo $champ['element'] . $help; ?>">
<select name="<?= $champ['key']; ?>" id="<?= $champ['key']; ?>" class="<?= $champ['key']; ?> form-control"<?= $required; ?> data-label="<?= $champ['name']; ?>">
 
<?php foreach ( $champ['fieldValues']['listValue'] as $list_value ) : ?>
 
<?php
$selected = '';
if ( '#' === substr( $list_value, -1 ) ) :
$selected = ' selected="selected"';
$list_value = substr( $list_value, 0, -1 );
endif;
?>
 
<?php if( 'other' !== $list_value ) : ?>
<option value="<?= $list_value; ?>"<?= $selected; ?>>
<?php echo ucfirst( $list_value ); ?>
</option>
<?php else : ?>
<option class="other form-control is-select" value="other" data-element="<?= $champ['element']; ?>">Autre</option>
<?php endif; ?>
 
<?php endforeach; ?>
 
</select>
</div>
</div>
<?php break;
 
case 'file' : ?>
<div class="control-group col-sm-12 mb-3">
<div class="input-file-container<?= $help; ?>">
<input type="<?= $champ['element']; ?>" name="<?= $champ['key']; ?>" class="<?php echo $champ['key'] . ' input-file'; ?> form-control" <?php echo $description . $placeholder . $required; ?> accept="application/pdf, image/*, video/*" data-label="<?= $champ['name']; ?>">
<label for="<?= $champ['key']; ?>" class="label-file<?= $mandatory; ?>" <?= $description; ?>><i class="fas fa-download" aria-hidden="true"></i> <?= $champ['name']; ?></label>
 
<?php if ( !$champ['mandatory'] ) : ?>
<div class="remove-file button" name="remove-file" title="Supprimer le fichier"><i class="fas fa-times" aria-hidden="true"></i></div>
<?php endif; ?>
 
</div>
</div>
<?php break;
 
case 'textarea': ?>
<div class="control-group">
<label for="<?= $champ['key']; ?>" class="col-sm-12<?php echo $help . $mandatory; ?>" <?= $description; ?>><?= $champ['name']; ?></label>
<div class="col-sm-8 mb-3">
<textarea type="<?= $champ['element']; ?>" id="<?= $champ['key']; ?>" name="<?= $champ['key']; ?>" class="<?= $champ['key'] . $help; ?> form-control" <?php echo $description . $placeholder . $required; ?> data-label="<?= $champ['name']; ?>"></textarea>
</div>
</div>
<?php break;
 
case 'range': ?>
<div class="control-group">
<label for="<?= $champ['key']; ?>" class="col-sm-12<?= $help . $mandatory; ?>" <?= $description; ?>><?= $champ['name']; ?></label>
<div class="col-sm-8 mb-3">
<input type="<?= $champ['element']; ?>" name="<?= $champ['key']; ?>" class="<?= $champ['key'] . $help; ?> form-control" <?php echo $description . $placeholder . $step . $default . $min . $max . $required; ?> data-label="<?= $champ['name']; ?>">
</div>
</div>
<?php break;
 
case 'number':
case 'date': ?>
<div class="control-group">
<label for="<?= $champ['key']; ?>" class="col-sm-12<?php echo $datepicker . $mandatory; ?>" <?= $description; ?>><?= $champ['name']; ?></label>
<div class="col-sm-8 mb-3">
<input type="<?= $champ['element']; ?>" name="<?= $champ['key']; ?>" class="<?= $champ['key'] . $help . $datepicker; ?> form-control"<?php echo $pattern . $description . $placeholder . $step . $default . $min . $max . $required; ?> data-label="<?= $champ['name']; ?>">
</div>
</div>
<?php break;
 
case 'text' :
case 'email':
default: ?>
<div class="control-group">
<label for="<?= $champ['key']; ?>" class="col-sm-12<?= $mandatory; ?>" <?= $description; ?>><?= $champ['name']; ?></label>
<div class="col-sm-8 mb-3">
<input type="<?= $champ['element']; ?>" name="<?= $champ['key']; ?>" class="<?= $champ['key'] . $help; ?> form-control" <?php echo $description . $placeholder . $required; ?> data-label="<?= $champ['name']; ?>">
</div>
</div>
<?php break;
}
?>
 
<?php endforeach; ?>
</div>
</div>
</form>
<?php endif; ?><!-- Fin champs supplémentaires -->
 
<div id="image" class="row"></div>
</div>
 
<!-- Bouton cr&ation d'une obs -->
<div class="row mb-3 bloc-bottom">
<div class="centre" title="Une fois les champs remplis, vous pouvez cliquer sur ce bouton pour
ajouter votre observation à la liste à transmettre.">
<a id="ajouter-obs" class="btn btn-primary">
<i class="fas fa-check-square"></i> Créer
</a>
</div>
</div>
 
<!-- Messages d'erreur du formulaire-->
<div class="row">
<div class="zone-alerte">
<div id="dialogue-bloquer-creer-obs" class="alert alert-warning alert-block hidden">
<a class="close">×</a>
<h4 class="alert-heading">Information : 10 observations maximum</h4>
<p>
Vous venez d'ajouter votre 10ème observation.<br/>
Pour en ajouter de nouvelles, il est nécessaire de les transmettre en cliquant sur le bouton ci-dessous.
</p>
</div>
</div>
<div class="zone-alerte">
<div id="dialogue-form-invalide" class="alert alert-warning alert-block hidden">
<a class="close">×</a>
<h4 class="alert-heading">Information : champs en erreur</h4>
<p>
Certains champs du formulaire sont mal remplis.<br/>
Veuillez vérifier vos données.
</p>
</div>
</div>
</div>
 
<!-- Affiche le tableau récapitualif des observations ajoutées -->
<div id="zone-liste-obs" class="hidden">
<div class="alert alert-info">
<h2 class="transmission-title"><strong>Observations à transmettre : <span class="obs-nbre badge badge-info">0</span></strong></h2>
<button id="transmettre-obs" class="btn btn-primary droite" disabled="disabled"
title="Ajoute les observations ci-dessous à votre Carnet en Ligne et les rend publiques." type="button">
Transmettre
</button>
</div>
<div id="liste-obs" ></div>
<div class="row">
<div class="zone-alerte">
<div id="dialogue-zero-obs" class="alert alert-block hidden">
<a class="close">×</a>
<h4 class="alert-heading">Attention : aucune observation</h4>
<p>Veuillez saisir des observations pour les transmettre.</p>
</div>
<div id="dialogue-obs-transaction-ok" class="alert alert-success alert-block hidden">
<a class="close">×</a>
<h4 class="alert-heading">Information : transmission des observations</h4>
<div class="alert-txt"></div>
</div>
<div id="dialogue-obs-transaction-ko" class="alert alert-error alert-block hidden">
<a class="close">×</a>
<h4 class="alert-heading">Erreur : transmission des observations</h4>
<div class="alert-txt"></div>
</div>
</div>
</div>
</div>
 
<!-- Fenêtres modales -->
<div id="chargement" class="modal-fenetre hidden">
<div id="chargement-centrage" class="modal-contenu">
<div class="progress progress-striped active">
<div id="barre-progression-upload" class="bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="10" style="">
<span class="sr-only">0/10 observations transmises</span>
</div>
</div>
<p id="chargement-txt" style="color:white;font-size:1.5em;">
Transfert des observations en cours...<br />
Cela peut prendre plusieurs minutes en fonction de la taille des images et du nombre
d'observations à transférer.
</p>
</div>
</div>
 
<!-- Templates HTML -->
<div id="tpl-transmission-ok" class="hidden">
<p class="msg">
Vos observations ont bien été transmises.<br />
Elles sont désormais consultables à travers les différents outils de visualisation
du réseau (<a href="https://www.tela-botanica.org/site:botanique">eFlore</a>,
<a href="https://www.tela-botanica.org/appli:pictoflora">galeries d'images</a>,
<a href="https://www.tela-botanica.org/appli:identiplante">identiplante</a>,
<a href="https://www.tela-botanica.org/widget:cel:cartoPoint">cartographie (widget)</a>...)<br />
Si vous souhaitez les modifier ou les supprimer, vous pouvez les retrouver en vous
connectant à votre <a href="https://www.tela-botanica.org/appli:cel">Carnet en ligne</a>.<br />
N'oubliez pas qu'il est nécessaire de
<a href="https://www.tela-botanica.org/page:inscription">s'inscrire à Tela Botanica</a>
au préalable, si ce n'est pas déjà fait.
</p>
</div>
<div id="tpl-transmission-ko" class="hidden">
<p class="msg">
Une erreur est survenue lors de la transmission d'une observation (indiquée en rouge).<br />
Vous pouvez tenter de la retransmettre en cliquant à nouveau sur le bouton transmettre ou bien la supprimer
et transmettre les suivantes.<br />
Néanmoins, les observations n'apparaissant plus dans la liste "observations à transmettre", ont bien été transmises lors de votre précédente tentative. <br />
Si le problème persiste, vous pouvez signaler le dysfonctionnement sur
<a href="<?= $url_remarques; ?>?service=cel&pageSource=<?php echo urlencode( 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'].'?'.$_SERVER['QUERY_STRING'] ); ?>" target="_blank"
onclick="
javascript: window.open( this.getAttribute( 'href' ), 'Tela Botanica - Remarques', config = 'height=700, width=640, scrollbars=yes, resizable=yes' );
return false;
"
>le formulaire de signalement d'erreurs</a>.
</p>
</div>
 
<footer>
<div class="row centre component-tools-item-link">
<a href="https://www.tela-botanica.org/appli:cel" target="" class="mr-1" style="color: #e16e37">
<span>Gestion</span>
</a>
<a href="https://www.tela-botanica.org/widget:cel:cartoPoint?projet=<?= $widget['projet']; ?>" target="" class="mr-2" style="color: #918a6f">
<span>Carto</span>
</a>
<a href="https://www.tela-botanica.org/widget:cel:photo?projet=<?= $widget['projet']; ?>" target="" class="mr-2" style="color: #964e75">
<span>Photo</span>
</a>
<a href="https://www.tela-botanica.org/widget:cel:observation?projet=<?= $widget['projet']; ?>" target="" class="mr-2" style="color: #b2cb43">
<span>Observation</span>
</a>
<a href="https://www.tela-botanica.org/widget:cel:export?projet=<?= $widget['projet']; ?>" target="" class="mr-2" style="color: #009fb8">
<span>Export</span>
</a>
<a href="https://www.tela-botanica.org/appli:pictoflora?projet=<?= $widget['projet']; ?>" target="" class="mr-2" style="color: #927fa2">
<span>PictoFlora</span>
</a>
<a href="https://www.tela-botanica.org/appli:identiplante?projet=<?= $widget['projet']; ?>" target="" style="color: #f25a52">
<span>IdentiPlante</span>
</a>
</div>
</footer>
</div>
</div>
<!-- Jquery -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.12.1.js"></script>
 
<!-- Jquery UI : nécessaire pour le minicalendrier et l'auto-complétion -->
<script type="text/javascript" src="https://resources.tela-botanica.org/jquery/jquery-ui/1.11.0/js/jquery-ui.min.js"></script>
<script type="text/javascript" src="https://resources.tela-botanica.org/jquery/jquery-ui/1.11.0/js/datepicker-fr.js"></script>
<!-- Jquery Plugins -->
<!-- Jquery Validate : nécessaire pour la validation des formulaires -->
<script type="text/javascript" src="https://resources.tela-botanica.org/jquery/validate/1.11.1/jquery.validate.min.js"></script>
<!-- <script type="text/javascript" src="https://resources.tela-botanica.org/jquery/validate/1.11.1/jquery.validate-patched.min.js"></script> -->
<script type="text/javascript" src="https://resources.tela-botanica.org/jquery/validate/1.11.1/additional-methods.min.js"></script>
<script type="text/javascript" src="https://resources.tela-botanica.org/jquery/validate/1.11.1/messages_fr.js"></script>
<!-- Jquery Form :nécessaire pour l'upload des images -->
<script type="text/javascript" src="https://resources.tela-botanica.org/jquery/form/3.51/jquery.form.min.js"></script>
<!-- Bootstrap -->
<!-- <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> -->
<!-- <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script> -->
<script type="text/javascript" src="https://resources.tela-botanica.org/bootstrap/2.3.2/js/bootstrap.min.js"></script>
<!-- Authentification -->
<script type="text/javascript" src="<?= $url_base; ?>modules/saisie2/squelettes/js/auth.js"></script>
<!-- Connexion, bloc de prévisualisation, date -->
<script type="text/javascript" src="<?= $url_base; ?>modules/saisie2/squelettes/js/WidgetSaisie.js"></script>
<script type="text/javascript" src="<?= $url_base; ?>modules/saisie2/squelettes/js/champs-supp.js"></script>
<script type="text/javascript">
//<![CDATA[
$( document ).ready( function() {
 
// OMG un modèle objet !!
var widget = new WidgetSaisie();
 
//
//
//
// La présence du parametre 'debug' dans l'URL enclenche le débogage
widget.debug = <?= isset( $_GET['debug'] ) ? 'true' : 'false'; ?>;
// La présence du parametre 'html5' dans l'URL enclenche les fonctions avancées HTML5
widget.html5 = <?= isset($_GET['html5']) ? 'true' : 'false'; ?>;
// Mot-clé du widget/projet
widget.tagProjet = "WidgetSaisie";
// Mots-clés à ajouter aux images
widget.tagImg = "<?= isset($_GET['tag-img']) ? $_GET['tag-img'] : ''; ?>";
widget.separationTagImg = "<?= isset($_GET['motcle']) && isset($_GET['tag-img']) ? ',' : ''; ?>";
widget.tagImg = <?= isset($_GET['motcle']) ? "'".$_GET['motcle']."' + widget.separationTagImg + widget.tagImg" : 'widget.tagImg'; ?>;
// Mots-clés à ajouter aux observations
widget.tagObs = "<?= isset($_GET['tag-obs']) ? $_GET['tag-obs'] : ''; ?>";
widget.separationTagObs = "<?= isset($_GET['projet']) && isset($_GET['tag-obs']) ? ',' : ''; ?>";
widget.tagObs = <?= isset($_GET['projet']) ? "'".$_GET['projet']."' + widget.separationTagObs + widget.tagObs" : 'widget.tagObs'; ?>;
// Précharger le formulaire avec les infos d'une observation
widget.obsId = "<?=isset($_GET['id-obs']) ? $_GET['id-obs'] : ''?>";
// URL du web service réalisant l'insertion des données dans la base du CEL.
widget.serviceSaisieUrl = "<?=$url_ws_saisie?>";
// URL du web service permettant de récupérer les infos d'une observation du CEL.
widget.serviceObsUrl = "<?=$url_ws_obs?>";
//
//
//
 
// langue
widget.langue = "<?= $widget['langue']; ?>";
// Squelette d'URL du web service de l'annuaire.
widget.serviceAnnuaireIdUrl = "<?= $url_ws_annuaire; ?>";
// URL de l'icône du chargement en cours
widget.chargementIconeUrl = "<?= $url_base?>modules/saisie/squelettes/defaut/img/icones/chargement.gif";
// URL de l'icône du chargement en cours d'une image
widget.chargementImageIconeUrl = "<?= $url_base?>modules/saisie/squelettes/defaut/img/icones/chargement-image.gif";
// URL de l'icône du calendrier
widget.calendrierIconeUrl = "<?= $url_base?>modules/saisie/squelettes/defaut/img/icones/calendrier.png";
// URL de l'icône pour une photo manquante
widget.pasDePhotoIconeUrl = "<?= $url_base?>modules/saisie/squelettes/defaut/img/icones/pasdephoto.png";
 
// Code du référentiel utilisé pour les nom scientifiques.
widget.nomSciReferentiel = "<?= strtolower( $widget['referentiel'] ); ?>";
// Indication de la présence d'une espèce imposée
widget.especeImposee = "<?= $espece_imposee; ?>";
// Tableau d'informations sur l'espèce imposée
widget.infosEspeceImposee = "<?= $infos_espece; ?>";
// Nombre d'élément dans les listes d'auto-complétion
widget.autocompletionElementsNbre = 20;
// Indication de la présence d'un référentiel imposé
widget.referentielImpose = "<?= $referentiel_impose; ?>";
 
// URL du web service permettant l'auto-complétion des noms scientifiques
widget.serviceAutocompletionNomSciUrl = "<?= $widget['especes']['url_ws_autocompletion_ns']; ?>?"+
"masque={masque}&"+
"recherche=etendue&"+
"retour.champs=famille,nom_retenu,nom_retenu_complet,num_taxonomique,nom_retenu.id&"+
"ns.structure=au&"+
"navigation.limite=" + widget.autocompletionElementsNbre;
// Squelette d'URL du web service permettant l'auto-complétion des noms scientifiques
widget.serviceAutocompletionNomSciUrlTpl = "<?= $widget['especes']['url_ws_autocompletion_ns_tpl']; ?>?"+
"masque={masque}&"+
"recherche=etendue&"+
"retour.champs=famille,nom_retenu,nom_retenu_complet,num_taxonomique,nom_retenu.id&"+
"retour.tri=alpharet&"+ // tri "à la CeL"
"ns.structure=au&"+
"navigation.limite=" + widget.autocompletionElementsNbre;
// Nombre d'observations max autorisé avant transmission
widget.obsMaxNbre = 10;
// Durée d'affichage en milliseconde des messages d'informations
widget.dureeMessage = 30000;
//
//
//
// Squelette d'URL du web service d'eFlore fournissant les noms de communes.
widget.serviceNomCommuneUrl = "https://api.tela-botanica.org/service:eflore:0.1/osm/nom-commune?lon={lon}&lat={lat}";
// Squelette d'URL du web service d'eFlore fournissant les noms de communes hors de France (localisation approximative).
widget.serviceNomCommuneUrlAlt = "https://api.tela-botanica.org/service:eflore:0.1/wikipedia/nom-commune?lon={lon}&lat={lat}&nbre=1";
// URL du marqueur à utiliser dans la carte Google Map
widget.googleMapMarqueurUrl = "<?=$url_base?>modules/saisie/squelettes/defaut/img/marqueurs/epingle.png";
//
//
//
 
// Initialisation du bousin
widget.init();
});
//]]>
</script>
 
<!-- Barre de navigation -->
<?php if ( $bar ): ?>
<script src="<?= $url_script_navigation; ?>"></script>
<?php endif; ?>
</body>
</html>
</html>
/trunk/widget/modules/saisie2/squelettes/navigation.tpl.html
New file
0,0 → 1,30
<div class="navbar navbar-default" role="navigation">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#tb-navbar"
title="Afficher / masquer le menu de navigation">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="http://www.tela-botanica.org">
<img id="logo" class="logo-tb" src="<?=$url_logo?>" />
<img id="logo_hires" class="logo-tb" src="<?=$url_logo_hires?>" />
</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
 
<!--la partie tb-navigation vient du widget stats http://svn.tela-botanica.net/websvn/filedetails.php?repname=eFlore%2FApplications.cel&path=%2Ftrunk%2Fwidget%2Fmodules%2Fstats%2Fsquelettes%2Fstats_utilisateur.tpl.html
la partie contenu-souce vient de http://svn.tela-botanica.net/websvn/filedetails.php?repname=Applications.reseau&path=%2Ftrunk%2Fwidget%2Fmodules%2Fnavigation%2Fsquelettes%2Fbootstrap3.tpl.php
le javascript auth.js vient de http://svn.tela-botanica.net/websvn/filedetails.php?repname=Applications.reseau&path=%2Ftrunk%2Fresources%2Fjs%2Fnavigation.js
de l'aide dans la partie Intégration dans l'interface (applications AJAX) de https://www.tela-botanica.org/wikini/DevInformatiques/wakka.php?wiki=MemoIntegrationSSO-->
 
<div id="contenu-source">
<!-- ici le contenu du div #tb-navigation de la page appelante -->
</div>
</div>
</div>
 
 
/trunk/widget/modules/saisie2/squelettes/css/saisie.css
1,124 → 1,684
@CHARSET "UTF-8";
 
body {
font-family: Muli,sans-serif;
font-size: 0.8rem;
font-weight: 300;
font-family: Muli,sans-serif;
font-size: 0.8rem;
font-weight: 300;
}
}
 
h1, h2, h3, h4, h5 {
font-family: Muli,sans-serif;
font-family: Muli,sans-serif;
}
 
form {
font-family: Muli,sans-serif;
float: none;
font-family: Muli,sans-serif;
float: none;
}
 
h1 {
font-weight: 700;
font-weight: 700;
font-size: 2rem;
}
 
#zone-appli .form-block {
margin-bottom: 2rem;
}
 
h2 {
font-weight: 700;
line-height: 1.15;
font-weight: 700;
line-height: 1.15;
font-size: 1.5rem;
}
 
h3 {
font-size: 1.2rem;
}
 
#zone-appli .obligatoire::before {
content: '*';
position: absolute;
left: 0;
}
 
.btn.focus,
.btn:focus {
box-shadow: none;
}
 
.btn.btn-primary,
.btn.btn-info,
.btn.btn-success,
.btn.btn-danger,
.btn.btn-inverse {
color: #fff !important;
}
 
button {
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
background-color: #a2b93b;
border-bottom-color: currentcolor;
border-bottom-left-radius: 0.2rem;
border-bottom-right-radius: 0.2rem;
border-bottom-style: none;
border-bottom-width: 0;
border-image-outset: 0 0 0 0;
border-image-repeat: stretch stretch;
border-image-slice: 100% 100% 100% 100%;
border-image-source: none;
border-image-width: 1 1 1 1;
border-left-color: currentcolor;
border-left-style: none;
border-left-width: 0;
border-right-color: currentcolor;
border-right-style: none;
border-right-width: 0;
border-top-color: currentcolor;
border-top-left-radius: 0.2rem;
border-top-right-radius: 0.2rem;
border-top-style: none;
border-top-width: 0;
color: #fff;
cursor: pointer;
display: inline-block;
font-family: Ubuntu,sans-serif;
font-size: 1.3rem;
font-weight: 500;
letter-spacing: 0.1rem;
line-height: 1.5rem;
padding-bottom: 1.25rem;
padding-left: 2rem;
padding-right: 2rem;
padding-top: 1.25rem;
text-align: center;
text-decoration-color: currentcolor;
text-decoration-line: none;
text-decoration-style: solid;
text-transform: uppercase;
transition-delay: 0s;
transition-duration: 0.2s;
transition-property: background;
transition-timing-function: ease;
-moz-border-bottom-colors: none;
-moz-border-left-colors: none;
-moz-border-right-colors: none;
-moz-border-top-colors: none;
background-color: #a2b93b;
border-bottom-color: currentcolor;
border-bottom-left-radius: 0.2rem;
border-bottom-right-radius: 0.2rem;
border-bottom-style: none;
border-bottom-width: 0;
border-image-outset: 0 0 0 0;
border-image-repeat: stretch stretch;
border-image-slice: 100% 100% 100% 100%;
border-image-source: none;
border-image-width: 1 1 1 1;
border-left-color: currentcolor;
border-left-style: none;
border-left-width: 0;
border-right-color: currentcolor;
border-right-style: none;
border-right-width: 0;
border-top-color: currentcolor;
border-top-left-radius: 0.2rem;
border-top-right-radius: 0.2rem;
border-top-style: none;
border-top-width: 0;
color: #fff;
cursor: pointer;
display: inline-block;
font-family: Ubuntu,sans-serif;
font-size: 1.3rem;
font-weight: 500;
letter-spacing: 0.1rem;
line-height: 1.5rem;
padding-bottom: 1.25rem;
padding-left: 2rem;
padding-right: 2rem;
padding-top: 1.25rem;
text-align: center;
text-decoration-color: currentcolor;
text-decoration-line: none;
text-decoration-style: solid;
text-transform: uppercase;
transition-delay: 0s;
transition-duration: 0.2s;
transition-property: background;
transition-timing-function: ease;
}
 
label {
color: #606060;
display: block;
font-size: 0.9rem;
font-weight: 700;
.mb2,
.mb-3 {
align-self: start;
}
 
label,
#zone-appli .list-label {
color: #606060;
display: block;
font-size: 0.9rem;
font-weight: 700;
}
 
#zone-appli .form-inline label,
#zone-appli .form-inline .list-label {
align-items: start;
align-self: start;
justify-content: left;
align-content: flex-start;
}
 
h1#widget-titre::before {
content: "";
display: block;
height: 100%;
left: -5rem;
position: absolute;
width: 0.4rem;
content: "";
display: block;
height: 100%;
left: -5rem;
position: absolute;
width: 0.4rem;
}
 
h1#widget-titre {
font-size: 2.6rem;
font-weight: 700;
line-height: 3.2rem;
margin-bottom: 0;
margin-left: 0;
margin-right: 0;
margin-top: 0;
position: relative;
color: #232323;
font-family: Ubuntu,sans-serif;
font-size: 2.6rem;
font-weight: 700;
line-height: 3.2rem;
margin-bottom: 0;
margin-left: 0;
margin-right: 0;
margin-top: 0;
position: relative;
color: #232323;
font-family: Ubuntu,sans-serif;
}
 
.droite {
background-color: #f8f5ef;
color: #232323;
float: right;
padding-bottom: 1rem;
padding-left: 1rem;
padding-right: 1rem;
padding-top: 1rem;
width: 48%;
#zone-appli .hidden {
display: none !important;
}
 
.clear {
#zone-appli .warning {
color: #ff5d55;
font-weight: 700;
}
 
.control-group.error input,
.control-group.error select,
.control-group.error textarea {
box-shadow: 0 0 1.5px 1px red;
border-color: #b94a48;
color: #b94a48;
}
 
.control-group.error {
color: #b94a48;
}
 
#zone-appli .centre {
margin: 0 auto !important;
justify-content: center !important;
}
 
#zone-appli .droite {
float: right;
}
 
#zone-appli .info {
padding: 1rem;
background-color: #ccecf1;
border-color: #7ccedb;
color: #006979;
fill: #006979;
border-radius: 0.2rem;
}
 
#zone-appli .clear {
clear: both;
height: 0; overflow: hidden; /* Précaution pour IE 7 */
}
 
.ui-widget{
font-family: Muli,sans-serif;
}
#zone-appli .ui-widget{
font-family: Muli,sans-serif;
}
 
#zone-appli .form-inline .form-control {
width: 100%;
}
 
#zone-appli #logo_hires {
display: none;
}
#zone-appli .logo-tb {
position:absolute;
left: 10px;
top: 10px;
}
 
#zone-appli .bloc-top {
border-top: 1px solid rgba(0,0,0,.1);
padding-top: 1rem;
}
 
#zone-appli .bloc-bottom {
border-bottom: 1px solid rgba(0,0,0,.1);
padding-bottom: 1rem;
}
 
.unstyled {
list-style-type: none;
}
 
#zone-appli #formulaire form {
margin-bottom: 1.5rem;
}
 
input[type="checkbox"],
input[type="radio"],
input.radio,
input.checkbox {
vertical-align:text-top;
padding: 0;
margin-right: 10px;
position:relative;
overflow:hidden;
top:2px;
}
 
#zone-appli #formulaire #form-supp #zone-supp .checkbox label,
#zone-appli #formulaire #form-supp #zone-supp .checkboxes label,
#zone-appli #formulaire #form-supp #zone-supp .radio label {
align-items: center;
display: flex;
font-weight: 400;
}
 
 
/*************************************************************************/
 
 
form#form-observateur,
form#form-observation,
form#form-supp,
#tb-navigation,
#tb-navbar{
min-width: 100%;
margin-left: 0;
margin-right: 0;
}
 
.navbar-nav,
.nav {
display: -ms-flexbox;
display: flex;
-ms-flex-wrap: wrap;
flex-wrap: wrap;
margin-right: -15px;
margin-left: -15px;
flex-direction: row;
}
 
.navbar.navbar-default {
margin-bottom: 0;
}
 
.open > a {
outline: 0;
}
 
.dropdown {
height: 5rem;
}
 
#anonyme {
height: auto;
}
 
#zone-courriel-confirmation {
 
}
 
#bouton-connexion,
#creation-compte {
display: -ms-flexbox;
display: flex;
height: 5rem;
-webkit-box-flex: 1;
-webkit-flex: 0 0 50%;
-ms-flex: 0 0 50%;
flex: 0 0 50%;
max-width: 50%;
-ms-flex-flow: row wrap;
flex-flow: row wrap;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
justify-content: left;
align-items: flex-start;
align-content: flex-middle;
}
 
#bouton-connexion label,
#creation-compte label {
width: 100%;
}
 
.navbar-default .navbar-nav > .dropdown #bouton-anonyme,
.navbar-default .navbar-nav > .dropdown #bouton-inscription {
width: auto;
}
 
.navbar-default .navbar-nav > .dropdown > a {
/* width: auto;
position: relative;*/
/* border: 1px solid #ccc;
border: 1px solid rgba(0,0,0,.15);*/
margin-left: 0.2rem;
}
 
.navbar-default .navbar-nav #bouton-connexion a{
color: #fff;
background-color: #b2cb43;
border-color: #a1b92e;;
}
 
.navbar-default .navbar-nav #bouton-connexion a:focus,
.navbar-default .navbar-nav #bouton-connexion a:hover {
background-color: #a2b93b;
border-color: #9ab227;
}
 
.navbar-default .navbar-nav #utilisateur-connecte.dropdown {
padding-left: 2rem;
}
 
.navbar-default .navbar-nav #utilisateur-connecte.dropdown > a {
margin-left: 0;
}
 
.navbar-default .navbar-nav #utilisateur-connecte.dropdown.open .dropdown-menu a {
font-size: 0.8rem;
font-weight: 400;
color: #606060;
background: inherit;
text-decoration: none;
display: block;
width: 100%;
padding-left: 5px;
line-height: 25px;
}
 
.navbar-default .navbar-nav #utilisateur-connecte.dropdown.open .dropdown-menu a:hover,
.navbar-default .navbar-nav #utilisateur-connecte.dropdown.open .dropdown-menu a:focus {
background: #1e90ff;
color: #fff;
}
 
/*.navbar-default .navbar-nav .dropdown .dropdown-toggle::after {
display: none;
}
*/
/*.navbar-default .navbar-nav > #utilisateur-connecte.open > a:focus,
.navbar-default .navbar-nav > .dropdown#utilisateur-connecte > a:hover {
border-right: 3px solid #92ad27;
}*/
 
.navbar-right .dropdown-menu {
/* left: auto;
right: 0;*/
}
.navbar-nav .open > .dropdown-menu {
display: inline-block;
}
.navbar-nav .dropdown-menu {
position: absolute;
left: 0;
right: 0;
top: 100%;
z-index: 1000;
min-width: auto;
margin-top: -10px;
margin-left: 1.9rem;
list-style: none;
background-color: #fff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
background-clip: padding-box;
}
 
.dropdown-menu div a {
color: #222;
}
 
/*************************************************************************/
 
#zone-appli #formulaire #form-supp #zone-supp .multiselect.list-checkbox {
padding: 0;
margin: 0;
}
 
#zone-appli #formulaire #form-supp #zone-supp select,
#zone-appli #formulaire #form-supp #zone-supp .selectBox select {
background-color: #fff;
border: 1px solid #ced4da;
}
 
#form-supp select,
#form-supp .selectBox select{
border-radius: 0.3rem;
}
 
/*#form-supp select,
#form-supp select:required {
text-transform:none;
/* On retire la 'flèche' par defaut */
/*-webkit-appearance: none;
-moz-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}*/
 
/*#form-supp .select-wrapper::after,
#zone-appli #formulaire #form-supp #zone-supp .selectBox::after,
#zone-appli #formulaire #form-supp #zone-supp .select-wrapper::after {*/
/* Ajout et style d'une "flèche bas" */
/*content: '⌄';
pointer-events: none;
position: absolute;
right: 0.5rem;
top:-10px;
font-size: 2rem;
font-weight: 300;
}*/
 
#form-supp .select-wrapper,
#zone-appli #formulaire #form-supp #zone-supp .selectBox {
position: relative;
z-index: 1000;
border-radius: 0.3rem;
}
 
#zone-appli #formulaire #form-supp #zone-supp .selectBox .focus {
border-color: #80bdff;
box-shadow: 0 0 0 .2rem rgba(0,123,255,.25);
}
 
#zone-appli #formulaire #form-supp #zone-supp .input-group .select-wrapper {
border:none;
}
 
#zone-appli #formulaire #form-supp #zone-supp .overSelect {
position: absolute;
z-index: 999;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
 
#zone-appli #formulaire #form-supp #zone-supp .checkboxes {
position: absolute;
z-index: 998;
left: 1rem;
right: 1rem;
background-color: #fff;
border: 1px solid #ced4da;
border-radius: 0 0 0.3rem 0.3rem;
margin-top: -0.3rem;
}
 
#zone-appli #formulaire #form-supp #zone-supp .label label,
#zone-appli #formulaire #form-supp #zone-supp .checkboxes label {
display: block;
padding: 0.5rem;
font-weight: 400;
margin:0;
}
 
#zone-appli #formulaire #form-supp #zone-supp .checkboxes label:hover {
background: #1e90ff;
color: #fff;
}
 
#zone-appli #formulaire #form-supp #zone-supp .selectBox select option {
padding-block-start: 0;
padding-block-end: 0;
padding-inline-start: 0;
padding-inline-end: 0;
}
 
#zone-appli #formulaire #form-supp #zone-supp .collect-other {
margin: 0.5rem;
}
 
/*************************************************************************/
 
/*******************************************/
 
.label-file {
overflow: hidden;
position: relative;
cursor: pointer;
border-radius: 0.25rem;
font-weight: 400;
font-size: 0.9rem;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
border: 1px solid transparent;
padding: .375rem .75rem;
line-height: 1.5;
transition:
color .15s ease-in-out,
background-color .15s ease-in-out,
border-color .15s ease-in-out,
box-shadow .15s ease-in-out;
margin: 0;
}
 
.label-file [type=file] {
cursor: inherit;
display: block;
font-size: 999px;
filter: alpha(opacity=0);
min-height: 100%;
min-width: 100%;
opacity: 0;
position: absolute;
right: 0;
text-align: right;
top: 0;
}
 
.label-file [type=file] {
cursor: pointer;
}
 
/*************************************/
 
/*#miniatures {
display: flex;
flex-flow: row wrap;
justify-content: flex-start;
align-content:flex-end;
}*/
 
#miniatures .miniature {
position: relative;
display: inline-block;
 
}
 
#miniatures .miniature .miniature-img {
vertical-align: top;
width: 10rem;
height: 100%;
}
 
#miniatures .miniature .effacer-miniature {
display: flex;
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
font-size: 2rem;
background-color: rgba(0, 0, 0, 0.3);
opacity: 0;
color: #fff;
padding: 0;
margin: 0;
height: 100%;
width: 100%;
align-items:center;
justify-content: center;
cursor: pointer;
}
 
#miniatures .miniature .effacer-miniature:hover,
#miniatures .miniature .effacer-miniature:focus {
opacity: 1;
}
 
.obs {
height: 10rem;
padding: 1rem;
border-radius: 0.25rem;
background-color: #fbfbfb;
border: 1px solid #eee;
}
 
.obs .nom-sci {
font-size: 1rem;
}
 
.defilement-miniatures .defilement-miniatures-cache,
.defilement-miniatures .miniature-cachee {
display: none;
}
 
.defilement-miniatures {
display: flex;
align-items:center;
justify-content: center;
height: 8rem;
}
.defilement-miniatures figure {
display: inline-block;
min-height: 8rem;
line-height: 8rem;
text-align: center;
min-width: 80%;
width: 80%;
margin:0 auto;
padding: 0;
}
 
.miniature-selectionnee {
vertical-align: middle;
max-height: 8rem;
max-width: 80%;
}
 
.defilement-miniatures-gauche,
.defilement-miniatures-droite {
display: inline-block;
color: #5bc0de;
vertical-align: middle;
outline-style: none;
}
 
.defilement-miniatures-gauche:active,
.defilement-miniatures-droite:active,
.defilement-miniatures-gauche:focus,
.defilement-miniatures-droite:focus {
color: #499fb7;
}
 
.defilement-miniatures-gauche:hover,
.defilement-miniatures-droite:hover {
color: #499fb7;
}
 
 
#transmettre-obs{
text-align: right;
}
 
#zone-liste-obs h2.transmission-title {
display: inline-block;
}
 
footer a {
display: inline-block;
}
 
/*************************************/
 
@media screen and ( max-width: 765px ) {
#bouton-connexion, #creation-compte {
display: block;
width: 100%;
}
}