Category Archives: HTML, CSS, JScript

IE: Při použití auto-complete se nevyvolá událost onChange

Internet Explorer při použití auto-complete nevyvolá na daném prvku (inputu) událost onChange, bug (i když někteří by možná řekli by-design).

Mimo obskurnějších řešení se dá auto-complete na daném prvku prostě vypnout:

<input ... autocomplete="off" />
<asp:TextBox ... autocomplete="off" />

Případně ho vypnout na celém formuláři:

<form ... autocomplete="off">

…nefunguje bohužel možnost na celém formuláři vypnout a uvnitř na některých prvcích zapnout.

Šířka tlačítek v IE (input type=“button“)

V Internet Exploreru je docela alchymie vyrobit tlačítko, které je široké stejně jako text na něm.

<input type="button" value="Text tlačítka" class="button"/>
<asp:Button ID="MyButton" Text="Text tlačítka" class="button"/>

Co jinde funguje, v IE selhává:

.button {
    margin:0;
    padding:0;
}

Co však kupodivu pomůže, je nastavení:

.button{
    padding:0;
    width:auto;
    overflow:visible;
}

…někdy je lepší nebádat, proč tomu tak je.

Mozilla FireFox: Nefunguje XHTML-validní image-map

Následující XHTML-validní image-map v Mozille nechodí:

<img id="reklama" src=".." width="200" height="600" alt="..." usemap="#mapa" />
<map id="mapa">
    <area shape="rect" coords="10,110,186,245" alt="..." href="..." target="_blank" >
</map>

Mozille nestačí <map id=“…“> nýbrž vyžaduje <map name=“…“>… :-(((

Demo: http://www.bernzilla.com/bugs/imagemap1.html

IE7: Vlastní vyhledávání – Search Provider – OpenSearch

O možnosti přidání vlastního vyhledávání do Internet Exploreru 7 psal už dávno Michal Altair Valášek v článku „Jak přidat vyhledávání na stránkách do IE 7.0„, nebudu ho tu tedy opakovat a úvodní informace najde každý tam.

Doplňuji pouze, že existuje také možnost vytvoření linku, který daný search provider „nainstaluje“, resp. existuje JScript funkce AddSearchProvider, která IE řekne, že má nějaký search provider nainstalovat:

&lt;a href=&quot;#&quot; onclick=&quot;window.external.AddSearchProvider('/mySearch.xml')&quot;&gt;My Search&lt;/a&gt;

Další související články a odkazy:

mailto: Příprava mailů pro poštovního klienta včetně cc, bcc, subject a body

I při vývoji webových aplikací se občas setkáme s výstředním požadavkem, kdy je potřeba, aby aplikace „generovala maily pro Outlook“ (či jakéhokoliv poštovního klienta). Obchodníci prostě aplikacím nevěří, chtějí si mail před odesláním upravit, připojit vlastní podpis a mít ho ve vlastní Odeslané poště.

Obvykle chtějí „kliknu tady na to tlačítko a objeví se mi nový předvyplněný mail v Outlooku“… :-))
(Nebudu tu teď hodnotit, do jaké míry je to vhodné, spolehlivé, …)

Jednou z možných cest, jak výsledku dosáhnout, je použít HTML element

<a href="mailto:jmeno@prijmeni.cz">Tlačítko</a>

…asi nikoho nepřekvapuje, že takovýto odkaz vytvoří na klientu nový mail pro odeslání na zadanou adresu.

Ne každý však ví, že takovýto odkaz lze odekorovat tak, že mimo adresy příjemce předáme poštovnímu klientovi i Cc, Bcc, Subject, Body, či dokonce libovolnou hodnotu do hlavičky mailu. Není to kupodivu nic proprietarního, nýbrž to vyplývá z RFC 2368. Jednotlivé hlavičky najdete v RFC 822.

Můžeme tak například vytvořit bohatší odkaz:

<a href="mailto:infobot@example.com?subject=current-issue&amp;body=current-issue-body&amp;cc=jmeno@prijmeni.cz">Tlačítko</a>

Ještě jeden drobný zádrhel – jak nakódovat mezery, konce řádek, či dokonce češtinu. V zásadě bychom měli encodovat URL podle RFC 1738, nicméně v praxi to tak jednoduché není, protože např. v ASP.NET si se samotnými HttpUtility.UrlEncode(), ani HttpUtility.UrlPathEncode() nevystačíme:

  • mezerníky musíme převést na %20, nikoliv na + (to sice dělá UrlPathEncode(), ale ten zase neřeší konce řádek) ,
  • konce řádek musíme převést na %0D%0A, z praxe stačí i %0A (UrlEncode() prozměnu kóduje mezery na +),
  • …atp. i další speciální znaky.

Takže nakonec to může odkaz vypadat nějak takto:

<a href="mailto:?Subject=Nab%eddka%20%e8.%20&amp;Body=Pos%edl%e1m%20nab%eddku%0a%0aCENA%20%3d%201%a0114%20(111%2c40%2fks)">Tlačítko</a>

přičemž v ASP.NET lze odkaz emitovat třeba takto:

TlacitkoHL.NavigateUrl = String.Format(
    "mailto:{0}?Body={1}",
    email,
    HttpUtility.UrlEncode("tělo\nzprávy", Encoding.GetEncoding(1250)).Replace("+", "%20")
);

Ještě zajímavý postřeh – problémy s kódováním. Nezbývá než testovat, např. přestože samotná HTML stránka je třeba v kódování utf-8, je potřeba mailto URL odkaz encodovat do win-1250. Zřejmě je to o tom, že browser předá URL v nezměněné podobě poštovnímu klientovi (např. Outlooku) a informace o encodingu tam nikde mezi nimi neproběhne. Moc pěkné to není. Pokud byste k tomu někdo měl přesnější informace, uvítám je v komentáři. Mě to takhle funguje všude, kde to potřebuji, takže nemám teď motivaci ani čas nad tím dál bádat… ;-)

