diff --git a/CHANGES.md b/CHANGES.md index 5a697598..d0ce6fdf 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,7 @@ - Corrections syntaxiques. - Rotation des fichiers journaux (plus de 4 mo et 5 archives compressées). - Nouvelle propriété *required* pour les template de saisie de texte obligatoire. Génération d'un repère sur le label du champ et interception du champ invalide par le navigateur qui affiche une popup. +- Nouvelle méthode de template *number()* pour créer un champ de saisie acceptant les propriétés min, max, step et pattern. **Corrections :** - Lors de l'ajout d'un nouvel utilisateur, en cas d'erreur de saisie et de validation du formulaire, le mail de confirmation n'est pas expédié. diff --git a/core/class/router.class.php b/core/class/router.class.php index 40a0cc45..a91661c0 100644 --- a/core/class/router.class.php +++ b/core/class/router.class.php @@ -140,7 +140,7 @@ class core extends common $css .= 'span.mce-text{background-color: unset !important;}'; $css .= 'body,.row > div{font-size:' . $this->getData(['theme', 'text', 'fontSize']) . '}'; $css .= 'body{color:' . $this->getData(['theme', 'text', 'textColor']) . '}'; - $css .= 'select,input[type=password],input[type=email],input[type=text],input[type=date],input[type=time],input[type=week],input[type=month],input[type=datetime-local],.inputFile,select,textarea{color:' . $this->getData(['theme', 'text', 'textColor']) . ';background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';}'; + $css .= 'select,input[type=password],input[type=email],input[type=text],input[type=date],input[type=time],input[type=week],input[type=month],input[type=datetime-local],input[type=number],.inputFile,select,textarea{color:' . $this->getData(['theme', 'text', 'textColor']) . ';background-color:' . $this->getData(['theme', 'site', 'backgroundColor']) . ';}'; // spécifiques au module de blog $css .= '.blogDate {color:' . $this->getData(['theme', 'text', 'textColor']) . ';}.blogPicture img{border:1px solid ' . $this->getData(['theme', 'text', 'textColor']) . '; box-shadow: 1px 1px 5px ' . $this->getData(['theme', 'text', 'textColor']) . ';}'; // Couleur fixée dans admin.css @@ -168,7 +168,7 @@ class core extends common $colors = helper::colorVariants($this->getData(['theme', 'button', 'backgroundColor'])); $css .= '.speechBubble,.button,.button:hover,button[type=submit],.pagination a,.pagination a:hover,input[type=checkbox]:checked + label:before,input[type=radio]:checked + label:before,.helpContent{background-color:' . $colors['normal'] . ';color:' . $colors['text'] . '}'; $css .= '.helpButton span{color:' . $colors['normal'] . '}'; - $css .= 'input[type=text]:hover,input[type=date]:hover,input[type=time]:hover,input[type=week]:hover,input[type=month]:hover,input[type=datetime-local]:hover,input[type=password]:hover,.inputFile:hover,select:hover,textarea:hover{border-color:' . $colors['normal'] . '}'; + $css .= 'input[type=text]:hover,input[type=date]:hover,input[type=time]:hover,input[type=week]:hover,input[type=month]:hover,input[type=datetime-local]:hover,input[type=number]:hover,input[type=password]:hover,.inputFile:hover,select:hover,textarea:hover{border-color:' . $colors['normal'] . '}'; $css .= '.speechBubble:before{border-color:' . $colors['normal'] . ' transparent transparent transparent}'; $css .= '.button:hover,button[type=submit]:hover,.pagination a:hover,input[type=checkbox]:not(:active):checked:hover + label:before,input[type=checkbox]:active + label:before,input[type=radio]:checked:hover + label:before,input[type=radio]:not(:checked):active + label:before{background-color:' . $colors['darken'] . '}'; $css .= '.helpButton span:hover{color:' . $colors['darken'] . '}'; @@ -361,7 +361,7 @@ class core extends common $css .= '.button.buttonGreen, button[type=submit] {background-color: ' . $colors['normal'] . ';color: ' . $colors['text'] . ';}.button.buttonGreen:hover, button[type=submit]:hover {background-color: ' . $colors['darken'] . ';color: ' . $colors['text'] . ';}.button.buttonGreen:active, button[type=submit]:active {background-color: ' . $colors['darken'] . ';color: ' . $colors['text'] . ';}'; $colors = helper::colorVariants($this->getData(['admin', 'backgroundBlockColor'])); $css .= '.buttonTab, .block {border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . ';}.buttonTab, .block h4 {background-color: ' . $colors['normal'] . ';color:' . $colors['text'] . ';}'; - $css .= 'table tr,input[type=email],input[type=date],input[type=time],input[type=month],input[type=week],input[type=datetime-local],input[type=text],input[type=password],select:not(#barSelectLanguage),select:not(#barSelectPage),textarea:not(.editorWysiwyg), textarea:not(.editorWysiwygComment),.inputFile{background-color: ' . $colors['normal'] . ';color:' . $colors['text'] . ';border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . ';}'; + $css .= 'table tr,input[type=email],input[type=date],input[type=time],input[type=month],input[type=week],input[type=datetime-local],input[type=text],input[type=number],input[type=password],select:not(#barSelectLanguage),select:not(#barSelectPage),textarea:not(.editorWysiwyg), textarea:not(.editorWysiwygComment),.inputFile{background-color: ' . $colors['normal'] . ';color:' . $colors['text'] . ';border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . ';}'; // Bordure du contour TinyMCE $css .= '.mce-tinymce{border: 1px solid ' . $this->getData(['admin', 'borderBlockColor']) . '!important;}'; // Enregistre la personnalisation diff --git a/core/class/template.class.php b/core/class/template.class.php index 5384d693..7a5d2a36 100644 --- a/core/class/template.class.php +++ b/core/class/template.class.php @@ -992,6 +992,106 @@ class template return $html; } + /** + * Génère un champ de saisie de type number (input[type="number"]) + * + * Cette méthode crée un champ numérique HTML complet avec son wrapper, + * son label et ses messages d'aide/erreur. Elle gère automatiquement + * la conversion des valeurs en nombres et les contraintes de validation. + * + * @param string $nameId Identifiant unique du champ, utilisé pour name et id + * @param array $attributes Tableau des attributs du champ avec les clés suivantes : + * @type boolean $before Active la récupération des données précédentes en cas d'erreur (défaut: true) + * @type string $class Classes CSS additionnelles pour l'input (défaut: '') + * @type string $classWrapper Classes CSS additionnelles pour le wrapper (défaut: '') + * @type boolean $noDirty Désactive le marquage dirty du champ (défaut: false) + * @type boolean $disabled Désactive le champ (défaut: false) + * @type string $help Texte d'aide affiché sous le label (défaut: '') + * @type string $label Texte du label (défaut: '') + * @type string $placeholder Texte de placeholder (défaut: '') + * @type boolean $readonly Rend le champ en lecture seule (défaut: false) + * @type mixed $value Valeur initiale du champ (défaut: '') + * @type number $min Valeur minimum autorisée (défaut: null) + * @type number $max Valeur maximum autorisée (défaut: null) + * @type number $step Pas d'incrémentation (ex: 1 pour entiers, 0.01 pour prix) (défaut: null) + * @type string $pattern Expression régulière de validation (défaut: null) + * + * @return string Code HTML du champ number complet + */ + public static function number($nameId, array $attributes = []) + { + // Attributs par défaut spécifiques aux champs numériques + $attributes = array_merge([ + 'type' => 'number', + 'before' => true, + 'class' => '', + 'classWrapper' => '', + 'noDirty' => false, + 'disabled' => false, + 'help' => '', + 'id' => $nameId, + 'label' => '', + 'name' => $nameId, + 'placeholder' => '', + 'readonly' => false, + 'value' => '', + 'min' => null, + 'max' => null, + 'step' => null, + 'pattern' => null + ], $attributes); + + // Conversion de la valeur en nombre si elle n'est pas vide + if ($attributes['value'] !== '') { + $attributes['value'] = floatval($attributes['value']); + } + + // Nettoyage des attributs null pour ne pas les afficher dans le HTML + foreach (['min', 'max', 'step', 'pattern'] as $attr) { + if ($attributes[$attr] === null) { + unset($attributes[$attr]); + } + } + + // Traduction de l'aide et de l'étiquette + $attributes['label'] = helper::translate($attributes['label']); + $attributes['help'] = helper::translate($attributes['help']); + + // Sauvegarde des données en cas d'erreur + if ($attributes['before'] && array_key_exists($attributes['id'], common::$inputBefore)) { + $attributes['value'] = common::$inputBefore[$attributes['id']]; + } + + // Début du wrapper + $html = '
'; + + // Label + if ($attributes['label']) { + $html .= self::label($attributes['id'], $attributes['label'], [ + 'help' => $attributes['help'] + ]); + } + + // Notice + $notice = ''; + if (array_key_exists($attributes['id'], common::$inputNotices)) { + $notice = common::$inputNotices[$attributes['id']]; + $attributes['class'] .= ' notice'; + } + $html .= self::notice($attributes['id'], $notice); + + // Input number + $html .= sprintf( + '', + helper::sprintAttributes($attributes) + ); + + // Fin du wrapper + $html .= '
'; + + return $html; + } + /** * Crée un champ texte long * @param string $nameId Nom et id du champ diff --git a/core/layout/common.css b/core/layout/common.css index 20571f37..220d5d2a 100755 --- a/core/layout/common.css +++ b/core/layout/common.css @@ -1180,6 +1180,7 @@ input[type='datetime-local'], input[type='time'], input[type='month'], input[type='week'], +input[type='number'], .inputFile, select, textarea { @@ -1205,6 +1206,7 @@ input[type='datetime-local']:hover, input[type='time']:hover, input[type='month']:hover, input[type='week']:hover, +input[type='number']:hover, .inputFile:hover, select:hover, textarea:hover { @@ -1219,6 +1221,7 @@ input[type='datetime-local'].notice, input[type='time'].notice, input[type='month'].notice, input[type='week'].notice, +input[type='number'].notice, .inputFile.notice, select.notice, textarea.notice { @@ -1234,6 +1237,7 @@ input[type='datetime-local'].notice:hover, input[type='time'].notice:hover, input[type='month'].notice:hover, input[type='week'].notice:hover, +input[type='number'].notice:hover, .inputFile.notice:hover, select.notice:hover, textarea.notice:hover { diff --git a/core/module/config/view/network/network.php b/core/module/config/view/network/network.php index aa4077dc..9925d76d 100644 --- a/core/module/config/view/network/network.php +++ b/core/module/config/view/network/network.php @@ -20,10 +20,10 @@ ]); ?>
- 'Port du proxy', 'placeholder' => '6060', - 'value' => $this->getData(['config', 'proxyPort']) + 'value' => $this->getData(['config', 'proxyPort']), ]); ?>