<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><atom:id>tag:blogger.com,1999:blog-30407200</atom:id><lastBuildDate>Thu, 03 Nov 2011 23:26:35 +0000</lastBuildDate><category>Alt.Net</category><category>Visual Studio</category><category>MVC</category><category>SQL</category><category>Server</category><category>Expression Blend</category><category>Design</category><category>ASP.Net och Ajax</category><category>Windows</category><category>SOA</category><category>Nyttoprogram</category><category>Test</category><category>Web</category><category>jslint</category><category>C#</category><category>Jasmine Test Runner</category><category>TDD</category><category>Stockholm Web Monkeys</category><category>Agile</category><category>Ruby</category><category>Specifikationer</category><category>BDD</category><category>Utveckling</category><category>HTML</category><category>b</category><category>Ny teknik</category><category>Events</category><category>Personligt</category><category>JavaScript</category><category>Arkitektur och Design</category><category>Entity Framework</category><category>Silverlight</category><category>HTML5</category><title>Anders Jönsson</title><description>I just love web and agile</description><link>http://andersjonsson.blogspot.com/</link><managingEditor>noreply@blogger.com (Anders Jönsson)</managingEditor><generator>Blogger</generator><openSearch:totalResults>263</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><feedburner:info uri="andersjonsson" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://andersjonsson.blogspot.com/feeds/posts/default?alt=rss" /><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Fandersjonsson.blogspot.com%2Ffeeds%2Fposts%2Fdefault%3Falt%3Drss" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Fandersjonsson.blogspot.com%2Ffeeds%2Fposts%2Fdefault%3Falt%3Drss" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Fandersjonsson.blogspot.com%2Ffeeds%2Fposts%2Fdefault%3Falt%3Drss" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://andersjonsson.blogspot.com/feeds/posts/default?alt=rss" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Fandersjonsson.blogspot.com%2Ffeeds%2Fposts%2Fdefault%3Falt%3Drss" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Fandersjonsson.blogspot.com%2Ffeeds%2Fposts%2Fdefault%3Falt%3Drss" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Fandersjonsson.blogspot.com%2Ffeeds%2Fposts%2Fdefault%3Falt%3Drss" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://www.addtoany.com/?linkname=Anders%20J%C3%B6nsson&amp;linkurl=http%3A%2F%2Fandersjonsson.blogspot.com%2Ffeeds%2Fposts%2Fdefault%3Falt%3Drss&amp;type=feed" src="http://www.addtoany.com/addfr-b.gif">Add to Any Feed Reader</feedburner:feedFlare><feedburner:browserFriendly>http://andersjonsson.blogspot.com/ feeds/posts/default?alt=rss</feedburner:browserFriendly><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-6856795577384810939</guid><pubDate>Thu, 03 Nov 2011 22:54:00 +0000</pubDate><atom:updated>2011-11-04T00:26:35.970+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><category domain="http://www.blogger.com/atom/ns#">Design</category><title>Deferred promise in JavaScript</title><description>One way to handle async behavior in your JavaScript application is to use deferred promises (&lt;a href="http://wiki.commonjs.org/wiki/Promises"&gt;CommonJS &lt;/a&gt;&lt;a href="http://wiki.commonjs.org/wiki/Promises/A"&gt;Promises/A&lt;/a&gt;). By using promises you can program in a way that focus more on the flow of the application than on specific callbacks. If you see everything as an async behavior (meaning that something will happen, but you don’t know when) you can also see the user interaction as an async behavior which has some benefits. Deferrers may also be used to simplify APIs/function calls by removing all callbacks from input parameters.
&lt;br /&gt;
&lt;br /&gt;
There are different frameworks for deferred promises; most of them have a similar syntax. You can setup things that will/will not occur and how to handle them. The syntax is pretty straight forward; you use “when” for the things that will happen/could happen and “done”/”fail” to handle success and failure actions. With the deferred object you can either resolve them and go to done action or reject them and go to fail action. 
&lt;br /&gt;
&lt;br /&gt;
In this example I will use jQuery’s (which also is used internally for ajax calls).  I have a “when” with two functions which both returns a deferred. If both functions resolve the deferred the done action will be invoked. The first function “userConfirmation” prompts at load and the result is used as an argument when resolving the deferred. The second function “userInput” wait until the user clicks the button, if the value has changed the deferred is rejected otherwise its resolved. 
&lt;br /&gt;
&lt;pre class="brush:js; html-script: true;"&gt;

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Deferred&amp;lt;/title&amp;gt;            
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

    &amp;lt;form method=&amp;quot;post&amp;quot;&amp;gt;
        &amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;data&amp;quot; value=&amp;quot;yes&amp;quot; /&amp;gt;
        &amp;lt;input type=&amp;quot;button&amp;quot; value=&amp;quot;ok&amp;quot; id=&amp;quot;ok&amp;quot;&amp;gt;    
    &amp;lt;/form&amp;gt;

    &amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;http://code.jquery.com/jquery-git.js&amp;quot;&amp;gt;
    &amp;lt;/script&amp;gt;

    &amp;lt;script type=&amp;quot;text/javascript&amp;quot; &amp;gt;

        var userConfirmation = function(){
            var deferred = $.Deferred();
            var answer = confirm(&amp;#39;press ok&amp;#39;);
            return deferred.resolve({&amp;#39;answer&amp;#39;: answer});        
        };

        var userInput = function(){
            var deferred = $.Deferred();

            $(&amp;#39;#ok&amp;#39;).click(function(){
                var text = $(&amp;#39;#data&amp;#39;).val();
                var obj = {data:text};
                
                if(text !== &amp;quot;yes&amp;quot;){
                    deferred.reject(obj);        
                }else{
                    deferred.resolve(obj);    
                }
            });
            
            return deferred.promise();
        };

        $.when(userConfirmation(),userInput())
            .done(function(confirmation, input){
                alert(&amp;#39;user confirmation: &amp;#39; + confirmation.answer 
                    + &amp;#39; and user input: &amp;#39; + input.data);    
            })
            .fail(function() {
                alert(&amp;#39;fail&amp;#39;);
            });

        // .progress(function() {
        //         when someone calls &amp;quot;deferred.notify()&amp;quot;
        //         alert(&amp;#39;progress);
        // })

    &amp;lt;/script&amp;gt;

&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

&lt;/pre&gt;
&lt;br /&gt;
If you want a progress of the resolves you can add a “progress” function what will be called every time someone calls “notify” on a deferred. (jQuery v1.7)
&lt;br /&gt;
&lt;br /&gt;
For more information and examples, please see:&lt;br /&gt;
&lt;a href="http://api.jquery.com/category/deferred-object"&gt;http://api.jquery.com/category/deferred-object&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://www.erichynds.com/jquery/using-deferreds-in-jquery"&gt;http://www.erichynds.com/jquery/using-deferreds-in-jquery&lt;/a&gt;&lt;br /&gt;
&lt;span style="background-color: transparent;"&gt;&lt;a href="https://github.com/briancavalier/when.js"&gt;https://github.com/briancavalier/when.js&lt;/a&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-6856795577384810939?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/krylCxx3JJk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/krylCxx3JJk/deferred-promise-in-javascript.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/11/deferred-promise-in-javascript.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-8318811508443714993</guid><pubDate>Fri, 07 Oct 2011 11:07:00 +0000</pubDate><atom:updated>2011-10-07T13:09:10.738+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">Stockholm Web Monkeys</category><title>Stockholm Webmonkeys - Tuesday, 18 October @ Betsson</title><description>After a well deserved break we are back - in style! This time we'll explore the synergic effects of web development and art. We will also take a deep dive into the world of LESS - The dynamic stylesheet language which helps creating and organizing CSS more efficiently.&lt;br /&gt;&lt;br /&gt;We hope this will be an inspiring event which will tickle your creative nerve and give you the tools to go off and create your own experiments!&lt;br /&gt;&lt;br /&gt;Someone at our last event asked what the business case is for bleeding edge technologies like WebGL. Our response to this is simply: "awesome needs no use-case" ;)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.webmonkeys.se/"&gt;http://www.webmonkeys.se/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-8318811508443714993?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/7QiYwYzZE68" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/7QiYwYzZE68/stockholm-webmonkeys-tuesday-18-october.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/10/stockholm-webmonkeys-tuesday-18-october.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-7968207264208833784</guid><pubDate>Tue, 02 Aug 2011 10:00:00 +0000</pubDate><atom:updated>2011-08-05T23:56:23.670+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><title>noSuchMethod / method_missing / doesNotUnderstand / __resolve in JavaScript</title><description>There is a powerful concept in some languages that lets you as a developer handle undefined methods call on objects. It sometimes refers as "method_missing", "noSuchMethod", etc. This means that if someone tries to call a method that’s not on the original object you can try to figure out what the intention was or do some other magical stuff.&lt;br /&gt;&lt;br /&gt;If you’re fortunate enough to live in Mozilla land you can use this concept by naming a function to “__noSuchMethod__”.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;&lt;iframe style="width: 90%; height: 300px" src="http://jsfiddle.net/bDKza/embedded/"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Browser support?&lt;br /&gt;FireFox = Yes&lt;br /&gt;Chrome / Opera / Safari / Internet Explorer = No&lt;br /&gt;&lt;br /&gt;Node.js = &lt;a href="https://groups.google.com/forum/#%21topic/nodejs/Yioiyp72blM"&gt;maybe*&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For more information, please see:&lt;br /&gt;• &lt;a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/noSuchMethod"&gt;https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/noSuchMethod&lt;/a&gt;&lt;br /&gt;• &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2008-August/006901.html"&gt;https://mail.mozilla.org/pipermail/es-discuss/2008-August/006901.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-7968207264208833784?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/MUDux1fSGug" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/MUDux1fSGug/nosuchmethod-methodmissing.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/08/nosuchmethod-methodmissing.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-2288993027098744717</guid><pubDate>Mon, 25 Jul 2011 09:34:00 +0000</pubDate><atom:updated>2011-07-25T11:35:54.344+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><title>Front-end Code Standards &amp; Best Practices</title><description>Interesting reading: "Front-end Code Standards &amp; Best Practices" http://na.isobar.com/standards/&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-2288993027098744717?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/F8pOKML8x2o" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/F8pOKML8x2o/front-end-code-standards-best-practices.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/07/front-end-code-standards-best-practices.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-2681408612290003869</guid><pubDate>Sat, 25 Jun 2011 21:25:00 +0000</pubDate><atom:updated>2011-11-03T23:51:01.607+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><category domain="http://www.blogger.com/atom/ns#">Arkitektur och Design</category><title>Mixins and mixers in JavaScript</title><description>&lt;a href="http://en.wikipedia.org/wiki/Mixin"&gt;Mixins &lt;/a&gt;is a powerful way to reuse code between different objects and types. Although JavaScript does not support mixins at the language level the approach can easily be mimicked by code. By using mixins you can extract code/functionality from one object/type and apply it to other object/types. Mixins can also be used to add roles to objects, and thereby take a somewhat &lt;a href="http://www.artima.com/articles/dci_vision.html"&gt;DCI&lt;/a&gt;  influenced approache. You can also use the mixin for areas like cache, security, transformations, etc.&lt;br /&gt;&lt;br /&gt;The mixer (or augmenter) is something you have to write by yourself, or copy mine. It’s easy, just go over all the things you want in the mixin and copy them to the target.&lt;br /&gt;&lt;br /&gt;Below is an example where I add JSONify functionality from a mixin, "JSONifyMixin", to a target type, "Book":&lt;br /&gt;&lt;pre class="brush:js"&gt;/* jsonify-mixin.js */&lt;br /&gt;var JSONifyMixin = function(){&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;JSONifyMixin.prototype.JSONify = function(){&lt;br /&gt;return JSON.stringify(this);&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;/* book.js */&lt;br /&gt;var Book = function(author, title){&lt;br /&gt;this.author = author;&lt;br /&gt;this.title = title;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;mixer.mix(Book, JSONifyMixin);&lt;br /&gt;&lt;br /&gt;/* demo.js */&lt;br /&gt;var book = new Book(&lt;br /&gt;"Andrew Hunt",&lt;br /&gt;"The Pragmatic Programmer: From Journeyman to Master");&lt;br /&gt;&lt;br /&gt;// {auther : "Andrew Hunt",&lt;br /&gt;//  title : "The Pragmatic Programmer: From Journeyman to Master"}&lt;br /&gt;var json = book.JSONify();&lt;/pre&gt;&lt;br /&gt;You can see the mixer as strict or loose. The strict mixer will fail if the function that you are trying to mixin already exists on the target object. The loose mixer will just ignore them.&lt;br /&gt;&lt;br /&gt;Depending on your needs you have to decide if you want to mix on object or type level. Example:&lt;br /&gt;&lt;pre name="code" class="js:nogutter:nocontrols"&gt;Type:&lt;br /&gt;mixer.mix(Book, JSONifyMixin);&lt;br /&gt;&lt;br /&gt;Object:&lt;br /&gt;var book = new Book(...)&lt;br /&gt;mixer.mix(book, JSONifyMixin);&lt;/pre&gt;&lt;br /&gt;For more examples and some materials from a presentation I had, please see &lt;a href="https://github.com/archive/mixin"&gt;https://github.com/archive/mixin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy mixing!&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-2681408612290003869?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/YeSxqPCVZeY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/YeSxqPCVZeY/mixin-and-mixins-in-javascript.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/06/mixin-and-mixins-in-javascript.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-4865808844970368616</guid><pubDate>Wed, 08 Jun 2011 19:20:00 +0000</pubDate><atom:updated>2011-06-08T21:22:40.561+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">Stockholm Web Monkeys</category><title>Stockholm Web Monkeys - Tuesday June 21st</title><description>Mmmyeah, it’s that time again! Webmonkeys all over Stockholm are gathering for one final opportunity to monkey about before the summer. As usual there will be food, drinks and a sweet mix of web technologies. We will cover Javascript OO design patterns, bleeding edge 3D technology using WebGL/CSS, and pragmatic insights into developing mobile web applications.&lt;br /&gt;&lt;br /&gt;Please see &lt;a href="http://www.webmonkeys.se/"&gt;http://www.webmonkeys.se/&lt;/a&gt; for more information!&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-4865808844970368616?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/V1R28hBZPrg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/V1R28hBZPrg/stockholm-web-monkeys-tuesday-june-21st.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/06/stockholm-web-monkeys-tuesday-june-21st.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-2246469121695334859</guid><pubDate>Tue, 10 May 2011 20:21:00 +0000</pubDate><atom:updated>2011-05-11T13:20:12.527+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Specifikationer</category><category domain="http://www.blogger.com/atom/ns#">Arkitektur och Design</category><category domain="http://www.blogger.com/atom/ns#">Design</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>TDD/BDD and design</title><description>I really like TDD/BDD. I really do. To drive my code from specifications/tests is not only fun but it will often help me to design my systems better. And making good design decisions is always nice, isn’t it?&lt;br /&gt;&lt;br /&gt;The sad part though is that many folks have an illusion of what TDD/BDD can help them with, especially when it comes to the design part. This is a topic that has been covered many times before, but still there is an idea that by just doing TDD/BDD you will get a better designed system and that is my folks the illusion. The problem is that if you suck at designing systems, the design that you get by doing TDD/BDD will unfortunately probably also suck. It will suck less than if you didn’t do TDD/BDD but it will not help you creating that wonderful design that you were hoping for. If you don’t know what to look after or what is bad smells, you will probably not find them nor smell them only by doing TDD/BDD. That is of course sad, very sad in fact, it would be nice if TDD/BDD magically solves the knowledge/experience/skill problems and automatically produced nice design and good design decision.&lt;br /&gt;&lt;br /&gt;It’s like this; if you suck at woodwork, buying an expensive knife won’t make you a great carver. It will still only be you, the knife and the crappy piece of wood.&lt;br /&gt;&lt;br /&gt;But here’s the good part, if you are good at designing systems, TDD/BDD will probably help you with creating great designed systems which is flexible, easy to change, has the right responsibilities and all the other good fluff that we all like.&lt;br /&gt;&lt;br /&gt;So I encourage you to keep doing TDD/BDD, but remember to learn about good design and good design principles.&lt;br /&gt;&lt;br /&gt;To quote a somewhat famous Bob:&lt;br /&gt;&lt;blockquote&gt;"&lt;span style="font-style: italic;"&gt;Is TDD a replacement for design? No. You still need all your design skills. You still need to know design principles, and design patterns. " ... "The bottom line is that TDD is a_ design technique but should not be the _sole design technique. All the old design rules and skills still apply; and TDD is a powerful way to inform and augment them."&lt;br /&gt;(&lt;a href="http://blog.objectmentor.com/articles/2009/10/08/tdd-triage"&gt;http://blog.objectmentor.com/articles/2009/10/08/tdd-triage&lt;/a&gt;)&lt;/span&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-2246469121695334859?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/vgVgiFgnHXk" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/vgVgiFgnHXk/tddbdd-and-design.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/05/tddbdd-and-design.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-1501313098444742488</guid><pubDate>Sun, 17 Apr 2011 18:49:00 +0000</pubDate><atom:updated>2011-04-18T20:50:30.189+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><category domain="http://www.blogger.com/atom/ns#">jslint</category><title>Fluent interfaces, jslint and "unexpected end of line"</title><description>A couple of days ago when I was running jslint (&lt;a href="http://www.javascriptlint.com/"&gt;jsl.exe&lt;/a&gt;) against my JavaScript code I got the following warning:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"&lt;span style="font-style: italic;"&gt;lint warning: unexpected end of line; it is ambiguous whether these lines are part of the same statement&lt;/span&gt;"&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;The warning was pointing at ".from(allProducts)" in the following code:&lt;br /&gt;&lt;pre name="code" class="js:nogutter:nocontrols"&gt;var enabledProducts = new Query()&lt;br /&gt; .from(allProducts)&lt;br /&gt; .select(["name","price"])&lt;br /&gt; .where("enabled")&lt;br /&gt; .isEqualTo(true);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Humm... so there was a problem with recognizing the fluent way of writing? Just for fun I changed the code so that the dots appear after the function name:&lt;br /&gt;&lt;pre name="code" class="js:nogutter:nocontrols"&gt;var enabledProducts = new Query().&lt;br /&gt; from(allProducts).&lt;br /&gt; select(["name","price"]).&lt;br /&gt; where("enabled").&lt;br /&gt; isEqualTo(true);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Now jslint was happy again, but not I, for this way of writing is totally doolally .&lt;br /&gt;&lt;br /&gt;In the configuration I found the following parameter:&lt;br /&gt;&lt;blockquote&gt;"&lt;span style="font-style: italic;"&gt;+ambiguous_newline # unexpected end of line; it is ambiguous whether these lines are part of the same statement&lt;/span&gt;"&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I turned it off and everything was green again.&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-1501313098444742488?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/VoLfcDE57ew" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/VoLfcDE57ew/fluent-interfaces-jslint-and-unexpected.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/04/fluent-interfaces-jslint-and-unexpected.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-6825515777742878677</guid><pubDate>Thu, 10 Mar 2011 07:00:00 +0000</pubDate><atom:updated>2011-03-10T08:02:34.224+01:00</atom:updated><title>Då var det dags igen! Stockholm Web Monkeys</title><description>&lt;i&gt;&lt;/i&gt;&lt;blockquote&gt;&lt;i&gt;"Hello web monkeys! &lt;/i&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;Our next meeting has a massive lineup, so you don’t want to miss this&lt;br /&gt;opportunity for all the bananas in the world. Like always, there will&lt;br /&gt;be something to eat, drink, listen and to discuss about. And did we&lt;br /&gt;mention it’s free? &lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;We only have 40 seats available, so please register yourself at:&lt;br /&gt;http://bit.ly/h4Mvqv&lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt; &lt;br /&gt;Agenda:&lt;br /&gt;18:30 Sandwiches &amp;amp; monkeying around&lt;br /&gt;19:00 Dude where’s my threads? - introduction to node.js (Karl&lt;br /&gt;Böhlmark)&lt;br /&gt;20:00 UX for monkeys (Michael Stratton)&lt;br /&gt;20:30 SVG Animation (Hakim el Hattab)&lt;br /&gt;21:00 HTML5 discussion: What's good, what's missing, web browser&lt;br /&gt;implementation takes (Robert Nyman) &lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;Location: Fantasy Interactive, Stureplan 2, Stockholm &lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;For more information, see: &lt;a href="http://groups.google.com/group/stockholm-web-monkeys"&gt;http://groups.google.com/group/stockholm-web-monkeys&lt;/a&gt;&lt;br /&gt;Follow us on twitter: @SthlmWebMonkeys &lt;/i&gt;&lt;/div&gt;&lt;div&gt;&lt;i&gt;&lt;br /&gt;See you there!&lt;br /&gt;/David, Marcus, Anders"&lt;/i&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;i&gt;&lt;/i&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-6825515777742878677?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/UW1V-jW5f7A" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/UW1V-jW5f7A/da-var-det-dags-igen-stockholm-web.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/03/da-var-det-dags-igen-stockholm-web.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-3182483787293232155</guid><pubDate>Sun, 06 Mar 2011 21:48:00 +0000</pubDate><atom:updated>2011-03-07T10:47:16.892+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><title>Different ways of handling “this” changes (self/createDelegate/bind)</title><description>Sometimes “this” won’t point at the object you want it to do. So in those occasions you have to write some code to fix it. For example the jQuery framework will always change what "this" points to, sometimes for good and sometimes for bad.&lt;br /&gt;&lt;br /&gt;Here are three different ways of handling "this". There is no right and wrong. You must decide which one you want to use based on what you like best (and performance issues).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;var self = this&lt;/span&gt;&lt;br /&gt;&lt;pre name="code" class="js:nogutter:nocontrols"&gt;var demo1 = {&lt;br /&gt;&lt;br /&gt;  attachOnClickForAllCheckboxes: function(){&lt;br /&gt;      var self = this;&lt;br /&gt;      $("input[type=checkbox]").click(function(checkbox){&lt;br /&gt;          self.doThisOnClick.call(self, this.value);&lt;br /&gt;      });      &lt;br /&gt;  },&lt;br /&gt;&lt;br /&gt;  doThisOnClick: function(checkboxValue){&lt;br /&gt;      console.log(typeof this.doThisOnClick === "function");&lt;br /&gt;      console.log(checkboxValue);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;};&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;createDelegate(this, function(){})&lt;/span&gt;&lt;br /&gt;&lt;pre name="code" class="js:nogutter:nocontrols"&gt;var createDelegate = function(instance, delegate)&lt;br /&gt;{&lt;br /&gt;  var self = instance;&lt;br /&gt;  var wrappedDelegate = function() {&lt;br /&gt;      return delegate.apply(instance, arguments);&lt;br /&gt;  } &lt;br /&gt;  return wrappedDelegate;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var demo2 = {&lt;br /&gt;&lt;br /&gt;  attachOnClickForAllCheckboxes: function(){&lt;br /&gt;      $("input[type=checkbox]").click(createDelegate(this, function(checkbox){&lt;br /&gt;          this.doThisOnClick(checkbox.target.value);&lt;br /&gt;      }));      &lt;br /&gt;  },&lt;br /&gt;&lt;br /&gt;  doThisOnClick: function(checkboxValue){&lt;br /&gt;      console.log(typeof this.doThisOnClick === "function");&lt;br /&gt;      console.log(checkboxValue);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;};&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;.bind(this)&lt;/span&gt;&lt;br /&gt;Note: Please read &lt;a href="http://pmuellr.blogspot.com/2010/06/bind-considered-harmful.html"&gt;http://pmuellr.blogspot.com/2010/06/bind-considered-harmful.html&lt;/a&gt;&lt;br /&gt;&lt;pre name="code" class="js:nogutter:nocontrols"&gt;Function.prototype.bind = function(obj) {&lt;br /&gt;     var that = this;&lt;br /&gt;     return function() {&lt;br /&gt;          return that.apply(obj, arguments);&lt;br /&gt;      };&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;var demo3 = {&lt;br /&gt;&lt;br /&gt;  attachOnClickForAllCheckboxes: function(){&lt;br /&gt;      $("input[type=checkbox]").click((function(checkbox){&lt;br /&gt;          this.doThisOnClick.call(this, checkbox.target.value);&lt;br /&gt;      }).bind(this));      &lt;br /&gt;  },&lt;br /&gt;&lt;br /&gt;  doThisOnClick: function(checkboxValue){&lt;br /&gt;      console.log(typeof this.doThisOnClick === "function");&lt;br /&gt;      console.log(checkboxValue);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;};&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-3182483787293232155?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/vwTU7kBGhxU" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/vwTU7kBGhxU/different-ways-of-handling-this-changes.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/03/different-ways-of-handling-this-changes.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-4153435329524637962</guid><pubDate>Sun, 27 Feb 2011 23:02:00 +0000</pubDate><atom:updated>2011-02-28T00:09:00.354+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">Design</category><title>Design Stencil Kit</title><description>Yahoo har en del snygga designstenciler som man kan använda om man vill mocka gränssnitt. Stencilen finns för massa olika format, se mer på: &lt;a href="http://developer.yahoo.com/ypatterns/about/stencils/"&gt;http://developer.yahoo.com/ypatterns/about/stencils/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Exempel:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-OcAwOv33u7c/TWrYlwSfQJI/AAAAAAAAApI/-bO4Nfb_HVE/s1600/Controls.png"&gt;&lt;img style="cursor: pointer; width: 200px; height: 197px;" src="http://3.bp.blogspot.com/-OcAwOv33u7c/TWrYlwSfQJI/AAAAAAAAApI/-bO4Nfb_HVE/s200/Controls.png" alt="" id="BLOGGER_PHOTO_ID_5578509231580987538" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/-E6v8HJ5Wk30/TWrYlkQMerI/AAAAAAAAApA/xnAajxtTP0Q/s1600/Carousel.png"&gt;&lt;img style="cursor: pointer; width: 153px; height: 200px;" src="http://3.bp.blogspot.com/-E6v8HJ5Wk30/TWrYlkQMerI/AAAAAAAAApA/xnAajxtTP0Q/s200/Carousel.png" alt="" id="BLOGGER_PHOTO_ID_5578509228350143154" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-4153435329524637962?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/5yeBL-VPdZI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/5yeBL-VPdZI/design-stencil-kit.html</link><author>noreply@blogger.com (Anders Jönsson)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/-OcAwOv33u7c/TWrYlwSfQJI/AAAAAAAAApI/-bO4Nfb_HVE/s72-c/Controls.png" height="72" width="72" /><thr:total>1</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/02/design-stencil-kit.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-3279690030122642638</guid><pubDate>Thu, 17 Feb 2011 19:29:00 +0000</pubDate><atom:updated>2011-02-17T21:59:47.533+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><category domain="http://www.blogger.com/atom/ns#">BDD</category><category domain="http://www.blogger.com/atom/ns#">Specifikationer</category><category domain="http://www.blogger.com/atom/ns#">Jasmine Test Runner</category><title>Stubs i JavaScript</title><description>Det finns många olika Mocking/Stubbing-ramverk för JavaScript som kan förenkla dina specifikationer. Dock så behöver man inte alltid dra in ännu ett ramverk för att göra enkla stubbningar. I exemplet nedan har jag en funktion som visar en varningsruta om man besöker sidan med en viss webbläsare:&lt;pre name="code" class="js:nogutter:nocontrols" style="display: none;"&gt;&lt;br /&gt;var demo = {&lt;br /&gt;  checkBrowserVersion : function(){&lt;br /&gt;      if($.browser.msie &amp;amp;&amp;amp; $.browser.version === "6.0"){&lt;br /&gt;          alert("Warning...");&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;};&lt;/pre&gt;&lt;br /&gt;"alert" och jQuery kan vi enkelt stubba bort och ersätta med egen kod. I specifikationen nedan så använder jag Jasmine som specifikationsramverk. I "beforeEach" så sparar jag först undan den gamla alert/jQuery innan jag sätter om det till det som jag vill ha: &lt;pre name="code" class="js:nogutter:nocontrols" style="display: none;"&gt;&lt;br /&gt;describe("Browser specifications", function() {&lt;br /&gt;&lt;br /&gt;describe("When browsing with ie 6.0", function() {&lt;br /&gt;&lt;br /&gt;  beforeEach( function() {&lt;br /&gt;    _alert = window.alert;&lt;br /&gt;    _$ = $;&lt;br /&gt;&lt;br /&gt;    window.alert = Function.createDelegate(this, function(message) {&lt;br /&gt;      messageCaught = message;&lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;    $ = {};&lt;br /&gt;    $.browser = {&lt;br /&gt;      msie : true,&lt;br /&gt;      version : "6.0"&lt;br /&gt;    };&lt;br /&gt;  });&lt;br /&gt;&lt;br /&gt;  it("A warning message should appear", function() {&lt;br /&gt;    demo.checkBrowserVersion();&lt;br /&gt;    expect(messageCaught).toEqual("Warning...");&lt;br /&gt;  });&lt;br /&gt;&lt;br /&gt;  afterEach( function() {&lt;br /&gt;    window.alert = _alert;&lt;br /&gt;    $ = _$;&lt;br /&gt;  });&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;Efter att specificationen har exekverats så sätter jag tillbak alert/jQuery till det som det var innan. Lätt eller hur?&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-3279690030122642638?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/b5596Ak8P7g" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/b5596Ak8P7g/stubs-i-javascript.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/02/stubs-i-javascript.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-5626414326445190316</guid><pubDate>Thu, 20 Jan 2011 21:03:00 +0000</pubDate><atom:updated>2011-01-20T22:15:56.370+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">b</category><category domain="http://www.blogger.com/atom/ns#">HTML5</category><title>Sommarens snyggaste t-shirt?</title><description>Det har väl knappas undgått någon att det för några dagar sedan lanserades en officiell HTML5 logga. Loggan är som en mashup mellan &lt;a href="http://en.wikipedia.org/wiki/Autobots"&gt;Autobots&lt;/a&gt; logga och &lt;a href="http://en.wikipedia.org/wiki/Superman"&gt;Supermans&lt;/a&gt;:&lt;div&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_MeG5IjL0yGQ/TTilpPLkCXI/AAAAAAAAAoo/_GYAxGLyydY/s1600/HTML5_Logo_256.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 256px; height: 256px;" src="http://3.bp.blogspot.com/_MeG5IjL0yGQ/TTilpPLkCXI/AAAAAAAAAoo/_GYAxGLyydY/s400/HTML5_Logo_256.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5564379467484498290" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I och med loggan finns det nu en rolig site där man kan läsa lite om den samt generera egna badges: &lt;a href="http://www.w3.org/html/logo/"&gt;http://www.w3.org/html/logo/&lt;/a&gt;&lt;div&gt;&lt;br /&gt;Så sommarens coolaste t-shirt (för über webbnördar) blir väl:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_MeG5IjL0yGQ/TTilpT-fOtI/AAAAAAAAAow/SpddJ7yi-JA/s1600/m-back.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 158px; height: 158px;" src="http://3.bp.blogspot.com/_MeG5IjL0yGQ/TTilpT-fOtI/AAAAAAAAAow/SpddJ7yi-JA/s400/m-back.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5564379468771834578" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;(&lt;a href="http://html5shirt.com/"&gt;http://html5shirt.com/&lt;/a&gt;)&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-5626414326445190316?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/OASxvYfGFoY" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/OASxvYfGFoY/sommarens-snyggaste-t-shirt.html</link><author>noreply@blogger.com (Anders Jönsson)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://3.bp.blogspot.com/_MeG5IjL0yGQ/TTilpPLkCXI/AAAAAAAAAoo/_GYAxGLyydY/s72-c/HTML5_Logo_256.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/01/sommarens-snyggaste-t-shirt.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-3776373615569440749</guid><pubDate>Sat, 08 Jan 2011 22:08:00 +0000</pubDate><atom:updated>2011-01-08T23:10:27.763+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">HTML5</category><category domain="http://www.blogger.com/atom/ns#">Stockholm Web Monkeys</category><title>Stockholm Web Monkeys - HTML5 development on google projects</title><description>Stockholm Web Monkeys - HTML5 development on google projects (18th of&lt;br /&gt;January)&lt;br /&gt;&lt;br /&gt;For mor information: &lt;a href="http://groups.google.com/group/stockholm-web-monkeys/browse_thread/thread/8f05fcb83d0d0697?hl=en"&gt;http://groups.google.com/group/stockholm-web-monkeys/browse_thread/thread/8f05fcb83d0d0697?hl=en&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-3776373615569440749?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/7K2qp37SyrQ" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/7K2qp37SyrQ/stockholm-web-monkeys-html5-development.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/01/stockholm-web-monkeys-html5-development.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-3819336691610044701</guid><pubDate>Thu, 06 Jan 2011 21:20:00 +0000</pubDate><atom:updated>2011-01-06T22:20:54.745+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">Utveckling</category><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><title>Tip of the day: dynaTrace &amp; WebStrom</title><description>Lately I have been using two awesome tools for JavaScript web development, dynaTrace and WebStrom. &lt;br /&gt;&lt;br /&gt;dynaTrace (free) is a tool for profiling web pages, for example JavaScript performance and markup rendering . The current version supports IE 6 and newer which make this an interesting alternative when you must fix slow scripts in IE. Of course there are plenty of tools for this kind of things in Firefox and Chrome, but not in IE 6/7.  I’m not saying that I like spending time fixing problems in IE, but sometimes you must.&lt;br /&gt;&lt;a href="http://ajax.dynatrace.com/ajax/en/"&gt;http://ajax.dynatrace.com/ajax/en/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;WebStorm (not free) is an IDE for web development. It’s a good IDE with a remarkable good JavaScript handling. For example you can do different refactoring’s (rename, move, etc.), find usages on function across all of your files, use go to definition on functions, etc. &lt;br /&gt;&lt;a href="http://www.jetbrains.com/webstorm/"&gt;http://www.jetbrains.com/webstorm/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Happy scripting!&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-3819336691610044701?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/QMhGBPDVe1s" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/QMhGBPDVe1s/tip-of-day-dynatrace-webstrom.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/01/tip-of-day-dynatrace-webstrom.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-9122632942049531482</guid><pubDate>Mon, 03 Jan 2011 23:07:00 +0000</pubDate><atom:updated>2011-03-18T16:16:32.756+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><category domain="http://www.blogger.com/atom/ns#">Jasmine Test Runner</category><category domain="http://www.blogger.com/atom/ns#">TDD</category><title>En simpel dictionary i JavaScript</title><description>Jag behövde en simpel abstraktion för en dictionary i JavaScript så jag satte ihop följande:&lt;br /&gt;&lt;pre class="js:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;var Dictionary = function(){&lt;br /&gt;   this._dictionary = {};&lt;br /&gt;   this._count = 0;   &lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Dictionary.prototype.count = function() {&lt;br /&gt;   return this._count;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Dictionary.prototype.add = function(key, value) {&lt;br /&gt;   if(this.get(key) === undefined){&lt;br /&gt;       this._count++;&lt;br /&gt;   }&lt;br /&gt;   this._dictionary[key] = value;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Dictionary.prototype.remove = function(key) {&lt;br /&gt;   this._count--;&lt;br /&gt;   delete this._dictionary[key];&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Dictionary.prototype.get = function(key) {&lt;br /&gt;   return this._dictionary[key];&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Dictionary.prototype.exists = function(key) {&lt;br /&gt;   return this._dictionary[key] !== undefined;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;Dictionary.prototype.forEach = function(func) {&lt;br /&gt;   for(var key in this._dictionary){&lt;br /&gt;       func(key, this._dictionary[key]);&lt;br /&gt;   }&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Med hjälp av ett object och lite prototyping så blev det helt okej. Funktionaliteten drev jag fram genom följande specifikationer:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_MeG5IjL0yGQ/TSJZUOnbu9I/AAAAAAAAAoQ/wUF0Map6xx4/s1600/dictionary.png"&gt;&lt;img style="cursor: pointer; width: 400px; height: 341px;" src="http://4.bp.blogspot.com/_MeG5IjL0yGQ/TSJZUOnbu9I/AAAAAAAAAoQ/wUF0Map6xx4/s400/dictionary.png" alt="" id="BLOGGER_PHOTO_ID_5558103094184360914" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Koden för specifikationerna var (använder mig av &lt;a href="http://pivotal.github.com/jasmine/index.html"&gt;Jasmine Test Runner&lt;/a&gt;):&lt;br /&gt;&lt;pre class="js:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;describe("Dictionary Specifications", function(){&lt;br /&gt;&lt;br /&gt;   describe("When having a dictionary with one key value pair", function(){&lt;br /&gt;  &lt;br /&gt;       var dictionary;&lt;br /&gt;      &lt;br /&gt;       beforeEach(function(){&lt;br /&gt;           dictionary = new Dictionary();&lt;br /&gt;           dictionary.add("key1", "value1");&lt;br /&gt;       });&lt;br /&gt;      &lt;br /&gt;       it("should be able to get value by key", function(){&lt;br /&gt;           var value = dictionary.get("key1");&lt;br /&gt;           expect(value).toEqual("value1");&lt;br /&gt;       });&lt;br /&gt;      &lt;br /&gt;       it("should get correct number of pairs in the dictionary", function(){&lt;br /&gt;           var count = dictionary.count();&lt;br /&gt;           expect(count).toEqual(1);&lt;br /&gt;       });&lt;br /&gt;&lt;br /&gt;   });&lt;br /&gt;&lt;br /&gt;   describe("When having a dictionary with two key value pair", function(){&lt;br /&gt;  &lt;br /&gt;       var dictionary;&lt;br /&gt;      &lt;br /&gt;       beforeEach(function(){&lt;br /&gt;           dictionary = new Dictionary();&lt;br /&gt;           dictionary.add("key1", "value1");&lt;br /&gt;           dictionary.add("key2", "value2");&lt;br /&gt;       });&lt;br /&gt;&lt;br /&gt;       it("it should be possible to loop through all pairs", function(){&lt;br /&gt;           var concatenatedKeyValues = "";&lt;br /&gt;           dictionary.forEach(function(key, value){&lt;br /&gt;              concatenatedKeyValues += key + ":" + value + ";"&lt;br /&gt;           });&lt;br /&gt;           expect(concatenatedKeyValues).toEqual("key1:value1;key2:value2;");&lt;br /&gt;       });&lt;br /&gt;&lt;br /&gt;   });&lt;br /&gt;  &lt;br /&gt;   describe("When adding two pairs with the same key", function(){&lt;br /&gt;  &lt;br /&gt;       var dictionary;&lt;br /&gt;      &lt;br /&gt;       beforeEach(function(){&lt;br /&gt;           dictionary = new Dictionary();&lt;br /&gt;           dictionary.add("key1", "value1");&lt;br /&gt;           dictionary.add("key1", "value2");&lt;br /&gt;       });&lt;br /&gt;      &lt;br /&gt;       it("the last added value should be used", function(){&lt;br /&gt;           var value = dictionary.get("key1");&lt;br /&gt;           expect(value).toEqual("value2");&lt;br /&gt;       });&lt;br /&gt;      &lt;br /&gt;   });&lt;br /&gt;  &lt;br /&gt;   describe("When removing an added pair", function(){&lt;br /&gt;  &lt;br /&gt;       var dictionary;&lt;br /&gt;      &lt;br /&gt;       beforeEach(function(){&lt;br /&gt;           dictionary = new Dictionary();&lt;br /&gt;           dictionary.add("key1", "value1");&lt;br /&gt;           dictionary.remove("key1");&lt;br /&gt;       });&lt;br /&gt;      &lt;br /&gt;       it("it should not be in the dictionary", function(){&lt;br /&gt;           var exists = dictionary.exists("key1");&lt;br /&gt;           expect(exists).toBeFalsy();&lt;br /&gt;       });&lt;br /&gt;      &lt;br /&gt;       it("it should return undefined if trying to get it", function(){&lt;br /&gt;           var value = dictionary.get("key1");&lt;br /&gt;           expect(value).toEqual(undefined);&lt;br /&gt;       });&lt;br /&gt;      &lt;br /&gt;   });&lt;br /&gt;  &lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-9122632942049531482?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/l5_-cszAz0o" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/l5_-cszAz0o/en-simpel-dictionary-i-javascript.html</link><author>noreply@blogger.com (Anders Jönsson)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_MeG5IjL0yGQ/TSJZUOnbu9I/AAAAAAAAAoQ/wUF0Map6xx4/s72-c/dictionary.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2011/01/en-simpel-dictionary-i-javascript.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-3573062487943268776</guid><pubDate>Mon, 29 Nov 2010 21:25:00 +0000</pubDate><atom:updated>2010-11-29T22:34:12.993+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">HTML5</category><category domain="http://www.blogger.com/atom/ns#">Design</category><title>Snygg bok i HTML5</title><description>Otroligt snygg bok gjord i HTML5: &lt;a href="http://www.20thingsilearned.com/"&gt;http://www.20thingsilearned.com/&lt;/a&gt;. Grym artwork.&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-3573062487943268776?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/i3DTNB0y7ew" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/i3DTNB0y7ew/snygg-bok-i-html5.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2010/11/snygg-bok-i-html5.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-2642380489052598124</guid><pubDate>Fri, 19 Nov 2010 11:00:00 +0000</pubDate><atom:updated>2010-11-19T12:00:11.537+01:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><title>Closure Compiler (JavaScript)</title><description>&lt;a href="http://code.google.com/intl/sv-SE/closure/compiler/"&gt;Closure Compiler&lt;/a&gt; är ett verktyg för att effektivisera JavaScript-filer utifrån nerladdningstid och körtid. Verktyget kompilerar om JavaScript-koden till ny JavaScript-kod som skall vara mer effektiv och ta mindre plats än originalkoden:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;"It parses your JavaScript, analyzes it, removes dead code and rewrites and minimizes what's left. It also checks syntax, variable references, and types, and warns about common JavaScript pitfalls."&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;Ett snabbtest på en av dn.se JavaScript-filer, &lt;a href="http://www.dn.se/js/dn/dnse-min.js"&gt;http://www.dn.se/js/dn/dnse-min.js&lt;/a&gt;,  visar intressant resultat:&lt;br /&gt;&lt;blockquote&gt;"Original Size:  302.05KB (87.6KB gzipped)&lt;br /&gt;Compiled Size:  212.31KB (71.18KB gzipped)&lt;br /&gt;Saved 29.71% off the original size (18.75% off the gzipped size)"&lt;/blockquote&gt;&lt;br /&gt;Utifrån vad som går att läsa på nätet så är det ganska många tunga aktörer som använder Closure Compiler till sin JavaScript-kod, bland annat har jQuery gått över till att köra Closure Compiler:&lt;br /&gt;&lt;blockquote&gt;&lt;span style="font-style: italic;"&gt;"Output from Closure Compiler is showing solid improvement over YUIMin"&lt;/span&gt; - &lt;a href="http://twitter.com/jeresig/status/5462879648"&gt;John Resig (skaparen av jQuery)&lt;/a&gt;&lt;/blockquote&gt;&lt;br /&gt;Läs mer på: &lt;a href="http://code.google.com/intl/sv-SE/closure/compiler/"&gt;http://code.google.com/intl/sv-SE/closure/compiler/&lt;/a&gt;&lt;br /&gt;Ett online verktyg finns på: &lt;a href="http://closure-compiler.appspot.com/home"&gt;http://closure-compiler.appspot.com/home&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-2642380489052598124?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/ep4t0_xDhKc" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/ep4t0_xDhKc/closure-compiler-javascript.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2010/11/closure-compiler-javascript.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-2026368768401780321</guid><pubDate>Tue, 26 Oct 2010 12:35:00 +0000</pubDate><atom:updated>2010-10-26T14:36:47.610+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Utveckling</category><category domain="http://www.blogger.com/atom/ns#">Alt.Net</category><title>ALT.NET – vad hände sen?</title><description>Det var ett tag sedan nu som ALT.NET-eran började ebba ut. Här i Sverige var det lugnt på maillistan sedan en tid tillbaka och sista spiken i kistan kom när Google utan förvarning valde att ta bort gruppen (någon som vet varför?). Dock är det viktigt att veta att ALT.NET inte bara var något temporärt eller något som bara var aktuellt under en viss tid, snarare tvärt om. Tankarna och idéerna som taggades som ALT.NET är lika högaktuella idag som för några år sedan. Viljan att ständigt förbättra sig, testa nya möjligheter och att finna nya metoder/tekniker lever vidare.&lt;br /&gt;&lt;br /&gt;Vissa tycker att ALT.NET misslyckades, att vi inte nådde ut till den stora massan samt att det blev ett forum för inbördes beundran. Andra tyckte den fick en snedvridning mot tooling samt till olika ramverk. Oavsett om detta är sant eller ej så tycker jag ALT.NET lyckades bra, speciellt med tanken på vilka förutsättningar som fanns. I och med rörelsen fick en mängd nya människor upp ögonen för att det fanns något bättre. Utöver det bildades många olika nya nätverk där kunskap och erfarenheter utbyttes. Men det var inte bara de nyupplysta som gynnades av detta, många av de gamla eldsjälarna som drev arbetet långt innan ALT.NET som begrepp myntades fick ny energi av alla hungriga nykomlingar.&lt;br /&gt;&lt;br /&gt;För den som inte brydde sig om ALT.NET-rörelsens tankar och idéer eller aldrig förstod vitsen med rörelsen kommer lugnt att jobba vidare idag såsom de gjorde förut, det blir nog ingen ändring där på länge. De låter sig glatt matas med hur man skall jobba samt med vilka verktyg.&lt;br /&gt;&lt;br /&gt;Tankarna, idéerna och viljan till något bättre finns kvar och frodas runt om i världen, med eller utan etiketten ALT.NET.&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-2026368768401780321?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/mc2F6zeQ6Gg" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/mc2F6zeQ6Gg/altnet-vad-hande-sen.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>2</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2010/10/altnet-vad-hande-sen.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-4900811916716812888</guid><pubDate>Wed, 15 Sep 2010 19:18:00 +0000</pubDate><atom:updated>2010-09-15T21:19:21.034+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">Utveckling</category><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><title>jsAutoBind - let it bind for you</title><description>One day when I was manually wiring up element events to functions in JavaScript I thought, why can't a light-weighted convention based framework do this for me? And if it can, can it also handle state changes from JavaScript into the UI?&lt;br /&gt;&lt;br /&gt;That was the reason for this micro framework, just a simple thing that would do all the plumbing for you. A way to stop thinking about HTML elements in the JavaScript code and instead just focus on the business logic. Before we go any further, let`s see a sample:&lt;br /&gt;&lt;br /&gt;Lets say that we have the following UI:&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_MeG5IjL0yGQ/TI_eil91PcI/AAAAAAAAAm4/hPq-FBbCDr0/s1600/1.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_MeG5IjL0yGQ/TI_eil91PcI/AAAAAAAAAm4/hPq-FBbCDr0/s1600/1.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5516872754440519106" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;We want to have validation on the name field and on the date field. The name should also be mandatory (that's why the button is disabled). You shall only be permitted to click on "Save" after the name has been validated correctly.&lt;br /&gt;&lt;br /&gt;The HTML markup is simple (for full markup see below):&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_MeG5IjL0yGQ/TI_ekcs5b_I/AAAAAAAAAnY/b2uHw-ic7Ag/s1600/markup.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_MeG5IjL0yGQ/TI_ekcs5b_I/AAAAAAAAAnY/b2uHw-ic7Ag/s1600/markup.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5516872786313310194" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For the behaviors we need some sort of model, in this case we have a behavior model named "sample2Behavior" in JavaScript (more about the naming further down):&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_MeG5IjL0yGQ/TI_esxSnXFI/AAAAAAAAAng/HPoJtfTzv6s/s1600/js.png"&gt;&lt;img style="cursor:pointer; cursor:hand" src="http://4.bp.blogspot.com/_MeG5IjL0yGQ/TI_esxSnXFI/AAAAAAAAAng/HPoJtfTzv6s/s1600/js.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5516872929279171666" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In this model we have described the behaviors for the view (HTML markup) and this will automatically be binded to respective elements event:&lt;br /&gt;- "init" it's like a constructor and will be the first thing thats is processed when the behaviors is loaded.&lt;br /&gt;- "save" is when the button is clicked&lt;br /&gt;- "name" is the validation for the name field&lt;br /&gt;- "signDate" is the validation for the date field&lt;br /&gt;&lt;br /&gt;When we in the "name" function change the value for the "canSave" variable, the state for the "save"-button will automatically change in the UI also. This means if the validation is ok, the button will be enabled - and you don't have to care about updating the UI.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;If you run the workflow it willl look like this:&lt;br /&gt;&lt;br /&gt;When the name textbox loses focus, the validation will begin:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_MeG5IjL0yGQ/TI_ei3ETwQI/AAAAAAAAAnA/YPkkIvTK4fo/s1600/2.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_MeG5IjL0yGQ/TI_ei3ETwQI/AAAAAAAAAnA/YPkkIvTK4fo/s1600/2.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5516872759031087362" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If the validation is successful the save button will be enabled:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_MeG5IjL0yGQ/TI_ejd1Au4I/AAAAAAAAAnI/3CzqIpmrHxY/s1600/3.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_MeG5IjL0yGQ/TI_ejd1Au4I/AAAAAAAAAnI/3CzqIpmrHxY/s1600/3.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5516872769435908994" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When you click on it you will see a message box:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_MeG5IjL0yGQ/TI_ejxGIqfI/AAAAAAAAAnQ/eWWHDnPF1JI/s1600/4.png"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_MeG5IjL0yGQ/TI_ejxGIqfI/AAAAAAAAAnQ/eWWHDnPF1JI/s1600/4.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5516872774608005618" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And all this without any binding code! All right, there is no magic at all - the way this work is that the framework goes through all the functions in the behavior model (JavaScript object) and then match them by name to the view model (HTML markup). By convention all buttons will be binded using the click event, text boxes by the changed event and so on. If there is something with a prefix "can" it will try to bind this to the disabled state of the element. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;By default the framework will look for a variable with the file name plus the suffix "Behavior". So in this case the file name is simple2 so the variable name would be simple2behavior. You can of course ignore this and manual specify the name for the behavior model (see sample four).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The full markup with the call to jsAutoBind function "Bind()":&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_MeG5IjL0yGQ/TI_etKyPU0I/AAAAAAAAAno/qKaRLTcC_4c/s1600/full_markup.png"&gt;&lt;img style="cursor:pointer; cursor:hand" src="http://1.bp.blogspot.com/_MeG5IjL0yGQ/TI_etKyPU0I/AAAAAAAAAno/qKaRLTcC_4c/s1600/full_markup.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5516872936122700610" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;As you can see in this sample i use jQuery to handle the DOM, but you can use whatever framework you like. The only thing you have to do to change this is to create a file that follows the contract in "jsAutoBind-3rd-party-contract.js" so it works with you favorite framework.&lt;br /&gt;&lt;br /&gt;There are some more samples that shows different scenarios, e.g. when you want to specify what model to use and in which context. Please look through the sample code. The samples and source code is located at &lt;a href="http://github.com/archive/jsAutoBind"&gt;http://github.com/archive/jsAutoBind&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;This is the 0.1 alpha release, which means that the framework is not complete nor have it been tested in different browsers. Right now it should work i Firefox and Chrome. There is plenty of things left to do. Play around with it and see if you like the concept.&lt;br /&gt;&lt;br /&gt;(No, this is not like &lt;a href="http://blog.stevensanderson.com/2010/07/05/introducing-knockout-a-ui-library-for-javascript/"&gt;Knockout&lt;/a&gt;, its a different approach. Although Knockout is a really cool framework.)&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-4900811916716812888?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/DAEw_BLo7ZI" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/DAEw_BLo7ZI/jsautobind-let-it-bind-for-you.html</link><author>noreply@blogger.com (Anders Jönsson)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_MeG5IjL0yGQ/TI_eil91PcI/AAAAAAAAAm4/hPq-FBbCDr0/s72-c/1.png" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2010/09/jsautobind-let-it-bind-for-you.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-4168649920642585772</guid><pubDate>Thu, 09 Sep 2010 04:26:00 +0000</pubDate><atom:updated>2010-09-09T06:53:31.848+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">Utveckling</category><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><title>Loggning av funktionsanrop i JavaScript</title><description>Ibland kan man behöva logga hur olika funktioner anropas samt med vilka parametrar. Det finns många sätt att göra det på, nedan är ett sätt där man slipper smutsa ner själva koden med en massa loggningsuttryck. Jag har i detta exempel valt att skapa en simpel "logger" som tar hand om hela arbetet.&lt;br /&gt;&lt;br /&gt;Exempel:&lt;br /&gt;Jag har följande funktioner i objektet "box" som jag vill skall loggas när de anropas:&lt;br /&gt;&lt;pre class="js:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;var box = {&lt;br /&gt;&lt;br /&gt;   begin: function(time){&lt;br /&gt;      // Stuff&lt;br /&gt;   },&lt;br /&gt;&lt;br /&gt;   getStatus: function(){&lt;br /&gt;      // Stuff&lt;br /&gt;      return this.buildStatusMessage();&lt;br /&gt;   },&lt;br /&gt;&lt;br /&gt;   buildStatusMessage: function(){&lt;br /&gt;      return "some status";&lt;br /&gt;   },&lt;br /&gt;&lt;br /&gt;   stop: function(time, reason){&lt;br /&gt;      // Stuff&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Med hjälp av loggern kan jag nu skriva följande för att initialisera loggning för "box" objektet:&lt;br /&gt;&lt;pre class="js:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;logger.determinator.set("\n");&lt;br /&gt;logger.initializeFor(box);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nu när jag kör lite olika funktioner på "box":&lt;br /&gt;&lt;pre class="js:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;box.begin("10:00:00");&lt;br /&gt;var status = box.getStatus();&lt;br /&gt;box.stop("22:00:00", "00x00");&lt;br /&gt;&lt;br /&gt;alert(logger.getLogEnties());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Så kommer följande log visas:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;calling function 'begin' with argument(s): '10:00:00'&lt;br /&gt;calling function 'getStatus'&lt;br /&gt;calling function 'buildStatusMessage'&lt;br /&gt;function 'buildStatusMessage' returned 'some status'&lt;br /&gt;function 'getStatus' returned 'some status'&lt;br /&gt;calling function 'stop' with argument(s): '22:00:00' '00x00'&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Loggern fungerar på så sätt att den wrappar alla funktioner samt deras returvärden. På detta sätt kan jag skära mellan anropen som görs till funktionerna.&lt;br /&gt;&lt;br /&gt;Principen är enkel, det man gör är att man skriver över original-funktionen med en annan funktion som både loggar och gör anropet till original-funktionen. Efter att man har anropat original-funktionen så loggar man det eventuella returvärdet för att sedan returnera det. På så sätt bryter man inte kedjan.&lt;br /&gt;&lt;br /&gt;Loggen som jag använder i följande simpla exempel ser ut så här:&lt;br /&gt;&lt;pre class="js:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;var logger = {&lt;br /&gt;&lt;br /&gt; log: function(){&lt;br /&gt;     var enties = "";&lt;br /&gt;  &lt;br /&gt;     return {&lt;br /&gt;         write: function(entry){&lt;br /&gt;             enties += entry + logger.determinator.get();&lt;br /&gt;         },&lt;br /&gt;         get: function(){&lt;br /&gt;             return enties;&lt;br /&gt;         },&lt;br /&gt;         clear: function(){&lt;br /&gt;             enties = "";&lt;br /&gt;         }&lt;br /&gt;     };&lt;br /&gt; }(),&lt;br /&gt;&lt;br /&gt; initializeFor: function(context){&lt;br /&gt;     for (func in context) {&lt;br /&gt;         this.setupLoggingFor(func, context);&lt;br /&gt;     }&lt;br /&gt; },&lt;br /&gt;&lt;br /&gt; writePreCallLogEntry: function(func, args){&lt;br /&gt;     var entry = this.buildCallingLogEntry(func);&lt;br /&gt;     entry += this.buildArgumentsLogEntry(args);&lt;br /&gt;     logger.log.write(entry);&lt;br /&gt; },&lt;br /&gt;&lt;br /&gt; buildCallingLogEntry: function(func){&lt;br /&gt;     return "calling function '" + func + "'";&lt;br /&gt; },&lt;br /&gt;&lt;br /&gt; buildArgumentsLogEntry: function(args){&lt;br /&gt;     var entry = "";&lt;br /&gt;     if (args.length != 0) {&lt;br /&gt;         entry += " with " + " argument(s): ";&lt;br /&gt;         for (index = 0; index &amp;lt; args.length; index++) {&lt;br /&gt;             entry += "'" + args[index] + "' ";&lt;br /&gt;         }&lt;br /&gt;     }&lt;br /&gt;     return entry;&lt;br /&gt; },&lt;br /&gt;&lt;br /&gt; writePostCallLogEntry: function(func, returnValue){ &lt;br /&gt;     var entry = "function '" + func + "' returned '" + returnValue + "'";&lt;br /&gt;     logger.log.write(entry);     &lt;br /&gt; },&lt;br /&gt;&lt;br /&gt; setupLoggingFor: function(func, context){&lt;br /&gt;     var self = this;&lt;br /&gt;     var originalFunc = context[func];&lt;br /&gt;  &lt;br /&gt;     context[func] = function(){&lt;br /&gt;         self.writePreCallLogEntry(func, arguments);&lt;br /&gt;      &lt;br /&gt;         var returnValue = originalFunc.call(this);&lt;br /&gt;      &lt;br /&gt;         if (typeof returnValue !== "undefined") {&lt;br /&gt;             self.writePostCallLogEntry(func, returnValue);&lt;br /&gt;             return returnValue&lt;br /&gt;         }&lt;br /&gt;     };&lt;br /&gt; },&lt;br /&gt;&lt;br /&gt; getLogEnties: function(){&lt;br /&gt;     return logger.log.get();&lt;br /&gt; },&lt;br /&gt;&lt;br /&gt; determinator: function(){&lt;br /&gt;     var currentToken = "";&lt;br /&gt;     return {&lt;br /&gt;         set: function(token){&lt;br /&gt;             currentToken = token&lt;br /&gt;         },&lt;br /&gt;         get: function(){&lt;br /&gt;             return currentToken;&lt;br /&gt;         }&lt;br /&gt;     };&lt;br /&gt; }(),&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Det är i "setupLoggingFor" som jag byter ut original-funktionen med en anonym funktion som wrappar original-funktionen. "func" är själva funktionen och "context" är i detta fall "box" objektet.&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-4168649920642585772?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/bLtGEiCR7Yo" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/bLtGEiCR7Yo/loggning-av-funktionsanrop-i-javascript.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2010/09/loggning-av-funktionsanrop-i-javascript.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-5024686690570345310</guid><pubDate>Sat, 04 Sep 2010 20:05:00 +0000</pubDate><atom:updated>2010-09-04T22:11:48.085+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">HTML</category><title>HTML5 och H.264</title><description>Jag snubblade över en intressant blogg för ett tag sedan: &lt;a href="http://itpastorn.blogspot.com/"&gt;http://itpastorn.blogspot.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Till exempel så var dessa mycket intressanta:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://itpastorn.blogspot.com/2010/09/why-h264-is-disqualified-from-being-web.html"&gt;Why H.264 is disqualified from being a web standard&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://itpastorn.blogspot.com/2010/09/why-h264-is-disqualified-from-being-web.html"&gt;&lt;/a&gt;&lt;a href="http://itpastorn.blogspot.com/2010/07/no-browser-supports-html5-yet-part-1.html"&gt;No browser supports HTML5 yet. Part 1. The rant.&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://itpastorn.blogspot.com/2010/07/no-browser-supports-html5-yet-part-1.html"&gt;&lt;/a&gt;&lt;a href="http://itpastorn.blogspot.com/2010/07/no-browser-supports-html5-yet-part-2.html"&gt;No browser supports HTML5 yet. Part 2. Technology.&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-5024686690570345310?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/bhjJI08Ya_M" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/bhjJI08Ya_M/html5-och-h264.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2010/09/html5-och-h264.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-396089733336506540</guid><pubDate>Thu, 27 May 2010 19:50:00 +0000</pubDate><atom:updated>2010-06-27T19:43:35.063+02:00</atom:updated><category domain="http://www.blogger.com/atom/ns#">Web</category><category domain="http://www.blogger.com/atom/ns#">Utveckling</category><category domain="http://www.blogger.com/atom/ns#">JavaScript</category><category domain="http://www.blogger.com/atom/ns#">Alt.Net</category><title>Stockholm Web Monkeys: Second Encounter</title><description>Tips:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;"&lt;i&gt;Hello all web monkeys.&lt;br /&gt;&lt;br /&gt;As previous announced it´s time for the second meeting. The meeting&lt;br /&gt;will take place at the 15th of June at Avega. We already have two&lt;br /&gt;great speakers lined up, Peter Svensson and Fredrik Bonander.&lt;br /&gt;Looking forward to see some old and new faces there!&lt;br /&gt;&lt;br /&gt;SWM: Second encounter&lt;br /&gt;&lt;br /&gt;Schedule:&lt;br /&gt;18:30 - 19:00 Mingle and Sandwich&lt;br /&gt;19:00 - 19:10 Welcome to SWM&lt;br /&gt;19:10 - 20:00 Using Google's MVC object with Google Maps API 3 -&lt;br /&gt;Fredirk Bonander.&lt;br /&gt;20:00 - 20:30 Prototyping intranets with Dojo's Layout Containers -&lt;br /&gt;Peter Svensson&lt;br /&gt;20:30 - 21:00 TBD&lt;br /&gt;21:00 -&gt; Beer at Bar 101&lt;br /&gt;&lt;br /&gt;Location: Avega, Avega Group, Grev Turegatan 11A, 114 46 Stockholm&lt;br /&gt;We only have a limited number of seats so only the first 40 to reply&lt;br /&gt;to this post will get a seat. If you replied on the last message your&lt;br /&gt;already registered.&lt;br /&gt;&lt;br /&gt;For more information, see: &lt;/i&gt;&lt;a href="http://groups.google.com/group/stockholm-web-monkeys"&gt;&lt;i&gt;http://groups.google.com/group/stockholm-web-monkeys &lt;/i&gt;&lt;/a&gt;&lt;i&gt;&lt;br /&gt;Follow us on twitter: @SthlmWebMonkeys&lt;br /&gt;&lt;br /&gt;If you have ideas and would like to contribute, don't hesitate to&lt;br /&gt;contact us or drop a message in the discussion group!&lt;/i&gt;"&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-396089733336506540?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/sqaLqrJj8sM" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/sqaLqrJj8sM/stockholm-web-monkeys-second-encounter.html</link><author>noreply@blogger.com (Anders Jönsson)</author><feedburner:origLink>http://andersjonsson.blogspot.com/2010/05/stockholm-web-monkeys-second-encounter.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-3275472874082612243</guid><pubDate>Mon, 24 May 2010 18:24:00 +0000</pubDate><atom:updated>2010-05-24T21:04:21.384+02:00</atom:updated><title>Mustache i JavaScript</title><description>För ett tag sedan stötte jag på en template-motor i JavaScript vid namnet &lt;a href="http://mustache.github.com/"&gt;Mustache&lt;/a&gt;. Mustache skulle vara en snabb och lättviktig motor och utifrån det jag har testat så verkar detta stämma.&lt;br /&gt;&lt;br /&gt;Syntaxen är enkel, för att fylla i ett värde på en viss plats så används notationen {{värde}}.&lt;br /&gt;&lt;br /&gt;Exempel: Här vill vi fylla i vissa värden i en sträng för att sedan visa det för användaren:&lt;br /&gt;&lt;pre class="js:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;var template = "The price is {{price}} {{currency}} per piece when buying {{threshold}} pieces.";&lt;br /&gt;    &lt;br /&gt;var data = {&lt;br /&gt;  price: 145.95,&lt;br /&gt;  currency: "EUR",&lt;br /&gt;  threshold: 9870&lt;br /&gt;};&lt;br /&gt;    &lt;br /&gt;var html = Mustache.to_html(template, data);&lt;br /&gt;    &lt;br /&gt;document.getElementById("price-information").innerHTML = html;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;"Mustache.to_html" tar in templaten och data för att sedan göra sin magi.&lt;br /&gt;&lt;br /&gt;Exempel: Här vill vi visa en lista för användaren med lite data.&lt;br /&gt;&lt;pre class="js:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;var template = "&amp;lt;ul&amp;gt;{{#list}}&amp;lt;li&amp;gt;{{level}} pieces: {{price}} {{currency}} / piecs&amp;lt;/li&amp;gt;{{/list}}&amp;lt;/ul&amp;gt;";&lt;br /&gt;    &lt;br /&gt;var data = {&lt;br /&gt;  currency: "EUR",&lt;br /&gt;  list: [{&lt;br /&gt;    level: "100 - 199",&lt;br /&gt;    price: 145.95&lt;br /&gt;  }, {&lt;br /&gt;    level: "200 - 299",&lt;br /&gt;    price: 125.95&lt;br /&gt;  }, {&lt;br /&gt;    level: "300 - 399",&lt;br /&gt;    price: 105.95&lt;br /&gt;  }]&lt;br /&gt;};&lt;br /&gt;    &lt;br /&gt;var html = Mustache.to_html(template, data);&lt;br /&gt;    &lt;br /&gt;document.getElementById("threshold-information").innerHTML = html;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Output:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_MeG5IjL0yGQ/S_rM6Yl6AjI/AAAAAAAAAmo/9NE7438abYs/s1600/kod.PNG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 380px; height: 194px;" src="http://4.bp.blogspot.com/_MeG5IjL0yGQ/S_rM6Yl6AjI/AAAAAAAAAmo/9NE7438abYs/s400/kod.PNG" border="0" alt="" id="BLOGGER_PHOTO_ID_5474913600428180018" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enkelt eller hur? Läs mer på: &lt;a href="http://mustache.github.com/"&gt;http://mustache.github.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Kod:&lt;br /&gt;&lt;pre class="html:nogutter:nocontrols" name="code"&gt;&lt;br /&gt;&amp;lt;!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"&amp;gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml"&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;    &amp;lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;mustache demo&amp;lt;/title&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;h1&amp;gt;Prices&amp;lt;/h1&amp;gt;&lt;br /&gt;    &amp;lt;span id="price-information"&amp;gt;&amp;lt;/span&amp;gt;&lt;br /&gt;    &amp;lt;br/&amp;gt;&lt;br /&gt;    &amp;lt;br/&amp;gt;&lt;br /&gt;    Thresholds:&lt;br /&gt;    &amp;lt;div id="threshold-information"&amp;gt;&lt;br /&gt;    &amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript" src="lib/mustache/mustache.js"&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;&lt;br /&gt;    (function(){&lt;br /&gt;&lt;br /&gt;        var template = "The price is {{price}} {{currency}} per piece when buying {{threshold}} pieces.";&lt;br /&gt;    &lt;br /&gt;        var data = {&lt;br /&gt;            price: 145.95,&lt;br /&gt;            currency: "EUR",&lt;br /&gt;            threshold: 9870&lt;br /&gt;        };&lt;br /&gt;    &lt;br /&gt;        var html = Mustache.to_html(template, data);&lt;br /&gt;    &lt;br /&gt;        document.getElementById("price-information").innerHTML = html;&lt;br /&gt;    &lt;br /&gt;    })();&lt;br /&gt;&lt;br /&gt;    (function(){&lt;br /&gt;&lt;br /&gt;        var template = "&amp;lt;ul&amp;gt;{{#list}}&amp;lt;li&amp;gt;{{level}} pieces: {{price}} {{currency}} / pieces&amp;lt;/li&amp;gt;{{/list}}&amp;lt;/ul&amp;gt;";&lt;br /&gt;    &lt;br /&gt;        var data = {&lt;br /&gt;  currency: "EUR",&lt;br /&gt;            list: [{&lt;br /&gt;                level: "100 - 199",&lt;br /&gt;                price: 145.95&lt;br /&gt;            }, {&lt;br /&gt;                level: "200 - 299",&lt;br /&gt;                price: 125.95&lt;br /&gt;            }, {&lt;br /&gt;                level: "300 - 399",&lt;br /&gt;                price: 105.95&lt;br /&gt;            }]&lt;br /&gt;        };&lt;br /&gt;    &lt;br /&gt;        var html = Mustache.to_html(template, data);&lt;br /&gt;    &lt;br /&gt;        document.getElementById("threshold-information").innerHTML = html;&lt;br /&gt;    &lt;br /&gt;    })();&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-3275472874082612243?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/s2s2EWhpEew" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/s2s2EWhpEew/mustache-i-javascript.html</link><author>noreply@blogger.com (Anders Jönsson)</author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://4.bp.blogspot.com/_MeG5IjL0yGQ/S_rM6Yl6AjI/AAAAAAAAAmo/9NE7438abYs/s72-c/kod.PNG" height="72" width="72" /><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2010/05/mustache-i-javascript.html</feedburner:origLink></item><item><guid isPermaLink="false">tag:blogger.com,1999:blog-30407200.post-3926105460418501805</guid><pubDate>Sun, 16 May 2010 18:14:00 +0000</pubDate><atom:updated>2010-05-24T20:24:29.178+02:00</atom:updated><title>_Why</title><description>Tips: _Why: A Tale Of A Post-Modern Genius, &lt;a href="http://www.smashingmagazine.com/2010/05/15/why-a-tale-of-a-post-modern-genius/"&gt;http://www.smashingmagazine.com/2010/05/15/why-a-tale-of-a-post-modern-genius/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;Anders Jönsson&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/30407200-3926105460418501805?l=andersjonsson.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/andersjonsson/~4/-NTRh0cuHp0" height="1" width="1"/&gt;</description><link>http://feedproxy.google.com/~r/andersjonsson/~3/-NTRh0cuHp0/why.html</link><author>noreply@blogger.com (Anders Jönsson)</author><thr:total>0</thr:total><feedburner:origLink>http://andersjonsson.blogspot.com/2010/05/why.html</feedburner:origLink></item></channel></rss>

