<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Facilitant la web &#187; jquery</title>
	<atom:link href="http://blog.facilitant.net/tag/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.facilitant.net</link>
	<description>Recursos, consells i reflexions sobre el món de la web</description>
	<lastBuildDate>Thu, 02 Feb 2012 07:12:55 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Protegir pàgines amb l&#8217;event onbeforeunload</title>
		<link>http://blog.facilitant.net/2009/09/09/protegir-pagines-amb-levent-onbeforeunload/</link>
		<comments>http://blog.facilitant.net/2009/09/09/protegir-pagines-amb-levent-onbeforeunload/#comments</comments>
		<pubDate>Wed, 09 Sep 2009 14:30:43 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[usabilitat]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=173</guid>
		<description><![CDATA[No us ha passat mai que mentre esteu acabant d&#8217;omplir un formulari, sense adonar-vos, feu clic allà on no toca i perdeu tot el que heu introduït? Doncs bé, hi ha una senzilla manera per evitar al màxim aquests errors: l&#8217;event onbeforeunload. Cap allà als mitjans dels noranta, Internet Explorer 4.0 introduí aquest event no [...]]]></description>
			<content:encoded><![CDATA[<p>No us ha passat mai que mentre esteu acabant d&#8217;omplir un formulari, sense adonar-vos, feu clic allà on no toca i perdeu tot el que heu introduït? Doncs bé, hi ha una senzilla manera per evitar al màxim aquests errors: l&#8217;event <code class="javascript">onbeforeunload</code>.</p>
<p>Cap allà als mitjans dels noranta, Internet Explorer 4.0 introduí aquest event no estàndard, però a diferència d&#8217;altres ocasions, aquest cop feu una cosa útil i els navegadors amb motor Gecko ho acabaren introduint a la versió 1.7 de Mozilla (Firefox 1.0).</p>
<p>Aquest event, tal i com resa el seu nom, es dispara just <strong>abans</strong> de l&#8217;event <code class="javascript">onunload</code>, és a dir, abans que es descarregui el contingut actual de la pàgina, i per tant, ens permet executar algun tipus d&#8217;acció en aquest moment.</p>
<p>A diferència dels altres events, aquest funciona força diferent: per tal de mostrar un missatge a l&#8217;usuari abans de descarregar la pàgina, el que cal fer és retornar una cadena amb el missatge que es vulgui mostrar. Un exemple podria ser:</p>
<pre><code class="javascript">
window.onbeforeunload = function(e) {
  return "No heu enviat el formulari. Si tanqueu la pàgina perdreu tots els canvis fets fins ara.";
}
</code></pre>
<p>Així, en cas d&#8217;abandonar la pàgina, se&#8217;ns mostraria un quadre amb el missatge:</p>
<blockquote><p>Esteu segur que voleu sortir d’aquesta pàgina?</p>
<p><em>No heu enviat el formulari. Si tanqueu la pàgina perdreu tots els canvis fets fins ara.</em></p>
<p>Premeu D’acord per a continuar, o cancel·la per a romandre a la pàgina actual</p></blockquote>
<p>Les frases que hi ha just abans i després de les nostres les posa el navegador (en aquest cas Firefox) i no es poden eliminar, substituir ni evitar de cap tipus de les maneres.</p>
<p>Val a dir que en cas que el navegador no tingui implementat aquest event, aquests simplement l&#8217;ignoraran i no mostraran pas el missatge a l&#8217;usuari.</p>
<h3>Pàgines protegides</h3>
<p>Recapitulem. La raó principal d&#8217;aquest article és que fa poc a la feina em varen demanar que implementés una funcionalitat per a protegir pàgines: volien poder mostrar un missatge quan un usuari intentés abandonar la pàgina enmig d&#8217;un formulari dins d&#8217;un procés amb un cert flux o bé intentés abandonar una pàgina, la construcció de la qual fos molt costosa. Un exemple ideal per a treure l&#8217;event <code class="javascript">onbeforeunload</code> de la nostra cartera de recursos. Anem a construir-ho.</p>
<p>Per tal de poder marcar si una pàgina la tractem com a protegida o no, és a dir, si registrem l&#8217;event <code class="javascript">onbeforeunload</code> per mostrar un missatge a l&#8217;usuari en cas d&#8217;abandonar la pàgina, afegirem la classe <code>protected</code> a l&#8217;element <code class="html">/body</code> de la pàgina:</p>
<pre><code class="html">&lt;body class="protected"&gt;</code></pre>
<p>Així, si usem jQuery, podem afegir les següents línies de codi per a tenir-ho fet:</p>
<pre><code class="javascript">$('body.protected').each(function () {
  window.onbeforeunload = function(e){
    return "Si abandones, ho perdràs tot per sempre!";
  };
});
</code></pre>
<p>Però tenim un petit inconvenient: si fem clic en un enllaç o si enviem el formulari fent clic a un botó, se&#8217;ns mostrarà el missatge, cosa que volem evitar. Això es pot resoldre inhabilitant l&#8217;event en cas de fer clic a certs elements:</p>
<pre><code class="javascript">$('body.protected p.botons input, body.protected a.sense-onbeforeunload', context).click(function () {
  window.onbeforeunload = null;
});</code></pre>
<p>I així de fàcil obtenim el que busquem. Fàcil, oi? I segur que a més d&#8217;un li sembla útil, i fins i tot, més que necessari en alguna situació quotidiana.</p>
<h3>Recursos</h3>
<ul>
<li><a lang="en" xml:lang="en" hreflang="en" href="http://msdn.microsoft.com/en-us/library/ms536907%28VS.85%29.aspx">Onbeforeunload event. Internet Explorer Developer Center</a></li>
<li><a lang="en" xml:lang="en" hreflang="en" href="https://developer.mozilla.org/en/DOM/window.onbeforeunload">Window.onbeforeunload. Mozilla Developer Center</a></li>
<li><a lang="es" xml:lang="es" hreflang="es" href="http://blog.scriptia.net/articulos/2007/01/onbeforeunload.html">onbeforeunload: tiende una mano al usuario</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/09/09/protegir-pagines-amb-levent-onbeforeunload/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Com fer un plugin per a jQuery. Contingut tabulat en pestanyes</title>
		<link>http://blog.facilitant.net/2009/07/22/com-fer-un-plugin-per-a-jquery-contingut-tabulat-en-pestanyes/</link>
		<comments>http://blog.facilitant.net/2009/07/22/com-fer-un-plugin-per-a-jquery-contingut-tabulat-en-pestanyes/#comments</comments>
		<pubDate>Wed, 22 Jul 2009 18:53:16 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[plugin]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=148</guid>
		<description><![CDATA[Durant el meu dia a dia professional, treballo (i força) amb jQuery, una meravellosa biblioteca JavaScript (s’entreveuen les meves preferències, oi?). Doncs bé, la segona cosa que cal saber quan s’entra en el món jQuery és desenvolupar, o com a mínim conèixer l&#8217;estructura bàsica, d&#8217;un plugin. Per a exemplificar la construcció, crearem un petit giny [...]]]></description>
			<content:encoded><![CDATA[<p>Durant el meu dia a dia professional, treballo (i força) amb jQuery, una meravellosa biblioteca JavaScript (s’entreveuen les meves preferències, oi?). Doncs bé, la segona cosa que cal saber quan s’entra en el món jQuery és desenvolupar, o com a mínim conèixer l&#8217;estructura bàsica, d&#8217;un plugin.</p>
<p>Per a exemplificar la construcció, crearem un petit giny per a construir contingut tabulat en pestanyes.</p>
<p>Partim d’un fragment HTML com el següent:</p>
<pre><code class="html">&lt;div class="pestanyes"&gt;
  &lt;h2&gt;Pestanya 1&lt;/h2&gt;
  &lt;div&gt;
    ...contingut...
  &lt;/div&gt;
  &lt;h2&gt;Pestanya 2&lt;/h2&gt;
  &lt;div&gt;
    ...contingut de la segona...
  &lt;/div&gt;
  &lt;h2&gt;Pestanya 3&lt;/h2&gt;
  &lt;div&gt;
    ...i una mica més...
  &lt;/div&gt;
&lt;/div&gt;</code></pre>
<p>Si ens centrem en el giny, podríem redactar una petita explicació funcional com la següent:</p>
<ul>
<li>En estat de repòs, es mostren les pestanyes amb la primera activa i només es mostra el contingut relacionat amb aquesta.</li>
<li>Una vegada cliquem a una pestanya, aquesta passa a ser l’activa i el contingut que es mostra passa a ser el relacionat amb aquesta.</li>
</ul>
<p>Ara només falta traduir això a codi JavaScript.</p>
<p>Comencem creant l&#8217;estructura general del plugin:</p>
<pre><code class="javascript">$('.pestanyes').each(function() {
  ...
});</code></pre>
<p>I les estructures necessàries per a crear el giny. Primer de tot caldrà amagar les capçaleres i el contingut d&#8217;aquestes i crear l&#8217;estructura per a les pestanyes que a nosaltres ens sigui còmode de treballar-hi. Per exemple una d&#8217;ideal seria una senzilla llista <code class="html">&lt;ul&gt;&lt;li&gt;...&lt;/li&gt;&lt;/ul&gt;</code>.</p>
<p>Anem a passar tot això a codi JavaScript:</p>
<pre><code class="javascript">$('div.pestanyes').each(function () {
  // creem una referència a les capçaleres i al contingut de les pestanyes
  var $headings = $('h2', this);
  var $content = $headings.next();

  // amaguem les capçaleres i els continguts
  $headings.hide();
  $content.hide();

  // creem l'estructura de les pestanyes
  var tabHtml = '';
  $headings.each(function() {
    tabHtml += '&lt;li&gt;' + $(this).text() + '&lt;\/li&gt;';
  });

  // i l'afegim al document
  $(this).prepend('&lt;ul class="tabs"&gt;' + tabHtml + '&lt;\/ul&gt;');
}</code></pre>
<p>Una vegada creada l&#8217;estructura, només queda marcar l&#8217;estat inicial amb la primera pestanya i el seu contingut relacionat com a actius:</p>
<pre><code class="javascript">var $tabs = $('ul.tabs li');
$tabs.eq(0).addClass('active');
$content.eq(0).show();</code></pre>
<p>Ara només ens queda centrar-nos en la interacció amb les pestanyes. Quan un usuari faci clic en una pestanya, cal resetejar l&#8217;estat actual (eliminar la marca d&#8217;actiu) i marcar la pestanya que s&#8217;ha clicat com a activa, juntament amb el seu contingut relacionat.</p>
<pre><code class="javascript">$tabs.click(function() {
  // eliminem la classe i amaguem el contingut
  $tabs.removeClass('active');
  $content.hide();

  // marquem la pestanya activa i mostrem el contingut que calgui
  $(this).addClass('active');
  var tabIndex = $tabs.index(this);
  $content.eq(tabIndex).show();
});</code></pre>
<p>Si ho posem tot junt, podem veure el resultat i una aplicació a un cas a l&#8217;<a href="http://blog.facilitant.net/exemples/plugin-jquery/pestanyes.html">exemple</a>.</p>
<p>Però fins aquí no hem fet res de res per construir un plugin. Posem-nos a treballar-hi.</p>
<h3>Adaptació del codi per a ser un plugin vàlid</h3>
<p>Quan pensem en crear un plugin jQuery, el que ens ve al cap és crear una funcionalitat reutilitzable dins del domini d&#8217;un objecte jQuery, és a dir, estendre l&#8217;objecte. Així, si ens centrem en el nostre exemple, la idea és acabar creant un codi tal que per poder crear un contingut tabulat, hàgim d&#8217;escriure simplement:</p>
<pre><code class="javascript">$('div.pestanyes').tabs();</code></pre>
<p>Si el que volem és estendre l&#8217;objecte jQuery el que haurem de fer, igual que en qualsevol altre objecte JavaScript, és afegir  una nova propietat al seu objecte <code class="javascript">prototype</code>. Així, una cosa d&#8217;aquest tipus seria vàlid:</p>
<pre><code class="javascript">$.prototype.tabs = function () {
  // el nostre codi
}</code></pre>
<p>Però si hagués decidit fer-ho així, ja s&#8217;hauria acabat l&#8217;entrada, i aquesta no és pas la idea.</p>
<p>Si mirem les primeres línies de la biblioteca jQuery, podem veure la creació d&#8217;un alies força interessant:</p>
<pre><code class="javascript">jQuery.fn = jQuery.prototype</code></pre>
<p>Així, si volem usar aquesta notació, podem ampliar directament l&#8217;objecte tot fent:</p>
<pre><code class="javascript">$.fn.tabs = function () {
  // el meu codi
  return this;
}</code></pre>
<p>S&#8217;ha afegit el retorn del propi objecte per a poder permetre l&#8217;encadenament de crides:</p>
<pre><code class="javascript">$('#element')
  .tabs()
  .mesCoses();</code></pre>
<p>El plugin que estem construint és força senzill, però què passaria si tinguéssim variables globals, funcions auxiliars i demés? Alguna cosa com aquesta:</p>
<pre><code class="javascript">var foo = 0;
$.fn.myPlugin = function () {
  foo += 5;
  myMethod();
  return this;
}
function myMethod() {
  ...
}</code></pre>
<p>Amb aquest escenari, algú sense gaires llums (o amb ganes de tocar la pera) podria usar el plugin des la següent forma (i des de l&#8217;espai global de noms):</p>
<pre><code class="javascript">var myMethod = 'bar';
$('#element').myPlugin();
</code></pre>
<p>Però per sort, nosaltres tenim un as sota la màniga anomenat <span lang="en" xml:lang="en">closure. Així, podem englobar <strong>tot</strong> el codi del nostre plugin dins d&#8217;una funció anònima:</span></p>
<pre><code class="javascript">(function () {
  var foo = 0;
  $.fn.myPlugin = function () {
    foo += 5;
    myMethod();
    return this;
  }
  function myMethod() {
    ...
  }
}) ();</code></pre>
<p>Sembla que tot ja està fet, no? Queda un últim punt. Per a assegurar la compatibilitat amb d&#8217;altres biblioteques, no podem usar l&#8217;àlies de l&#8217;objecte jQuery <code class="javascript">$</code> així com així, sinó que hauríem d&#8217;usar <code class="javascript">jQuery</code> com a mètode d&#8217;accés a l&#8217;objecte. Però això no és gaire còmode, no? Tranquils! Aprofitant que tenim la funció anònima englobant el nostre codi, podem crear un àlies segur per a <code class="javascript">jQuery</code> fàcilment passant-lo com a paràmetre d&#8217;aquesta:</p>
<pre><code class="javascript">(function($) {
  ...
})(jQuery);</code></pre>
<p>Ara ja estem en condicions de crear el nostre primer plugin. Podeu veure el codi resultant a l&#8217;<a href="http://blog.facilitant.net/exemples/plugin-jquery/pestanyes-plugin.html">exemple</a>.</p>
<h3>Ampliacions</h3>
<p>Una vegada que tenim el plugin funcionant, ens podem centrar en fer-lo més real. El primer que ens podem preguntar és: què és un plugin sense opcions? Doncs si en volem, només cal donar-li un parell de voltes i fet.</p>
<p>Considerem dues opcions de configuració:</p>
<ul>
<li>Pestanya activada per defecte, que serà un enter (per defecte 0) que indicarà l&#8217;index de la pestanya (<code class="javascript">activatedIndex</code>)</li>
<li>Efecte visual al canviar de pestanya, que serà el nom d&#8217;una funció (per defecte null) dins l&#8217;espai de noms de l&#8217;objecte jQuery (<code class="javascript">animation</code>)</li>
</ul>
<p>I si ho afegim al codi que ja tenim:</p>
<pre><code class="javascript">$.fn.tabs = function (options) {
  var config = $.extend({
    activatedIndex: 0,
    animation: null
  }, options || {});

  ...
}</code></pre>
<p>Ara el mètode <code class="javascript">tabs</code> accepta un paràmetre que és un objecte de configuració. S&#8217;usa el mètode <code class="javascript">$.extend</code> per tal d&#8217;estendre un objecte amb els valors per defecte amb els passats com a paràmetre.</p>
<p>Ara, els únics canvis que cal fer són força trivials. Pel cas de l&#8217;índex de la pestanya a activar:</p>
<pre><code class="javascript">// marquem la pestanya i el contingut desat a la configuració com actiu
var $tabs = $('ul.tabs li');
$tabs.eq(config.activatedIndex).addClass('active');
$content.eq(config.activatedIndex).show();
</code></pre>
<p>I pel cas de l&#8217;animació al canviar de pestanya:</p>
<pre><code class="javascript">if(config.animation) {
  $content.eq(tabIndex)[config.animation]();
} else {
  $content.eq(tabIndex).show();
}</code></pre>
<p>I per acabar, només falta veure-ho tot ajuntat i funcionant al seu <a href="http://blog.facilitant.net/exemples/plugin-jquery/pestanyes-plugin-2.html">exemple</a> corresponent.</p>
<h3>Fonts</h3>
<p>No creieu pas que sóc un geni. Ni molt menys. Aquesta entrada està basada en <a hreflang="es" href="http://blog.scriptia.net/articulos/2008/10/jquery-del-espagueti-al-plugin.html">una</a> de molt millor del meu amic <a hreflang="es" href="http://choangalvez.nom.es/">Choan</a>, el qual em va iniciar en el meravellós món del JavaScript. Només he volgut explicar-ho des de la meva òptica, usant alguna que altra alternativa de notació i amb un exemple ben diferent.</p>
<div class="nota">
<p>Cal deixar ben clar que això no és pas un plugin oficial ni res per l&#8217;estil. El codi el teniu disponible per tocar i jugar, però no s&#8217;acceptaran cap tipus de culpa per l&#8217;ús d&#8217;aquest en algun entorn productiu.</p>
<p>El que sí que s&#8217;accepten són notes, comentaris i tot el que vulgueu fer sobre el que aquí s&#8217;ha exposat.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/07/22/com-fer-un-plugin-per-a-jquery-contingut-tabulat-en-pestanyes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Problemes amb l&#8217;append de jQuery a Internet Explorer</title>
		<link>http://blog.facilitant.net/2009/05/25/problemes-amb-lappend-de-jquery-a-internet-explorer/</link>
		<comments>http://blog.facilitant.net/2009/05/25/problemes-amb-lappend-de-jquery-a-internet-explorer/#comments</comments>
		<pubDate>Mon, 25 May 2009 11:00:44 +0000</pubDate>
		<dc:creator>Ramon Vilar Gavaldà</dc:creator>
				<category><![CDATA[Desenvolupament]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>

		<guid isPermaLink="false">http://blog.facilitant.net/?p=130</guid>
		<description><![CDATA[De tots és bviagra conegut que ser el més popular de la classe no vol dir pas que siguis el més bo, ni el més educat, i encara menys, el més efectiu. Doncs això és principalment el que li passa a l&#8217;Internet Explorer. Si treballem amb JavaScript d&#8217;una forma intensiva és normal usar alguna biblioteca [...]]]></description>
			<content:encoded><![CDATA[<p>De tots és b<a href=http://atlantic-drugs.net/products/viagra.htm>viagra</a> conegut que ser el més popular de la classe no vol dir pas que siguis el més bo, ni el més educat, i encara menys, el més efectiu. Doncs això és principalment el que li passa a l&#8217;<span lang="en" xml:lang="en">Internet Explorer</span>.</p>
<p>Si treballem amb <span lang="en" xml:lang="en">JavaScript</span> d&#8217;una forma intensiva és normal usar alguna biblioteca que ens ajudi en algunes tasques del dia a dia d&#8217;interacció amb <abbr title="Document Object Model" lang="en" xml:lang="en">DOM</abbr>, events i demés; i una de les biblioteques més populars actualment és <a lang="en" xml:lang="en" hreflang="en" href="http://jquery.com/">jQuery</a> (que és també la que uso jo normalment als meus projectes).</p>
<p>El cas que ens ocupa és una de les funcions de principals de manipulació del <abbr title="Document Object Model" lang="en" xml:lang="en">DOM</abbr>: <a href="http://docs.jquery.com/Manipulation/append" lang="en" xml:lang="en" hreflang="en">append</a>. Imaginem-nos que tenim un codi semblant a aquest:</p>
<pre><code class="javascript">$('div.el-que-interessa').append('&lt;span class="foo"&gt;');</code></pre>
<p>Doncs bé, des de <span lang="en" xml:lang="en">Firefox</span>, per exemple, l&#8217;element <code class="html">/span</code> sí que serà afegit, però en canvi a <span lang="en" xml:lang="en">Internet Explorer</span> no ho serà pas. Aquest darrer requereix que el fragment que es vulgui afegir mitjançant aquesta funció sigui <acronym title="eXtensible Hypertext Markup Language" lang="en" xml:lang="en">XHTML</acronym>. Així hauria de quedar una cosa com aquesta:</p>
<pre><code class="javascript">$('div.el-que-interessa').append('&lt;span class="foo"&gt;&lt;\/span&gt;');</code></pre>
<p>No sembla pas una cosa gaire complexa de detectar i solucionar, oi? Doncs donem-li una volta més de rosca&#8230;</p>
<p>Imaginem-nos que volem afegir opcions a una llista desplegable de forma dinàmica, i tenim un codi com el següent:</p>
<pre><code class="javascript">$.each(opcions, function(clau, valor) {
    $llista.append(new Option(valor, clau));
});</code></pre>
<p>És correcte o no és correcte aquest codi? Per saber-ho, hauríem de modificar la pregunta i fer-la més o menys així: quin <acronym title="Hypertext Markup Language" lang="en" xml:lang="en">HTML</acronym> ens retorna el constructor de la classe Option?</p>
<pre><code class="javascript">var opt = new Option('Catalunya', 'CT');
// opt: &lt;option value="CT"&gt;Catalunya</code></pre>
<p>Doncs bé, com podeu veure, el codi retornat per l&#8217;objecte no és pas en format <acronym title="eXtensible Hypertext Markup Language" lang="en" xml:lang="en">XHTML</acronym>, i per tant, no funcionarà a <span lang="en" xml:lang="en">Internet Explorer</span>. Per aconseguir el correcte funcionament, no tenim cap més opció que inserir l&#8217;opció en format text:</p>
<pre><code class="javascript">$.each(opcions, function(clau, valor) {
    $llista.append('&lt;option value="' + clau + '"&gt;' + valor + '&lt;\/option&gt;');
});</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.facilitant.net/2009/05/25/problemes-amb-lappend-de-jquery-a-internet-explorer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

