Total.js - UI knižnica

Element ui-plugin

Element ui-plugin musí byť deklarovaný v HTML kóde a môže byť použitý na zjednoduchšenie ciest pre komponenty, ui-bind elementy alebo iné vnorené ui-plugin elementy. Plugin môže obsahovať atribúty path a config.

<ui-plugin path="userform" config="aclass:1;class:form">
  <ui-component name="input" path="?.email" config="type:email;required:1" default="'@'">Email</ui-component>
  <ui-component name="input" path="?.address.country" config="required:1" default="'Slovakia'">Country</ui-component>
  <ui-component name="input" path="?.address.city" config="required:1" default="'Banská Bystrica'">City</ui-component>
</ui-plugin>

V tejto ukážke môžeme vidieť deklarovaný ui-plugin s cestou userform a v konfigurácií môžeme vidieť nastavenie aclass (to znamená, že hodnota z cesty sa nám nastaví aj ako trieda pre tento element) a class. S týmito nastaveniami sa nám triedy userform a form pridajú do nášho HTML elementu ui-plugin.

Ukážkový kód zobrazený na webovej stránke

Ako môžeme vidieť, všetky komponenty použité v plugine majú použitý otáznik v atribúte path. Tento otáznik sa nahradí cestou z atribútu path nastavenou v plugine. Takže výsledná cesta pre komponenty bude userform.email, userform.address.country a userform.address.city (všetky cesty sú uložené vo window objekte). Takže model pre tento plugin bude vyzerať nasledovne:

{
    "address": {
        "city": "Banská Bystrica",
        "country": "Slovakia"
    },
    "email": "@"
}

Vnorené pluginy

Systém pluginov podporuje aj ich vnáranie medzi sebou, takže kód zobrazený vyššie môžeme zjednodušiť pomocou ďalšieho pluginu s cestou address a následým upravením ciest nastavených v komponentoch.

<ui-plugin path="userform" config="aclass:1;class:form">
  <ui-component name="input" path="?.email" config="type:email;required:1" default="'@'">Email</ui-component>
  <ui-plugin path="address">
    <ui-component name="input" path="?.country" config="required:1" default="'Slovakia'">Country</ui-component>
    <ui-component name="input" path="?.city" config="required:1" default="'Banská Bystrica'">City</ui-component>
  </ui-plugin>
</ui-plugin>

Ako môžeme vidieť v upravenom kóde, atribút path vo vnorenom plugine neobsahuje otáznik. Táto cesta sa rozšíri automaticky na pozadí o cestu z nadradeného pluginu. Model pre dáta takto upraveného kódu bude vyzerať presne rovnako ako predtým. Pridanie nového pluginu sa nám neprejaví ani na zobrazení komponentov na webovej stránke, takže všetko ostatné ostáva nezmenené.

Preskočenie nadradeného pluginu

V niektorých špeciálnych prípadoch sa môže stať, že budeme potrebovať preskočiť nadradený plugin. Je to možné pridaním čísla za otáznik vo zvolenej ceste. V príklade, ktorý sme si ukázali na to nie je dôvod, ale z edukačných dôvodov si to ukážeme v kóde, s ktorým sme už oboznámený.

<ui-plugin path="userform" config="aclass:1;class:form">
  <ui-component name="input" path="?.email" config="type:email;required:1" default="'@'">Email</ui-component>
  <ui-plugin path="address">
    <ui-component name="input" path="?.country" config="required:1" default="'Slovakia'">Country</ui-component>
    <ui-component name="input" path="?1.city" config="required:1" default="'Banská Bystrica'">City</ui-component>
  </ui-plugin>
</ui-plugin>

Ako môžeme vidieť, tak sme pridali číslo 1 do cesty za otáznik pre input komponent, kde zadávame mesto. V tomto prípade bude náš model vyzerať takto:

{
    "city": "Banská Bystrica",
    "address": {
        "country": "Slovakia"
    },
    "email": "@"
}

V predchádzajúcom príklade vyzerala cesta pre uloženie mesta (city) ako userform.address.city, ale v tomto príklade preskočíme nadradený plugin a "skočíme" do rodičovského pluginu. Nová cesta pre tento komponent bude userform.city. Môžeme preskočiť aj viacero nadradených pluginov tak, že zväčšíme číslo pridané do cesty zvoleného komponentu.

Izolované pluginy

Ďalším špeciálnym prípadom môže byť situácia, keď potrebujeme použiť v našej HTML štruktúre vnorené pluginy, ale chceme niektorý plugin izolovať od nadradeného pluginu. Môžeme tak urobiť pomocou nastavenia isolated s hodnotou true.