onBeforeUnload – Potvrzovací dialog před odchodem ze stránky

V browseru, na stránkách, kde dochází k editaci záznamů, či jiné aktivitě, kterou je potřeba zakončit uložením či volbou nějakého tlačítka, se nám může hodit využít události onBeforeUnload k zobrazení potvrzovacího dialogu s dotazem, zde si uživatel opravdu přeje stránku opustit.

<html>
<head>
   <script type="text/jscript">
      // inicializace  
      g_blnCheckUnload = true;     
      function RunOnBeforeUnload()
      {
         if (g_blnCheckUnload)
         {
            window.event.returnValue = 'Text, který bude přidán do confirmačního dialogu';
         }
      }
      function bypassCheck()
      { 
         g_blnCheckUnload  = false; 
      }
   </script>
</head>
<body onBeforeUnload="RunOnBeforeUnload();">
   <a href="http://www.havit.cz">dotaz zobrazen</a>
   <a href="http://www.havit.eu" onClick="bypassCheck">dotaz nezobrazen</a>
</body>
</html>

Událost onBeforeUnload se volá nejenom na odkazech a tlačítkách, ale i při zavírání okna prohlížeče a prakticky veškerých událostech, kde by mělo dojít k opuštění stránky.

Funguje to minimálně v Internet Exploreru a FireFoxu.

Modifikace s hlídáním změn

Nakonec se mi podařilo rozchodit i rozumnou podobu výše uvedeného, kdy je potvrzovací dotaz zobrazen jen při změně formulářových dat (a je tedy potřeba změny uložit):

<html>
<head>
   <script type="text/jscript">
      // inicializace  
      g_blnCheckUnload = false;     
      function RunOnBeforeUnload()
      {
         if (g_blnCheckUnload)
         {
            window.event.returnValue = 'Text, který bude přidán do confirmačního dialogu';
         }
      }
      function bypassCheck()
      { 
         g_blnCheckUnload  = false; 
      }
      function setupCheck()
      {
         g_blnCheckUnload  = true; 
      }
      registerEvents()
      {
         for (i = 0; i < document.forms[0].elements.length; i++)
         {
            document.forms[0].elements[i].onchange = setupCheck;
         }
      }
   </script>
