forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -323,45 +323,94 @@ class Duration {
|
|||||||
class ScoDocDateTimePicker extends HTMLElement {
|
class ScoDocDateTimePicker extends HTMLElement {
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
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" });
|
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");
|
const dateInput = document.createElement("input");
|
||||||
dateInput.type = "date";
|
dateInput.type = "date";
|
||||||
dateInput.id = "date";
|
dateInput.id = "date";
|
||||||
|
|
||||||
// Création de l'input pour l'heure.
|
// Créer l'input pour l'heure
|
||||||
const timeInput = document.createElement("input");
|
const timeInput = document.createElement("input");
|
||||||
timeInput.type = "time";
|
timeInput.type = "time";
|
||||||
timeInput.id = "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(dateInput);
|
||||||
shadow.appendChild(timeInput);
|
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());
|
dateInput.addEventListener("change", () => this.updateValue());
|
||||||
timeInput.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");
|
const style = document.createElement("style");
|
||||||
style.textContent = `
|
style.textContent = `
|
||||||
input {
|
input {
|
||||||
display: inline-block;
|
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);
|
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() {
|
updateValue() {
|
||||||
const dateInput = this.shadowRoot.querySelector("#date");
|
const dateInput = this.shadowRoot.querySelector("#date");
|
||||||
const timeInput = this.shadowRoot.querySelector("#time");
|
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._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.
|
// 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.
|
// Setter pour définir la valeur. Sépare la valeur en date et heure et les définit individuellement.
|
||||||
set value(val) {
|
set value(val) {
|
||||||
const [date, time] = val.split("T");
|
let [date, time] = val.split("T");
|
||||||
this.shadowRoot.querySelector("#date").value = date;
|
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.shadowRoot.querySelector("#time").value = time;
|
||||||
this._value = val;
|
this._value = val;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user