forked from ScoDoc/ScoDoc
Update opolka/ScoDoc from ScoDoc/ScoDoc #2
@ -407,196 +407,17 @@ class Duration {
|
||||
}
|
||||
}
|
||||
|
||||
class ScoDocDateTimePicker extends HTMLElement {
|
||||
constructor() {
|
||||
super();
|
||||
// Définir si le champ est requis
|
||||
this.required = this.hasAttribute("required");
|
||||
|
||||
// Initialiser le shadow DOM
|
||||
const shadow = this.attachShadow({ mode: "open" });
|
||||
|
||||
// Créer l'input pour la date
|
||||
const dateInput = document.createElement("input");
|
||||
dateInput.type = "date";
|
||||
dateInput.id = "date";
|
||||
|
||||
// Créer l'input pour l'heure
|
||||
const timeInput = document.createElement("input");
|
||||
timeInput.type = "time";
|
||||
timeInput.id = "time";
|
||||
timeInput.step = 60;
|
||||
|
||||
// Ajouter les inputs dans le shadow DOM
|
||||
shadow.appendChild(dateInput);
|
||||
shadow.appendChild(timeInput);
|
||||
|
||||
// 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
|
||||
const style = document.createElement("style");
|
||||
style.textContent = `
|
||||
input {
|
||||
display: inline-block;
|
||||
}
|
||||
input:invalid {
|
||||
border: 1px solid red;
|
||||
}
|
||||
`;
|
||||
|
||||
// Ajouter le style au shadow DOM
|
||||
shadow.appendChild(style);
|
||||
|
||||
//Si une value est donnée
|
||||
|
||||
let value = this.getAttribute("value");
|
||||
if (value != null) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
static get observedAttributes() {
|
||||
return ["show"]; // Ajoute 'show' à la liste des attributs observés
|
||||
}
|
||||
|
||||
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.toFakeIso()
|
||||
: "";
|
||||
}
|
||||
});
|
||||
this.updateDisplay();
|
||||
}
|
||||
|
||||
attributeChangedCallback(name, oldValue, newValue) {
|
||||
if (name === "show") {
|
||||
this.updateDisplay(); // Met à jour l'affichage si l'attribut 'show' change
|
||||
}
|
||||
}
|
||||
|
||||
updateDisplay() {
|
||||
const mode = this.getAttribute("show") || "both";
|
||||
const dateInput = this.shadowRoot.querySelector("#date");
|
||||
const timeInput = this.shadowRoot.querySelector("#time");
|
||||
|
||||
switch (mode) {
|
||||
case "date":
|
||||
dateInput.style.display = "inline-block";
|
||||
timeInput.style.display = "none";
|
||||
break;
|
||||
case "time":
|
||||
dateInput.style.display = "none";
|
||||
timeInput.style.display = "inline-block";
|
||||
break;
|
||||
case "both":
|
||||
default:
|
||||
dateInput.style.display = "inline-block";
|
||||
timeInput.style.display = "inline-block";
|
||||
}
|
||||
}
|
||||
|
||||
// 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");
|
||||
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.
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
get valueAsObject() {
|
||||
const dateInput = this.shadowRoot.querySelector("#date");
|
||||
const timeInput = this.shadowRoot.querySelector("#time");
|
||||
return {
|
||||
date: dateInput.value,
|
||||
time: timeInput.value,
|
||||
};
|
||||
}
|
||||
|
||||
// Getter pour obtenir la valeur en tant qu'objet Date.
|
||||
get valueAsDate() {
|
||||
return new Date(this._value);
|
||||
}
|
||||
|
||||
// Setter pour définir la valeur. Sépare la valeur en date et heure et les définit individuellement.
|
||||
set value(val) {
|
||||
let [date, time] = val.split("T");
|
||||
this.shadowRoot.querySelector("#date").value = date;
|
||||
|
||||
time = time.substring(0, 5);
|
||||
|
||||
this.shadowRoot.querySelector("#time").value = time;
|
||||
this._value = val;
|
||||
}
|
||||
|
||||
// Setter pour définir la valeur à partir d'un objet avec les propriétés 'date' et 'time'.
|
||||
set valueAsObject(obj) {
|
||||
const dateInput = this.shadowRoot.querySelector("#date");
|
||||
const timeInput = this.shadowRoot.querySelector("#time");
|
||||
|
||||
if (obj.hasOwnProperty("date")) {
|
||||
dateInput.value = obj.date || ""; // Définit la valeur de l'input de date si elle est fournie
|
||||
}
|
||||
|
||||
if (obj.hasOwnProperty("time")) {
|
||||
timeInput.value = obj.time.substring(0, 5) || ""; // Définit la valeur de l'input d'heure si elle est fournie
|
||||
}
|
||||
|
||||
// Met à jour la valeur interne en fonction des nouvelles valeurs des inputs
|
||||
this.updateValue();
|
||||
}
|
||||
|
||||
// Setter pour définir la valeur à partir d'un objet Date.
|
||||
set valueAsDate(dateVal) {
|
||||
// Formatage de l'objet Date en string et mise à jour de la valeur.
|
||||
this.value = `${dateVal.getFullYear()}-${String(
|
||||
dateVal.getMonth() + 1
|
||||
).padStart(2, "0")}-${String(dateVal.getDate()).padStart(2, "0")}T${String(
|
||||
dateVal.getHours()
|
||||
).padStart(2, "0")}:${String(dateVal.getMinutes()).padStart(2, "0")}`;
|
||||
}
|
||||
/**
|
||||
* Fonction qui vérifie si une période est dans un interval
|
||||
* Objet période / interval
|
||||
* {
|
||||
* deb: Date,
|
||||
* fin: Date,
|
||||
* }
|
||||
* @param {object} period
|
||||
* @param {object} interval
|
||||
* @returns {boolean} Vrai si la période est dans l'interval
|
||||
*/
|
||||
function hasTimeConflict(period, interval) {
|
||||
return period.deb.isBefore(interval.fin) && period.fin.isAfter(interval.deb);
|
||||
}
|
||||
|
||||
// Définition du nouvel élément personnalisé 'scodoc-datetime'.
|
||||
customElements.define("scodoc-datetime", ScoDocDateTimePicker);
|
||||
|
Loading…
Reference in New Issue
Block a user