V článcích Intervalu jsme popsali několik aplikací, které umožňují poslat zprávu danému adresátu. V tomto článku vyrobíme jakýsi seznam kontaktů, díky kterému bude posílání SMS nebo instantních zpráv v intranetu mnohem pohodlnější.

Předem je potřeba si říct, že následující aplikace není ničím extra novým. Jde jen o chytře poskládané funkce, které byly v článcích Intervalu dávno probrány, proto se nebudu zabývat v popisu úplnými detaily, ale uvedu jen odkaz na konkrétní článek. Náš kontakt list bude tvořen víceřádkovým select-boxem. Pro práci s ním využijeme funkce pro práci s cookies, pro přidávání, odebírání položek selectboxu, jejich třídění, přesouvání a označování. Dále ještě využijeme funkce pro práci se schránkou (clipboardem) a doplníme „finty“, které obejdou odlišnosti chování různých prohlížečů. Prohlédněte si ukázku (zdrojový kód) – přidejte do kontakt listu aspoň tři položky, vyzkoušejte jejich třídění a přesouvání. Kromě možnosti vybrat více položek a vložit je do pole adresáta tlačítkem „Použít“, můžete také použít jednotlivé položky dvojím kliknutím.

Aplikaci tvoří formulář s poli pro odeslání zprávy a víceřádkový selectbox s tlačítky funkcí:

 <script type=“text/javascript“ src=“ClientScripts/Cookies.js“></script>
<script type=“text/javascript“ src=“ClientScripts/Messenger.js“></script>
<form id=“smsform“ style=“margin:0px;padding:0px;“>
  <fieldset style=“width:400px;float:left;“>
    <legend>Odeslat zprávu<br /></legend>
    <strong>Příjemce:</strong>
    <div>
      <input type=“text“ id=“txtMsgTarget“ name=“txtMsgTarget“ size=“40″ />
      <!–[if gte IE 5]><input type=“button“ title=“Vloží příjemce ze schránky“ onclick=“javascript: if (this.form.txtMsgTarget.value.length>0) {this.form.txtMsgTarget.value+=‘,‘}; this.form.txtMsgTarget.value += window.clipboardData.getData(‚Text‘)“ value=“&#9668;“ /><![endif]–>
      <input type=“button“ title=“Vymaže příjemce“ onclick=“javascript: this.form.txtMsgTarget.value=“;“ value=“x“ />
    </div>
    <div>
      <textarea id=“txtMessage“ name=“txtMessage“ maxlength=“1024″ Cols=“60″ rows=“3″ style=“overflow:auto;width:340px;“></textarea>
      <input type=“submit“ value=“Odeslat“ title=“Odešle zprávu (ALT-S)“ accesskey=“s“ />
    </div>
  </fieldset>
  <fieldset style=“width:320px;“>
    <legend>Moje kontakty<br /></legend>
    <div style=“margin:2px;“>
      <input type=“button“ title=“Použít vybrané kontakty“ onclick=“javascript:AddSelectedTargets(this.form.lsbContactList,this.form.txtMsgTarget)“ value=“Použít“ />
      <input type=“button“ title=“Vybrat všechny kontakty“ onclick=“javascript:SelectAll(this.form.lsbContactList,true)“ value=“Vše“ />
      <input type=“button“ title=“Zrušit výběr“ onclick=“javascript:SelectAll(this.form.lsbContactList,false)“ value=“Odznačit“ />
      <input type=“button“ title=“Invertovat vybrané kontakty“ onclick=“javascript:SelectInvert(this.form.lsbContactList)“ value=“Prohodit“ />
    </div>
    <div style=“margin:2px;“>
      <div style=“float:left;width:200px;“>
        <select id=“lsbContactList“ multiple=“multiple“ style=“width:200px;overflow:auto;“ size=“10″ onchange=“javascript: window.status=this.value;“ ondblclick=“javascript: AddTarget(this, this.form.txtMsgTarget);“></select>
      </div>
      <div style=“float:left;width:80px;“>
        <input type=“button“ onclick=“javascript:AddContact(document.getElementById(‚lsbContactList‘));“ title=“Přidat kontakt“ value=“Nový“ />
        <input type=“button“ onclick=“javascript:EditContact(document.getElementById(‚lsbContactList‘));“ title=“Upravit kontakt“ value=“Upravit“ />
        <input type=“button“ onclick=“javascript:RemoveContact(document.getElementById(‚lsbContactList‘));“ title=“Odebrat kontakt“ value=“Smazat“ />
        <input type=“button“ onclick=“javascript:MoveUp(document.getElementById(‚lsbContactList‘));“ title=“Přesunout nahoru“ value=“Nahoru“ />
        <input type=“button“ onclick=“javascript:MoveDown(document.getElementById(‚lsbContactList‘));“ title=“Přesunout dolů“ value=“Dolů“ />
        <input type=“button“ onclick=“javascript:SortDown(document.getElementById(‚lsbContactList‘),false);“ title=“Seřadit sestupně“ value=“Sestupně“ />
        <input type=“button“ onclick=“javascript:SortUp(document.getElementById(‚lsbContactList‘),false);“ title=“Seřadit vzestupně“ value=“Vzestupně“ />
      </div>
    </div>
  </fieldset>