<ui-plugin path="userform" config="aclass:1;class:form">
  <ui-component name="input" path="?.email" config="type:email;required:1" default="'@'">Email</ui-component>
  <ui-plugin path="address" config="isolated:true">
    <ui-component name="input" path="?.country" config="required:1" default="'Slovakia'">Country</ui-component>
    <ui-component name="input" path="?.city" config="required:1" default="'Banská Bystrica'">City</ui-component>
  </ui-plugin>
</ui-plugin>

V tomto prípade nebude adresa - address - súčasťou pluginu userform, ale dostaneme dva oddelené modely.

// model pre userform
{
    "email": "@"
}

// model pre address
{
    "city": "Banská Bystrica",
    "country": "Slovakia"
}

Anonymný plugin

Atribút path ui-pluginu musí obsahovať cestu alebo otáznik. Otáznik sa používa pre vytvorenie anonymného pluginu, ktorý môže byť použitý pre vytváranie nezávislých znovupoužiteľných častí, kde otáznik (?) bude nahradený vygenerovaným náhodným reťazcom s 15 znakmi. Tento reťazec môže vyzerať napríklad takto - wcqokaxluzo6rvs - a táto cesta bude taktiež uložená vo window objekte.

JavaScript PLUGIN

PLUGIN slúži pre dynamické časti, stránky, formuláre, okná alebo pre jednostránkové aplikácie. Je odporúčané používať pre názov PLUGINu len malé písmená.

Deklarácia pre PLUGIN

Názov pre PLUGIN musí byť reťazec znakov bez bielych znakov. V PLUGINe môžeme definovať vlastné funkcie, vlastnosti, sledovače, alebo udalosti, ktoré sa viažu k danému PLUGINu, ale môžu byť aj nezávislé.

PLUGIN('plugin_name', function(exports) {
    // nejaký kód
});

Môžeme vytvoriť PLUGIN aj bez definovania jeho názvu, keď použijeme ui-import alebo jComponent j-Importer na importovanie častí našej aplikácie.

Ukážeme si príklad použitia PLUGINu bez definovania mena s komponentou j-Importer. V tomto príklade budeme chcieť importovať Užívateľský formulár do našej aplikácie.

<ui-component name="importer" path="common.form" config="if:userform;url:/forms/user.html"></ui-component>

Ak by ste chceli získať viac informácií o tom ako funguje jComponent, prosím prečítajte si môj starší blog, alebo pre viac informácií konkrétne o komponente j-Import, môžete navštíviť stránku componentator.com.

Príklad PLUGIN

j-Importer naimportuje celý HTML súbor user.html (definovaný v kóde vyššie). Tento komponent môže obsahovať štýli, html štruktúru a taktiež aj script.

Kompletný kontent súboru user.html

Tento kód zobrazený na webovej stránke bude vyzerať takto:

Vyrenderovaný obsah súboru user.html

