Znak wodny w polu tekstowym

2010-07-10 13:16

Panuje obecnie moda na to, aby strony WWW jak najskuteczniejszej udawały, że nimi nie są i zamiast tego mieniły się ‘aplikacjami internetowymi’. Duża w tym zasługa możliwości JavaScriptu w nowoczesnych przeglądarkach. Jeśli potrafimy przeboleć pisanie w nim, to możemy osiągnąć całkiem efektowne rezultaty. Albo takie nieco mniej imponujące, ale też zgrabne :)
Do tej drugiej kategorii należy efekt znany jako watermark textbox, niemający wbrew pozorom żadnego związku ze znakami wodnymi w obrazkach. Trik ten – z którym zapewne tutejsza większość się zetknęła – polega na wyświetlaniu nieco przyszarzonego komunikatu w polu tekstowym, który następnie znika, gdy użytkownik umieści w nim kursor. Oprócz sprawiania wrażenia, że “strona żyje”, ta prosta sztuczka ma też wymiar praktyczny: pozwala oszczędzić na zbędnej etykiecie textboxa.

Chcąc “wodne” pole tekstowe umieścić na swojej stronie, możemy skorzystać z jednego z gotowych rozwiązań. Wiele z nich używa jQuery – darmowej biblioteki ułatwiającej pisanie w JS. Jeśli jednak nie korzystamy z niej w innych miejscach strony, to wymaganie jej obecności nie musi się nam podobać. A ponieważ watermark textbox jest efektem łatwym do zakodowania, spokojnie możemy napisać go własnoręcznie. Prześledźmy zatem, jak da się to zrobić.

Definiujemy najpierw styl naszego pola tekstowego, określający jego wygląd podczas wyświetlania wskazówki-znaku wodnego:

  1. input.watermarkTextBox { color: #808080; }

Szary kolor jest oczywiście tylko propozycją. Potrzebujemy w każdym razie osobnej klasy CSS, by oznaczać nią te textboksy, które mają wyświetlać znak wodny. Jako wskazówkę będziemy pokazywali początkową wartość pola tekstowego, czyli to co zostało fabrycznie przypisane atrybutowi value elementu input:

  1. <input type="text" size="20" value="Szukaj..." class="watermarkTextBox"/>

To właściwie tyle, jeśli chodzi o statyczny HTML; resztę musimy załatwić JavaScriptem. Interesują nas dwa zdarzenia: zyskania oraz utraty fokusu przez kontrolkę. Są to odpowiednio: onfocus i onblur. (Właśnie za takie nieintuicyjne nazwy “kochamy” JavaScript ;P). W reakcji na pierwsze z nich powinniśmy ukryć nasz szary tekst i pozwolić użytkownikowi na wpisanie nowego. Jeśli jednak tego nie zrobi, to w drugim zdarzeniu wykrywamy, że textbox jest wciąż pusty i ponawiamy wyświetlanie znaku wodnego. Oto procedury zdarzeniowe, które wykonują te czynności:

  1. function onWatermarkTextBoxFocus()
  2. {
  3.     if (this.value == this.watermark)
  4.     {
  5.         this.value = "";
  6.         this.className = this.className.replace("watermarkTextBox", "");
  7.     }
  8. }
  9.  
  10. function onWatermarkTextBoxBlur()
  11. {
  12.     if (this.value.length == 0)
  13.     {
  14.         this.value = this.watermark;
  15.         this.className += " watermarkTextBox";
  16.     }
  17. }

Jak można zauważyć, rzecz polega na dodaniu lub usunięciu nazwy uprzednio zdefiniowanej klasy CSS z listy klas pola tekstowego. Zakładamy tutaj, że atrybut watermark zawiera jego etykietę, czyli znak wodny. Żeby jednak tak było, musimy go ustawić, przy okazji podpinając (fuj, nie lubię tego słowa) przypisując powyższe funkcje do zdarzeń kontrolki. Czynimy to podczas wczytywania strony:
function initWatermarkTextBoxes()
{
var inputs = document.getElementsByTagName(“input”);
for (i = 0; i < inputs.length; ++i) if (inputs[i].type == "text" && inputs[i].className.indexOf("watermarkTextBox") != -1) { inputs[i].watermark = inputs[i].value; inputs[i].onfocus = onWatermarkTextBoxFocus; inputs[i].onblur = onWatermarkTextBoxBlur; } } window.onload = initWatermarkTextBoxes;[/javascript] Przechodzimy po prostu po wszystkich tagach input, szukając zwykłych pól tekstowych (type równe “text”), które mają przypisaną “wodną” klasę CSS. Ustawiamy im następnie m.in. watermark na ich aktualną zawartość.

I właściwie to już wszystko. Okazuje się więc, że czasami JavaScript nie jest taki straszny ;) A jeśli chodzi o działający przykład praktyczny, to można go oglądać gdzieś nieopodal w postaci długo oczekiwanego formularza wyszukiwarki :)

