chevron-left chevron-right

[HTML5] Autopodpowiadanie do pól wyboru koloru w formularzach

Nie wiem czy wiesz, ale HTML5 wprowadził nowy rodzaj pól, które można zaimplementować w formularzach na stronie internetowej. Dzięki nim można znacznie uprościć proces wprowadzania danych a także sprawić, że wypełnianie go nie będzie mordęgą.

HTML5 - nowe rodzaje pól

O HTML5 ciężko mówić jak o czymś co jest najświeższą nowinką, ale wciąż jest to teren nie do końca odkryty przez wielu z nas. Jedną z ciekawszych rzeczy jakie można spotkać korzystając z HTML5 są nowe typy pól formularzy:

search
Jest to pole bardzo podobne do standardowego pola tekstowego <input type="text" />, ale ma jedną ciekawą rzecz. W przeglądarkach z silnikiem Webkit w polu pojawi się znak x, który służy do szybkiego czyszczenia pola. Mała, ale przydatna rzecz.
email
To pole jest szczególnie użyteczne na urządzeniach mobilnych, ponieważ ustawia taki uklad klawiatury, aby łatwiej było wpisywać adresy email. Dzieje się tak poprzez dodanie znaku @ do widoku domyślnej klawiatury.
url
Podobnie jak wyżej, tylko tym razem zamiast @ pojawia się przycisk z tekstem .com.
tel
Kolejny typ użyteczny na urządzeniach mobilnych. Ustawia klawiaturę numeryczną jako interfejs do wprowadzania danych w tym polu.
number
Podobnie jak wyżej, ustawiony jest widok numeryczny klawiatury. Dodatkowo, w przeglądarkach desktopowych pojawiają się w polu 2 dodatkowe przyciski do zwiększania/zmniejszania numeru o 1.
range
Pole to służy do określania wartości w przedziale zdefiniowanym przez developera (min i max). Pole to jest przedstawiane jako pasek z suwakiem.
date, month, week, time, datetime, datetime-local
Te typy pól służą do określania czasu. Najczęściej w momencie wybrania takie pola pojawia się jakaś forma kalendarza w którym można wybrać odpowiednią datę lub jako odpowiednio sformatowane pole w którym można ustawić interesujący nas czas.
color
Ostatni nowy typ pola to pole pozwalające wybrać kolor z systemowej palety kolorów. W tym artykule skupimy się na tym polu oraz na sposobie zwiększenia jego użyteczności za pomocą odrobiny JS i możliwości HTML5.

Wszystkie powyższe pola w przeglądarkach, które nie obsługują danego typu pola będą zachowywały się jak standardowe pole typu tekstowego - <input type="text" />.

Jak usprawnić pole wyboru koloru?

Wyobraź sobie sytuację, że użytkownik jest poproszony o wprowadzenie kodu HEX wybranego koloru, np. #bb3300. Ty natomiast w swoim formularzu chcesz wprowadzić mechanizm podpowiadania wyboru innego koloru, który ma listę kolorów o innych odcieniach - ciemniejszych bądź jaśniejszych.

Mając w pamięci taki przypadek użycia, możemy przystąpić do zebrania potrzebnych nam rzeczy, które pomogą w realizacji tego zadania. Wykorzystamy do tego pole typu kolor i pole tesktowe, listę danych oraz trochę kodu JS do generowania odcieni koloru:

1
2
3
4
5
6
7
8
9
<form>
  <label for="color-hex">
    <span>Wpisz kod koloru:</span> <input type="text" id="color-hex" name="color-hex"/>
  </label><br/>
  <label for="color-pick">
    <span>Lub wybierz kolor lub odcień koloru wpisanego w polu obok:</span> <input type="color" id="color-pick" list="shades" value="#ffffff"/>
  </label>
  <datalist id="shades"></datalist>
</form>

Przykładowy formularz został przedstawiony powyżej. Jak można zauważyć, mamy 2 pola typu <input> - jedno tekstowe, drugie wyboru koloru - oraz mamy pusty element <datalist>, który będzie zawierał wygenerowane odcienie kolorów. Warto zauważyć jeszcze że pole wyboru koloru posiada atrybut list, który jest wskaźnikiem na listę danych które będą podpowiadały inne kolory do wyboru.

Kolejnym krokiem jest napisanie kodu odpowiedzialnego za generowanie odcieni koloru a następnie kodu odpowiedzialnego za automatyczne generowanie odcieni bazując na wyborach użytkownika:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
(function () {
  var generateColorShade = function (hex, lum) {
    // hex - kod HEX koloru
    // lum - jasnośc
 
    // sprawdzenie czy dany ciąg znaków jest poprawnym zapisem koloru typu heksadecymalnego (HEX)
    hex = String(hex).replace(/[^0-9a-f]/gi, '');
 
    if (hex.length < 6) {
      hex = hex[0] + hex[1] + hex[2] + hex[3] + hex[4] + hex[5];
    }
    lum = lum || 0;
 
    // przekonwertuj zapis hex do dziesiętnego i zmień jasnośc
    var rgb = "#";
    var partial;
    var i;
 
    // zapis hex dzielimy na 3 części po 2 znaki i wyliczamy składowe koloru
    for (i = 0; i < 3; i++) {
      partial = parseInt(hex.substr(i * 2, 2), 16);
      partial = Math.round(Math.min(Math.max(0, partial + (partial * lum)), 255)).toString(16);
      rgb    += ("00" + partial).substr(partial.length);
    }
 
    // zwracamy wyliczony kod hex koloru
    return rgb;
  };
 
  var $dataList = $('#shades');
  var step      = 0.1;
 
  // wygenerowanie domyślnych odcieni bazując na wartości startowej pola typu kolor
  for (var i = 0; i < 5; i++) {
    $dataList.prepend($('<option/>', {
      'value' : generateColorShade($('#color-pick').val(), - (i * 0.1))
    }));
  }
 
  // gdy użytkownik przeniesie się do innego pola lub kliknie w inne miejsce na stronie
  // wygeneruj nowe odcienie kolorów bazując na jego wyborach
  $('input').on('blur', function () {
    var $element = $(this);
 
    // jesli pole tekstowe nie jest puste
    if ($element.val()) {
      var i;
 
      // wyczyśc dotychczasową listę podpowiedzi kolorów
      $dataList.empty();
 
      // dodaj wybrany kolor
      $('#color-pick').val($element.val());
 
      $dataList.append($('<option/>', {
        'value' : $element.val()
      }));
 
      // wygerenuj jaśniejsze odcienie koloru i dodaj je na koniec listy
      for (i = 1; i < 3; i++) {
        $dataList.append($('<option/>', {
          'value' : generateColorShade($element.val(), i * step)
        }));
      }
 
      // wygeneruj ciemniejszej odcienie koloru i dodaj je na początek listy
      for (i = 1; i < 3; i++) {
        $dataList.prepend($('<option/>', {
          'value' : generateColorShade($element.val(), - (i * step))
        }));
      }
    }
  });
})();

