<?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>Guillermo Rauch&#039;s Devthought &#187; mootools</title>
	<atom:link href="http://www.devthought.com/tag/mootools/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.devthought.com</link>
	<description></description>
	<lastBuildDate>Mon, 30 Jan 2012 16:38:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>JavaScript RegExp based highlighting for MooTools and jQuery</title>
		<link>http://www.devthought.com/2009/04/04/javascript-regexp-based-highlighting-function-for-mootools-and-jquery/</link>
		<comments>http://www.devthought.com/2009/04/04/javascript-regexp-based-highlighting-function-for-mootools-and-jquery/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 18:55:07 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Client side]]></category>
		<category><![CDATA[highlighting]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[snippet]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=725</guid>
		<description><![CDATA[How it works A regular expression looks for text outside HTML tags. It uses a callback function to perform replacements to simulate native lookahead support. When is this sort of replacement suitable ? Remote HTML responses (ajax) highlighting Autocompleters suggestion &#8230; <a href="http://www.devthought.com/2009/04/04/javascript-regexp-based-highlighting-function-for-mootools-and-jquery/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>How it works</h3>
<p>A regular expression looks for text outside HTML tags. It uses a callback function to perform replacements to simulate native lookahead support.</p>
<p>When is this sort of replacement suitable ?</p>
<ul>
<li>Remote HTML responses (ajax) highlighting</li>
<li>Autocompleters suggestion highlighting</li>
<li>User-typed HTML, WYSIWIGs, etc.</li>
</ul>
<p>Generally speaking, the only downside of this method, since it deals with the innerHTML, is that all attached events and properties are lost when the replacement is performed.</p>
<p><span id="more-725"></span></p>
<p>Note: this code is designed to match only beginning of words. If you want to match anywhere, remove <code class="inline">\\b</code> from the regular expression. And if you expect <code class="inline">&lt;script&gt;</code> tags, definitely don&#8217;t use it.</p>
<h3>MooTools version (<a href="/wp-content/articles/highlight-moo/">demo</a>)</h3>
<pre class='highlight ' lang="javascript">
Element.implement({

	highlight: function(search, insensitive, klass){
		var regex = new RegExp('(<[^>]*>)|(\\b'+ search.escapeRegExp() +')', insensitive ? 'ig' : 'g');
		return this.set('html', this.get('html').replace(regex, function(a, b, c){
			return (a.charAt(0) == '<') ? a : '<strong class="'+ klass +'">' + c + '</strong>';
		}));
	}

});
</pre>
<h3>jQuery version (<a href="/wp-content/articles/highlight-jquery/">demo</a>)</h3>
<pre class='highlight ' lang="javascript">
jQuery.fn.extend({

	highlight: function(search, insensitive, klass){
		var regex = new RegExp('(<[^>]*>)|(\\b'+ search.replace(/([-.*+?^${}()|[\]\/\\])/g,"\\$1") +')', insensitive ? 'ig' : 'g');
		return this.html(this.html().replace(regex, function(a, b, c){
			return (a.charAt(0) == '<') ? a : '<strong class="'+ klass +'">' + c + '</strong>';
		}));
	}

});
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2009/04/04/javascript-regexp-based-highlighting-function-for-mootools-and-jquery/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>More please.</title>
		<link>http://www.devthought.com/2009/03/09/more-please/</link>
		<comments>http://www.devthought.com/2009/03/09/more-please/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 23:36:48 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Client side]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[mootools more]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=429</guid>
		<description><![CDATA[You wanted more, we give you More. Today the new MooTools More RC1 is being released, with an outstanding number of new plugins. More functionality, but with the quality you come to expect from the MooTools framework. Most of the &#8230; <a href="http://www.devthought.com/2009/03/09/more-please/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img src="http://devthought.com/wp-content/uploads/2009/03/mootools.png" alt="mootools" title="mootools" width="184" height="46" class="alignnone size-medium wp-image-430" /></p>
<p>You wanted more, we give you More. Today the new MooTools More RC1 <a href="http://mootools.net/blog/2009/03/09/more-to-love/">is being released</a>, with an outstanding number of new plugins. More functionality, but with the quality you come to expect from the MooTools framework.</p>
<p>Most of the new components come from the excellent Aaron&#8217;s <a href="http://clientcide.com">Clientcide</a> library. I contributed to the improvement, refining and testing of some of his vast code, which brings More to its present state.</p>
<p>The goal here is to provide more great, simple and extensible tools to make developers&#8217; lives easier. I suggest you head to the <a href="http://www.mootools.net/docs_rc1/">Docs</a> or <a href="http://www.mootools.net/more_rc1">Builder</a> page right away to start trying out the new stuff. As always, head to Lighthouse to report the bugs you encounter, or even to suggest new additions or features.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2009/03/09/more-please/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Don&#039;t repeat your moo</title>
		<link>http://www.devthought.com/2009/03/02/dont-repeat-your-moo/</link>
		<comments>http://www.devthought.com/2009/03/02/dont-repeat-your-moo/#comments</comments>
		<pubDate>Mon, 02 Mar 2009 14:25:22 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Client side]]></category>
		<category><![CDATA[dry]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[oop]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=390</guid>
		<description><![CDATA[Given the Object-Oriented nature of the MooTools framework, code repetition is something that is long forgotten (or should be) in the scripts your write. With the avoidance of code repetition comes code reusability, which results in your website being easier &#8230; <a href="http://www.devthought.com/2009/03/02/dont-repeat-your-moo/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Given the Object-Oriented nature of the MooTools framework, code repetition is something that is long forgotten (or should be) in the scripts your write. With the avoidance of code repetition comes code reusability, which results in your website being easier to read, extend and maintain, and your scripts smaller in size.</p>
<p>At this point there&#8217;s no doubt in anyone&#8217;s mind that <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a> is a principle we should stick to. However, let&#8217;s examine how to achieve this in the right way.</p>
<p><span id="more-390"></span></p>
<h3>Natives extension</h3>
<p>A script, no matter its purpose, deals with various native objects all the time. These may be native types, such as Strings, Arrays, Objects, Numbers, or objects that are not native to the language but are to the browser rendering engine, such as HTMLElement.</p>
<p>MooTools, as you already know, empowers us to extend these Natives really easily. To add a <strong>repeat()</strong> method to a String, this is all it takes:</p>
<pre class='highlight ' lang="javascript">
String.implement({
	repeat: function(times){
		return new Array(times + 1).join(this);
	}
});
</pre>
<p>This is one of the pillars of code reusability within MooTools code. But, as I&#8217;ll explain later, it can be misused.</p>
<h3>Self-invoking functions</h3>
<p>Probably the most natural and straightforward way of avoiding code repetition is defining a function. The code above could have been written as:</p>
<pre class='highlight ' lang="javascript">
function repeat(str, times){
	return new Array(times +1).join(str);
}
</pre>
<p>A downside of the snippet above is the pollution of the global namespace. The function <em>repeat</em> would be available to all your scripts within the window you execute it in, potentially colliding with other functions. Or making it harder to maintain when another programmer comes along and writes another <em>repeat</em> function, which may even do something different.</p>
<p>That&#8217;s when self-invoking functions come to the rescue. As you already know, the local variables defined within a function are only available to that context. If you decide to use functions instead of extending a native, this is the smart way to do it:</p>
<pre class='highlight ' lang="javascript">
// we wrap our code in a self-invoking function
(function(){

   // local function within this context
   var repeat(str,times) = function(){
   	// ...
   });

   // notice we don't use var here, we want the Car class to be globally available
   Car = new Class({

      run: function() {
          var a = repeat('test', 20);
      }

   });

   ConvertibleCar = new Class({

      Extends: Car,

      display: function() {
          var b = repeat('some string', 20);
      }

   });

})();

// the repeat() we defined before is no longer accessible here
</pre>
<h3>When to use which method</h3>
<p>First of all, you might be wondering why you&#8217;d go through the trouble of defining a function within a sub-context if you could have extended String in the first place. That&#8217;s valid reasoning, but only because of the nature of the example.</p>
<p>If you&#8217;ve been writing MooTools code for a long time, maybe sometimes you found yourself <em>polluting your own Natives</em>, by extending them with functions that added little reusability value. An example:</p>
<pre class='highlight ' lang="javascript">
Element.implement({

	doSomethingSoSpecificThatIevenFindItHardToName: function(){
        	// ...
	}

});
</pre>
<p>Sometimes extending the natives just doesn&#8217;t feel right, specially if it&#8217;s for a logic you repeat several times but only within a class or subset of classes, and <em>it doesn&#8217;t award a public method</em> within your class. That&#8217;s when a function wrapped in a self-invoking function described above is best suited.</p>
<p>To finalize, let&#8217;s see a real-world example that contrasts these two approaches, taken from the MooTools Core.</p>
<pre class='highlight ' lang="javascript">
(function(){

var walk = function(element, walk, start, match, all, nocash){
	// internal dom walking logic
};

Element.implement({

	getPrevious: function(match, nocash){
		return walk(this, 'previousSibling', null, match, false, nocash);
	},

	getAllPrevious: function(match, nocash){
		return walk(this, 'previousSibling', null, match, true, nocash);
	},

	getNext: function(match, nocash){
		return walk(this, 'nextSibling', null, match, false, nocash);
	},

	getAllNext: function(match, nocash){
		return walk(this, 'nextSibling', null, match, true, nocash);
	},

	getFirst: function(match, nocash){
		return walk(this, 'nextSibling', 'firstChild', match, false, nocash);
	},

        // ...

});

})();
</pre>
<p>As you can see, it extends Element with methods that you reuse a lot, and that even MooTools utilizes in its other components. However, there&#8217;s no point in making the <strong>walk</strong> function available to the rest of the Core, let alone your scripts, since it&#8217;s used in a very specific part which deals with the DOM manipulation. Its only purpose is avoiding code repetition in the several methods it implements to Element.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2009/03/02/dont-repeat-your-moo/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>BarackSlideshow and MorphList updated</title>
		<link>http://www.devthought.com/2009/01/18/barackslideshow-and-morphlist-updated/</link>
		<comments>http://www.devthought.com/2009/01/18/barackslideshow-and-morphlist-updated/#comments</comments>
		<pubDate>Sun, 18 Jan 2009 13:52:06 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[mootools plugin]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[update]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=44</guid>
		<description><![CDATA[These two widely used scripts have been updated. BarackSlideshow now supports transition effects and can autoplay (requested by the community many times). MorphList is now even more flexible, supporting custom markup for the dynamic background.]]></description>
			<content:encoded><![CDATA[<p>These two widely used scripts have been updated. <a href="http://devthought.com/barackslideshow-an-elegant-lightweight-slideshow-script/">BarackSlideshow</a> now supports transition effects and can autoplay (requested by the community many times).</p>
<p><a href="http://devthought.com/morphlist/">MorphList</a> is now even more flexible, supporting custom markup for the dynamic background.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2009/01/18/barackslideshow-and-morphlist-updated/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>BarackSlideshow &#8211; An elegant, lightweight slideshow script</title>
		<link>http://www.devthought.com/2008/06/11/barackslideshow-an-elegant-lightweight-slideshow-script/</link>
		<comments>http://www.devthought.com/2008/06/11/barackslideshow-an-elegant-lightweight-slideshow-script/#comments</comments>
		<pubDate>Wed, 11 Jun 2008 05:44:53 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=36</guid>
		<description><![CDATA[I guess pretty much everyone has seen Barack Obama&#8217;s website by now, which is clearly one of the prettiest of all candidates we&#8217;ve heard of so far. Not only is it an example of state-of-the-art design, but it&#8217;s also nice &#8230; <a href="http://www.devthought.com/2008/06/11/barackslideshow-an-elegant-lightweight-slideshow-script/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><a class="thumb" href="http://devthought.com/wp-content/uploads/2009/05/barack.jpg"><img src="http://devthought.com/wp-content/uploads/2009/05/barack-300x137.jpg" alt="Demo" title="Demo" width="300" height="137" class="alignright size-medium wp-image-945" /></a></p>
<p>I guess pretty much everyone has seen <a href="http://barackobama.com">Barack Obama&#8217;s website</a> by now, which is clearly one of the prettiest of all candidates we&#8217;ve heard of so far. Not only is it an example of state-of-the-art design, but it&#8217;s also nice to navigate and interact with.</p>
<p>I decided to imitate the homepage slideshow. I had already experimented with <a href="http://devthought.com/cssjavascript-true-power-fancy-menu/">similar animated lists</a>, which allowed me to have it ready within minutes</p>
<p><span id="more-63"></span></p>
<h3>The creation</h3>
<p>I took my previous class (SlideList), and made a few changes here and there. It works with MooTools 1.2, and supports all kinds of shape transformations (top and left coordinates, and height and width properties), which means it can now be used with vertical, horizontal, or even irregular lists.</p>
<p>I extended it and came up with a new class that receives the images and loading spinner as parameters (note: it&#8217;s arguable whether this is the best decision OOP-wise, but due to the simplicity of this script, this was the right call)</p>
<h3>The code</h3>
<p>To ensure all images are loaded before the user makes any interaction, the MooTools <strong>Assets</strong> component is used.</p>
<p>The CSS plays a major role (as in every other animation-focused script). I suggest you analyze it carefully before implementing it in your applications or websites. You&#8217;ll probably need to adjust the ids, or use classes instead to keep your stylesheets clean.</p>
<p>The markup is meaningful and simple. Two lists are used (one for the images and the other for the links). The loading element is included in the HTML, but it&#8217;s probably better to inject it from the script directly.</p>
<h3>The pictures</h3>
<p>The beautiful pictures were taken from Flickr with permission of the owners, unless they were directly released for non-commercial use. Thanks <a href="http://www.flickr.com/photos/vgm8383/1299339710/">vgm8383</a>, <a href="http://www.flickr.com/photos/93136519@N00/203892226/">dogonnit</a>, <a href="http://www.flickr.com/photos/topogigio_428/503418708/">M. TANIGUCHI</a>, <a href="http://www.flickr.com/photos/catambu/155201667/">GustavoBuriola</a> &#038; others!</p>
<h3>The demo</h3>
<p><a href="/wp-content/projects/mootools/barackslideshow/Demo/">Click here</a> to see it in action or go to the <a href="/projects/mootools/barackslideshow/">project page</a> for download and other details.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2008/06/11/barackslideshow-an-elegant-lightweight-slideshow-script/feed/</wfw:commentRss>
		<slash:comments>259</slash:comments>
		</item>
		<item>
		<title>TextboxList meets Autocompletion</title>
		<link>http://www.devthought.com/2008/01/12/textboxlist-meets-autocompletion/</link>
		<comments>http://www.devthought.com/2008/01/12/textboxlist-meets-autocompletion/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 19:59:31 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[mootools plugin]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://devthought.com/textboxlist-meets-autocompletion/</guid>
		<description><![CDATA[Demo here In my previous blogpost I explained how to extend TextboxList to add closing functionality via a link added to each box. But it was missing an important ingredient: autocompletion! Again, all we have to do is extend the &#8230; <a href="http://www.devthought.com/2008/01/12/textboxlist-meets-autocompletion/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><img src='/wp-content/uploads/2008/01/auto.png' alt='TextboxList Autocompletion' /></p>
<p><a href="http://devthought.com/wp-content/articles/autocompletelist/test.html">Demo here</a></p>
<p>In my <a href="http://devthought.com/textboxlist-fancy-facebook-like-dynamic-inputs/">previous</a> blogpost I explained how to extend TextboxList to add closing functionality via a link added to each box. But it was missing an important ingredient: autocompletion!</p>
<p><span id="more-57"></span></p>
<p>Again, all we have to do is extend the TextboxList class, override some methods, some events, and create some new ones (all prefixed by <em>auto</em>)</p>
<pre class='highlight ' lang="javascript" line="1">
var FacebookList = new Class({

  Extends: TextboxList,

  data: [],

  options: {
    onInputFocus: function() { this.autoShow(); },
    onInputBlur: function(el) {
      el.value = '';
      this.autoHide();
    },
    onBoxDispose: function(item) {
      this.autoFeed(item.$attributes.$text);
    },
    autocomplete: {
      'opacity': 0.8,
      'maxresults': 10,
      'minchars': 1
    }
  },

  initialize: function(element, autoholder, options) {
    arguments.callee.parent(element, options);
		this.autoholder = $(autoholder).set('opacity', this.options.autocomplete.opacity);
		this.autoresults = this.autoholder.getElement('ul');
		var children = this.autoresults.getElements('li');
    children.each(function(el) { this.add(el.innerHTML); }, this);
  },

  autoShow: function(search) {
    this.autoholder.setStyle('display', 'block');
    this.autoholder.getElements('*').setStyle('display', 'none');
    if(! search || ! search.trim() || (! search.length || search.length < this.options.autocomplete.minchars ))
    {
      this.autoholder.getElement('.default').setStyle('display', 'block');
      this.resultsshown = false;
    } else {
      this.resultsshown = true;
      this.autoresults.setStyle('display', 'block').empty();
      this.data.filter(function(str) { return str ? str.test(search, 'i') : false; }).each(function(result, ti) {
        if(ti >= this.options.autocomplete.maxresults) return;
        var el = new Element('li').set('html', this.autoHighlight(result, search)).inject(this.autoresults);
        el.$attributes.$result = result;
        if(ti == 0) this.autoFocus(el);
      }, this);
    }
  },

  autoHighlight: function(html, highlight) {
    return html.replace(new RegExp(highlight, 'gi'), function(match) {
      return '<em>' + match + '</em>';
    });
  },

  autoHide: function() {
    this.resultsshown = false;
    this.autoholder.setStyle('display', 'none');
  },

  autoFocus: function(el) {
    if(! el) return;
    if(this.autocurrent) this.autocurrent.removeClass('auto-focus');
    this.autocurrent = el.addClass('auto-focus');
  },

  autoMove: function(direction) {
    if(!this.resultsshown) return;
    this.autoFocus(this.autocurrent['get' + (direction == 'up' ? 'Previous' : 'Next')]());
  },

  autoFeed: function(text) {
    if(this.data.indexOf(text) == -1)
      this.data.push(text);
  },

  autoAdd: function(el) {
    if(!el || ! el.$attributes.$result) return;
    this.add(el.$attributes.$result);
    delete this.data[this.data.indexOf(el.$attributes.$result)];
    this.autoHide();
    this.current.$attributes.$input.value = '';
  },

  createInput: function(options) {
    var li = arguments.callee.parent(options);
    var input = li.$attributes.$input;
    input.addEvents({
      'keydown': function(e) {
        e = new Event(e);
        this.dosearch = false;
        switch(e.code) {
          case Event.Keys.up: return this.autoMove('up');
          case Event.Keys.down: return this.autoMove('down');
          case Event.Keys.enter:
            this.autoAdd(this.autocurrent);
            this.autocurrent = false;
            this.autoenter = true;
            break;
          default: this.dosearch = true;
        }
      }.bind(this),
      'keyup': function() {
        if(this.dosearch) this.autoShow(input.value);
      }.bind(this)
    });
    input.addEvent(Browser.Engine.trident ? 'keydown' : 'keypress', function(e) {
      if(this.autoenter) new Event(e).stop();
      this.autoenter = false;
    }.bind(this));
    return li;
  },

  createBox: function(text, options) {
    var li = arguments.callee.parent(text, options);
    li.addEvents({
      'mouseenter': function() { this.addClass('bit-hover') },
      'mouseleave': function() { this.removeClass('bit-hover') }
    });
    li.adopt(new Element('a', {
      'href': '#',
      'class': 'closebutton',
      'events': {
        'click': function(e) {
          new Event(e).stop();
          if(! this.current) this.focus(this.maininput);
          this.dispose(li);
        }.bind(this)
      }
    }));
    li.$attributes.$text = text;
    return li;
  }

});

window.addEvent('domready', function() {
  // init
  var tlist2 = new FacebookList('facebook-demo', 'facebook-auto');

  // fetch and feed
  new Request.JSON({'url': 'json.html', 'onComplete': function(j) {
    j.each(tlist2.autoFeed, tlist2);
  }}).send();
});
</pre>
<p>It works by caching all the results from a JSON Request and feeding them to the autocompleter object. When a item is added as a box, it&#8217; removed from the feed array, and when the box is disposed it&#8217;s added back, so that it becomes available in the list when the user types.</p>
<p>Another new feature is that you&#8217;ll be able to let it add boxes from the HTML directly:</p>
<pre class='highlight ' lang="html4strict" line="1">
<label>FacebookList input</label>
<input type="text" value="" id="facebook-demo" />
<div id="facebook-auto">
<div class="default">Type the name of an argentine writer you like</div>
<ul class="feed">
<li>Jorge Luis Borges</li>
<li>Julio Cortazar</li>
</ul>
</div>
</pre>
<p>The constructor now takes new parameters to configure the autocompletion, like the minimum number of characters to trigger the dropdown, and more.</p>
<h3>Changelog</h3>
<ul>
<li><strong>0.1:</strong> initial release
<li><strong>0.2:</strong> added click support, removed $attributes use, code cleanup</li>
</ul>
<h3>Download</h3>
<p>Click here to download the zip with <a href="http://devthought.com/wp-content/articles/autocompletelist/AutocompleteList.zip?v0.2">code and examples</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2008/01/12/textboxlist-meets-autocompletion/feed/</wfw:commentRss>
		<slash:comments>323</slash:comments>
		</item>
		<item>
		<title>TextboxList: Fancy Facebook-Like dynamic inputs!</title>
		<link>http://www.devthought.com/2008/01/11/textboxlist-fancy-facebook-like-dynamic-inputs/</link>
		<comments>http://www.devthought.com/2008/01/11/textboxlist-fancy-facebook-like-dynamic-inputs/#comments</comments>
		<pubDate>Fri, 11 Jan 2008 20:26:48 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[mootools plugin]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://devthought.com/textboxlist-fancy-facebook-like-dynamic-inputs/</guid>
		<description><![CDATA[Check out a demo of TextboxList before reading! While working on my big and exciting new project, I decided to include an input that resembles the famous Apple Mail to: textfield. I&#8217;d seen it in Facebook before, which has a &#8230; <a href="http://www.devthought.com/2008/01/11/textboxlist-fancy-facebook-like-dynamic-inputs/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Check out <a href="http://devthought.com/wp-content/articles/textboxlist/test.html">a demo of TextboxList</a> before reading!</p>
<p>While working on my big and exciting new project, I decided to include an input that resembles the famous Apple Mail <strong>to:</strong> textfield. I&#8217;d seen it in Facebook before, which has a really decent implementation of this concept (it work well, but it doesn&#8217;t respect any modern programming principles; basically, it&#8217;s a big tag soup with lots of inline Javascript)</p>
<p>I created my own, MooTools 1.2 compatible, in just 5kb. It&#8217;s not only small, but also really frexible! Here are some notes of the creation process and how to implement it in your own projects.</p>
<p><span id="more-26"></span></p>
<h3>Anatomy of the control</h3>
<p>As usual, I try to come up with a semantic, unobstrusive approach. I start with the CSS and the markup that will be my end result.</p>
<p>I want to go from something like this:</p>
<pre class='highlight ' lang="html4strict">
<li id="facebook-list" class="input-text">
	<label>FacebookList input</label>
<input type="text" value="" id="input-demo2" />
</li>
</pre>
<p>to something like this (only one possible scenario, naturally)</p>
<pre class='highlight ' lang="html4strict">
<li id="facebook-list" class="input-text">
	<label>FacebookList input</label>
<ul class="holder">
<li class="bit-input">
<input type="text" value="" class="smallinput" /></li>
<li class="bit-box">Jorge Luis Borges <a href="#" class="closebutton"></a></li>
<li class="bit-input">
<input type="text" value="" class="smallinput" /></li>
<li class="bit-box">Julio Cortazar <a href="#" class="closebutton"></a></li>
<li class="bit-input">
<input type="text" value="" class="maininput" /></li>
</ul>
</li>
</pre>
<p>Basically, it&#8217;s a group of pieces (that I&#8217;ll call bits), that can be either a box or an input (small, except for the main one). The user is able to move around between the bits by using his keyboard or his mouse.</p>
<h3>Javascript</h3>
<p>As far as the javascript goes, I try to first think about reusable code (usually classes) that I may use. I thus first coded the class that adds resizing capabilities to the small fields as the user types, and a small utility method to find the caret position.</p>
<p>The only challenges I found was handling the complex events while keeping everything crossbrowser. Again, none of this would have been possible if it wasn&#8217;t for MooTools (1.2). </p>
<h3>Using it</h3>
<p>All you have to do is:</p>
<pre class='highlight ' lang="javascript">
new TextboxList('input-demo');
</pre>
<p>Where input-demo is the id of the desired input to replace</p>
<p>The constructor can take these options:</p>
<ul>
<li><strong>onInputFocus</strong> (event, fired when an input gets focus)</li>
<li><strong>onInputBlur</strong> (event, fired when an input loses focus)</li>
<li><strong>onBoxFocus</strong> (event, fired when a box gets focus)</li>
<li><strong>onBoxBlur</strong> (event, fired when a box loses focus)</li>
<li><strong>onBoxDispose</strong> (event, fired when a box is removed)</li>
<li><strong>resizable</strong> (option, hash, passed to ResizableTextbox constructor)</li>
<li><strong>className</strong> (option, string, prefix of the classnames of the generated objects)</li>
<li><strong>extrainputs</strong> (option, boolean, adds small inputs between boxes if true)</li>
<li><strong>startinput</strong> (option, boolean, adds a small input before the first box if true)</li>
<li><strong>hideempty</strong> (option, boolean, hides the small inputs by default)</li>
</ul>
<h3>Extending it</h3>
<p>One of the my favorite features of MooTools is how easily you can create and extend classes. It makes you feel in a truly Object-Oriented environment, overcoming all Javascript limitations and complexities to handle functionalities like this by default.</p>
<p>I decided that, for the sake of simplicity, the class would not incorporate stuff like boxes removal through clicks, or even autocompletion (like Facebook does), since the scenarios to use this control are multiple and diverse.</p>
<p>Here is an example of how easily you can add the small remove links next to the name (and some CSS, of course)</p>
<pre class='highlight ' lang="javascript" line="1">
var FacebookList = new Class({

Extends: TextboxList,

	createBox: function(text, options) {
		var li = arguments.callee.parent(text, options);
		li.addEvents({
			'mouseenter': function() { this.addClass('bit-hover') },
			'mouseleave': function() { this.removeClass('bit-hover') }
		});
		li.adopt(new Element('a', {
			'href': '#',
			'class': 'closebutton',
			'events': {
				'click': function(e) {
					new Event(e).stop();
					if(! this.current) this.focus(this.maininput);
					this.dispose(li);
				}.bind(this)
			}
		}));
		return li;
	}

});
</pre>
<h3>Changelog</h3>
<ul>
<li><strong>0.1:</strong> initial release</li>
<li><strong>0.2:</strong> code cleanup, small blur/focus fixes</li>
</ul>
<h3>Download</h3>
<p><a href="http://devthought.com/wp-content/articles/textboxlist/TextboxList.zip?v0.2">Click here</a> to download a zip file containing examples, TextboxList documented (8kb) and compressed (5kb)</p>
<p><strong>New!</strong> TextboxList with <a href="http://devthought.com/textboxlist-meets-autocompletion/">autocompletion</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2008/01/11/textboxlist-fancy-facebook-like-dynamic-inputs/feed/</wfw:commentRss>
		<slash:comments>59</slash:comments>
		</item>
		<item>
		<title>CSS+Javascript power. Fancy menu</title>
		<link>http://www.devthought.com/2007/01/29/cssjavascript-true-power-fancy-menu/</link>
		<comments>http://www.devthought.com/2007/01/29/cssjavascript-true-power-fancy-menu/#comments</comments>
		<pubDate>Mon, 29 Jan 2007 18:46:24 +0000</pubDate>
		<dc:creator>Guillermo Rauch</dc:creator>
				<category><![CDATA[Projects]]></category>
		<category><![CDATA[mootools]]></category>
		<category><![CDATA[mootools plugin]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[tutorial]]></category>

		<guid isPermaLink="false">http://devthought.com/?p=5</guid>
		<description><![CDATA[Let me introduce you to Fancy Menu: When it comes to creating the navigation part of your Website, the first thing you might think of is an unordered list that you style as tabs. Lately, such navbars are everywhere, as &#8230; <a href="http://www.devthought.com/2007/01/29/cssjavascript-true-power-fancy-menu/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Let me introduce you to Fancy Menu:</p>
<p><img src="http://devthought.com/wp-content/uploads/2007/01/fancymenu.png" alt="fancymenu" title="fancymenu" width="458" height="72" class="alignnone size-full wp-image-231" /></p>
<p>When it comes to creating the navigation part of your Website, the first thing you might think of is an unordered list that you <a href="http://unraveled.com/projects/css_tabs/">style</a> as <a href="http://www.alistapart.com/articles/slidingdoors/">tabs</a>. Lately, such navbars are everywhere, as many people believe they&#8217;ll make their site more Web 2.0-compatible. Personally, I just think they&#8217;re semantically better and accessible.</p>
<p>In this article I&#8217;ll go through the creation of a custom navigation bar with some cute Javascript effects that will certainly impress your friends. Thanks to the great <a href="http://www.mootools.net">Mootools</a> library, this beauty is contained in 1.5kb. Not only that, but it&#8217;s also cross browser (tested on Internet Explorer 6/7, Firefox and Safari) and accessible!</p>
<p><span id="more-44"></span></p>
<h3>Introduction</h3>
<p>Every time that I know I&#8217;m going to use Javascript to alter the behavior or look of something, I try to come up with a simple markup, and make sure it renders perfectly with Javascript turned off. To illustrate this point, imagine that you want to make an element wider on rollover. The property Javascript would change is <em>width:</em>, so I make sure first that my style works when I modify the width randomly.</p>
<p>For this menu, as we&#8217;ll be having a movable element that acts as the background, we should first make sure that just by using css, we can freely move it and that it won&#8217;t affect the display of the menu. If you didn&#8217;t do this, when you&#8217;re coding the JS and face a bug, you&#8217;ll find yourself wondering if it is caused by the CSS, the Javascript, the browser?</p>
<h3>Mark it up</h3>
<p>Just like any other navigation, we&#8217;re going to use an unordered list with some anchors:</p>
<pre class='highlight ' lang="html4strict" toolbar="0">
<div id="fancymenu">
<ul>
<li class="current" id="menu_home"><a href="#">Home</a></li>
<li id="menu_plantatree"><a href="#">Plant a tree</a></li>
<li id="menu_travel"><a href="#">Travel</a></li>
<li id="menu_rideanelephant"><a href="#">Ride an elephant</a></li>
</ul>
</div>
</pre>
<p>This is the foundation of a semantically correct, degradable navigation structure.</p>
<h3>The CSS styling</h3>
<p>As I said before, it&#8217;s paramount that we create flawless, cross browser CSS code. Let&#8217;s get to it</p>
<p>The first problem we face is that it&#8217;s impossible to use the background property for the rounded box that follows your mouse, with the current CSS specs shared by most browsers. That forces us to add a new LI item that will act as the moving background.</p>
<p>We&#8217;re going to set position: relative to the unordered list, and position: absolute to the moving item, so that it&#8217;s easy to move it between the menu boundaries from Javascript. If you don&#8217;t quite understand how this works, I encourage you to quickly read <a href="http://www.barelyfitz.com/screencast/html-training/css/positioning/">this article about CSS positioning</a>. You&#8217;ll understand that if we simply set position: absolute to it, we&#8217;d have to do some hard, useless calculations Javascript side to positionate it correctly.</p>
<p>Then, this is the code we have so far:</p>
<pre class='highlight ' lang="css" line="1">
#fancymenu {
  position: relative;
  height: 29px;
  width: 421px;
  background: url('images/bg.gif') no-repeat top;
  padding: 15px;
  margin: 10px 0;
  overflow: hidden;
}

#fancymenu ul {
  padding: 0;
  margin: 0;
}

/* Don't apply padding here (offsetWidth will differ in IE)
If you need padding add it to the child anchor */
#fancymenu ul li {
  float: left;
  list-style: none;
}

#fancymenu ul li a {
  text-indent: -500em;
  z-index: 10;
  display: block;
  float: left;
  height: 30px;
  position: relative;
  overflow: hidden;
}
</pre>
<p>So far it&#8217;s quite easy, and I included some comments for the tricky parts. The text-indent property is used to hide the text without adding extra markup, and keeping it accesible.</p</p>
<p>Now, we have to add the background images for each link:</p>
<pre class='highlight ' lang="css" line="1">
#menu_home a {
  width: 59px;
  background: url('images/menu_home.png') no-repeat center !important;
  background: url('images/menu_home.gif') no-repeat center; // ie!
}

#menu_plantatree a {
  width: 119px;
  background: url('images/menu_plantatree.png') no-repeat center !important;
  background: url('images/menu_plantatree.gif') no-repeat center;
}

#menu_travel a {
  width: 70px;
  background: url('images/menu_travel.png') no-repeat center !important;
  background: url('images/menu_travel.gif') no-repeat center;
}

#menu_rideanelephant a {
  width: 142px;
  background: url('images/menu_rideanelephant.png') no-repeat center !important;
  background: url('images/menu_rideanelephant.gif') no-repeat center;
}
</pre>
<p>In the following section you&#8217;ll see why we use .gif images for Internet Explorer by using the !important hack.</p>
<h3>The moving background</h3>
<p>As we discussed, there&#8217;s a LI that moves in a lower layer and stretches to take the shape of each element. Because of its structure, we&#8217;re going to implement something similar to the <a href="http://alistapart.com/articles/slidingdoors">Sliding Doors technique</a>, but without text.</p>
<p>Its markup would be the following:</p>
<pre class='highlight ' lang="html4strict">
<li class="background">
<div class="left">&nbsp;</div>
</li>
</pre>
<p>As it doesn&#8217;t have any semantic role in the unordered list, we&#8217;re going to include it from Javascript. Of course, for testing, you can include it first manually and then remove it. This is the style for it:</p>
<pre class='highlight ' lang="css" line="1">
#fancymenu li.background {
  background: url('images/bg_menu_right.png') no-repeat top right !important;
  background: url('images/bg_menu_right.gif') no-repeat top right;
  z-index: 8;
  position: absolute;
  visibility: hidden;
}

#fancymenu .background .left {
  background: url('images/bg_menu.png') no-repeat top left !important;
  background: url('images/bg_menu.gif') no-repeat top left;
  height: 30px;
  margin-right: 9px; /* 7px is the width of the rounded shape */
}
</pre>
<p>The use of this technique is one of the main reasons why we don&#8217;t use filters to display the PNGs in Internet Explorer. You can&#8217;t decide the position of the background with them, which would make the right corner side display above the left part. Read this article about the <a href="http://www.themaninblue.com/writing/perspective/2004/06/18/">png hack limitations</a> to find out more. Another reason is that Microsoft is updating users to IE7 automatically, which supports png perfectly.</p>
<p>Keep in mind, as well, that when you export the .gifs you&#8217;ll have to set the Matte to match the background color, otherwise everything will look really bad. This picture illustrates what your images should look like:</p>
<p><img src="/wp-content/articles/fancy-menu/images/comparison.gif" alt="PNG and GIF comparison" /></p>
<h3>Scripting it</h3>
<p>Thanks to our smart CSS code, our Javascript is very short and simple. Its job is limited to adding the extra background markup, and of course the effects for shrinking and moving it.</p>
<p>We&#8217;re just going to need Mootools&#8217; <strong>Fx.Style.js</strong>, <strong>Dom.js</strong>, and of course their dependencies. For this article&#8217;s example, I also used a custom transition found in the <strong>Fx.Transitions</strong> package (remember that transitions are what make the movement of the background vary). It&#8217;s coded in the form of a Class, so that it&#8217;s possible to initialize several menus on the same page.</p>
<pre class='highlight ' lang="javascript" line="1">
var SlideList = new Class({
	initialize: function(menu, options) {
		this.setOptions(this.getOptions(), options);

		this.menu = $(menu), this.current = this.menu.getElement('li.current');

		this.menu.getElements('li').each(function(item){
			item.addEvent('mouseover', function(){ this.moveBg(item); }.bind(this));
			item.addEvent('mouseout', function(){ this.moveBg(this.current); }.bind(this));
			item.addEvent('click', function(event){ this.clickItem(event, item); }.bind(this));
		}.bind(this));

		this.back = new Element('li').addClass('background').adopt(new Element('div').addClass('left')).injectInside(this.menu);
		this.back.fx = this.back.effects(this.options);
		if(this.current) this.setCurrent(this.current);
	},

	setCurrent: function(el, effect){
		this.back.setStyles({left: (el.offsetLeft)+'px', width: (el.offsetWidth)+'px'});
		(effect) ? this.back.effect('opacity').set(0).start(1) : this.back.setOpacity(1);
		this.current = el;
	},

	getOptions: function(){
		return {
			transition: Fx.Transitions.sineInOut,
			duration: 500, wait: false,
			onClick: Class.empty
		};
	},

	clickItem: function(event, item) {
		if(!this.current) this.setCurrent(item, true);
		this.current = item;
		this.options.onClick(new Event(event), item);
	},

	moveBg: function(to) {
		if(!this.current) return;
		this.back.fx.custom({
			left: [this.back.offsetLeft, to.offsetLeft],
			width: [this.back.offsetWidth, to.offsetWidth]
		});
	}
});

SlideList.implement(new Options);
</pre>
<p>Finally, it&#8217;s time to start it. Just create the object, by passing the id and desired options. The following example shows how to do it when the page DOM tree is loaded.</p>
<pre class='highlight ' lang="javascript">
window.addEvent('domready', function() {
	new SlideList($E('ul', 'fancymenu'), {transition: Fx.Transitions.backOut, duration: 700, onClick: function(ev, item) { ev.stop(); }});
});
</pre>
<p>The script first looks for the element that has the current class. If it finds it, it positions the background behind it. If it doesn&#8217;t, it waits till the user first click on some item to set the &#8216;current&#8217; class. This comes in very handy for menus meant for user selection, like the example below, instead of menus with links to actual URLs.</p>
<p>There&#8217;s an onClick option, which calls a function with an <a href="http://docs.mootools.net/files/Native/Event-js.html">Event</a> object, and the clicked element object reference as parameters. You can also change the effect duration, transition, etc.</p>
<h3>Extend it</h3>
<p>If you&#8217;ve made it this far, you must&#8217;ve noticed that it hasn&#8217;t been dead easy. In fact, the tutorial is not aimed solely to teach you how to create a menu, but for you to understand the possibilities you have using CSS and Javascript to make something stand out, and at the same time provide some tips to get you started if you want to create your own.</p>
<p>Here&#8217;s another example, using the very same Javascript class!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devthought.com/2007/01/29/cssjavascript-true-power-fancy-menu/feed/</wfw:commentRss>
		<slash:comments>690</slash:comments>
		</item>
	</channel>
</rss>