</form>

V kódu zavádíme skript pro práci s cookies a skript s funkcemi pro kontakt list. Zvlášť bych zde jen upozornil na tlačítko, které vloží do pole adresáta obsah schránky získaný z objektu clipboardData. Pokud v poli adresáta již nějaký adresát je, přidá se navíc čárka pro oddělení příjemců zprávy. Protože práce se schránkou je specifická pouze pro prohlížeč IE, je tlačítko v ostatních prohlížečích odfiltrováno podmíněným komentářem. Některá tlačítka jsou pro rychlejší použití doplněna klávesovou zkratkou pomocí atributu accesskey. Použito je také sdružení položek formuláře pomocí fieldset a legend.

Dále si probereme jednotlivé funkce volané při kliknutí na tlačítka ve formuláři nebo dvojím kliknutím na vybranou položku seznamu. Obslužné funkce jsou definované v externím souboru Messenger.js. Nejprve funkce pro přidávání, odebírání a editaci položek seznamu.

function AddContact(theSelect)
{
  var target = prompt(„Zadejte příjemce zprávy (login name, počítač nebo IP adresu):“,““);
  if (target != null && target.length > 0)
  {
    var nick = prompt(„Zadejte přezdívku příjemce:“,““);
    if (nick == null || nick.length < 1)
      nick = target;
    var no = new Option();
    no.value = target;
    no.text = nick;
    var sIndex = theSelect.selectedIndex;
    if (sIndex > -1)
      theSelect.add(no,sIndex);
    else
    {
      if (navigator.appName == „Netscape“)
        theSelect.add(no,null);
      else
        theSelect.add(no,theSelect.length);
    }
    SaveContactList(theSelect);
  }
}
function EditContact(theSelect)
{
  var sIndex = theSelect.selectedIndex;
  if (sIndex > -1)
  {
    var target = prompt(„Zadejte příjemce zprávy (login name, počítač nebo IP adresu):“,theSelect.value);
    if (target != null && target.length > 0)
    {
      theSelect.options[sIndex].value = target;
      window.status = target;
      SaveContactList(theSelect);
    }
  }
}
function RemoveContact(theSelect)
{
  with (theSelect)
    if (length >0 && selectedIndex > -1 && confirm(‚Opravdu chcete odebrat vybrané kontakty?‘))
    {
      for( var i=length-1; i>=0; i– )
        if (options[i].selected)
          remove(i);
      SaveContactList(theSelect);
    }
}

