<?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/"
xmlns:series="http://unfoldingneurons.com/"
><channel><title>David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞. &#187; Dojo</title> <atom:link href="http://davidwalsh.name/tutorials/dojo/feed" rel="self" type="application/rss+xml" /><link>http://davidwalsh.name</link> <description>Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</description> <lastBuildDate>Sat, 04 Feb 2012 19:28:58 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3</generator> <item><title>Using&#160;dojo/aspect</title><link>http://davidwalsh.name/dojo-aspect</link> <comments>http://davidwalsh.name/dojo-aspect#comments</comments> <pubDate>Thu, 05 Jan 2012 16:23:51 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Dojo]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5360</guid> <description><![CDATA[Simply put: the Dojo Toolkit has tools that other JavaScript toolkits don&#8217;t. One of those tools includes Dojo 1.7&#8242;s aspect, a module that allows developers to react to function calls by executing another function before or after that call. This aspect resource originates from Dojo&#8217;s awesome connect mechanism. Let&#8217;s check out how it works! aspect&#160;Basics [...]<p><a
href="http://davidwalsh.name/dojo-aspect">Using&nbsp;dojo/aspect</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>Simply put:  the Dojo Toolkit has tools that other JavaScript toolkits don&#8217;t.  One of those tools includes Dojo 1.7&#8242;s <code>aspect</code>, a module that allows developers to react to function calls by executing another function before or after that call.  This aspect resource originates from <a
href="http://davidwalsh.name/dojo-connect">Dojo&#8217;s awesome connect mechanism</a>. Let&#8217;s check out how it works!</p><h2>aspect&nbsp;Basics</h2><p>The idea and value of aspect is that it allows you to be notified of function calls without needing to modify the original function&#8217;s contents.  You also don&#8217;t need to implement pub/sub to know when methods are called.  The basic setup looks like:</p><pre class="js">
// Load the dojo/aspect dependency
require(["dojo/aspect"], function(aspect) {
	
	// Create an object and method to spy on
	var original = {
		someMethod: function(arg1, arg2) {
			console.warn("original.someMethod called: ", arg1, arg2);
			return "Hello " + arg1 + " " + arg2;
		}
	};
	
	// Use aspect.after ("before" also available)
	aspect.after(original, "someMethod", function(arg1, arg2) {
		console.warn("After method called with arguments: ", arg1, arg2);
	}, true);
	
	// ...and a while later, call the original method
	original.someMethod("David", "Walsh");
	
});
</pre><p>The first argument is the origin object, the second argument is the method to listen in on, and the third is the function to fire before or after, depending on which aspect method you call.</p><h2>aspect.before</h2><p>The <code>before</code> method will fire before the originally called method fires:</p><pre class="js">
// Fire a function before the original
aspect.before(original, "someMethod", function(arg1, arg2) {
	console.warn("aspect.before: ", arg1, arg2);
});

// "aspect.before: ", David, Walsh
// "original.someMethod called:", David, Walsh
</pre><p>Since this method is fired before the original function call, the arguments passed to the original method are automatically received by the aspect method.</p><h2>aspect.after</h2><p>The <code>after</code> method fires after the original method fires, and accepts an extra parameter called <code>receiveArguments</code>, where you may direct the second method to receive the original method&#8217;s arguments, or the return value of the original method.</p><h3>receiveArguments =&nbsp;true</h3><p>Passing the receiveArguments as true will pass the two arguments from the original function call to the <code>aspect</code> method:</p><pre class="js">
// First scenario:  aspect.after that accepts the same arguments as the origin function
// because the fourth argument is passed as "true"
aspect.after(original, "someMethod", function(arg1, arg2) {
	console.warn("After method called with arguments: ", arg1, arg2);
}, true);

// Call the original method, see what happens!
original.someMethod("David", "Walsh");

// "original.someMethod called:", David, Walsh
// "aspect.after: ", David, Walsh
</pre><p>Removing the last argument instead allows the <code>aspect</code> method to receive the return value of the original function call:</p><pre class="js">
// Second scenario: aspect.after that accepts the result of the original function call
aspect.after(original, "someMethod", function(arg1, arg2) {
	console.warn("aspect.after: ", arg1, arg2);
	
	// "arg2" will be "undefined" since only the return value is provided 
	
}); // No "true"

// Call the original method, see what happens!
original.someMethod("David", "Walsh");

// "original someMethod: David Walsh"
// "aspect.after: ", David Walsh
</pre><p>In most cases, <code>aspect.after</code> is what you will want to use.  An object with a remove method will be returned, allowing you to remove the connection whenever you&#8217;d like.</p><h2>aspect.around</h2><p> What if you want to execute code both before and after the original method?  Simple:  use <code>aspect.around</code>.  The <code>around</code> method allows you to call the original function when you want, within your listener:</p><pre class="js">
// Call the around method, which gets one argument, the original method
aspect.around(original, "someMethod", function(originalMethod) {
	// Return a new method, which receives the same arguments as the original, just like "aspect.after"
	return function(arg1, arg2) {
		// Execute "before" functionality
		console.warn("before!", arg1, arg2);
		
		// Execute the original method as desired
		originalMethod.apply(this, arguments);
		
		// Execute "after" functioanlity
		console.warn("after!");
	};
});

// Call the original method, see what happens!
original.someMethod("David", "Walsh");

