enhance check steps and UI impact

* Update settings validity check and modal order to avoid seeing transition color between valid / invalid input + better focus timer on modal open
* Fix invalid message not visible on modal open and focus on invalid input
This commit is contained in:
Jordan Blasenhauer 2024-04-24 11:12:21 +02:00
parent 22a53ac39f
commit 6a4e137771
4 changed files with 54 additions and 28 deletions

File diff suppressed because one or more lines are too long

View file

@ -761,10 +761,16 @@ class ServiceModal {
const errMsg = form.querySelector("[data-services-modal-error-msg]");
if (!isAllValid) {
invalidInp.classList.add("invalid");
const invalidEl = invalidInp
.closest("form")
.querySelector(`[data-invalid=${invalidInp.getAttribute("id")}]`);
invalidEl.classList.remove("hidden", "md:hidden");
// Wait a little that modal is fully open to focus on invalid input, because not working when element is hidden
setTimeout(() => {
invalidInp.focus();
}, 30);
errMsg.textContent = `${invalidInpName} must be valid to submit`;
errMsg.classList.remove("hidden");
formMode == "simple"
@ -934,9 +940,10 @@ class ServiceModal {
document.querySelector("button[data-tab-select-handler]").click();
} catch (e) {}
this.checkVisibleInpsValidity();
//show modal el
this.modal.classList.add("flex");
this.modal.classList.remove("hidden");
setTimeout(() => {
this.modal.classList.add("flex");
this.modal.classList.remove("hidden");
}, 20);
}
}

View file

@ -515,9 +515,7 @@ class FilterSettings {
multSetting.classList.add("hidden");
multSettingHiddenCount++;
}
} catch (err) {
console.log(err);
}
} catch (err) {}
});
// check for each multiple groups if all are hidden
@ -923,43 +921,64 @@ class CheckNoMatchFilter {
class showInvalid {
constructor() {
this.init();
this.isChecking = false;
}
init() {
window.addEventListener("change", (e) => {
if (this.isChecking) return;
this.setInvalidState(e);
});
window.addEventListener("input", (e) => {
if (this.isChecking) return;
this.setInvalidState(e);
});
window.addEventListener("click", (e) => {
if (this.isChecking) return;
this.setInvalidState(e);
});
window.addEventListener("focusin", (e) => {
if (this.isChecking) return;
this.setInvalidState(e);
});
}
setInvalidState(e) {
this.isChecking = true;
try {
if (e.target.hasAttribute("data-setting-input")) {
const settingName = e.target.getAttribute("id");
const invalidEl = document.querySelector(
`[data-invalid=${settingName}]`,
);
const isValid = e.target.validity.valid;
setTimeout(() => {
const elsToCheck = [
e.target,
...document.querySelectorAll("input.invalid"),
];
elsToCheck.forEach((el) => {
if (el.hasAttribute("data-setting-input")) {
const settingName = el.getAttribute("id");
const invalidEl = el
.closest("form")
.querySelector(`[data-invalid=${settingName}]`);
const isValid = el.validity.valid;
if (isValid) {
e.target.classList.remove("invalid");
invalidEl.classList.add("hidden", "md:hidden");
return;
}
if (!isValid) {
e.target.classList.add("invalid");
invalidEl.classList.remove("hidden", "md:hidden");
return;
}
}
} catch (e) {}
if (isValid) {
el.classList.remove("invalid");
invalidEl.classList.add("hidden", "md:hidden");
return;
}
if (!isValid) {
el.classList.add("invalid");
invalidEl.classList.remove("hidden", "md:hidden");
return;
}
}
});
this.isChecking = false;
}, 20);
} catch (e) {
this.isChecking = false;
}
}
}

View file

@ -52,7 +52,7 @@
/*----------------------------------------------*/
.checkbox {
@apply cursor-pointer disabled:cursor-default
@apply transition-none cursor-pointer disabled:cursor-default
relative dark:border-slate-600 dark:bg-slate-700 z-10 data-checked:z-0 w-5 h-5
text-base rounded-1.4 data-checked:bg-primary data-checked:border-primary
dark:data-checked:bg-primary dark:data-checked:border-primary duration-250 float-left
@ -72,7 +72,7 @@
}
.custom-dropdown-btn {
@apply min-h-[38px] border-b border-l border-r border-gray-300 hover:brightness-90 bg-white text-gray-700 my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-200;
@apply transition-none min-h-[38px] border-b border-l border-r border-gray-300 hover:brightness-90 bg-white text-gray-700 my-0 relative px-6 py-2 text-center align-middle transition-all rounded-none cursor-pointer leading-normal text-sm ease-in tracking-tight-rem dark:border-slate-600 dark:bg-slate-700 dark:text-gray-200;
}
.active.custom-dropdown-btn {
@ -80,7 +80,7 @@
}
.regular-input {
@apply outline-none dark:border-slate-600 dark:bg-slate-700 dark:text-gray-200 disabled:opacity-75 focus:border-gray-300/0 focus:ring-1 focus:valid:ring-green-500 focus:invalid:ring-red-500 text-sm leading-5.6 ease-in block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 md:py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500 disabled:bg-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 dark:disabled:text-gray-300 disabled:text-gray-700;
@apply transition-none outline-none dark:border-slate-600 dark:bg-slate-700 dark:text-gray-200 disabled:opacity-75 focus:border-gray-300/0 focus:ring-1 focus:valid:ring-green-500 focus:invalid:ring-red-500 text-sm leading-5.6 ease-in block w-full appearance-none rounded-lg border border-solid border-gray-300 bg-white bg-clip-padding px-1.5 py-1 md:px-3 md:py-2 font-normal text-gray-700 transition-all placeholder:text-gray-500 disabled:bg-gray-400 dark:disabled:bg-gray-800 dark:disabled:border-gray-800 dark:disabled:text-gray-300 disabled:text-gray-700;
}
.invalid.regular-input {