Powyższy kod, dla uproszczenia, bazuje na bibliotece jQuery. Dlatego należy pamiętać o tym, aby ją dołączyć do kodu.
Powyżej zdefiniowaliśmy funkcję generateColorShade, której celem jest wyliczenie kodu heksadecymalnego nowego koloru. Następnie, tworzymy kod który będzie nasłuchiwał zdarzeń opuszczenia pola przez użytkownika, np. użytkownik przeniesie się do następnego pola lub kliknie gdziekolwiek indzie na stronie. Wtedy następuje szybkie wygenerowanie podpowiedzi odcieni kolorów, które będą widoczne, gdy użytkownik kliknie w pole wyboru koloru.

Podsumowanie

Mam nadzieję, że zaprezentowane przeze mnie rozwiązanie zainspiruje Ciebie i sprawi, że formularze napisane przez Ciebie będą o wiele fajniejsze w użytkowaniu niż do tej pory. Taki system podpowiedzi można wykorzystać do wielu innych rzeczy, a nie tylko do wyboru koloru.

Przykład działa dobrze w przeglądarkach Google Chrome i nowej Operze. Pozostałe przeglądarki niestety nie współpracują dobrze z tym rozwiązaniem.

Demo z tego artykułu można zobaczyć tutaj: demo z wyborem koloru

źródło 1, źródło 2

  • Osobiście datalist nigdy mnie do siebie nie przekonało. Powód jest trywialny: de facto nie istnieje żaden sensowny sposób jego ostylowania. Tutaj wręcz się prosi, żeby te pola z podpowiedziami miały odpowiedniego koloru tło 😉
    Jedynym plusem datalist jest to, że ma natywnie podpięte odpowiednie atrybuty ARIA (a przynajmniej powinno mieć..). I to wszystko, co można powiedzieć dobrego na jego temat. Mimo wszystko to ważna cecha – od 2 lat szukam _poprawnej_ implementacji takiego cuda w JS i jak na razie natrafiłem na 10 sprzecznych 😀

  • Gapi

    Witaj Piotrze.
    Bardzo fajna funkcjonalność, wypróbowałem i wszystko gra.
    Tylko mam problem jak bym chciał wstawić dwa takie pola do formularza, wtedy się gryzą ze sobą. Ustawiając kolor w pierwszym polu tekstowym zmienia się kolor w drugim polu pick i nie potrafię tego zmienić. czy możesz mi pomóc?
    z góry dziękuję za jakieś podpowiedzi i pozdrawiam.

  • Trzeba trochę zmodyfikować kod, tak aby nie wstawiał koloru do inputa z id #color-pick.
    W przykładzie powyżej, nowy kod koloru jest wstawiany za pomocą:

    $(‚#color-pick’).val($element.val());

    i to właśnie tą linijkę trzeba poprawić.

  • Gapi

    Dzięki za szybką odpowiedź.
    Tu właśnie zaczynają się u mnie schody, opanowałem w miarę php, ale jeżeli chodzi o js to jestem noga.
    Jeszcze dużo mnie czeka nauki.
    Pozdrawiam.

  • Gapi

    Zupełnie nie wiem jak do tego podejść.
    Na pewno w drugim zestawie input type=”text” + input type=”color” chciałbym nadać inne id.
    W pierwszym zestawie jest id=”color-hex” i id=”color-pick” a w drugim ustawię n.p. id=”color-hex1″ i id=”color-pick1″ i chciałbym aby wstawił kod z hex do pick i z hex1 do pick1. Ale jeszcze nie mam zielonego pojęcia jak to zrobić w js.
    Pozdrawiam.

  • możesz spróbować to rozwiązać następująco:

    kod HTML

    kod JS

    $('#' + $element.data('color-preview') + ').val($element.val());

  • Gapi

    Bardzo dziękuję za podpowiedź, ale Dreamweaver nie przyjmuje tej linijki w JS, wyświetla że jest błąd składniowy a ja nie mam zielonego pojęcia w którym miejscu.
    Pozdrawiam.

  • Gapi

    Ja u siebie mam taki formularz:

    Wpisz kod koloru:

    Lub wybierz kolor lub odcień koloru wpisanego w polu obok:


    Wpisz kod koloru:

    Lub wybierz kolor lub odcień koloru wpisanego w polu obok: