Použití JavaScriptu není striktně omezeno pouze na stránky vystavené na internetu. Jednou z užitečných aplikací může být jeho použití v místech, kde nelze počítat se serverovými skripty, například na demonstračních CD. Podívejme se, jak lze JavaScriptem zvládnout jednoduchou strukturu HTML menu cédéčka a především „fulltextové“ vyhledávání v zobrazených textech.

Chceme-li mít možnost vyhledávat v textu stránek, zobrazených na CD jako HTML menu, máme nejméně tři možnosti:

  • Použít samostatný obslužný program.
  • Použít windows scripting host a metody objektu FileSystemObject.
  • Uložit texty stránek do nějaké struktury a tu zobrazovat a prohledávat pomocí JavaScriptu.

Každý z těchto způsobů má své výhody a nevýhody. My si v tomto článku popíšeme způsob třetí, který vyžaduje pouze prohlížeč se zapnutým JavaScriptem, což je v současné době u většiny uživatelů téměř standardní vybavení (pro puristy dodávám, že uživatele bez JavaScriptu lze vcelku jednoduše detekovat a věnovat jim speciální verzi HTML menu, bez možnosti vyhledávání).

Podívejme se na ukázku fiktivního CD fiktivní firmy, plné fiktivních produktů a fotografií (odkazy na spustitelné soubory jsou nefunkční, fotografie v ukázce zahrnuty jsou). Vyzkoušejte si procházení celé úrovně menu, případně vyhledávání některých klíčových slov (například „foto“, „program“ apod.)

Použitý JavaScript

HTML soubor, uvedený v příkladu, se jmenuje sample_cdmenu.htm. Veškeré odkazy v použitých skriptech jsou směřovány na tento soubor. Při přejmenování je tedy potřeba příslušné odkazy upravit nebo modifikovat skript, například s použitím location.pathname.

Jádrem celého řešení je objekt Menu, který slouží především jako úložiště textů a odkazů. Pokud máme veškeré zobrazené texty uloženy na jednom místě, lze je později snadno prohledávat. Zde si ukážeme základ kódu objektu Menu, tedy jeho metody a vlastnosti použité při ukládání dat. Kód dalších metod objektu Menu, sloužící k prohledávání a dalším funkcím, uvedeme níže. Pomocná proměnná lastid je použita ke generování unikátního id pro každé vytvořené menu. Zbytek kódu je triviální:

var lastid=0;
function Menu( title, txt ) {
    this.title = title;
    this.txt = txt;
    this.id = lastid++;
    this.submenuscount = 0;
    this.submenus = new Array()
    this.linkscount = 0;
    this.linkurls = new Array()
    this.linktexts = new Array()
    this.AddMenu = function( mnu ) {
        this.submenus[this.submenuscount] = mnu
        this.submenuscount++;
    }
    this.AddLink = function( txt, url ) {
        this.linktexts[this.linkscount] = txt;
        this.linkurls[this.linkscount] = url;
        this.linkscount++;
    }
}

Strukturu konkrétního menu vytvoříme opakovaným vytvářením nových objektů třídy Menu a jejich spojováním pomocí metody AddMenu. K vytvoření „finálních“ odkazů na externí stránky, obrázky či produkty slouží metoda AddLink. Konkrétní kód pak může vypadat například takto:

var Menus = new Menu( „Vítejte na CD firmy XYZ“, „Na tomto CD najdete fotografie našich zaměstanců a nějaký software.“ );
Menus.AddMenu( m1 = new Menu( „Fotografie“, „Vyberte si kategorii fotografií.“) );
    m1.AddMenu( m2 = new Menu( „Vedení“, „Toto jsou naši hlavouni:“ ) );
        m2.AddLink( „Pepa, ředitel“, „pepa.jpg“ );
        m2.AddLink( „Franta, náměstek“, „franta.jpg“ );
    m1.AddMenu( m2 = new Menu( „Kancelář“, „Sekretářky a jiné:“ ) );
        m2.AddLink( „Janička“, „jana.jpg“ );
        m2.AddLink( „Lucinka“, „lucie.jpg“ );
        m2.AddLink( „Martička“, „marta.jpg“ );
    m1.AddMenu( m2 = new Menu( „Dělníci“, „Tito lidé nás všechny živí:“ ) );
        m2.AddLink( „Zdeněk, výroba software“, „zdenek.jpg“ );
        m2.AddLink( „Tomáš, odhánění dotěrných zákazníků“, „tomas.jpg“ );
Menus.AddMenu( m1 = new Menu( „Software“, „Vyberte si typ software.“ ));
    m1.AddMenu( m2 = new Menu( „Naše programy“, „Naše skvělé produkty:“ ) );
        m2.AddLink( „Operační systém Krach 2001“, „krach/krach.exe“ );
        m2.AddLink( „Prohlížeč obrázků“, „imgview/setup32.exe“ );
    m1.AddMenu( m2 = new Menu( „Service packy“, „Tyto programy napravují chyby, které jsme udělali ve starších verzích našich programů:“) );
        m2.AddLink( „Service pack 1 k operačnímu systému Krach 2001“, „sp/sp1setup.exe“ );
        m2.AddLink( „Service pack 1a k service packu 1“, „sp/sp1asetup.exe“ );
        m2.AddLink( „Service pack 1aB k service packu 1a k service packu 1“, „sp/sp1aBsetup.exe“ );

Dalším úkolem je zjistit, které konkrétní menu máme právě zobrazit (ID tohoto menu je předáváno v URL adrese). K tomu slouží následující kód, který zároveň v případě, že bylo žádáno vyhledávání, získá z URL hledaný řetězec. Menu, které se má zobrazit, je uloženo do pomocné proměnné aMenu. Pokud byl hledán řetězec, je tento uložen do proměnné strtofind:

var id = 0;
var strtofind=““;
if((index = location.search.indexOf(„?“))!=-1) {
    if((i2 = location.search.indexOf(„find=“))!=-1) {
        var pomstr = location.search.slice(i2+5);
        if((i2 = pomstr.indexOf(„&“))!=-1) pomstr = pomstr.slice(0,i2);
        strtofind = unescape(pomstr);
    } else {
        var pomstr = location.search.slice(index+4)
        if( pomstr.length > 0 )  id = Math.ceil(pomstr);
    }
}
var aMenu = Menus.GetMenuByID(id);

V posledním řádku předchozího kódu je použita metoda GetMenuByID objektu Menu. Tato metoda hledá rekurzivně ve struktuře menu to jedno jediné s odpovídajícím ID a její kód vypadá následovně:

this.GetMenuByID = function( theId ) {
    var x,i;
    if ( theId==this.id ) return this;
    for( i=0; i<this.submenuscount; i++ ) {
        x = this.submenus[i].GetMenuByID(theId);
        if ( x != null ) return x;
    }
    return null;
}

V místě stránky, ve kterém si přejeme vypsat texty právě zvoleného menu a odkazy na další úrovně menu, použijeme kód, který může vypadat třeba takto (konkrétní formátování lze samozřejmě upravit dle potřeby):

if(strtofind==““) {
    document.write(„<h1>“+aMenu.title+“</h1>“);
    document.write(aMenu.txt+“<br><br>“);
    var i;
    for(i=0;i<aMenu.submenuscount;i++) {
        document.write(‚<a href=“sample_cdmenu.htm?id=’+aMenu.submenus[i].id+'“>’+aMenu.submenus[i].title+'</a><br>‘);
    }
    for(i=0;i<aMenu.linkscount;i++) {
        document.write(‚<a href=“‚+aMenu.linkurls[i]+'“>’+aMenu.linktexts[i]+'</a><br>‘);
    }
}

K vyhledávání použijeme ve vhodném místě stránky formulář s následujícím HTML kódem („podivné“ odesílání výsledků přes handler události onSubmit je zde proto, aby bylo zachováno správné kódování českých znaků):

<form action=““ onSubmit=“location.href=’sample_cdmenu.htm?find=’+escape(this.find.value);return false;“>
    Vyhledávání:<br>
    <input type=“text“ value=““ name=“find“ size=“10″> <input type=“submit“ name=“s“ value=“Najdi“>
</form>

Poté, co uživatel odešle formulář, je do proměnné strtofind uložen hledaný text (viz kód uvedený výše). Zbývá prohledat uložená data a výsledky zobrazit ve formě jednoduché tabulky s odkazy na nalezené dokumenty. Výpis výsledků zajistí následující kód…

if(strtofind!=““) {
    document.write(„<h1>Výsledky vyhledávání</h1>“);
    Menus.WriteFindResults(strtofind);
    if(found)
        document.write(„<p>Hledaný text byl nalezen „+found+“ x</p>“);
    else
        document.write(„<p>Hledaný text nebyl nalezen.</p>“);
}

…v kombinaci s pomocnou proměnnou found, uchovávající počet nalezených výsledků, a novou metodou (opět použijeme rekurzi) WriteFindResults objektu Menu:

// v hlavičce stránky
var found=0;
// v kódu objektu Menu
this.WriteFindResults = function( strfind ) {
    var i,s1;
    s1=this.title.toLowerCase() + this.txt.toLowerCase();
    if( s1.indexOf(strfind.toLowerCase())!=-1) {
        document.write(‚<a href=“sample_cdmenu.htm?id=’+this.id + ‚“>‘ + this.title + ‚</a><br>‘);
        found++;
    }
    for( i=0; i<this.submenuscount; i++ ) {
        this.submenus[i].WriteFindResults(strfind);
    }
}

Uvedený kód lze samozřejmě použít všude tam, kde chceme návštěvníkům nabídnout vyhledávání a nemáme možnost použít serverové skripty. Daní za to je však složitější editace stránek než v případě „obyčejného“ HTML – musíme „vyprogramovat“ více věcí než obvykle.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

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

Odpovědět