A teraz si kód rozoberieme na menšie časti, ktoré si postupne vysvetlíme.

 .CLASS .buttons { display: flex; }
 .CLASS .custom { height: 40px; padding: 0 20px; color: #fff; background-color: #83c83c; cursor: pointer; font-family: Arial; line-height: 38px; font-size: 14px; border-radius: var(--radius); }</style>

V štýloch môžeme vidieť, že sme použili triedu .CLASS. Slovo CLASS je v tomto prípade rezervované slovo, ktoré bude nahradené slovom userform (rovnako aj ~PATH~). Pretože userform je definované v našom kóde v komponente j-Importer. To zjednoduší nastavenie vlastných štýlov pre formulár. Túto triedu môžeme použiť pre celý rodičovský element nášho HTML formuláru a tým ovplyvniť štýly len pre tento konkrétny formulár.

<ui-component name="miniform" path="common.form" config="if:userform;title:User;width:400;reload:?/reload;submit:?/submit;icon:ti ti-user" class="hidden CLASS" plugin="~PATH~">
  <div class="padding">
    <div class="m">
      <ui-component name="input" path="?.email" config="type:email;required:1" default="'@'">Email</ui-component>
    </div>
    <ui-plugin path="address">
      <div class="m">
        <ui-component name="input" path="?.country" config="required:1" default="'Slovakia'">Country</ui-component>
      </div>
      <div class="m">
        <ui-component name="input" path="?.city" config="required:1" default="'Banská Bystrica'">City</ui-component>
      </div>
    </ui-plugin>
    <div class="buttons">
      <div class="exec custom mr5" data-exec="?/complete">Complete</div>
      <div class="exec custom" data-exec="?/complete_email">Complete email</div>
    </div>
  </div>
  <nav>
    <ui-component name="validate" path="?">
      <button name="submit">Submit</button>
      <button name="cancel">Cancel</button>
    </ui-component>
  </nav>
</ui-component>

Toto je náš HTML kód pre daný formulár. Pre tento príklad sme zvolili použitie komponentu j-MiniForm. Môžeme vidieť, že sme použili slová CLASS a ~PATH~, ale je vhodné používať len jedno, kvôli konzistentnosti v kóde.

Tu by som chcel poukázať na dve tlačidlá v spodnej časti s triedou exec (tu sme použili komponent j-Exec) a atribútom data-exec. Hodnota z tohto atribútu je názov funkcie z nášho PLUGINu, ktorú chceme vyvolať po kliknutí na dané tlačidlo. Ako môžeme vidieť, názov tejto funkcie je v tvare ?/complete, kde otáznik bude na pozadí nahradený slovom userform, pretože to je hodnota, ktorú máme v komponente j-MiniForm definovanú v atribúte plugin a teda sa nám vyvolá funkcia z daného PLUGINu.

PLUGIN(function(exports) {
  exports.submit = function() {
    var model = exports.model;
    console.log('Model -->', model);
  };

  exports.complete = function() {
    var obj = { email: 'total@avengers.com', address: { country: 'USA', city: 'New York' }};
    exports.set(obj);
  };

  exports.complete_email = function() {
    exports.set('email', 'avengers@totaljs.com');
  };
});

Ako môžeme vidieť v ukážke kódu, v deklarácií PLUGINu sme nezadali jeho názov. V tomto prípade bude názov automaticky doplnený komponentou j-Importer a metódou ADAPT(). Existuje viacero spôsobov ako sa to dá docieliť. Názov môže byť vzatý z konfigurácie komponentu j-Importer z nastavenia if alebo path, alebo môže byť nájdený ako hodnota z atribútu path v prvom plugine z nášho HTML kódu (HTML kód bude transformovaný na reťazec znakov a hodnota z prvého nájdeného pluginu bude použitá).

Všetky tieto deklarácie budú v tomto príklade fungovať úplne rovnako:

// PLUGIN('CLASS', function(exports) {
// PLUGIN('~PATH~', function(exports) {
// PLUGIN('userform', function(exports) {
PLUGIN(function(exports) {
  // nejaký kód
}

exports.model

Funkcie, ktoré sa viažu na konkrétny PLUGIN môžeme definovať ako súčasť exports objektu. Definovali sme si niekoľko funkcií, ktoré si teraz vysvetlíme.

Prvá funkcia slúži na odoslanie formulára a bude vyvolaná kliknutím na tlačidlo Submit, pretože sme to nastavili v konfigurácií komponentu j-MiniForm. Vo funkcií submit som chcel ukázať ako môžeme získať hodnoty vyplnené vo formulári ako model. Kompletné dáta sú uložené na ceste userform a môžeme ich získať v objekte exports ako exports.model. Taktiež sa dajú získať v exports.data, ktorý je alias pre exports.model alebo v exports.form, ale toto použitie by nám reštartovalo stav komponentov, ktoré sme použili vo formulári. Pridali sme console.log pre demonštráciu funkčnosti.

Ukážka funkcie exports.submit

exports.set()

Taktiež môžeme vidieť dve zelené tlačidlá, ktoré sa nachádzajú v spodnej časti formulára. Pridali sme ich sem pre vysvetlenie ďalšej funkcionality, ktorú môžeme použiť v PLUGINoch a to exports.set(), ktorý je podobný ako SET() funkcia pre PLUGINy. Túto funkciu sme použili v oboch vlastných funkciách (complete a complete_email) s malým rozdielom.

Funkcia complete

var obj = { email: 'total@avengers.com', address: { country: 'USA', city: 'New York' }};
exports.set(obj);

Keď vyvoláme funkciu exports.set() len s jedným argumentom (v tomto prípade to je objekt obj), tak tento objekt bude uložený do našej cesty userform (pretože sa nachádzame v PLUGINe userform). Po vyvolaní funkcie complete bude náš model na ceste window.userform vyzerať takto:

{ 
  "email": "total@avengers.com",
  "address": { 
    "country": "USA",
    "city": "New York"
  }
}
Ukážka funkcie complete

Funkcia complete_email

exports.set('email', 'avengers@totaljs.com');

V tomto príklade sme použili vo funkcii exports.set() dva argumenty. Prvý argument je cesta, kde chceme nastaviť novú hodnotu. V tomto príklade to bude cesta email, ktorá bude automaticky rozšírená na window.userform.email (pretože sa nachádzame v PLUGINe userform). Ostatné cesty, ktoré sa týkajú cesty userform zostanú nezmenené. Po vyvolaní funkcie complete_email bude náš model na ceste window.userform vyzerať takto:

{
  "address": {
    "city": "Banská Bystrica",
    "country": "Slovakia"
  },
  "email": "avengers@totaljs.com"
}
Ukážka funkcie complete_email

Tieto funkcie (exports.set(), exports.model, ...) môžu byť použité jedine v PLUGINoch. Existujú aj globálne ekvivalenty týchto funkcií, ktoré môžeme použiť aj vo vnútri PLUGINov na ovplyvnenie ciest mimo daného PLUGINu.