Poznajemy HTMLInputElement, jego metody. Kolejny krok w poznaniu dokumentacji HTML/CSS/JS. Do dzieła!
Ok, metoda pierwsza, to checkValidity. Przykład inputów z atrybutami walidacyjnymi:
<form action="#" method="post">
<p>
<label for="age">Your (21 to 65) </label>
<input type="number" name="age" required id="age" min="21" max="65" />
</p>
<p>
<button type="submit">Submit</button>
<button type="button" id="check">checkValidity()</button>
</p>
<p id="log"></p>
</form>
A oto przykład użycia (z MDN):
const output = document.querySelector("#log");
const checkButton = document.querySelector("#check");
const ageInput = document.querySelector("#age");
ageInput.addEventListener("invalid", () => {
console.log("Invalid event fired.");
});
checkButton.addEventListener("click", () => {
const checkVal = ageInput.checkValidity();
output.innerHTML = `checkValidity returned: ${checkVal}`;
});
Metoda checkValidity zwraca true albo false, i tyle. Mamy też metodę reportValidity, ona robi to, co checkValidity + wyświetla w przeglądarce te domyślne informacje walidacyjne (typu to pole musi być wypełnione).
Jeżeli ktoś bardzo lubi walidację po stronie klienta (jako dodatek do walidacji po stronie serwera, prawdziwej walidacji, której nie da się usunąć poprzez ten przysłowiowy zbadaj element) to ma jeszcze setCustomValidity, przykład z MDN:
function validate(inputID) {
const input = document.getElementById(inputID);
const validityState = input.validity;
if (validityState.valueMissing) {
input.setCustomValidity("You gotta fill this out, yo!");
} else if (validityState.rangeUnderflow) {
input.setCustomValidity("We need a higher number!");
} else if (validityState.rangeOverflow) {
input.setCustomValidity("That's too high!");
} else {
input.setCustomValidity("");
}
input.reportValidity();
}
Mamy też metodę select:
function selectText() {
const input = document.getElementById("text-box");
input.focus();
input.select();
}
Select zaznacza cały tekst w inputach tekstowych. Focus to metoda generycznego HTMLElementu, jej przeciwieństwo to blur.
Ok, coś ciekawszego, czyli setRangeText. Może najpierw sygnatury:
setRangeText(replacement)
setRangeText(replacement, start)
setRangeText(replacement, start, end)
setRangeText(replacement, start, end, selectMode)
Tylko replacement jest obowiązkowy, start i end to chyba wiadomo, indeksy, 0-based, end to pierwszy indeks po wstawieniu tekstu (pierwszy, który ma zostać).
Argument selectMode jest od zaznaczania tekstu wstawionego, albo tekstu od początku aż do replacement, albo tego po replacement, albo do zachowania poprzedniej selekcji. Przykład z MDN:
<input
type="text"
id="text-box"
size="30"
value="This text has NOT been updated." />
<button onclick="selectText()">Update text</button>
Teraz JS:
function selectText() {
const input = document.getElementById("text-box");
input.focus();
input.setRangeText("ALREADY", 14, 17, "select");
}
Mamy też metodę setSelectionRange:
function selectText() {
const input = document.getElementById("text-box");
input.focus();
input.setSelectionRange(2, 5);
}
Czyli zaznaczanie tekstu od indeksu start do end, end nie wchodzi, indeks 0-based. Oba argumenty obowiązkowe, trzeci opcjonalny to forward albo backward.
Ok, showPicker to głupota. Dla elementów, które mają jakiegoś pickera (file picker, date picker, color picker) go wyświetla, nie wiem po co mielibyśmy robić to w kodzie:
document.querySelectorAll("button").forEach((button) => {
button.addEventListener("click", (event) => {
const input = event.srcElement.previousElementSibling;
try {
input.showPicker();
} catch (error) {
window.alert(error);
}
});
});
Oczywiście zawsze możemy sprawdzić, jakie przeglądarki wspierają tę metodę i później zrobić coś takiego:
if ("showPicker" in HTMLInputElement.prototype) {
// showPicker() is supported.
}
Warto mieć takie rzeczy na uwadze. Można robić wykrywanie przeglądarki a nawet jej konkretnej wersji wnioskując w ten sposób (omawialiśmy sobie przykład jakiegoś prostego malware), warto też mieć na uwadze, że przeglądarka + rozszerzenia daje nam możliwość zrobienia fingerprintu swego rodzaju, i nie jest ważne, jakie mamy IP…
Ok, kolejne metody Są inputy numeryczne, które mają atrybut step, mam nadzieję, że to znamy:
<input type="time" max="17:00" step="900" />
<!-- decrements by intervals of 7 days (one week) -->
<input type="date" max="2019-12-25" step="7" />
<!-- decrements by intervals of 12 months (one year) -->
<input type="month" max="2019-12" step="12" />
I na tych inputach można robić metody stepUp i stepDown. Jak stepu nie ma, to domyślnie są zwiększane/zmniejszane o 1, jak jest, to o ten step. I tak możemy kodem JS tym sterować.