<?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>Ajax Bestiary &#187; jQuery</title>
	<atom:link href="http://www.ajaxbestiary.com/category/jquery/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ajaxbestiary.com</link>
	<description>AJAX Development, News, Techniques &#38; More</description>
	<lastBuildDate>Wed, 01 Feb 2012 12:46:54 +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>jQ.Mobi: Less compatible, but better performance</title>
		<link>http://www.ajaxbestiary.com/2012/01/17/jq-mobi-less-compatible-but-better-performance/</link>
		<comments>http://www.ajaxbestiary.com/2012/01/17/jq-mobi-less-compatible-but-better-performance/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 12:00:23 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=641</guid>
		<description><![CDATA[The plain reality is that the vast majority of mobile web traffic is on Android and iOS devices. BlackBerry users have, by and large, been so disappointed by the poor web experience out of the box that they tend not to go on the web. Windows smartphones are still a small slice of the mobile [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>The plain reality is that the vast majority of mobile web traffic is on Android and iOS devices. BlackBerry users have, by and large, been so disappointed by the poor web experience out of the box that they tend not to go on the web. Windows smartphones are still a small slice of the mobile market, especially when you focus on 3G and LTE devices, which use the lion&#8217;s share of the traffic, at least until Nokia ramps up its smartphone production.</p>
<p>With that in mind, <a href="http://www.jqmobi.com/">jQ.Mobi</a> saw its first <a href="http://www.businesswire.com/news/home/20120116005506/en/jQ.Mobi-jQuery-Rewritten-Ground-Up-iOS-Android">public release</a> on Monday. Its developer, <a href="http://www.appmobi.com/">appMobi</a>, calls it a beta.</p>
<p>The core engine <em>and</em> UI is 15KB gripped, which means that even when your user drops to <a href="http://askville.amazon.com/speed-difference-edge-network-3g/AnswerViewer.do?requestId=2566828">EDGE</a>, they&#8217;ll still have a good experience, since you still have 10KB leeway for images and markup. It is also optimized for simulating apps, including support for integration in tools like <a href="http://phonegap.com/">PhoneGap</a>.</p>
<p>Further, it&#8217;s designed to make the interface as consistent as possible between Android and iOS devices, including fixed headers and footers and smooth CSS3 transitions. It&#8217;s not quite ready for tablet devices. If you watch the video, the interface during the Kindle Fire segment feels clunky, but they say they are working on tablet-optimized CSS.</p>
<p>In terms of syntax, jQuery users will feel at home. Still, be cautious with jQuery plugins, because while they should be run, many are still optimized for desktop environments and jQ.mobi is <em>not</em> intended for desktop use. </p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/MwNdWZsRXgk" frameborder="0" allowfullscreen></iframe></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2012/01/17/jq-mobi-less-compatible-but-better-performance/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Loopy Optimizations</title>
		<link>http://www.ajaxbestiary.com/2012/01/16/loopy-optimizations/</link>
		<comments>http://www.ajaxbestiary.com/2012/01/16/loopy-optimizations/#comments</comments>
		<pubDate>Mon, 16 Jan 2012 19:11:18 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Article]]></category>
		<category><![CDATA[Browsers]]></category>
		<category><![CDATA[Chrome]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[YUI]]></category>
		<category><![CDATA[loops]]></category>
		<category><![CDATA[optimization]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=623</guid>
		<description><![CDATA[We all know that code optimization is important, especially when processing large quantities of data. It is also common knowledge that adding layers of code to loops reduces performance. Except this maxim doesn&#8217;t always hold when it comes to JavaScript in browsers and even native methods can vary wildly in performance. In fact, in almost [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>We all know that code optimization is important, especially when processing large quantities of data. It is also common knowledge that adding layers of code to loops reduces performance. Except this maxim doesn&#8217;t always hold when it comes to JavaScript in browsers and even native methods can vary wildly in performance. In fact, in almost all cases, Underscore, jQuery and YUI outperformed any of the native methods. Interestingly, the newest implementation for native looping, forEach, consistently trumped a traditional <code>for (var i = 0; i &lt; 2500; i++)</code> loop.</p>
<p>I set up a testing framework that looped through a normal array instantiated like so:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> v <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">//This value doesn't seem to affect performance at the data size I chose</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&amp;</span>lt<span style="color: #339933;">;</span> loops<span style="color: #339933;">;</span> i<span style="color: #339933;">++</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #006600; font-style: italic;">//loops is defined elsewhere</span>
   data.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>v<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code></p>
<p>I looped through this array using the following methods:</p>
<ul>
<li>for loop</li>
<li>for &#8230; in &#8230; loop</li>
<li>forEach loop (not supported in IE9 Quirks Mode)</li>
<li>Prototype 1.7: Enumerable.each</li>
<li>jQuery 1.7.1: $.each</li>
<li>Underscore 1.2.3: _.each</li>
<li>YUI 3.1.4: YUI.each</li>
</ul>
<p>Each loop was passed the value of the array element and returned immediately, like so:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">//From the native for and for ... in ... tests</span>
<span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>el<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span><span style="color: #000066; font-weight: bold;">return</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>I eventually settled upon an array of 2500 elements and running the test 200 times to collect a reasonable number of samples. These numbers were not chosen arbitrarily. Prototype would time out on Firefox at 5000 array elements and Safari seemed to have wildly varying results on each run of the suite with fewer than 200 samples. With 200 samples, the variance in mean time between runs became a few hundredths of a millisecond, not enough to be of consequence. Disturbingly, while Prototype froze the browser with 5000 array elements and 100 samples, it had no issue with 2500 elements and 200 samples. Even so, with some tests averaging less than a hundredth of a millisecond, we will soon require much larger data sets to get meaningful results at all, which may preclude the inclusion of Prototype (and even native methods!) in future tests.</p>
<p>All tests were run in a freshly launched browser on an updated operating system (either MacOS 10.7.2 or Windows 7 Home Premium) running on a MacBook Pro with a 2.53GHz Intel Core 2 Duo processor and 4GB of 1067MHz DDR3 RAM. Firefox had all add-ons disabled and Internet Explorer had the Developer Tools open (to switch between Standards and Quirks mode).</p>
<p>So let&#8217;s look at some charts!</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/mac-safari.png" alt="Mac safari" title="mac-safari.png" border="0" width="600" height="337" /><br />
This was certainly an interesting start to the process. YUI, Underscore and jQuery all clocked in at 0.005 ms. Prototype would prove to be faster than native methods, with the exception of forEach, on all browsers. Underscore was only be outperformed on IE 9 (32-bit, Standards Mode).</p>
<p><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/mac-chrome.png" alt="Mac chrome" title="mac-chrome.png" border="0" width="600" height="338" /><br />
Chrome was exceptional as well, with the traditional for loop actually running slower than <code>for ... in ...</code>. This behavior was also seen on Chrome for Windows and Safari for Windows.</p>
<p>Since all of the major browsers are clearly pre-optimized for these libraries (as they themselves wrap the native looping language structures), let&#8217;s look at just the libraries:<br />
<img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/all-libraries.png" alt="Loop run times, by library" title="loop-by-library.png" border="0" width="600" height="338" /><br />
Here we can begin to see that Prototype really is behind its peers in loop performance. While we are talking fractions of a millisecond, our apps are growing larger by the day and this could become a serious issue.</p>
<p><a href="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/sans-prototype.png"><img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/sans-prototype.png" alt="Run times of non-prototypical libraries by browser" title="sans-prototype.png" border="0" width="600" height="399" /></a><br />
Hey! It looks like Firefox really is slow. Curiously, IE 9 is significantly faster, which flies in the face of most generalized JavaScript performance metrics.</p>
<p>Still, something looks odd about IE:<br />
<img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.ajaxbestiary.com/wp-content/uploads/2012/01/ie9-libraries.png" alt="Run times by library and version of Internet Explorer 9" title="mac-chrome.png" border="0" width="600" height="338" /><br />
Your mileage varies wildly depending on whether you choose standards or quirks mode, and not always in obvious ways. In general, 64-bit is faster, but only marginally, and most people are not using it. (You have to explicitly launch it, as it is not the default, even on 64-bit Windows). Meanwhile, quirks mode apparently embeds some performance hacks. As a note to benchmark developers, this should be evidence enough that not all IE&#8217;s are the same and we need to start breaking down by rendering mode and compilation.</p>
<p>So far, we&#8217;ve seen the average times and most browsers are quite acceptable. What are the worst case scenarios?</p>
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<p>Platform</p>
</td>
<td>
<p>Browser</p>
</td>
<td>
<p>Method</p>
</td>
<td>
<p>Max (ms)</p>
</td>
<td>
<p>Mean (ms)</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (64-bit IE 9 Quirks)</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>93</p>
</td>
<td>
<p>5.29</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (32-bit IE 9 Standards)</p>
</td>
<td>
<p>forEach</p>
</td>
<td>
<p>81</p>
</td>
<td>
<p>4.04</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (64-bit IE 9 Quirks)</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>81</p>
</td>
<td>
<p>6.27</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (32-bit IE 9 Standards)</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>76</p>
</td>
<td>
<p>9.87</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (64-bit IE 9 Standards)</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>71</p>
</td>
<td>
<p>4.89</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (32-bit IE 9 Quirks)</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>67</p>
</td>
<td>
<p>5.995</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Firefox 9.0.1</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>55</p>
</td>
<td>
<p>1.885</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>Firefox 9.01</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>52</p>
</td>
<td>
<p>6.055</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (32-bit IE 9 Quirks)</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>49</p>
</td>
<td>
<p>4.66</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (64-bit IE 9 Standards)</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>48</p>
</td>
<td>
<p>4.76</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>IE 9.0.8112.16421 (32-bit IE 9 Standards)</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>39</p>
</td>
<td>
<p>7.845</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>Chrome 16.0.912.75 m</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>30</p>
</td>
<td>
<p>1.13</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>Chrome 16.0.912.75 m</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>26</p>
</td>
<td>
<p>1.315</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Chrome 16.0.912.75</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>23</p>
</td>
<td>
<p>1.175</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Chrome 16.0.912.75</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>22</p>
</td>
<td>
<p>1.085</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Safari 5.1.2</p>
</td>
<td>
<p>for in</p>
</td>
<td>
<p>16</p>
</td>
<td>
<p>1</p>
</td>
</tr>
<tr>
<td>
<p>Windows 7</p>
</td>
<td>
<p>Firefox 9.01</p>
</td>
<td>
<p>jQuery</p>
</td>
<td>
<p>6</p>
</td>
<td>
<p>0.185</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Safari 5.1.2</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>5</p>
</td>
<td>
<p>0.52</p>
</td>
</tr>
<tr>
<td>
<p>MacOS 10.7.2</p>
</td>
<td>
<p>Firefox 9.0.1</p>
</td>
<td>
<p>for</p>
</td>
<td>
<p>5</p>
</td>
<td>
<p>0.7</p>
</td>
</tr>
</table>
<p>Those averages hid some extreme variations within Internet Explorer. Fortunately, most of these are found using native language structures, which we know better than to use.</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2012/01/16/loopy-optimizations/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>jQuery Mobile 1.0 Final</title>
		<link>http://www.ajaxbestiary.com/2012/01/10/jquery-mobile-1-0-final/</link>
		<comments>http://www.ajaxbestiary.com/2012/01/10/jquery-mobile-1-0-final/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 15:10:29 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Javascript Frameworks]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[mobile]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=607</guid>
		<description><![CDATA[The long anticipated jQuery Mobile library has hit version 1.0 Final. With support for most mobile devices, it facilitates rapid development of mobile friendly sites. Note that it does require jQuery 1.6.4 and the jQuery Mobile 1.0 CSS file, in addition to the jQuery Mobile 1.0 JavaScript file. This means that pages that use it [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>The long anticipated <a href="http://jquerymobile.com/">jQuery Mobile</a> library has hit version 1.0 Final. With support for most mobile devices, it facilitates rapid development of mobile friendly sites.</p>
<p>Note that it does require jQuery 1.6.4 and the jQuery Mobile 1.0 CSS file, in addition to the jQuery Mobile 1.0 JavaScript file. This means that pages that use it will very likely exceed the 25KB limit of some very old phones, preventing the page from loading at all on them. That said, most phones sold since 2008 do not have this limitation, so it shouldn&#8217;t hinder you too much. Still, focus on keeping image assets, JS, CSS and HTML as optimized as possible, because mobile performance is still pretty slow for most users.</p>
<p>Also, it does require a number of custom attributes, so you will want to explore their <a href="http://jquerymobile.com/demos/1.0/docs/about/getting-started.html">Getting Started documentation</a>.</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2012/01/10/jquery-mobile-1-0-final/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Gantt charts made easier, with ideas for improvements</title>
		<link>http://www.ajaxbestiary.com/2011/12/13/gantt-charts-made-easier-with-ideas-for-improvements/</link>
		<comments>http://www.ajaxbestiary.com/2011/12/13/gantt-charts-made-easier-with-ideas-for-improvements/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 23:02:03 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Javascript Frameworks]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[chart]]></category>
		<category><![CDATA[gantt]]></category>
		<category><![CDATA[gantt chart]]></category>
		<category><![CDATA[jquery extension]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=542</guid>
		<description><![CDATA[Tait Brown has released an interesting jQuery extension for generating Gantt charts. The most recent version adds support for local as well as JSON data sources and improves standard compliance while reducing the likelihood of CSS rule collisions. One of the very first comments to the tumblr announcement was from jh asking, &#8220;Is it possible [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p><a href="http://taitems.tumblr.com/post/14143450461/ive-just-pushed-some-pretty-hefty-changes-to-the">Tait Brown</a> has released an interesting jQuery extension for generating <a href="http://en.wikipedia.org/wiki/Gantt_chart">Gantt charts</a>.</p>
<p>The most recent version adds support for local as well as JSON data sources and improves standard compliance while reducing the likelihood of CSS rule collisions.</p>
<p>One of the very first comments to the tumblr announcement was from jh asking, &#8220;Is it possible to represent dependencies among tasks?&#8221; This is an important Gantt chart feature, but not one that seems implemented &#8211; yet.</p>
<p>Using the live demo, I was able to inject a simple snippet between div.bar.ganttGreen and div.fn-label:<br />
<code class="html">&lt;div style=&quot;border-left: 1px solid #000; border-bottom: 1px solid #000; margin-top:-18px;height:30px; width:1px;&quot;&gt;&lt;/div&gt;</code></p>
<p>This produces a small black line to represent the relationship. While an arrow would be nicer, there is not enough space to represent it cleanly. I&#8217;m also using border-left and border-bottom so that it can eventually show relationships that don&#8217;t start and end at the same time.</p>
<p>Obviously, this is incomplete.</p>
<p>We will need to find a way to represent the relationship with another bar in the data. Each one is rendered by fillBars(), which simply iterates over the data property of the passed object, calling createProgressBar(). Presumably, we could add a parent property and use the array index of the parent bar as the value of parent.</p>
<p>We would still, however, need to calculate the relative positions of the bars, which will require a store of the row ID&#8217;s for each bar, so that we can test for visibility and horizontal and vertical positions.</p>
<p>These are not trivial changes, but they&#8217;re not insurmountable.</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2011/12/13/gantt-charts-made-easier-with-ideas-for-improvements/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Hovercard &#8211; tooltips on steroids</title>
		<link>http://www.ajaxbestiary.com/2011/12/08/hovercard-tooltips-on-steroids/</link>
		<comments>http://www.ajaxbestiary.com/2011/12/08/hovercard-tooltips-on-steroids/#comments</comments>
		<pubDate>Thu, 08 Dec 2011 22:08:10 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Widget]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=530</guid>
		<description><![CDATA[Hovercard is a jQuery plugin that lets you hover what amounts to a tooltip. Except unlike your normal tooltip, this one supports event callbacks and lets you use arbitrary HTML and use as much space as you need. They also provide support for Twitter and Facebook integration out of the box! Suggested uses include virtual [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p><a href="http://designwithpc.com/Plugins/Hovercard">Hovercard</a> is a jQuery plugin that lets you hover what amounts to a tooltip. Except unlike your normal tooltip, this one supports event callbacks and lets you use arbitrary HTML and use as much space as you need.</p>
<p>They also provide support for Twitter and Facebook integration out of the box!</p>
<p>Suggested uses include virtual business cards, price comparisons and editing in place. Personally, my mind leaps to a web-based implementation of Civilization &#8211; it&#8217;s instant feedback on any cell in the world.</p>
<p>Check out their sample screenshot and imagine what you could do with it.<br />
<img src="http://www.ajaxbestiary.com/wp-content/uploads/2011/12/inplace-preview.png" alt="Hovercard Sample Screenshot" title="inplace-preview.png" border="0" width="450" height="222" /></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2011/12/08/hovercard-tooltips-on-steroids/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unexpected call to method or property access</title>
		<link>http://www.ajaxbestiary.com/2011/11/14/unexpected-call-to-method-or-property-access/</link>
		<comments>http://www.ajaxbestiary.com/2011/11/14/unexpected-call-to-method-or-property-access/#comments</comments>
		<pubDate>Mon, 14 Nov 2011 06:26:27 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Javascript Frameworks]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=475</guid>
		<description><![CDATA[If you&#8217;ve ever used jQuery&#8217;s append or prepend methods in IE8 with complex HTML fragments, you&#8217;ll probably recognize this message. I ran into it very recently when I was loading relatively simple HTML containing a relatively complex script into a modal window. Naturally, the bug only occurred in Internet Explorer and the failure happened at [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>If you&#8217;ve ever used jQuery&#8217;s append or prepend methods in IE8 with complex HTML fragments, you&#8217;ll probably recognize this message. I ran into it very recently when I was loading relatively simple HTML containing a relatively complex script into a modal window.</p>
<p>Naturally, the bug only occurred in Internet Explorer and the failure happened at line 4 of this block:<br />
<code> append: function() {<br />
		return this.domManip(arguments, true, function( elem ) {<br />
			if ( this.nodeType === 1 ) {<br />
				this.appendChild( elem );<br />
			}<br />
});}<br />
</code></p>
<p>This seems like the least likely point of failure imaginable, but there was the error preventing the rest of the script from executing.</p>
<p>I found <a href="http://forum.jquery.com/topic/ie-issue-with-append#14737000000469433">plenty</a> <a href="http://forum.jquery.com/topic/unexpected-call-to-method-or-property-access-in-ie8#14737000001826148">of</a> <a href="http://forum.jquery.com/topic/unexpected-call-to-method-or-property-access-in-ie8#14737000001150221">theories</a>. There were some recurring themes though.</p>
<p>First, it is critical that you append well-formed HTML or the browser may justifiably fail. I tested mine fragment by wrapping it in some very basic HTML, HEAD and BODY tags with a DOCTYPE declaration and feeding it to the <a href="http://validator.w3.org/#validate_by_input">W3C Validator</a>. That, unfortunately, did not work.</p>
<p>I disregarded the theories about buttons, because I had other scripts that referenced buttons and they worked fine.</p>
<p>One commenter (<a href="http://forum.jquery.com/topic/problem-with-append-elem-method-in-ie8#14737000001512065">zmonteca</a>) in the jQuery forums mentioned, &#8220;DispHTMLCommentElement,&#8221; which got me thinking. What exactly <em>were</em> <code>this</code> and <code>elem</code> and the moment of failure? After adding <code>this</code> to the Watch variables, I saw the problem. At some point in the loop, <code>this</code> <em>became</em> the SCRIPT element and <code>elem</code> <em>became</em> the DIV. Infuriatingly, at earlier iterations, the same nodes were in the correct order!</p>
<p>Now it all made sense. Both are valid HTML DOM nodes of type 1 (element), but it makes no sense to the browser to embed a DIV inside of a SCRIPT, just as you wouldn&#8217;t embed a BUTTON inside of an IMG. It would be downright&#8230; unexpected!</p>
<p>So the morals of the story are</p>
<ol>
<li>Always write clean, valid markup</li>
<li>Be comfortable performing stack traces</li>
<li>Really understand not just JavaScript, but HTML as well</li>
</ol>
<p>Oh, and are you&#8217;re wondering how I dealt with the situation? I&#8217;ll own up to introducing a hack-ish patch to my copy of jQuery 1.7. I simply checked the tagName property of <code>this</code> and if it is SCRIPT, I reverse <code>this</code> and <code>elem</code>. This particular project is unlikely to have dynamically loaded OBJECT tags, so this seemed the fastest, cleanest way to deal with a bad issue when the markup itself validated.</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2011/11/14/unexpected-call-to-method-or-property-access/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to Write a jQuery Plugin</title>
		<link>http://www.ajaxbestiary.com/2010/06/09/how-to-write-a-jquery-plugin/</link>
		<comments>http://www.ajaxbestiary.com/2010/06/09/how-to-write-a-jquery-plugin/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 21:00:00 +0000</pubDate>
		<dc:creator>Don Albrecht</dc:creator>
				<category><![CDATA[Article]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[plugins]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/2010/06/09/how-to-write-a-jquery-plugin/</guid>
		<description><![CDATA[I know there’s a slew and a half of tutorials on this out there, but I’m adding my own to the mix.&#160; I’ve been working on a generic template for plugin development and have cobbled together what I feel is a solid one. First thing first, however, building a plugin is about being a good [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>I know there’s a slew and a half of tutorials on this out there, but I’m adding my own to the mix.&#160; I’ve been working on a generic template for plugin development and have cobbled together what I feel is a solid one.</p>
<p>First thing first, however, building a plugin is about being a good citizen</p>
<ol>
<li><font color="#333333">You’ve got a naming convention to deal with.&#160; jquery[your plugin name].js</font> </li>
<li><font color="#333333">Be considerate of the $.XXX namespace.&#160; Only claim 1, and try to make it both developer friendly and unique.&#160; In our case it will be $.plugin</font> </li>
<li><font color="#333333">Always return this.</font> </li>
<li><font color="#333333">Always end with a “;”</font> </li>
<li><font color="#333333">Wrap the entire thing in an anonymous function call, this will protect the plugin from instances where jquery has been renamed.&#160; </font></li>
</ol>
<p><font color="#333333">So, with all that said and done, the skeleton of a plugin looks like this:</font></p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> (<span style="color: #0000ff">function</span>($) {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>   $.fn.myPlugin = <span style="color: #0000ff">function</span>(settings) {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     <span style="color: #0000ff">var</span> config = {<span style="color: #006080">'foo'</span>: <span style="color: #006080">'bar'</span>};</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>     <span style="color: #0000ff">if</span> (settings) $.extend(config, settings);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     <span style="color: #0000ff">this</span>.each(<span style="color: #0000ff">function</span>() {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>       <span style="color: #008000">// element-specific code here</span></pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>     });</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>     <span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span>   };</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum11">  11:</span>   </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum12">  12:</span>    <span style="color: #0000ff">var</span> newMethods = {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum13">  13:</span>        a   : <span style="color: #0000ff">function</span>() {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum14">  14:</span>                 <span style="color: #0000ff">var</span> config = {<span style="color: #006080">'foo'</span>: <span style="color: #006080">'bar'</span>};</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum15">  15:</span>                 <span style="color: #0000ff">if</span> (settings) $.extend(config, settings);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum16">  16:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum17">  17:</span>                <span style="color: #0000ff">this</span>.each(<span style="color: #0000ff">function</span>() {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum18">  18:</span>                   <span style="color: #008000">// element-specific code here</span></pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum19">  19:</span>                 });</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum20">  20:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum21">  21:</span>                 <span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum22">  22:</span>                   },</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum23">  23:</span>        b   : <span style="color: #0000ff">function</span>() { <span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span> },</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum24">  24:</span>        c     : <span style="color: #0000ff">function</span>() { <span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span> }</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum25">  25:</span>       };</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum26">  26:</span>       </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum27">  27:</span>  jQuery.each(newMethods, <span style="color: #0000ff">function</span>(i) {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum28">  28:</span>    jQuery.fn.myPlugin[i] = <span style="color: #0000ff">this</span>;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum29">  29:</span>  });</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum30">  30:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: white; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum31">  31:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum32">  32:</span> })(jQuery);</pre>
<p><!--CRLF--></div>
</div>
<p>&#160;</p>
<p>Note, what this code is doing.</p>
<p>First, we define the core behavior of the plugin, then extend the plugin once.&#160; This way we keep our declarations concise, clear and well encapsulated.</p>
<p>We have an established closure structure for shared private functions.</p>
<p>We keep everything encapsulated to protect the jquery namespace as much as possible, and iterate over the child functions to extend the plugin.</p>
<p>PS– most of this is adapted from the jquery extension guide here: <a title="http://docs.jquery.com/Plugins/Authoring" href="http://docs.jquery.com/Plugins/Authoring">http://docs.jquery.com/Plugins/Authoring</a></p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2010/06/09/how-to-write-a-jquery-plugin/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Getting and setting values for jQuery widgets</title>
		<link>http://www.ajaxbestiary.com/2009/12/11/getting-and-setting-values-for-jquery-widgets/</link>
		<comments>http://www.ajaxbestiary.com/2009/12/11/getting-and-setting-values-for-jquery-widgets/#comments</comments>
		<pubDate>Fri, 11 Dec 2009 22:30:34 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Widget]]></category>
		<category><![CDATA[Widgets]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=397</guid>
		<description><![CDATA[If you come from an OOP background you’re likely used to defining class variables like this: class MyClass &#123; var internalValue1; var internalValue2; function constructor&#40;&#41; &#123; … &#125; &#125; The values which are to be stored in your object are simple, straightforward, likely to be typed, and the compiler will detect typos in the variable [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>If you come from an OOP background you’re likely used to defining class variables like this:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">class</span> MyClass <span style="color: #009900;">&#123;</span>
   <span style="color: #003366; font-weight: bold;">var</span> internalValue1<span style="color: #339933;">;</span>
   <span style="color: #003366; font-weight: bold;">var</span> internalValue2<span style="color: #339933;">;</span>
   <span style="color: #003366; font-weight: bold;">function</span> constructor<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>  … <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p></code></p>
<p>The values which are to be stored in your object are simple, straightforward, likely to be typed, and the compiler will detect typos in the variable names. JavaScript, as a loosely types language which treats its objects more like collections than discrete objects, can’t really offer us those protections. Conversely, that also means that we have a great deal of flexibility.</p>
<p>In essence, we can dynamically subclass our objects, which you have to admit is a neat trick.</p>
<p>So, for jQuery.UI widgets, the variables stored within our widget are not defined until we assign them. The act of assignment defines the variable name, which can then be called upon at will.</p>
<p>Assignment is simply:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">this</span>._setData<span style="color: #009900;">&#40;</span>‘variablename’<span style="color: #339933;">,</span> variablevalue<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>Retrieval of this value is similarly straightforward:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">this</span>._getData<span style="color: #009900;">&#40;</span>‘variablename’<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>This does mean that the old problem of misnamed variables is alive and well. It also means that you need to be prepared to handle an undefined response to the _getData call.</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/12/11/getting-and-setting-values-for-jquery-widgets/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Event handling in jQuery widgets</title>
		<link>http://www.ajaxbestiary.com/2009/12/08/event-handling-in-jquery-widgets/</link>
		<comments>http://www.ajaxbestiary.com/2009/12/08/event-handling-in-jquery-widgets/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 18:00:57 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Widget]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=390</guid>
		<description><![CDATA[This is simple – provided you understand that the reference the keyword this refers to changes depending on when it is called. When called during initialization, this refers to the widget you’re initializing. When the event itself is triggered, this refers to the DOM node node and not the widget. As such, we need to [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>This is simple – provided you understand that the reference the keyword <strong>this</strong> refers to changes depending on when it is called.</p>
<p>When called during initialization, <strong>this</strong> refers to the widget you’re initializing. When the event itself is triggered, <strong>this</strong> refers to the DOM node node and not the widget.</p>
<p>As such, we need to introduce a new variable during initialization which the jQuery.UI library calls <strong>self</strong> which is, of course, equal to the initialization <strong>this</strong>, not triggered <strong>this</strong>. (Those of you familiar with Object Oriented Programming and by-reference calls should have no issue with this concept).</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;</span>$.<span style="color: #660066;">widget</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;ui.clicker&quot;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
   _init<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      self <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span>.<span style="color: #660066;">click</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         self.<span style="color: #660066;">increment</span><span style="color: #009900;">&#40;</span>self<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         self.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">render</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
   increment<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>target<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      target.<span style="color: #660066;">value</span><span style="color: #009900;">&#40;</span>target.<span style="color: #660066;">value</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #006600; font-style: italic;">//The exact handling of target.value will be shown another day</span>
   <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
   render<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">element</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">value</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
   value<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>val<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      …
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>You’ll note that we have to pass <strong>self</strong> to the increment method or the widget won’t actually be able to find itself, but the render method, which was called during initialization, is henceforth always able to correctly reference <strong>this</strong> (the widget)!</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/12/08/event-handling-in-jquery-widgets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Customized context menu handling with jQuery</title>
		<link>http://www.ajaxbestiary.com/2009/12/07/customized-context-menu-handling-with-jquery/</link>
		<comments>http://www.ajaxbestiary.com/2009/12/07/customized-context-menu-handling-with-jquery/#comments</comments>
		<pubDate>Mon, 07 Dec 2009 22:26:33 +0000</pubDate>
		<dc:creator>Dave Mahon</dc:creator>
				<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[context menu]]></category>
		<category><![CDATA[right click]]></category>

		<guid isPermaLink="false">http://www.ajaxbestiary.com/?p=384</guid>
		<description><![CDATA[Can you think of some times you might want to disable the right click context menu? Or better still, insert your own behavior or application specific context menu? This is a simple and useful trick: element.bind&#40;'contextmenu',function&#40;e&#41;&#123; //Optional customized handling here return false; &#125;&#41;; If you don’t return false, the normal context menu will appear, which [...]]]></description>
			<content:encoded><![CDATA[
<!-- google_ad_section_start -->
<p>Can you think of some times you might want to disable the right click context menu? Or better still, insert your own behavior or application specific context menu?</p>
<p>This is a simple and useful trick:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">element.<span style="color: #660066;">bind</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'contextmenu'</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #006600; font-style: italic;">//Optional customized handling here</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<p>If you don’t return false, the normal context menu will appear, which could actually be desirable, depending on what exactly you want it to do (say, exiting a field and recording it as dirty).</p>
<p><img src="http://www.ajaxbestiary.com/?voyeur=1"></p>
<!-- google_ad_section_end -->
]]></content:encoded>
			<wfw:commentRss>http://www.ajaxbestiary.com/2009/12/07/customized-context-menu-handling-with-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

