date_utils.js : support formulaire HTML

This commit is contained in:
Iziram 2023-11-10 15:25:25 +01:00
parent 8957264dc6
commit 48d89ac278
1 changed files with 66 additions and 12 deletions

View File

@ -323,45 +323,94 @@ class Duration {
class ScoDocDateTimePicker extends HTMLElement {
constructor() {
super();
// Initialisation du shadow DOM pour l'encapsulation du style et du comportement.
// Définir si le champ est requis
this.required = this.hasAttribute("required");
// Initialiser le shadow DOM
const shadow = this.attachShadow({ mode: "open" });
// Création de l'input pour la date.
// Créer l'input pour la date
const dateInput = document.createElement("input");
dateInput.type = "date";
dateInput.id = "date";
// Création de l'input pour l'heure.
// Créer l'input pour l'heure
const timeInput = document.createElement("input");
timeInput.type = "time";
timeInput.id = "time";
// Ajout des inputs date et heure dans le shadow DOM.
// Ajouter les inputs dans le shadow DOM
shadow.appendChild(dateInput);
shadow.appendChild(timeInput);
// Ajout de gestionnaires d'événements pour mettre à jour la valeur lorsque les inputs changent.
// Gestionnaires d'événements pour la mise à jour de la valeur
dateInput.addEventListener("change", () => this.updateValue());
timeInput.addEventListener("change", () => this.updateValue());
// Style CSS pour les inputs, ici pour les afficher côte à côte.
// Style CSS pour les inputs
const style = document.createElement("style");
style.textContent = `
input {
input {
display: inline-block;
}
}
input:invalid {
border: 1px solid red;
}
`;
// Ajout du style dans le shadow DOM.
// Ajouter le style au shadow DOM
shadow.appendChild(style);
}
// Méthode pour mettre à jour la valeur interne basée sur les inputs de date et d'heure.
connectedCallback() {
// Récupérer l'attribut 'name'
this.name = this.getAttribute("name");
// Créer un input caché pour la valeur datetime
this.hiddenInput = document.createElement("input");
this.hiddenInput.type = "hidden";
this.hiddenInput.name = this.name;
this.appendChild(this.hiddenInput);
// Gérer la soumission du formulaire
this.closest("form")?.addEventListener("submit", (e) => {
if (!this.validate()) {
e.preventDefault(); // Empêcher la soumission si non valide
this.dispatchEvent(
new Event("invalid", { bubbles: true, cancelable: true })
);
} else {
// Mettre à jour la valeur de l'input caché avant la soumission
this.hiddenInput.value = this.isValid()
? this.valueAsDate.toIsoUtcString()
: "";
}
});
}
// Vérifier si la valeur forme une date valide
isValid() {
return !Number.isNaN(this.valueAsDate.getTime());
}
// Valider l'élément
validate() {
if (this.required && !this.isValid()) {
return false;
}
return true;
}
// Mettre à jour la valeur interne
updateValue() {
const dateInput = this.shadowRoot.querySelector("#date");
const timeInput = this.shadowRoot.querySelector("#time");
// Formatage de la valeur en format datetime ISO (YYYY-MM-DDTHH:MM).
this._value = `${dateInput.value}T${timeInput.value}`;
this.dispatchEvent(new Event("change", { bubbles: true }));
// Appliquer le style 'invalid' si nécessaire
dateInput.classList.toggle("invalid", this.required && !this.isValid());
timeInput.classList.toggle("invalid", this.required && !this.isValid());
}
// Getter pour obtenir la valeur actuelle.
@ -371,8 +420,13 @@ class ScoDocDateTimePicker extends HTMLElement {
// Setter pour définir la valeur. Sépare la valeur en date et heure et les définit individuellement.
set value(val) {
const [date, time] = val.split("T");
let [date, time] = val.split("T");
this.shadowRoot.querySelector("#date").value = date;
if ((time.match(/0/g) || []).length > 1) {
time = time.slice(0, time.indexOf(":") + 3);
}
this.shadowRoot.querySelector("#time").value = time;
this._value = val;
}