Disclaimer: rozwiązanie testowane na najnowszych wersjach dwóch najsensowniejszych przeglądarek, czyli FF3.6 i IE8. Za Opery, Safari i inne chromy nie ręczę ;P

Tags: , , , ,
Author: Xion, posted under Internet, Programming »


14 comments for post “Znak wodny w polu tekstowym”.
  1. michał b.:
    July 10th, 2010 o 15:11
    1. this.className = this.className.replace("watermarkTextBox", "");

    na rozmowe kwalifikacyjnej w jednej z dużych korporacji tworzącej telefony komorkowe zjebali mnie za takie rozwiazanie i nie zostawili suchej nitki, mówiąc ze inzynier oprogramowania zawsze do operacji na stringach uzywa regexow, bo jak jakis element ma dodatkowo klase np. watermarkTextBoxFooBar odpowiadajaca za zupelnie co innego to po takiej akcji zostawi mu nic nie zanczące ‘FooBar’. Osobiscie uwazam ze to troche przekobinowane i tez bym zrobił tak jak Ty.
    A kwestia tego że JS zachowuje sie inaczej w różnych przegladarkach tak na prawde nie istnieje jeśli trzymasz sie standardów (które czasem trzeba naginać jeśli zależy na wsparciu też dla starych IE jak np. IE6, lub instalowac dodatkowe pluginy jeśli zależy Ci na canvasie czy SVG). Uważąm że JS jest językiem który mimo swoich wybryków (polecam http://wtfjs.com/ mozna sie niezle ubawić) ma wielki potencjał i jest często bardzo niedoceniany. W końcu to najpopularniejszy (pod wzgledem ilości i dostępności interpretatorów) język świata, nie:)?

  2. Xion:
    July 10th, 2010 o 15:29

    Hyhy zabawne :) Ja bym odpowiedział, że w praktyce i tak bym użył wspomnianego jQuery, który dla elementów strony daje po prostu metody add/removeClass. A co do kompatybilności JS z różnymi przeglądarkami, to faktycznie – o ile nie bierzemy pod uwagę antyków typu IE6 (chociaż o 7 też różne dziwne, acz bliżej nieokreślone rzeczy słyszałem) to powinno być ok.

  3. Adawo:
    July 10th, 2010 o 15:33

    W HTML5 już jest atrybut placeholder w znaczniku input (Na dzień dzisiejszy do obejrzenia np. w chrome) dająca taki efekt.

    Co do jQuery to ja uważam że naprawdę warto, waga tej biblioteki(24Kb) w stosunku do jej możliwości traci znaczenie…

    A co do CSS to zamiast dodatkowej klasy można użyć pseudoklasy :focus

    Pozdrawiam ;)

  4. Eadf:
    July 10th, 2010 o 15:40

    @Adawo
    W dużej korpo to by cie na dzieńdobry przecwelili za propozycje użycia html5

  5. Xion:
    July 10th, 2010 o 15:43

    A dokładnie to jak użyć :focus? Bo jeśli damy po prostu:

    1. input[type="text"] { color #888; }
    2. input[type="text"]:focus { color: inherit; }

    to (przy założeniu taki selektor w ogóle działa ;) ) wszystko będzie OK do momentu, gdy user coś wpisze i opuści pole tekstowe. Wtedy *jego* tekst ładnie poszarzeje :)

  6. PiotrLegnica:
    July 10th, 2010 o 17:18

    Don’t do this. Just… no.

    Słowa nie potrafią opisać, jak bardzo denerwujące jest zmuszanie mnie do usuwania tekstu z inputboxa zanim będę mógł łaskawie wpisać własny, albo, co gorsza, odblokowania JS dla całej strony. A nie tylko ja używam NoScripta.

    Omijanie nigdy nie jest dobre.

  7. PiotrLegnica:
    July 10th, 2010 o 17:20

    Omijanie label, that is.

  8. michał b.:
    July 10th, 2010 o 17:28

    blokowanie javascriptu przy przegladaniu internetu w dzisiejszych czasach to jak przywiązywanie konia do mercedesa – niby bedzie jechal tylko to nie tak ma wygladac.

  9. jpjpjp:
    July 12th, 2010 o 10:32

    Przecież wystarczy poczytać artykuły o bezpieczeństwie linuxa by przekonać się, że sa przepełnione ideologią, nieprawdami, półprawdami itp.itd. A porównania do windowsa? Sam pisałem o tym prace magisterską. Kilka miesięcy później nieznani sprawcy obrzucili mi dom jajkami… Na spotkaniu przy wódce moi koledzy przyznali, że źle skonfigurowali proxy w firefoxie, więc na forum uczelni widać było oczywisty trolling na rzecz windowsa z naszych ip. No, ale o tym ataku na mój dom już się nie pamięta. Bo Paweł M. i jego koledzy – zagorzali ewangeliści linuksa, wiedzą, w jaki sposób tworzyć „kultowe” towary, których nie wolno tknąć. Moim zdaniem linux to jedno z najbardziej szkodliwych zjawisk w IT. Niesie bowiem ze sobą pseudowolność, która, dzięki kultowemu statusowi FSF, staje się wolnością objawioną która na dłuższą mete prowadzić będzie do pedofilii. A tłumy lubią wolności objawione, nawet, jeśli z wolnością mają one tyle wspólnego, co Korwin-Mikke z liberalizmem.

  10. Kos:
    July 14th, 2010 o 11:56

    Jestem zdania, że w tych czasach jeśli nie piszemy czegoś performance-critical typu własna kontrolka do sformatowanego tekstu z ręcznie rysowanym kursorem, dzieleniem wyrazów, itd (hi, Google!), to pisanie javascriptu bez jQuery jest po prostu nieuprzejme ;).

  11. Kacper Kołodziej:
    July 16th, 2010 o 15:11

    Ja bym tu użył JQuery. Niedawno zacząłem poznawać tajniki tej biblioteki i muszę przyznać, że pisanie bez nie było marnowaniem czasu, ponieważ wcześniej pisałem 10 linijek kodu, a teraz – do tego samego – jedną.
    Podobny artykuł ukazał się jakiś czas temu na webmade.org – zalecam przejrzenie obydwu i znalezienia czegoś dla siebie.
    P.S. Xion, mógłbyś zainstalować sobie do WP wtyczkę obsługującą IntenseDebate.
    P.S. 2 jpjpjp – chyba nie wiesz co to liberalizm

  12. Xion:
    July 17th, 2010 o 16:03

    @P.S.#1 – Spojrzałem na tę wtyczkę i o ile się nie mylę, do pełnej funkcjonalności wymaga ona jakiejś rejestracji od userów, a dodaje coś, czego bardzo na forach i wyrobach foropodobnych nie lubię, tj. numerologię w postaci ocen dodatnich i ujemnych. Jeśli mam rację, to zasadniczo odpada. Wolę coś, co do rejestracji nie zmusza i udostępnia raczej prostą funkcjonalność, jak np. edycję posta przez kilkanaście minut po opublikowaniu (via ciastko) i/lub podgląd, plus tagi typu [quote] do cytowania i przyciski do tego.

  13. dynax:
    July 18th, 2010 o 16:30

    Nigdy nie wiedziałem co takiego fajnego jest w pisaniu aplikacji webowych. Przecież pisanie gier/aplikacji desktopowych jest o wiele ciekawsze :P

  14. Pablo_Wawa:
    September 20th, 2012 o 14:44

    Duży plus za podanie przykładu bez użycia biblioteki jQuery – dzięki temu początkujący użytkownik zrozumie mechanizmy tu użyte, a jak ktoś zna jQuery to sobie to prosto przerobi.
    Minus za zbytnie uproszczenie przykładu w kwestii obsługi zdarzeń – bezpośrednie przypisywanie swoich funkcji do metod onfocus, onblur i onload nie jest właściwe – zaleca się używanie funkcji addEventListener i attachEvent (IE). Można by przynajmniej tutaj o tym wspomnieć.
    Co do AdBlocków i wyłączonego JS – można wtedy nie używać w inputach pola value (niech będzie miał pustą wartość) tylko watermark i mu nadać stosowną wartość (tekst) i wartość tę przepisywać w kodzie JS do pola value przy inicjalizacji.

    A co do samego JavaScriptu, to kiedyś służył on właśnie do tworzenia takich dodatkowych “bajerów”, teraz coraz więcej (dużych) aplikacji jest w nim tworzona (z użyciem m.in. AJAX).

Comments are disabled.
 


© 2017 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.