// "before!", David, Walsh
// "original someMethod: David Walsh"
// "after! David Walsh"
</pre><p>The idea behind <code>aspect.around</code> is very much like using <code>this.inherited(arguments)</code> within Dojo classes;  you can make that call any time you&#8217;d like, so other code may run before or after.</p><h2>Real Use of&nbsp;aspect</h2><p>One realistic use of <code>aspect</code> relates to extending Dijit widgets, or building a Dijit layout that uses multiple widgets.  Often you&#8217;ll see something like:</p><pre class="js">
// When the onChange event fires
aspect.after(this.dropdown, "onChange", function(value) {
	// ...fire an xhr request to get information about it
	dojo.xhrGet({
		url: "/data.php?value=" + value
	}).then(function(data) { 
		// Do something with it.
	});
}, true);
</pre><p>When the dropdown&#8217;s value changes, an XHR request is fired to get information about that value.</p><p>Explaining aspect and the value of function-to-function connections can be difficult.  I usually try a parent-to-child analogy that just further confuses people. Think of it this way:  aspect allows you to know when other functions are called, without needing to modify the other function.  This happens all over the Dijit UI framework, Brilliant!</p><p><a
href="http://davidwalsh.name/dojo-aspect">Using&nbsp;dojo/aspect</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/dojo-aspect/feed</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>File Uploads and&#160;C:\fakepath\</title><link>http://davidwalsh.name/fakepath</link> <comments>http://davidwalsh.name/fakepath#comments</comments> <pubDate>Thu, 29 Sep 2011 01:24:48 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Browsers]]></category> <category><![CDATA[Dojo]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5300</guid> <description><![CDATA[I was recently working on a project that required providing an AJAX uploading widget to users. I decided to use Dojo&#8217;s dojox.form.FileInput widget so the &#8220;Upload&#8221; button would look just like every other button within the web application. Everything worked great until I tested the widget in Chrome and found that the value of the [...]<p><a
href="http://davidwalsh.name/fakepath">File Uploads and&nbsp;C:\fakepath\</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>I was recently working on a project that required providing an AJAX uploading widget to users.  I decided to use Dojo&#8217;s dojox.form.FileInput widget so the &#8220;Upload&#8221; button would look just like every other button within the web application.  Everything worked great until I tested the widget in Chrome and found that the value of the input node was being set to <code>C:\fakepath</code>\{Original File Name}.  I then checked Internet Explorer and Safari;  both of them were prepending &#8220;<code>C:\fakepath</code>&#8221; to the file name.  WTF?!</p><p>After doing some research, I found <a
href="http://acidmartin.wordpress.com/2009/06/09/the-mystery-of-cfakepath-unveiled/" rel="nofollow">this blog post</a>, which explained:</p><blockquote><p>According to the specifications of HTML5, a file upload control should not reveal the real local path to the file you have selected, if you manipulate its value string with JavaScript. Instead, the string that is returned by the script, which handles the file information is <code>C:\fakepath</code>.</p><p>This requirement is already implemented in Internet Explorer 8 – the real path to the file will be shown only if the page that contains the control is added to the trusted sites collection of the browser.</blockquote></p><p>That made sense;  essentially the browser is feeding that lame <code>C:\fakepath</code>\ text in.  Luckily all I needed to do was fix the issue by doing a simple string replace call:</p><pre class="js">
// Change the node's value by removing the fake path
inputNode.value = fileInput.value.replace("C:\\fakepath\\", "");
</pre><p>Whew &#8212; dodged a bullet there.  Just wanted to post this for everyone in case you run into it in the future.</p><p><a
href="http://davidwalsh.name/fakepath">File Uploads and&nbsp;C:\fakepath\</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/fakepath/feed</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Dojo, Dijit, Dropdowns, and&#160;_aroundNode</title><link>http://davidwalsh.name/dijit-dropdowns</link> <comments>http://davidwalsh.name/dijit-dropdowns#comments</comments> <pubDate>Tue, 27 Sep 2011 14:51:25 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Dojo]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5301</guid> <description><![CDATA[The Dojo Toolkit&#8217;s awesome UI framework, Dijit, has loads of awesome widgets to allow developers to quickly create themed, feature-rich web applications. Dijit provides form widgets, layout widgets, dropdown-based widgets, and much more. What&#8217;s nice about Dijit is that there&#8217;s so much functionality provided that you don&#8217;t need to code everything yourself. The down side [...]<p><a
href="http://davidwalsh.name/dijit-dropdowns">Dojo, Dijit, Dropdowns, and&nbsp;_aroundNode</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>The Dojo Toolkit&#8217;s awesome UI framework, Dijit, has loads of awesome widgets to allow developers to quickly create themed, feature-rich web applications.  Dijit provides form widgets, layout widgets, dropdown-based widgets, and much more.  What&#8217;s nice about Dijit is that there&#8217;s so much functionality provided that you don&#8217;t need to code everything yourself.  The down side of that?  That it can be difficult to find the undocumented pieces of functionality required to accomplish your goal.</p><p>One case recently came up where I was working on a widget that extended <code>dijit.form.FilteringSelect</code>. My custom widget displayed messages under the widget&#8217;s <code>INPUT</code> instead of the default tooltip behavior.  The problem that introduced was that the widget&#8217;s dropdown displayed a full 20 pixels under the <code>INPUT</code> node, so the two elements looked &#8220;detached.&#8221;  My assumption was that this was happening because the <code>domNode</code> grew in height because of my template change.</p><p>This is where it became difficult to know exactly where to look to fix the issue.  I attempted a hack of adding <code>margin-top: -20px</code> to the <code>FilteringSelect's</code> <code>dropdown</code> node, which worked, but if the error text went down to two lines, the dropdown would still be detached &#8212; obviously not the reliable solution.  Where to look next?</p><p>I knew that <code>dijit.popup</code> manages the position of a popup, so that was my next stop. <code>dijit.popup</code> accepts one argument (an object) about the popup, with information about the widget, the node to pop up, an <code>around</code> property telling the method where to fit the popup by, and more.  Seeing that, I needed to figure out where <code>FilteringSelect's</code> <code>around</code> setting was coming from.  I also knew there is no property named <code>around</code> on the <code>FilteringSelect</code> widget, so more investigation was needed.</p><p>Within the creation signature for <code>FilteringSelect</code>, I saw that <code>dijit._HasDropDown</code> is a mixin.  Looking at the <code>_HasDropDown</code> resource, I saw a method called <code>openDropdown</code> and right at the top of that method I found exactly what I needed:</p><pre class="js">
openDropDown: function(){
	// summary:
	//		Opens the dropdown for this widget.   To be called only when this.dropDown
	//		has been created and is ready to display (ie, it's data is loaded).
	// returns:
	//		return value of dijit.popup.open()
	// tags:
	//		protected

	var dropDown = this.dropDown,
		ddNode = dropDown.domNode,
		aroundNode = this._aroundNode || this.domNode,
		self = this;
		
	// more...
	
</pre><p>The <code>_aroundNode</code> that was being passed to <code>dijit.popup</code> is the <code>domNode</code> <em>unless</em> a special <code>_aroundNode</code> property is explicitly set.  Now I could set the <code>_aroundNode</code> property to my widget&#8217;s <code>focusNode</code> (the <code>INPUT</code>):</p><pre class="js">
this._aroundNode = this.focusNode;
</pre><p>This small addition fixes the detachment issue, directing <code>dijit.popup</code> to open the dropdown around the <code>INPUT</code> element and <em>not</em> the entire <code>domNode</code>.</p><p>These type of exercises are very helpful in both learning a framework and improving your debugging skills.  Undocumented properties and features are present in any set of code, so the ability to trace through and find what you need is hugely important.  It definitely was in this case!</p><p><a
href="http://davidwalsh.name/dijit-dropdowns">Dojo, Dijit, Dropdowns, and&nbsp;_aroundNode</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/dijit-dropdowns/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>JavaScript Coding with&#160;Class</title><link>http://davidwalsh.name/javascript-coding-class</link> <comments>http://davidwalsh.name/javascript-coding-class#comments</comments> <pubDate>Thu, 15 Sep 2011 15:08:16 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[AJAX]]></category> <category><![CDATA[Dojo]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[MooTools]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5291</guid> <description><![CDATA[I&#8217;ve spent the last two weeks in London, eating fish&#8217;n'chips, drinking cup&#8217;o'tea, and being a hooligan at the Arsenal. Oh yeah, there was a MooTools hackathon too. The MooTools hackathon was hugely successful and I&#8217;ll be providing more detail about what was accomplished and where MooTools is going over the coming weeks. It was also [...]<p><a
href="http://davidwalsh.name/javascript-coding-class">JavaScript Coding with&nbsp;Class</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<a
href="http://skillsmatter.com/podcast/ajax-ria/ajax-mootools-dojo" rel="nofollow"><img
src="http://davidwalsh.name/dw-content/london_ajax_logo.gif" class="image" alt="London Ajax" /></a><p>I&#8217;ve spent the last two weeks in London, eating fish&#8217;n'chips, drinking cup&#8217;o'tea, and being a hooligan at the Arsenal.  Oh yeah, there was a MooTools hackathon too.  The MooTools hackathon was hugely successful and I&#8217;ll be providing more detail about what was accomplished and where MooTools is going over the coming weeks.  It was also great to meet some of the development team in person instead of simple IRC.  MooTools FTW!</p><p>Another exciting part of my time in London was presenting at London Ajax.  My presentation was called &#8220;JavaScript Coding with Class&#8221;, preaching the values of class-based JavaScript frameworks like MooTools and Dojo.  I kept the talk high-level but I&#8217;m confident I got my point across, showing the value of class structures.</p><div
class="actions"><a
href="http://skillsmatter.com/podcast/ajax-ria/ajax-mootools-dojo" class="demo" rel="nofollow">Watch Presentation</a><div
class="clear"></div></div><p>This was my first time presenting this deck, so let me know if you see room for improvement (outside of the billion &#8220;um&#8217;s&#8221; I used.)</p><div
style="width:425px" id="__ss_9275189"> <strong
style="display:block;margin:12px 0 4px"><a
href="http://www.slideshare.net/davidwalsh83/javascript-coding-with-class" title="JavaScript Coding with Class" target="_blank">JavaScript Coding with Class</a></strong> <iframe
src="http://www.slideshare.net/slideshow/embed_code/9275189" width="425" height="355" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe><div
style="padding:5px 0 12px"> View more <a
href="http://www.slideshare.net/" target="_blank">presentations</a> from <a
href="http://www.slideshare.net/davidwalsh83" target="_blank">davidwalsh83</a></div></div><p><em>Due to popular request, my slides have been embedded above.</em></p><p><a
href="http://davidwalsh.name/javascript-coding-class">JavaScript Coding with&nbsp;Class</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/javascript-coding-class/feed</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Custom AJAX Content Handling with the Dojo&#160;Toolkit</title><link>http://davidwalsh.name/dojo-xhr-handleas</link> <comments>http://davidwalsh.name/dojo-xhr-handleas#comments</comments> <pubDate>Wed, 17 Aug 2011 14:13:44 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[AJAX]]></category> <category><![CDATA[Dojo]]></category> <category><![CDATA[JavaScript]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5283</guid> <description><![CDATA[If you were to ask me for the top five words that should describe any JavaScript framework, one of them would be flexible.  The Dojo Toolkit is ultra-flexible in just about every way, using customizable classes and dojo-namespaced objects to to allow for maximal flexibility.  One of those dojo-namespaced objects, dojo.contentHandlers, is an object containing [...]<p><a
href="http://davidwalsh.name/dojo-xhr-handleas">Custom AJAX Content Handling with the Dojo&nbsp;Toolkit</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>If you were to ask me for the top five words that should describe any JavaScript framework, one of them would be flexible.  The Dojo Toolkit is ultra-flexible in just about every way, using customizable classes and <code>dojo</code>-namespaced objects to to allow for maximal flexibility.  One of those <code>dojo</code>-namespaced objects, <code>dojo.contentHandlers</code>, is an object containing key-&gt;value pairs for handling the result of AJAX requests.  Let me show you how to use these content handlers and how you can create your own!</p><h2><code>dojo.xhr</code> and&nbsp;<code>handleAs</code></h2><p>Making AJAX requests is done with Dojo&#8217;s <code>dojo.xhr</code> methods.  Sending a basic GET request would look like:</p><pre class="js">
dojo.xhrGet({
	url: "/ajax.php",
	load: function(result) {
		// Do something with the result here
	}
});
</pre><p>The request above assumes that the response should be handled as plain text, as you would expect.  Dojo&#8217;s <code>dojo.xhr</code> methods all accept an object with properties for handling the request, and one property you can add is <code>handleAs</code>.  The <code>handleAs</code> property should be a string representing the type of parsing that should be done to the result before its passed to the <code>load</code> method or deferred callback.  Values for the handleAs property could be json, javascript, xml, or other variants of json.  If I want my request to be handled as JSON, I&#8217;d code:</p><pre class="js">
dojo.xhrGet({
	url: "/ajax.php",
	handleAs: "json",
	load: function(result) { // result is a JS object
		// Do something with the result here
	}
});
</pre><p>The resulting object provided to the load handler is text parsed into JavaScript object.  Likewise, if I want the result to be handled as XML, I&#8217;d code:</p><pre class="js">
dojo.xhrGet({
	url: "/ajax.php",
	handleAs: "xml",
	load: function(result) { // result is a XMLDocument object
		// Do something with the result here
	}
});
</pre><p>The load callback is provided a <code>XMLDocument</code> object.  One simple parameter changes the way the request response is parsed.  So how is this possible, and how can you create custom <code>handleAs</code> methods?  Simple!</p><h2>dojo.contentHandlers</h2><p>The <code>dojo.contentHandlers</code> object acts as dictionary for ajax request parsing.  The handleAs parameter you  supply maps to the key within <code>dojo.contentHandlers</code>.  The <code>dojo.contentHandlers</code> object comes with the following content handlers:  javascript, json, json-comment-filtered, json-comment-optional, text, and xml.  Here&#8217;s a snippet containing those &#8220;parsers&#8221;:</p><pre class="js">
var handlers = dojo._contentHandlers = dojo.contentHandlers = {

	text: function(xhr){ 
		// summary: A contentHandler which simply returns the plaintext response data
		return xhr.responseText; 
	},
	json: function(xhr){
		// summary: A contentHandler which returns a JavaScript object created from the response data
		return _d.fromJson(xhr.responseText || null);
	},
	"json-comment-filtered": function(xhr){ 

		if(!dojo.config.useCommentedJson){
			console.warn("Consider using the standard mimetype:application/json."
				+ " json-commenting can introduce security issues. To"
				+ " decrease the chances of hijacking, use the standard the 'json' handler and"
				+ " prefix your json with: {}&#038;&#038;\n"
				+ "Use djConfig.useCommentedJson=true to turn off this message.");
		}

		var value = xhr.responseText;
		var cStartIdx = value.indexOf("\/*");
		var cEndIdx = value.lastIndexOf("*\/");
		if(cStartIdx == -1 || cEndIdx == -1){
			throw new Error("JSON was not comment filtered");
		}
		return _d.fromJson(value.substring(cStartIdx+2, cEndIdx));
	},
	javascript: function(xhr){ 
		// summary: A contentHandler which evaluates the response data, expecting it to be valid JavaScript

		// FIXME: try Moz and IE specific eval variants?
		return _d.eval(xhr.responseText);
	},
	xml: function(xhr){
		// summary: A contentHandler returning an XML Document parsed from the response data
		var result = xhr.responseXML;
		//>>excludeStart("webkitMobile", kwArgs.webkitMobile);
		if(_d.isIE &#038;&#038; (!result || !result.documentElement)){
			//WARNING: this branch used by the xml handling in dojo.io.iframe,
			//so be sure to test dojo.io.iframe if making changes below.
			var ms = function(n){ return "MSXML" + n + ".DOMDocument"; }
			var dp = ["Microsoft.XMLDOM", ms(6), ms(4), ms(3), ms(2)];
			_d.some(dp, function(p){
				try{
					var dom = new ActiveXObject(p);
					dom.async = false;
					dom.loadXML(xhr.responseText);
					result = dom;
				}catch(e){ return false; }
				return true;
			});
		}
		//>>excludeEnd("webkitMobile");
		return result; // DOMDocument
	},
	"json-comment-optional": function(xhr){
		// summary: A contentHandler which checks the presence of comment-filtered JSON and 
		//		alternates between the `json` and `json-comment-filtered` contentHandlers.
		if(xhr.responseText &#038;&#038; /^[^{\[]*\/\*/.test(xhr.responseText)){
			return handlers["json-comment-filtered"](xhr);
		}else{
			return handlers["json"](xhr);
		}
	}
};
</pre><p>What if we want to add our own content handler though?  All you need to do is add the key=&gt;parser to the <code>dojo.contentHandlers</code> object!</p><pre class="js">
// CSV parsing found at:  http://stackoverflow.com/questions/1293147/javascript-code-to-parse-csv-data

dojo.contentHandlers.csv = function(xhr) {
	
	// Set the data
	var responseText = xhr.responseText;
	var delimiter = ",";
	
	// Create a regular expression to parse the CSV values.
	var objPattern = new RegExp(
		 (
			  // Delimiters.
			  "(\\" + delimiter + "|\\r?\\n|\\r|^)" +

			  // Quoted fields.
			  "(?:\"([^\"]*(?:\"\"[^\"]*)*)\"|" +

			  // Standard fields.
			  "([^\"\\" + delimiter + "\\r\\n]*))"
		 ), "gi");


	// Create an array to hold our data. Give the array
	// a default empty first row.
	var arrData = [[]];

	// Create an array to hold our individual pattern
	// matching groups.
	var arrMatches = null;


	// Keep looping over the regular expression matches
	// until we can no longer find a match.
	while (arrMatches = objPattern.exec(responseText)){

		 // Get the delimiter that was found.
		 var strMatchedDelimiter = arrMatches[1];

		 // Check to see if the given delimiter has a length
		 // (is not the start of string) and if it matches
		 // field delimiter. If id does not, then we know
		 // that this delimiter is a row delimiter.
		 if (strMatchedDelimiter.length &#038;&#038; (strMatchedDelimiter != delimiter)){
			  // Since we have reached a new row of data,
			  // add an empty row to our data array.
			  arrData.push([]);
		 }
		
		 // Now that we have our delimiter out of the way,
		 // let's check to see which kind of value we
		 // captured (quoted or unquoted).
		 if (arrMatches[2]){

			  // We found a quoted value. When we capture
			  // this value, unescape any double quotes.
			  var strMatchedValue = arrMatches[2].replace(
				   new RegExp("\"\"", "g"),
				   "\""
				   );
		 } else {
			  // We found a non-quoted value.
			  var strMatchedValue = arrMatches[3];
		 }
		 // Now that we have our value string, let's add
		 // it to the data array.
		 arrData[arrData.length - 1].push(strMatchedValue);
	}

	// Return the parsed data.
	return(arrData);
}

</pre><p>The code snippet above allows you to have your XHR request&#8217;s result be parsed as CSV content;  the result becomes a JavaScript object representing the CSV data.  Here&#8217;s how you&#8217;d use it:</p><pre class="js">
dojo.xhrGet({
	url: "/ajax.php",
	handleAs: "csv",
	load: function(result) { // result is a JS object
		// Do something with the result here
	}
});
</pre><p>One key to flexibility within JavaScript framework is &#8220;dictionaries&#8221; or &#8220;property bags&#8221;, allowing for adding, removing, and modifying of existing properties.  Thanks to Dojo&#8217;s use of <code>dojo.contentHandlers</code> and <code>dojo.xhr</code>&#8216;s <code>handleAs</code> property, you can handle the result of your AJAX requests before they are passed to a callback!</p><p><a
href="http://davidwalsh.name/dojo-xhr-handleas">Custom AJAX Content Handling with the Dojo&nbsp;Toolkit</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/dojo-xhr-handleas/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Full Awesomeness with dojo.partial and MooTools&#8217;&#160;Function.partial</title><link>http://davidwalsh.name/dojo-partial</link> <comments>http://davidwalsh.name/dojo-partial#comments</comments> <pubDate>Wed, 03 Aug 2011 16:52:18 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Dojo]]></category> <category><![CDATA[JavaScript]]></category> <category><![CDATA[MooTools]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5274</guid> <description><![CDATA[Much like MooTools, the Dojo Toolkit features a host of JavaScript language helpers.  One of those helpers is dojo.partial.  This method, which lives in Dojo Base, allows you to call a method with additional arguments appended to the front of a function signature.  Sound a bit weird?  It did to me too.  Let&#8217;s take a [...]<p><a
href="http://davidwalsh.name/dojo-partial">Full Awesomeness with dojo.partial and MooTools&#8217;&nbsp;Function.partial</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>Much like MooTools, the Dojo Toolkit features a host of JavaScript language helpers.  One of those helpers is <code>dojo.partial</code>.  This method, which lives in Dojo Base, allows you to call a method with additional arguments appended to the front of a function signature.  Sound a bit weird?  It did to me too.  Let&#8217;s take a quick peek at <code>dojo.partial</code>&#8216;s syntax and when you&#8217;d use it.</p><h2>dojo.partial</h2><p>Let&#8217;s say you have a function whose main purpose is to place content into a node:</p><pre class="js">
// A sample function which could use partial
function placeContent(node, content) {
	node.innerHTML = content;
}
</pre><p>Note that the function expects two arguments: <code>node</code> and <code>content</code>.  This is a simple, general purpose function that could be used anywhere and by many different functions, right?  Now let&#8217;s say that I&#8217;m making a <code>xhrGet</code> call:</p><pre class="js">
dojo.xhrGet({
	url: "content.html",
	load: function(content, ioArgs) {  }
});
</pre><p>The signature of the <code>load</code> method is (<code>content</code>, <code>ioArgs</code>).  To use my <code>placeContent</code> function with the <code>load</code> handler, you&#8217;d have to code:</p><pre class="js">
dojo.xhrGet({
	url: "content.html",
	load: function(content, ioArgs) {
		placeContent("myNode", content);
	}
});
</pre><p>That&#8217;s not the worst thing in the world, but it&#8217;s a bit&#8230;meh.  Using <code>dojo.partial</code>, we could instead code:</p><pre class="js">
dojo.xhrGet({
	url: "content.html",
	load: dojo.partial(placeContent, "myNode")
});
</pre><p>Even though the first argument of the <code>load</code> callback signature is the content, the <code>dojo.partial</code> call shifts the provided arguments to the front of the <code>argument</code> list, thus placing the <code>node</code> argument before the <code>content</code> argument when used with <code>placeContent</code>. <code>dojo.partial</code> allows us to avoid using &#8220;wrapping&#8221; functions to add an argument to the <code>arguments</code> array. <code>dojo.partial</code> allows you to add any number of arguments which may be pushed to the front of the signature, not just one.</p><h2>Function.partial</h2><p>I&#8217;ve taken a quick moment to duplicate the <code>dojo.partial</code> function for MooTools:</p><pre class="js">
// The implementation
Function.implement("partial", function(/* all args */) {
	var self = this, args = Array.from(arguments);
	return function() {
		self.apply(this, args.append(arguments));
	};
});
</pre><p>An example usage would look like:</p><pre class="js">
new Request({
	url: "partial.html",
	//onComplete: myFn.partial("myNode").bind(this)
	onComplete: placeContent.partial("myNode")
}).send();
</pre><p>Just as easy to use as Dojo&#8217;s method and just as useful.  I love that this method allows you to skip writing one-line callback wrappers <em>and</em> allow you to keep your utility function signatures the way they are.  <code>dojo.partial</code> and <code>Function.partial</code> are fully FTW!</p><p><a
href="http://davidwalsh.name/dojo-partial">Full Awesomeness with dojo.partial and MooTools&#8217;&nbsp;Function.partial</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/dojo-partial/feed</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Create Your Own Dijit CSS Theme with LESS&#160;CSS</title><link>http://davidwalsh.name/dijit-theme</link> <comments>http://davidwalsh.name/dijit-theme#comments</comments> <pubDate>Mon, 13 Jun 2011 14:02:46 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[CSS]]></category> <category><![CDATA[Dojo]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5242</guid> <description><![CDATA[The Dojo Toolkit seems to just get better and better.  One of the new additions in Dojo 1.6 was the use of LESS CSS to create Dijit themes.  The move to using LESS is a brilliant one because it makes creating your own Dijit theme much easier.  Let&#8217;s take a look at how Dojo leverages [...]<p><a
href="http://davidwalsh.name/dijit-theme">Create Your Own Dijit CSS Theme with LESS&nbsp;CSS</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p><a
href="http://davidwalsh.name/dw-content/dojotoolkit/1.6.1/dijit/themes/themeTester.html"><img
src="http://davidwalsh.name/dw-content/dijit-custom-theme.png" alt="Dijit Theme" /></a></p><p>The Dojo Toolkit seems to just get better and better.  One of the new additions in Dojo 1.6 was the use of LESS CSS to create Dijit themes.  The move to using LESS is a brilliant one because it makes creating your own Dijit theme much easier.  Let&#8217;s take a look at how Dojo leverages LESS to create Dijit themes and create our own theme.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/dojotoolkit/1.6.1/dijit/themes/themeTester.html" class="demo">View Demo</a><div
class="clear"></div></div><h2>LESS&nbsp;CSS</h2><p>The idea behind <a
href="http://lesscss.org/">LESS CSS</a> is quite simple:  extend CSS with dynamic behavior such as variables, mixins, operations and functions.  Simply put:  fix CSS&#8217; inherit limitations. LESS can be used on the command line / server-side with NodeJS or with a JavaScript file on the client side.  For the purposes of building Dojo themes, we&#8217;ll be using the NodeJS solution.  To install LESS, and assuming you have <code>npm</code>, run the following command:</p><pre class="shell">
npm install less
</pre><p>The LESS package should now be installed on your machine, ready to use with <a
href="http://nodejs.org/">NodeJs</a>, which must also be installed on your machine.</p><h2>Dijit&#8217;s Use of&nbsp;LESS</h2><p>Navigate to the following directory within your Dojo 1.6+ checkout:</p><pre class="shell">
cd dijit/themes/claro/
</pre><p>You&#8217;ll see built <code>{WidgetName}.css</code> files but also a number of <code>{WidgetName}.less</code> files &#8212; the <code>.css</code> files were built using LESS!  Before popping into individual <code>.less</code> files, open <code>variables.less</code>.  The <code>variables.less</code> file contains the declared variables which are used throughout other CSS files;  consider <code>variables.css</code> a &#8220;defaults&#8221; file.  Take a look at a few snippets from <code>variables.less</code>:</p><pre class="css">
/* General */
@text-color: #000000;				/* Text color for enabled widgets */

@border-color: #b5bcc7;				/* Border color for (enabled, unhovered) TextBox, Slider, Accordion, BorderContainer, TabContainer */
@popup-border-color: #769dc0;		/* Border for Dialog, Menu, Tooltip.   Must also update tooltip.png (the arrow image file) to match */
@minor-border-color: #d3d3d3;		/* Color of borders inside widgets: horizontal line in Calendar between weeks, around color swatches in ColorPalette, above Dialog action bar */

@disabled-border-color: #d3d3d3;	/* Border color for disabled/readonly Button, TextBox etc. widgets */
@disabled-background-color: #efefef;/* Disabled button, textbox, etc. */
@disabled-text-color: #818181;		/* Text color for disabled/readonly widgets */

/* ... */

/* Input widgets
@focused-border-color: #769dc0;				/* Focused textbox, editor, select, etc. */
@error-border-color: #d46464;				/* Border for textbox in error state */
@error-focused-border-color: #ce4f4f;		/* Border of textbox in error state, and focused */
@erroricon-background-color: #d46464;		/* Background color for exclamation point validation icon (for TextBox in error state) */
@textbox-background-color: #fff;			/* Default background color of TextBox based widgets */
@textbox-hovered-background-color: #e9f4fe;	/* Background color when hovering a unfocused TextBox, Select, Editor, or other input widget */
@textbox-focused-background-color: @textbox-background-color;
@textbox-error-background-color: @textbox-background-color;
@textbox-disabled-background-color: @disabled-background-color;

/* mixins */
.border-radius (@radius) {
	-moz-border-radius: @radius;
	border-radius: @radius;
}

.box-shadow (@value) {
	-webkit-box-shadow: @value;
	-moz-box-shadow: @value;
	box-shadow: @value;
}
</pre><p>You&#8217;ll notice how LESS CSS works:</p><ul><li>To define a variable, start with &#8220;@&#8221; symbol along with the variable name.</li><li>To use a variable, define the property and provide the @-prefixed variable name as the value.</li><li>To define a mixin, provide a selector name with arguments and define sub-properties of that property.</li></ul><p>You can bring link definitions into other <code>.less</code> files by using the following directive which you&#8217;ll find in all of the theme <code>.less</code> files:</p><pre class="css">
@import "variables";
</pre><p>Now open Calendar.less and look for instances of &#8220;@border-color&#8221;.  You&#8217;ll note that those instances reference the &#8220;@border-color&#8221; variable provided in variables.css file.  All other variables beginning with &#8220;@&#8221; will be replaced within the build process as well!</p><h2>Creating Your Own Dijit&nbsp;Theme</h2><p>The easiest way to get started with your own theme is to copy the most recently-created, officially supported them.  In this case, that theme would be claro.  The claro theme is a professional-looking blue theme which makes use of <a
href="http://davidwalsh.name/css-gradients">CSS gradients</a>, <a
href="http://davidwalsh.name/css-zoom">transitions</a>, and <a
href="http://davidwalsh.name/css-rounded-corners">rounded corners</a> when supported by the browser.</p><p>Run a quick cp to copy the claro folder to a folder which you&#8217;d like to call your theme:</p><pre class="shell">
cpmac claro davidwalsh
</pre><p>Before embarking on editing the existing code, it&#8217;s important to change the &#8220;.claro&#8221; declarations in every CSS file to &#8220;.{yournamespacename}&#8221;.  My theme will be called &#8220;davidwalsh&#8221; so I&#8217;ll use my text editor to find every instance of &#8220;.claro&#8221; and replace it with <code>@theme</code>, which we can map to &#8220;davidwalsh&#8221;.  With the copy of claro ready, jump into the <code>variables.less</code> file and make any color changes you see fit.  I&#8217;m more of a &#8220;green guy&#8221; myself so I&#8217;ll adjust the colors within <code>variables.less</code> to greenish counterparts:</p><pre class="css">
/* General */
@text-color: #000000;				/* Text color for enabled widgets */

@border-color: #b7c7b5;				/* Border color for (enabled, unhovered) TextBox, Slider, Accordion, BorderContainer, TabContainer */
@popup-border-color: #b7c7b5;		/* Border for Dialog, Menu, Tooltip.   Must also update tooltip.png (the arrow image file) to match */
@minor-border-color: #b7c7b5;		/* Color of borders inside widgets: horizontal line in Calendar between weeks, around color swatches in ColorPalette, above Dialog action bar */

@disabled-border-color: #d3d3d3;	/* Border color for disabled/readonly Button, TextBox etc. widgets */
@disabled-background-color: #efefef;/* Disabled button, textbox, etc. */
@disabled-text-color: #818181;		/* Text color for disabled/readonly widgets */

/* ... */

/* Input widgets
@focused-border-color: #7bc076;				/* Focused textbox, editor, select, etc. */
@error-border-color: #d46464;				/* Border for textbox in error state */
@error-focused-border-color: #ce4f4f;		/* Border of textbox in error state, and focused */
@erroricon-background-color: #d46464;		/* Background color for exclamation point validation icon (for TextBox in error state) */
@textbox-background-color: #fff;			/* Default background color of TextBox based widgets */
@textbox-hovered-background-color: #e9fee9;	/* Background color when hovering a unfocused TextBox, Select, Editor, or other input widget */
@textbox-focused-background-color: @textbox-background-color;
@textbox-error-background-color: @textbox-background-color;
@textbox-disabled-background-color: @disabled-background-color;
</pre><p>After editing my <code>variables.less</code> file to match my desired design, it&#8217;s time to look at each <code>{WidgetName}.less</code> file to make appropriate changes if I&#8217;d prefer the widget to look different than its claro look.  Once all of the <code>{WidgetName}.less</code> files are edited to your liking, it&#8217;s time to compile the <code>.less</code> files into working CSS files!</p><h2>Compiling Your Less CSS&nbsp;Theme</h2><p>Before compiling the theme, let&#8217;s take a look at another file within the theme directory:  <code>compile.js</code>.  <code>compile.js</code> was written to scan the current directory as well as the form and layout directories looking for <code>.less</code> files.  All <code>less</code> files are parsed and, using the <code>variables.less</code> directives, variable values are inject into their corresponding places and CSS file are created.</p><p>To use <code>compile.js</code>, navigate to your theme&#8217;s folder via the command line and run the following command:</p><pre class="shell">
node compile.js
</pre><p>Upon running this command, <code>.css</code> files will be generated with the same name as their <code>.less</code> counterparts.  A quick scan of these files will confirm that all variables have been placed in their proper spots!  Now your theme files are ready to go!</p><h2>Implementing Your Custom Dijit&nbsp;Theme</h2><p>Find the themeTester.html file (<code>/dijit/themes/themeTester.html</code>) and modify it to include your theme:</p><pre class="js">
// Fill in menu/links to get to other themes.		
// availableThemes[] is just a list of 'official' dijit themes, you can use ?theme=String
// for 'un-supported' themes, too. (eg: yours)
var availableThemes = [
	{ theme:"davidwalsh", author:"David Walsh", baseUri:"../themes/" },
	{ theme:"claro", author:"Dojo", baseUri:"../themes/" },
	{ theme:"tundra", author:"Dojo", baseUri:"../themes/" },
	{ theme:"soria", author:"nikolai", baseUri:"../themes/" },
	{ theme:"nihilo", author:"nikolai", baseUri:"../themes/" }
];
</pre><p>I recommend this approach because you can compare your theme against every widget in the book.  You&#8217;ll also want to tweak your theme as your continually develop your web application.</p><div
class="actions"><a
href="http://davidwalsh.name/dw-content/dojotoolkit/1.6.1/dijit/themes/themeTester.html" class="demo">View Demo</a><div
class="clear"></div></div><p>Switching from hardcoded, static CSS files to LESS-powered stylesheets should make developing themes many times easier.  LESS saves developers from running numerous search/replace commands and allows for stylesheet creation to be more dynamic and organized.  Now that Dijit theme creation has been made exponentially easier, I look forward to seeing many more themes pop up!</p><p><a
href="http://davidwalsh.name/dijit-theme">Create Your Own Dijit CSS Theme with LESS&nbsp;CSS</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/dijit-theme/feed</wfw:commentRss> <slash:comments>10</slash:comments> </item> <item><title>Using Pub Sub with The Dojo&#160;Toolkit</title><link>http://davidwalsh.name/dojo-pub-sub</link> <comments>http://davidwalsh.name/dojo-pub-sub#comments</comments> <pubDate>Wed, 08 Jun 2011 13:20:04 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Dojo]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5239</guid> <description><![CDATA[As I&#8217;ve stated many times, the Dojo Toolkit is probably the most complete JavaScript toolkit out there, especially when it comes to event management and application communication.  I&#8217;ve already done a very brief introduction to dojo.connect so I thought I&#8217;d also do a short introduction to Dojo&#8217;s other event system:  pub/sub with dojo.publish and dojo.subscribe. [...]<p><a
href="http://davidwalsh.name/dojo-pub-sub">Using Pub Sub with The Dojo&nbsp;Toolkit</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>As I&#8217;ve stated many times, the Dojo Toolkit is probably the most complete JavaScript toolkit out there, especially when it comes to event management and application communication.  I&#8217;ve already done a very brief introduction to <a
href="http://davidwalsh.name/dojo-connect"><code>dojo.connect</code></a> so I thought I&#8217;d also do a short introduction to Dojo&#8217;s other event system:  pub/sub with <code>dojo.publish</code> and <code>dojo.subscribe</code>.</p><p>The publish/subscribe strategy has many advantage over basic event connectivity:</p><ul><li>No reference to another object or element is required</li><li>It&#8217;s not the concern of the publisher who subscribes</li><li>As a result of not needing reference to another object or element, your code is instantly more portable</li></ul><p>So let&#8217;s take a look at how pub/sub is used!</p><h2>Publishing</h2><p>The first part of pub/sub is publishing to a <em>channel</em>.  When publishing to a channel, you provide the channel name and arguments to be passed to any subscriber:</p><pre class="js">
// dojo.publish("{channel}", [arg1, arg2, arg3]);
dojo.publish("/app/login", [username, userData]);
</pre><p>Arguments should be passed within an array and may be of any type.  Your channel can be any number of channels deep; the more specific the channel, the more specific your event can be.  While the slash is used as the standard channel specifier, you can use any string name you&#8217;d like.</p><h2>Subscribing</h2><p><code>dojo.publish</code> broadcasts message but it&#8217;s dojo.subscribe that that must listen for and react to the message.  You <em>must </em>match the exact channel name when subscribing:</p><pre class="js">
// Subscribe to the same channel, accepting each argument individually
var handle = dojo.subscribe("/app/login", function(username, userData) {
	// Now do something!
	
	
	// Unsubscribe if you want
	dojo.unsubscribe(handle);
});
</pre><p>Note how a handle is returned from <code>dojo.subscribe</code>.  The Dojo Toolkit does <em>not </em>support wildcard channel subscription, so the following will not work:</p><pre class="js">
// Wildcards don't work!
var handle = dojo.subscribe("/app/*", fn);
</pre><p>So how is pub/sub used internally within Dojo?  One prime example is the dojo.hash method.  dojo.hash notifies you of when the window hash changes.  You can catch the hash change event by subscribing as follows:</p><pre class="js">
// This is how you respond to hash changes!
dojo.subscribe("/dojo/hashchange", function(currentHash){ 
	// Do something!
});
</pre><p>Now you can modify AJAX-ified portions of your application when the hash changes!</p><p>What&#8217;s great about pub/sub in any toolkit or platform is that it&#8217;s easy to both use and code the API for.  The code and idea are both very simply yet also very powerful.  If you&#8217;ve got a large application that you&#8217;d like to be flexible and decoupled from individual objects, try using pub/sub &#8212; it will relieve unnecessary complexity!</p><p><a
href="http://davidwalsh.name/dojo-pub-sub">Using Pub Sub with The Dojo&nbsp;Toolkit</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/dojo-pub-sub/feed</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Display Unique Results within&#160;dijit.form.ComboBox</title><link>http://davidwalsh.name/unique-combobox</link> <comments>http://davidwalsh.name/unique-combobox#comments</comments> <pubDate>Wed, 25 May 2011 20:54:52 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Dojo]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5235</guid> <description><![CDATA[The Dojo Toolkit does well in allowing easy integration of web services with Dijit widgets via dojo.store.JsonRest.  One such widget is the dijit.form.ComboBox, which uses data stores to displays an autosuggest pane populated with items based on the store&#8217;s contents.  One problem I&#8217;ve run into is that some services return duplicate labels (i.e. two persons [...]<p><a
href="http://davidwalsh.name/unique-combobox">Display Unique Results within&nbsp;dijit.form.ComboBox</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>The Dojo Toolkit does well in allowing easy integration of web services with Dijit widgets via <code>dojo.store.JsonRest</code>.  One such widget is the <code>dijit.form.ComboBox</code>, which uses data stores to displays an autosuggest pane populated with items based on the store&#8217;s contents.  One problem I&#8217;ve run into is that some services return duplicate labels (i.e. two persons named &#8220;David Walsh&#8221;).  You want both items if you can use both of them but what if you&#8217;re using ComboBox for search?  You wouldn&#8217;t want duplicates.  That&#8217;s where I created a small custom class to prevent duplicates within the ComboBox&#8217;s dropdown menu.</p><h2>Custom Dojo&nbsp;Class</h2><p><code>dijit.form.ComboBox</code> provides a <code>dropDownClass</code> parameter which allows you to customize which class should handle dropdown duties.  The default class is <code>dijit.form._ComboBoxMenu</code>.  We will extend <code>dijit.form._ComboBoxMenu</code> and for our custom duplicate-preventing class, then change the <code>dropDownClass</code> parameter for any instance of ComboBox where we don&#8217;t want duplicates.</p><p>The method that handles items before placing them into the dropdown is the <code>createOptions</code> method. <code>createOptions</code> cycles through the results and creates the HTML for them.  What we need to do is &#8220;intercept&#8221; the results before they can be added to the dropdown.  Let&#8217;s create our custom <code>_UniqueComboBoxMenu</code> class with intercept capabilities:</p><pre class="js">
// Provide the class
dojo.provide("davidwalsh.form._UniqueComboBoxMenu");

// Get dependencies
dojo.require("dijit.form.ComboBox");

// Declare the class
dojo.declare("davidwalsh.form._UniqueComboBoxMenu", dijit.form._ComboBoxMenu, {
	
	createOptions: function(results, dataObject, labelFunc) {
		
		// Cycle through to find uniques
		var uniqueKeys = {}, uniqueItems = [];
		dojo.forEach(results,function(result,index) {
			var label = labelFunc(result);
			if(typeof label != "string") {
				label = label.label;
			}
			if(!uniqueKeys[label]) {
				uniqueKeys[label] = result;
				uniqueItems.push(result);
			}
		});
		
		// Update arguments arr
		arguments[0] = uniqueItems;
		
		// Call inheritance chain for this method, return result
		return this.inherited(arguments);
	}
});
</pre><p>Our custom <code>createOptions</code> method receives the <code>options</code>, <code>dataObject</code>, and <code>labelFunc</code>, a function which generates the item&#8217;s label text/HTML.  Before any other processing, we cycle through each item, create its label, and store the label in an object so that we know when it&#8217;s been used.  If the label hasn&#8217;t been used yet, we add the option to the <code>uniqueItems</code> array.</p><p>Once the uniques have been created, we push them into the original <code>arguments</code> array&#8217;s first position, then call <code>this.inherited(arguments)</code> to call the method&#8217;s original functionality.  In plain English, all we&#8217;re doing is stripping duplicates from the results array and carrying on as usual.  This technique is less evasive than directly editing the existing class and, as you can see, our custom class stays small.</p><h2>Implementing the&nbsp;Class</h2><p>Implementing the class is simple.  Since ComboBox provides the <code>dropDownClass</code> option, all you need to do is provide our custom class to each instance that should implement it:</p><pre class="js">
var combo = new dijit.form.ComboBox({
	store: myDataStore
	dropDownClass: "davidwalsh.form._UniqueComboBoxMenu"
},"myNode");
</pre><p>The instance above will only return unique suggestions!</p><p>This post should highlight one aspect of Dojo that I love &#8212; extreme flexibility and the ability to create tiny classes thanks to the awesome inheritance pattern provided by <code>dojo.declare()</code>.  Keep this class handy if you use Dijit forms and web services!</p><p><a
href="http://davidwalsh.name/unique-combobox">Display Unique Results within&nbsp;dijit.form.ComboBox</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/unique-combobox/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Dojo&#160;Tutorials</title><link>http://davidwalsh.name/dojo-tutorials</link> <comments>http://davidwalsh.name/dojo-tutorials#comments</comments> <pubDate>Wed, 11 May 2011 23:48:33 +0000</pubDate> <dc:creator>David Walsh</dc:creator> <category><![CDATA[Dojo]]></category><guid
isPermaLink="false">http://davidwalsh.name/?p=5229</guid> <description><![CDATA[Over the last few months, I&#8217;ve written several Dojo Toolkit tutorials to help explain basic and intermediate Dojo concepts.  Here&#8217;s a rundown of the tutorials that have been released thus far: Classy JavaScript with&#160;dojo.declare The dojo.declare method is the foundation of class creation within the Dojo Toolkit. dojo.declare allows for multiple inheritance to allow developers to create [...]<p><a
href="http://davidwalsh.name/dojo-tutorials">Dojo&nbsp;Tutorials</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></description> <content:encoded><![CDATA[<p>Over the last few months, I&#8217;ve written several <a
href="http://dojotoolkit.org/documentation/tutorials">Dojo Toolkit tutorials</a> to help explain basic and intermediate Dojo concepts.  Here&#8217;s a rundown of the tutorials that have been released thus far:</p><h2>Classy JavaScript with&nbsp;dojo.declare</h2><p>The <code>dojo.declare</code> method is the foundation of class creation within the Dojo Toolkit. <code>dojo.declare</code> allows for multiple inheritance to allow developers to create flexible code and avoid writing the same code routines. Dojo, Dijit, and Dojox modules all use <code>dojo.declare</code>; in this tutorial, you&#8217;ll learn why you should too.</p><div
class="actions"><a
href="http://dojotoolkit.org/documentation/tutorials/1.6/declare/" class="demo">View Tutorial</a><div
class="clear"></div></div><h2>Dojo&nbsp;Charting</h2><p>Presenting statistical data in a readable, eye-catching manner is important, but it can also be difficult. The <code>dojox.charting</code>system was created to alleviate those pains by allowing developers to create dynamic, unique, and functional charts from varying sets of data. In addition, <code>dojox.charting </code>provides numerous themes and chart types to allow developers to display their data any way they&#8217;d like. This tutorial will show you how to create basic charts with varying data, plots, axes, and themes.</p><div
class="actions"><a
href="http://dojotoolkit.org/documentation/tutorials/1.6/charting/" class="demo">View Tutorial</a><div
class="clear"></div></div><h2>Advanced Charting with&nbsp;Dojo</h2><p>While most developers only need basic charts, <code>dojox.charting</code>is capable of highly advanced charts: charts with animations, charts that respond to changes in data, and charts that respond to events. In this tutorial, you will learn about using some these advanced capabilities within <code>dojox.charting</code>.</p><div
class="actions"><a
href="http://dojotoolkit.org/documentation/tutorials/1.6/charting_advanced/" class="demo">View Tutorial</a><div
class="clear"></div></div><h2>Dialogs &amp;&nbsp;Tooltips</h2><p>User interaction is extremely important in building responsive, interactive web applications. Web browsers provide basic methods for user interaction in the form of alerts and dialogs, but this functionality is not elegant or flexible. Dijit, the Dojo Toolkit&#8217;s UI framework, provides cross-browser, extendable, and themeable answers to what the browser&#8217;s basic functionality lack, in the form of <code>dijit.Tooltip</code>, <code>dijit.Dialog</code>, and<code>dijit.TooltipDialog</code>. In this tutorial, you&#8217;ll learn about each of these widgets, sample usages of each, and the ins and outs of creating them.</p><div
class="actions"><a
href="http://dojotoolkit.org/documentation/tutorials/1.6/dialogs_tooltips/" class="demo">View Tutorial</a><div
class="clear"></div></div><h2>Dijit&nbsp;Editor</h2><p>Dijit&#8217;s Editor widget is everything a developer looks for in a<abbr
title="What You See is What You Get">WYSIWYG</abbr> editor: flexible, themeable, and above all, functional. In this tutorial, you&#8217;ll learn how to easily implement dijit.Editor (programatically and declaratively), customize its toolbars, and include Editor plugins from DojoX.</p><div
class="actions"><a
href="http://dojotoolkit.org/documentation/tutorials/1.6/editor/" class="demo">View Tutorial</a><div
class="clear"></div></div><h2>Ajax with&nbsp;Dojo</h2><p>Ajax has become a fundamental technique for creating dynamic, usable web applications. In this tutorial, you&#8217;ll learn about the Dojo Toolkit&#8217;s Ajax communication methods, including basic XHR concepts, how to customize your Ajax calls, handling multiple types of data, and strategies for cross-domain JSON gathering (JSONP).</p><div
class="actions"><a
href="http://dojotoolkit.org/documentation/tutorials/1.6/ajax/" class="demo">View Tutorial</a><div
class="clear"></div></div><p>There are plenty more tutorials available, written by Dojo committers and contributors.  Expect more to come!</p><p><a
href="http://davidwalsh.name/dojo-tutorials">Dojo&nbsp;Tutorials</a> is a post from: <a
href="http://davidwalsh.name">David Walsh :: Legendary scribbles about JavaScript, HTML5, AJAX, PHP, CSS, and ∞.</a></p> ]]></content:encoded> <wfw:commentRss>http://davidwalsh.name/dojo-tutorials/feed</wfw:commentRss> <slash:comments>1</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced (User agent is rejected)
Database Caching 1/58 queries in 0.055 seconds using disk: basic
Object Caching 1419/1521 objects using disk: basic

Served from: davidwalsh.name @ 2012-02-09 00:38:44 -->