</head>
<body onLoad="registerEvents();" onBeforeUnload="RunOnBeforeUnload();">
   <form ...>
      <input .../>
      ...
   </form>
   <a href="http://www.havit.cz">dotaz zobrazen, jsou-li změny</a>
   <a href="http://www.havit.eu" onClick="bypassCheck">dotaz nezobrazen</a>
</body>
</html>

…další vylepšování je samozřejmě možné.

Update (PetrF): Pokud nějaké existující události onChange chceme zachovat

function registerEvents()
{
 for (i = 0; i < document.forms[0].elements.length; i++)
 {
   var elem = document.forms[0].elements[i];
   var fnOnChangeOld = (elem.onchange) ? elem.onchange : function () {};
   elem.onchange = function () { fnOnChangeOld(); setupCheck() };
 }
}

…nebo přes jQuery.

Tisk dlouhých tabulek – záhlaví a zápatí na každé stránce

Poměrně neznámým fíglem lze v některých browserech zajistit, aby se při tisku dlouhých tabulek, které se nevejdou na jednu stránku, vytiskly určité jejich řádky na každé stránce (záhlaví a zápatí).

Stačí využít sekce tabulky thead a tfoot a nastavit jim ty správné styly.

 ...
<style type="text/css">
   thead {display: table-header-group;}
   tfoot {display: table-footer-group;}
</style>
...
<table>
   <thead>
      <tr>
         <td>Hlavička 1</td>
         <td>Hlavička 2</td>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td>123</td>
         <td>456</td>
      </tr>
      ...
   </tbody>
   <tfoot>
      <tr>
         <td>Patička 1</td>
         <td>Patička 2</td>
      </tr>
   </tfoot>
</table>

Velikost okna browseru univerzálně

V jednotlivých prohlížečích se informace o aktuální velikosti okna zjišťuje dost různě, je tedy nutno použít určitou kaskádu pro „univerzální“ (alespoň trochu) vyhodnocení:

var winWidth, winHeight, d=document;
if (typeof window.innerWidth!='undefined')
{
   winWidth = window.innerWidth;
   winHeight = window.innerHeight;
}
   else
{
   if (d.documentElement && )typeof d.documentElement.clientWidth != 'undefined') && (d.documentElement.clientWidth != 0))
   {
       winWidth = d.documentElement.clientWidth;
       winHeight = d.documentElement.clientHeight;
   }
   else
   {
       if (d.body && (typeof d.body.clientWidth != 'undefined'))
       {
           winWidth = d.body.clientWidth;
           winHeight = d.body.clientHeight;
       }
   }
}

CSS: Vertikální centrování

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>
   <title>Vertikální centrování</title>
   <style>
      .greenBorder {border: 1px solid green;} /* nepodstatný styl */
   </style>
</head>
<body>
   <div class="greenBorder" style="display: table; height: 400px; _position: relative; overflow: hidden;">
      <div style=" _position: absolute; _top: 50%;display: table-cell; vertical-align: middle;">
         <div class="greenBorder" style=" _position: relative; _top: -50%">
            libovolný prvek<br>
            libovolné výšky<br>
            a libovolného obsahu<br>
            zůstává vertikálně vystředěný
         </div>
      </div>
   </div>
</body>
</html>

Zdroj: JakPsatWeb.cz
Funguje i s jinými DOCTYPE, vyzkoušeno např. s HTML 4.01 Transitional s loose.dtd.

Pozicování obrázkových bulletů – ul, li

S pozicování obrázkových bulettů použitých jako list-style-image je děsnej opruz, každý prohlížeč to interpretuje jinak a spolehlivě to snad ani nejde.

Je mnohem jednodušší dát list-style-type:none a obrázkové bulettky udělat jako správně pozicované pozadí li:

ul { list-style-type: none; }
li
{
   background-image: url(...);
   background-repeat: no-repeat;
   background-position: 0 5px;
   padding-left: 10px;
}