Jak vložit do stránek solidní systém nápovědy, který by se pokud možno podobal nápovědě ve Windows? To je úkol, který lze řešit nejrůznějšími způsoby, mimo jiné i pomocí JavaScriptu. Dnes si ukážeme základní prvek nápovědy – dvojici oken, v levém rozbalovací strom s jednotlivými tématy nápovědy, v pravém pak obsah jednotlivých témat nápovědy.

Jako obvykle nejprve ukázka. Mezi jednotlivými položkami v levém okně se lze pohybovat klikáním myší, eventuelně klávesami se šipkami, rozbalování podúrovní se děje v Internet Exploreru dvojklikem na příslušné položce, v Netscape k tomu účelu slouží tlačítko +/-, umístěné mezi okny.

 JavaScript  Nápověda

Protože se jedná o poměrně rozsáhlý skript, omezíme se tentokrát na stručné popisy jeho jednotlivých částí.

Valnou většinu práce zajišťuje objekt MeHelp, do kterého jednak ukládáme samotná data (tj. texty) nápovědy, navíc tento objekt obsahuje množství funkcí pro zobrazení. Kód objektu si ukážeme po částech (vhodné umístění je ve vloženém .js souboru). Hlavička objektu:

function MeHelp( ){
    this.iLength = 0
    this.arrNames = new Array()
    this.arrTexts = new Array()
    this.arrNodes = new Array()
    this.arrExtracted = new Array()
    this.recLevel = 0

Význam uvedených členských proměnných je následující:

  • iLength – počet položek nápovědy
  • arrNames – názvy položek zobrazované v levém okně
  • arrTexts – texty k položkám zobrazované v pravém okně
  • arrNodes – pole s odkazy na rodičovský uzel příslušné položky
  • arrExtracted – pole s příznaky, zda je příslušný uzel rozbalen čili nic
  • recLevel – pomocná proměnná pro rekurzivní metodu WriteTree

První metodou objektu je funkce SetForm, pomocí které navážeme daný objekt na HTML formulář, do nějž se má nápověda zobrazovat. První parametr určuje „levé“ pole, druhý pole „pravé“:

    this.SetForm = function( selectfield, textfield ) {
        this.selectfield = selectfield    
        this.textfield = textfield   
    }

Metoda Add slouží k přidávání jednotlivých položek nápovědy. Prvním parametrem je číslo rodičovského uzlu (pro root je to nula), druhým text v levém poli, třetím text v pravém poli. Metoda vrací číslo přidané položky:

    this.Add = function( parent, name, txt ) {
        this.iLength++;
        this.arrNames[this.iLength] = name
        this.arrTexts[this.iLength] = txt
        this.arrNodes[this.iLength] = parent
        this.arrExtracted[this.iLength] = false
        return this.iLength
    }

Další metoda WriteTree, je rekurzivní funkce, která vypíše celý strom do levého pole, přičemž zohledňuje stav jednotlivých uzlů (sbaleno/rozbaleno). Parametr node určuje uzel, od nějž se vypisuje podstrom, a je využíván hlavně při rekurzi (při volání „zvenku“ použijeme hodnotu nula jako root). Pomocná proměnná spc (řetězec mezer) slouží ke grafickému odsazení jednotlivých podpoložek – pokud očekáváme hlubší úroveň zanoření, je dobré na to pamatovat jejím zvětšením.

    this.WriteTree = function(node) {
        var spc = "                                                                                    "
        spc = spc.slice(0,this.recLevel*3)
        for( var i=1; i<=this.iLength; i++ ) {
            if(this.arrNodes[i]==node) {
                this.selectfield.options[this.selectfield.options.length] = new Option( spc + this.arrNames[i] );
                this.selectfield.options[this.selectfield.options.length-1].value = i
                if( this.arrExtracted[i] ) {
                    this.recLevel++;
                    this.WriteTree( i );
                    this.recLevel–;
                }
            }
        }   
        this.WriteTxt()
    }

Metoda WriteTxt má za úkol zjistit, zda je v levém poli formuláře (stromu) vybrána nějaká položka, a pokud ano, vypíše do pravého pole její hodnotu (vlastní obsah nápovědy).

    this.WriteTxt = function() {
        if( (selindex=this.selectfield.selectedIndex) != -1 ) {
            index = this.selectfield.options[selindex].value
            this.textfield.value = this.arrTexts[index];
        } else {
            this.textfield.value = ""
        }
    }

Metoda Extract je volána při požadavku na sbalení/rozbalení podúrovně stromu. Je volána po stisku tlačítka +/- (u Netscape) nebo dvojkliku u Internet Exploreru. Sama si zjistí z levého okna formuláře uzel, jenž je třeba rozbalit či sbalit.

    this.Extract = function( ) {
        if( (selindex=this.selectfield.selectedIndex) != -1 ) {
            index = this.selectfield.options[selindex].value
            this.arrExtracted[index] = !this.arrExtracted[index]
            this.DeleteSelect()
            this.WriteTree(0)
        }
    }

Konečně poslední metoda, DeleteSelect, má za úkol smazat všechny položky z levého okna formuláře – je volána zpravidla před voláním metody WriteTree, aby pro tuto vyčistila místo. Za definicí metody je uvedena jedna pravá složená závorka navíc jako ukončení definice celého objektu MeHelp.

    this.DeleteSelect = function() {
        while(this.selectfield.length > 0 ) {
        this.selectfield.options[0] = null;
        }
    }
}

