Linux E X P R E S

Facebook

jQuery (32) – vlastní widget v jQuery UI

jquery.png

Nenajdeme-li v jQuery vhodný widget, můžeme to řešit vytvořením vlastního, přímo pro konkrétní potřeby. Následující odstavce ukazují, jak na to.


Opravdu potřebujeme něco vlastního?

Na podobnou otázku se celkem logicky nabízí odpověď „ne“. A často to tak je. Kromě widgetů, které jsou obsaženy v jQuery UI, totiž existuje spousta takových, které už někdo vytvořil, protože řešil v minulosti stejný problém. Háček je ale v tom, že většina takových widgetů je nějak licenčně omezena – jejich licence je proprietární a za použití se platí buď vždy, nebo třeba při komerčním užití.

Základní jQuery a jQuery UI mají licenci MIT. Ta je svobodná, ale není copyleftová. Proto lze prakticky bez omezení vytvářet widgety s libovolnými licencemi.

Proto je leckdy vhodnější si widgety vytvořit a nakládat s nimi podle svého – tedy používat je ve svých projektech nebo je i nabídnout k dalšímu použití, ať už pod jakoukoli licencí.

Továrna na widgety

Nejsnazší cesta, jak si vytvořit vlastní widget, je „továrna na widgety“, tedy tovární metodu widget() objektu jQuery. Této metodě se předá název widgetu, bázový typ widgetu a objekt pro použití jako prototyp. Název je jasný (musí být ale jedinečný). Od bázového typu bude odvozen nový widget – pokud se nezadá explicitně, použije se jQuery.Widget. A konečně prototypový objekt  bude ten, podle něhož se budou vyrábět instance widgetu.

Možná to není úplně srozumitelné, takže bude nejlepší se podívat na příklad. Vytvoříme si nový widget odvozením od tlačítka, tedy widgetu Button:

$.widget('mynamespace.mybutton', $.ui.button,
 {
   _create: function() {
     this.element.button();
   }
 });

Název je žádoucí vytvářet v samostatném jmenném prostoru (zde mynamespace). Pro odvození se použije třída $.ui.button (standardní widget Button) a v rámci prototypového objektu si připravíme metodu _create(), která zajistí vytvoření widgetu. V tomto případě jen vytvoří standardní tlačítko. Widget by se následně použil například takto (bez uvedení jmenného prostoru):

$('#button').mybutton();

Pracujeme s parametry

Jako parametry budeme chtít nastavovat barvu textu a pozadí. Definujeme si tedy výchozí hodnoty, které si tvůrce instance případně předefinuje podle potřeby:

$.widget('mynamespace.mybutton', $.ui.button,
{
  options: {
    foreground: 'black',
    background: 'yellow'
  },
  _create: function() {
    this.element.button();
    this.element.css('color', this.options.foreground)
        .css('background-color', this.options.background);
  }
});

Při následném vytvoření widgetu bez parametrů bude text černý a pozadí žluté. Můžeme ale zadat některý z parametrů či oba dva, jako u běžných widgetů:

$('#button').mybutton({ foreground: 'white', background: 'black'});

Zjišťování a změna parametrů za běhu

Zjišťování hodnot parametrů není potřeba vůbec řešit. Už tím, že vytvoříme v prototypu objekt options, hodnoty parametrů zpřístupníme. Problém je se změnou hodnot, protože ta musí často mít vedlejší efekt (nestačí jen nastavit hodnoty, ale musí se stát ještě něco dalšího – tedy u toho tlačítka změna barev). Bude proto potřeba si definovat metody _setOption()_setOptions().

Zbývající část kódu prototypu se nemění.

  _setOption: function(key, value) {
     switch (key) {
       case 'foreground':
         this.options.foreground = value;
         this.element.css('color', this.options.foreground);
         break;
       case 'background':
         this.options.background = value;
         this.element.css('background-color', this.options.background);
         break;
       this._super(key, value);
     }
   },
   
   _setOptions: function(options) {
     this._super(options);
     this.element.css('color', this.options.foreground)
         .css('background-color', this.options.background);
   }

Rozeberme si to. Metoda _setOption() zde pro jednotlivé parametry vždy nejdřív nastaví hodnotu a pak ji ještě uplatní na elementu. Následně je potřeba zavolat stejnou metodu na předkovi. U metody _setOptions() je to podobné, nejdřív se ale volá metoda předka (která vše nastaví) a pak se hodnoty nastaví na elementu. Netestuje se, zda se něco změnilo, protože v tomto případě to nevadí. Někdy by ale bylo žádoucí otestovat (třeba už jen výkonových důvodů), zda došlo ke změně, a teprve potom provádět nějaký výkonný kód.



Metody widgetu

Podobně jako standardní widgety, také ty vlastnoručně implementované mohou mít různé metody pro ovládání. Widget přebere do svého prototypu metody z předka, ty lze poté předefinovat nebo si nadefinovat metody zcela nové.

Například Button má metodu showLabel(), které se můžeme chtít zbavit, tak ji implementujeme s prázdným tělem (správně by bylo potřeba zamezit i změně přes parametry, ale to už jistě každý dokáže dotvořit sám). Naopak si přidáme metodu invert(), která prohodí barvu popředí a pozadí.

  showLabel: function() {},
  invert: function() {
    this._setOptions({
      foreground: this.options.background,
      background: this.options.foreground
    });
  }
Takto by se pak zvenčí nastavilo, aby se barevnost invertovala na kliknutí:
$('#button').click(function() {
   $(this).mybutton('invert');
 });

Další informace o metodách a další práci s widgety najdete v dokumentaci.

Úklid

Pokud si vytvoříme nějaká data v DOM (atributy, elementy…), která by po skončení práce s widgetem neměla přetrvat, je potřeba je uvolnit. Totéž se týká například i tříd, které nastavujeme elementu, s nímž pracujeme.

_create: function() {
   this.element.addClass('mybutton');
 },
 
 _destroy: function() {
   this.element.removeClass('mybutton');
 }

Příklad ukazuje odstranění třídy přidané elementu při vytvoření widgetu.

Události

Pro interakci mezi widgetem a okolím (iniciovanou ve widgetu) využijeme události. Není třeba se starat o to, zda na události někdo reaguje, událost prostě nastane (spustí se).

if (this.options.foreground == this.options.background) {
   this._trigger('coloridentity', null, { color: this.options.foreground });
 }

Kód příkladu bychom přidali jako ověření nastavených barev. Pokud budou obě barvy shodné, nastane událost coloridentity, na niž může někdo reagovat. Jako parametr do obslužné rutiny se předá konkrétní barva. Lze předávat také objekt události (zde je null).

Widget může také reagovat na cizí události. Netřeba dodávat, že nastavené reakce je potřeba při rušení widgetu zrušit (v metodě _destroy()).

Mobilní prostředí

Úsek seriálu o jQuery UI je u konce. Příště už přejdeme do mobilního prostředí, které je u jQuery reprezentováno frameworkem jQuery Mobile. Tvorba webových aplikací pro mobilní telefony a tablety s jeho použitím je doslova hračkou.

Diskuze (0) Nahoru