Princip funkcí vychází z popisu prvku select, na konci funkcí je volána funkce pro uložení kontaktů do cookies, tuto si popíšeme později. Vždy je otestováno, zda je vybrán nějaký prvek, pokud ano, pracuje se s ním. Funkce pro mazání kontaktů prochází celou kolekci options v cyklu – vybrané prvky jsou v cyklu odstraněny. Vstup textu od uživatele je zajišťován dialogem prompt. Každý kontakt se skládá z přezdívky a skutečné adresy, proto jsou při přidávání nového kontaktu dotazy dva. Pokud je druhý dotaz stornován, nebo zadán prázdný řetězec, je jako adresa použita stejná hodnota jako pro přezdívku – text i hodnota prvku v seznamu budou stejné.

Funkce pro vzestupné a sestupné třídění vychází z článku Editace položek ve vícesloupcovém seznamu (II.):

function Swap( index, theSelect )
{
  var tmp = theSelect.options[index].value;
  theSelect.options[index].value = theSelect.options[index+1].value;
  theSelect.options[index+1].value = tmp;
  tmp = theSelect.options[index].text;
  theSelect.options[index].text = theSelect.options[index+1].text;
  theSelect.options[index+1].text = tmp;
}
function SortDown(theSelect,numeric)
{
  with(theSelect)
    if (theSelect.length > 0)
    {
      for (var j = 0; j<length; j++)
      {
        for(var i=0; i<length-1; i++)
        {
          if(numeric)
          {
            if((1*options[i].text)>(1*options[i+1].text))
              Swap(i,theSelect);
          }
          else
          {
            if(options[i].text>options[i+1].text)
              Swap(i,theSelect);
          }
        }
      }
      selectedIndex = -1;
      SaveContactList(theSelect);
    }
}
function SortUp(theSelect,numeric)
{
  with(theSelect)
    if (theSelect.length > 0)
    {
      for (var j = 0; j<length; j++)
      {
        for(var i=0; i<length-1; i++)
        {
          if(numeric)
          {
            if((1*options[i].text)<(1*options[i+1].text))
              Swap(i,theSelect);
          }
          else
          {
            if(options[i].text<options[i+1].text)
            Swap(i,theSelect);
          }
        }
      }
      selectedIndex = -1;
      SaveContactList(theSelect);
    }
}
function MoveDown(theSelect)
{
  var sIndex = theSelect.selectedIndex;
  if (sIndex > -1 && sIndex < theSelect.length-1)
  {
    Swap(sIndex,theSelect);
    theSelect.selectedIndex = sIndex+1;
    SaveContactList(theSelect);
  }
}
function MoveUp(theSelect)
{
  var sIndex = theSelect.selectedIndex;
  if (sIndex > 0)
  {
    Swap(sIndex – 1,theSelect);
    theSelect.selectedIndex = sIndex-1;
    SaveContactList(theSelect);
  }
}

Funkce Swap() byla využita i pro posun vybrané položky nahoru nebo dolů ve funkcích MoveDown() a MoveUp(), které v původním článku nejsou. Prakticky jde jen o otestování, zda je co posunout a kam, změnu indexu vybrané položky (aby i po přesunu byla vybrána položka, kterou jsme přemístili) a nakonec opět uložení kontaktů.

Funkce pro označování, odznačování a inverzi výběru jsou převzaty z článku Další hrátky s formulářovým polem SELECT:

function SelectAll(theSelect,value)
{
  for( var i=0; i<theSelect.length; i++ )
    theSelect.options[i].selected = value
}
function SelectInvert(theSelect)
{
  for( var i=0; i<theSelect.length; i++ )
    theSelect.options[i].selected = !theSelect.options[i].selected
}

Následují funkce pro přenesení kontaktu do pole adresáta:

function AddTarget(theSelect,fieldObj)
{
  with(theSelect)
    if (length > 0 && selectedIndex > -1)
    {
      if (fieldObj.value.length>0)
        fieldObj.value+=‘,‘;
      fieldObj.value += options[selectedIndex].value;
    }
}
function AddSelectedTargets(theSelect,fieldObj)
{
  with (theSelect)
    if (length > 0)
    {
      var stringTargets = „“;
      for( var i=0; i<length; i++ )
        if (options[i].selected)
        {
          if (stringTargets.length > 0)
            stringTargets += „,“;
          stringTargets += options[i].value;
        }
      if (fieldObj.value.length>0)
        fieldObj.value+=‘,‘;
      fieldObj.value += stringTargets;
    }
}