Tolik k objektu MeHelp. Vzorovou nápovědu sestavíme (po vytvoření instance objektu MeHelp) sérií volání metody Add – všimněte si, že vrácená hodnota u hlavních uzlů je využívána při vytváření podpoložek. Text v pravém poli (třetí parametr funkce Add) explicitně zalamujeme pomocí znaku nového řádku (úlitba pro Netscape):

var h1 = new MeHelp()
u1 = h1.Add( 0, "Všechny kategorie",
        "Kliknutím na nadpis\nv levém okně zobrazíte\npopis" );
u2 = h1.Add( u1, "ASP",
        "Všechno o ASP technologii…" );
h1.Add( u2, "ASP a databáze",
    "Technologie ASP se často používá s databázemi" );
h1.Add( u2, "ASP a Session object",
    "Užitečným objektem je objekt Session" );
u3 = h1.Add( u1, "JavaScript",
        "Vsechno o Java skriptu" );
h1.Add( u3, "JS a formuláře",
    "Pro ověřování formulářů používejte JavaScript" );
h1.Add( u3, "JS a cookies",
    "Cookies jsou dalším zajímavým využitím JavaScriptu." );
h1.Add( u3, "Další informace",
    "Další informace o JS najdete na\nwww.interval.cz!" );

Pro rozbalování uzlů dvojitým klikem v Internet Exploreru potřebujeme ještě jednu pomocnou funkci:

function ExtractOnDblClick(evnt) {
    h1.Extract()
}

Nyní si předvedeme vzorový HTML kód formuláře. Grafiku a rozmístění položek můžete přizpůsobit svým požadavkům, důležité je správné volání příslušných metod objektu MeHelp u příslušných handlerů událostí, pro Netscape uvedení aspoň jedné položky OPTION v poli SELECT kvůli správnému nastavení šířky tohoto pole (položka bude vzápětí smazána) a konečně vložený skript, jenž detekuje prohlížeč, načež pro Internet Explorer zajistí rozbalení/sbalení stromu na dvojí kliknutí, kdežto pro Netscape zajistí náhradní řešení pomocí tlačítka +/-. Celý kód je poměrně dlouhý, většinu však tvoří formátovací tagy tabulky, v níž je formulář rozvržen:

<form name="menu"><table border="0" cellpadding="0" cellspacing="0" width="200" bgcolor="#C0C0C0">
<tr>
    <td align="left" colspan="3" bgcolor="#000080"><font color="#FFFFFF"><b>JS Nápověda</b></font></td>
</tr>
<tr>
    <td align="left" valign="top">
    <select name="links" size="10" onChange="h1.WriteTxt()">
    <option value="0">************************</option>
    </select>
</td>
<td align="left" valign="top">
<script>
<!–
    if( navigator.userAgent.indexOf("MSIE") != -1 ) {
        document.ondblclick = ExtractOnDblClick;
    } else {
        document.write(‚<input type="button" value="+/-" name="extract" onClick="h1.Extract()">‘)
    }
//–>
</script>
</td>
<td align="left" valign="top"><textarea rows="9" name="popis" cols="28">&nbsp;</textarea></td>
</tr>
</table></form>

Nakonec zbývá propojit instanci objektu MeForm s právě vytvořeným formulářem a zajistit první vykreslení stromu do levého pole:

h1.SetForm( document.menu.links, document.menu.popis );
h1.DeleteSelect();
h1.WriteTree( 0 );

Příště si ukážeme rozšíření tohoto skriptu o další funkce Windows nápovědy.

Přeji vám příjemný den.

Žádný příspěvek v diskuzi

Odpovědět