Przy okazji prac nad nową wersją (web) aplikacji do zgłaszania lotów dronami, która powstała z powodu problemów z działaniem DroneRadar, pojawił się pomysł, by niektóre pola ustawić tylko do odczytu, bo w nich są prezentowane informacje, które są wynikiem działania różnych skryptów i nic tam nie powinno być ręcznie modyfikowane. Jest to dość prosta operacja, bo sprowadza się do dodania tagu “readonly” np. do pola typu “input” lub “textarea”. Sytuacja jednak skomplikowała się w przypadku jednego z pól formularza, które choć najlepiej, by było właśnie tylko do odczytu, to jednak koniecznie musiało też być polem wymaganym do wypełnienia. Pozornie się kłoci ze sobą, ale tylko pozornie… ;-)

Wymagane pole w formularzu w trybie tylko do odczytu

Mowa o polu, do którego za pomocą funkcji napisanych w JavaScript wstawiana jest lokalizacja osoby, chcącej dokonać zgłoszenia lotu dronem za pomocą poczty e-mail (przygotować e-mail ze zgłoszeniem lotu). Pole to musi być obowiązkowe do wypełnienia, ale jednocześnie dobrze, by modyfikacja jego zawartości odbywała się tylko przez “uprawnione” do tego skryptu, bez możliwości ręcznej modyfikacji (tak sobie założyłem ;-)).

Można by tu oczywiście wykorzystać JavaScript, ale po co, jak są odpowiednie tagi dla takich pól przewidziane w HTMLu. Problem jednak w tym, że wzajemnie się one znoszą.

Punktem wyjścia jest pole typu “input” z tagiem “required”, czyli wymaganego do wypełnienia, by można było przesłać formularz:

<input class="form-control" type="text" name="lokalizacja" required>

To, co wydaje się najprostsze, to dodać do niego tag “readonly”:

<input class="form-control" type="text" name="lokalizacja" required readonly>

Problem tylko w tym, że tag “readonly” znosi działanie tagu “required”, bo w standardowej sytuacji faktycznie może być ciężko wypełnić pole, które jest tylko do odczytu, i zazwyczaj takie pola są już wstępnie wypełnione, więc nie ma co sprawdzać, czy jest wypełnione. A nawet jak nie jest, to i tak nie da się go wypełnić, więc nie można by przesłać formularza.

I choć zazwyczaj ma to sens, to w omawianym przypadku dwa pozornie sprzeczne stany mogą ze sobą współpracować. Jednak przez to, że początkowo wartość tego pola jest pusta i to dopiero użytkownik swoim działaniem sprawia, że zostaje ono przez skrypt udostępnione, to gdy użytkownik nie wykona tego działania, to formularz i tak zostanie przesłany. A to oznacza błąd.

Kolejny tag, po który można potencjalnie sięgnąć, to “disabled”:

<input class="form-control" type="text" name="lokalizacja" required disabled>

Tutaj jednak sytuacja jest jeszcze gorsza, bo nie tylko znosi on działanie tagu “required”, ale ogólnie sprawia, że dane z tego pola nie są przesyłane, nawet jak użytkownik wykona akcję, która uruchomi skrypt przypisujący do niego odpowiednie wartości.

Na szczęście z pomocą przychodzi CSS, i zamiast kombinować z opisanymi wyżej tagami, można do elementu “imput” dodać np. klasę o nazwie “readonly” (nazwa przykładowa, może być inna):

<input class="form-control readonly" type="text" name="lokalizacja" required>

A następnie “ostylować” tę klasę:

input.readonly {
	pointer-events: none;
}

Dzięki temu pole będzie wymagane, a jednocześnie będzie tylko do odczytu, bez bezpośredniej możliwości modyfikacji jego treści przez użytkownika.

(!) Zgłoś błąd na stronie | Lub postaw nam kawę :-)
LUTy dla D-Cinelike (DJI Mini 3 Pro, DJI Avata, OSMO Pocket) od MiniFly
Wdrożenie Omnibusa w sklepie na WooCommerce
Jak (legalnie) latać dronem w Kategorii Otwartej
Patryk