První funkce je volána na dvojklik v seznamu kontaktů – pokud je nějaká položka vybrána, její hodnotu přidáme do formulářového pole adresáta. Pokud toto pole není prázdné, přidáme navíc čárku k oddělení adresátů. Druhá funkce přenáší všechny vybrané kontakty (je volána tlačítkem „Použít“). V cyklu připravíme řetězec z hodnot vybraných položek oddělených čárkou. Tento řetězec nakonec přidáme do pole adresáta, stejně jako v předchozí funkci přidáme navíc čárku, pokud v poli adresáta již něco zadáno je.

Před popisem funkcí pro čtení a ukládání kontaktů do cookies si nejprve osvětlíme, v jaké podobě budeme seznam kontaktů ukládat. Princip vychází z již zmiňovaného článku Ukládání dat pomocí JavaScriptu – forma cookies, kde je popsáno, jak celý záznam uložit do jedné cookie. Všechny kontakty sloučíme do řetězce, kde jsou text a hodnota položky odděleny znakem „=“ a jednotlivé položky znakem „;“. Tento celý řetězec je pak uložen do jediné cookie s názvem IMS a dobou platnosti jeden rok.

function SaveContactList(theSelect)
{
  var saveStr = „“;
  with(theSelect)
  {
    for(var i=0; i<length; i++)
      saveStr += options[i].value + „=“ + options[i].text + „;“;
    MyCookie.Write(‚IMS‘,saveStr+“ „, 365);
  }
}
function ReadContactList(theSelect)
{
  var readStr = MyCookie.Read(‚IMS‘);
  if (readStr != null && readStr.length > 0)
  {
    var cookieList = readStr.split(„;“);
    var cookieArray = new Array();
    for (var i=0; i < cookieList.length-1; i++)
    {
      cookieArray = cookieList[i].split(„=“);
      var no = new Option();
      no.value = cookieArray[0];
      no.text = cookieArray[1];
      var sIndex = theSelect.selectedIndex;
      if (navigator.appName == „Netscape“)
        theSelect.add(no,null);
      else
        theSelect.add(no,theSelect.length);
    }
  }
}

Funkce pro načtení seznamu kontaktů přečte hodnotu cookie. Pokud existuje a není prázdná, pak je její obsah opět rozdělen metodou split() podle znaku „;“ na jednotlivé položky. Tyto položky jsou pak v cyklu dále rozděleny opět pomocí split() na hodnotu a text a naplněny jako nové položky selectboxu. Stejně jako ve funkci pro přidání záznamu je zde navíc řešeno odlišné pojetí metody add() v prohlížečích na bázi Mozilly a IE.

Nakonec nám zbývá zajistit naplnění našeho kontakt listu při načtení stránky. Připravíme funkci, která zavolá funkci pro načtení seznamu se správným parametrem objektu našeho selectboxu, a přidáme ji ke spuštění při události onload okna.

function OnStart()
{
  ReadContactList(document.getElementById(‚lsbContactList‘));
}
window.onload = OnStart;

Naše ukázka předpokládá použití v aplikaci pro zasílání instantních zpráv v intranetu, ale jistě se bude hodit v řadě jiných aplikací, jako je například SMS brána. Na závěr jen podotýkám, že kapacita cookies uložitelných v prohlížeči není neomezená, a tak kontakt list jistě nebude schopen pojmout stovky položek. Pár jednotek či desítek záznamů, které pojme, však rozhodně pomůže zvýšit komfort uživatele. Zvýšení kapacity by bylo možné ukládáním pouze hodnoty a nikoli textu položky, případně použít více hodnot cookie než jednu dlouhou.

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

Odpovědět