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

<channel>
	<title>A Log on JavaScript</title>
	<atom:link href="http://www.jslog.com/feed" rel="self" type="application/rss+xml" />
	<link>http://www.jslog.com</link>
	<description></description>
	<lastBuildDate>Tue, 20 Jul 2010 06:04:43 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Testing ExtJS with Selenium &#8211; Automating UI Tests</title>
		<link>http://www.jslog.com/testing-extjs-with-selenium-automating-ui-tests</link>
		<comments>http://www.jslog.com/testing-extjs-with-selenium-automating-ui-tests#comments</comments>
		<pubDate>Wed, 14 Jul 2010 17:00:33 +0000</pubDate>
		<dc:creator>radu</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[quick tips]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.jslog.com/?p=217</guid>
		<description><![CDATA[Automation testing of UI interfaces is essential in any big project, but it is difficult to achieve this for user interfaces built with ExtJS. Selenium records user actions, by clicks on elements, and memorizes the ids of the selected elements. Yet since ExtJS auto-generates ids which are not guaranteed to stay the same, you cannot [...]]]></description>
			<content:encoded><![CDATA[<p>Automation testing of UI interfaces is essential in any big project, but it is difficult to achieve this for user interfaces built with ExtJS. Selenium records user actions, by clicks on elements, and memorizes the ids of the selected elements. Yet since ExtJS auto-generates ids which are not guaranteed to stay the same, you cannot rely on this. The same problem is when you simply add a small change (add a label, etc), so the generation (if you relied on it to be the same) will totally change and the automated tests will be ruined.
</p>
<p>
Instead, <b>Selenium tests for ExtJS should rely on CSS selectors</b>. For every button, grid, label, tab or any significant UI element, I simply chose to use the <strong>cls</strong> attribute and specify a CSS class.</p>
<pre class="prettyprint">
new Ext.Button({
    text: 'Ok',
    cls: 'seleniumOkButton', //can have more classes, separated by space
    scope: this,
    handler: function(){ ... }
})
</pre>
<p>This is how a basic button that is used in automation testing looks like. And I use the following XPath selector in Selenium:</p>
<pre class="prettyprint">
//table[contains(@class,'seleniumOkButton')]
</pre>
</p>
<p>Happy automated testing!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jslog.com/testing-extjs-with-selenium-automating-ui-tests/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Function arguments</title>
		<link>http://www.jslog.com/function-arguments</link>
		<comments>http://www.jslog.com/function-arguments#comments</comments>
		<pubDate>Mon, 31 May 2010 09:32:17 +0000</pubDate>
		<dc:creator>radu</dc:creator>
				<category><![CDATA[functions]]></category>
		<category><![CDATA[quick tips]]></category>
		<category><![CDATA[utilities]]></category>
		<category><![CDATA[arguments]]></category>
		<category><![CDATA[array]]></category>
		<category><![CDATA[prototype]]></category>

		<guid isPermaLink="false">http://www.jslog.com/?p=209</guid>
		<description><![CDATA[Well, if you are programming in JavaScript for a while, you are familiar with the arguments &#8216;array&#8217; which gives you access to function arguments by index, without the need of argument names. And if you are programming JavaScript for a bit longer while, you will know that arguments is not even a normal array. It [...]]]></description>
			<content:encoded><![CDATA[<p>Well, if you are programming in JavaScript for a while, you are familiar with the <b>arguments</b> &#8216;array&#8217; which gives you access to function arguments by index, without the need of argument names. And if you are programming JavaScript for a bit longer while, you will know that <b>arguments</b> is not even a normal array. It does not have any methods of an array. You can just use it to access items by index and also access it&#8217;s <b>length</b> property. That&#8217;s all. What if you want to make a copy of the array? What if you want to push or pop items? Well&#8230; you have some work to do&#8230; OR &#8230;</p>
<p>Or do something smart. Like call the slice method from Array.prototype on the arguments, something like:</p>
<pre class="prettyprint">
//this makes a copy of the arguments and returns a true array
Array.prototype.slice.call(arguments, 0) 

//pushes the value '5' in the arguments
Array.prototype.push(arguments, 5)
//this is not valid: arguments.push(5)
</pre>
<p>Well, maybe most of you expert JavaScript programmers have thought about this, and this is not a news. But, let&#8217;s share from our experience to the more novice/newcomers to JavaScript and show them the beauty of this language! </p>
<p>JavaScript is a great language! It&#8217;s expressive! It&#8217;s powerful! That&#8217;s why we love JavaScript.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jslog.com/function-arguments/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Window &#8216;tofront&#8217; and &#8216;toback&#8217; events</title>
		<link>http://www.jslog.com/window-tofront-and-toback-events</link>
		<comments>http://www.jslog.com/window-tofront-and-toback-events#comments</comments>
		<pubDate>Wed, 26 May 2010 10:07:51 +0000</pubDate>
		<dc:creator>radu</dc:creator>
				<category><![CDATA[ExtJS Components]]></category>
		<category><![CDATA[events]]></category>
		<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[overriding]]></category>
		<category><![CDATA[window]]></category>

		<guid isPermaLink="false">http://www.jslog.com/?p=200</guid>
		<description><![CDATA[I like ExtJs and the way it is so modular. This time I needed to have something very easy, which is not implemented by default in Ext, so I rolled my own. I needed windows to fire &#8216;tofront&#8217; and &#8216;toback&#8217; events. In an app I am working on, the user can have quite many windows [...]]]></description>
			<content:encoded><![CDATA[<p>I like ExtJs and the way it is so modular. This time I needed to have something very easy, which is not implemented by default in Ext, so I rolled my own. I needed windows to fire &#8216;tofront&#8217; and &#8216;toback&#8217; events. In an app I am working on, the user can have quite many windows opened and I needed to know programatically when a window comes to front (and to back). The approach was to override the <strong>toFront</strong> method in <strong>Ext.Window</strong>. Below you can see the code, with some basic comments.</p>
<p><b>NOTE</b>: I know there are the <b>activate</b> and <b>deactivate</b> events on every window, but when a window triggers the &#8216;deactivate&#8217; event, <b>Ext.WindowMgr.getActive()</b> still returns it as the active window. This is why I needed the &#8216;tofront&#8217; and &#8216;toback&#8217; events.</p>
<pre class="prettyprint">
(function(){

    // get the previous implementation of the toFront method
    var prevToFront = Ext.Window.prototype.toFront;

    Ext.override(Ext.Window, {

        toFront: function(){

            //get the window manager of this window, or Ext.WindowMgr if it doesn't have one
            var manager = (this.manager || Ext.WindowMgr);
            //get the window which is currently to front
            var activeWindow = manager.getActive();

            prevToFront.apply(this, arguments);

            //only fire tofront and toback events if the current window was not already to front
            if (this != activeWindow){
                this.fireEvent('tofront');
            }

            if (activeWindow){
                activeWindow.fireEvent('toback');
            }

            return this;
        }

    });
})();
</pre>
<p>I needed to run code both <strong>before</strong> and <strong>after</strong> the default implementation of the <strong>toFront</strong> method. If I didn&#8217;t need this, an easier approach would have been to use createSequence:</p>
<pre class="prettyprint">
Ext.override(Ext.Window,{
       toFront: Ext.Window.prototype.toFront.createSequence(function(){
             // code here.
       })
})
</pre>
<p>Nice ExtJs! Go try it!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jslog.com/window-tofront-and-toback-events/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ExtJS TextField that cannot start with whitespace</title>
		<link>http://www.jslog.com/extjs-textfield-that-cannot-start-with-whitespace</link>
		<comments>http://www.jslog.com/extjs-textfield-that-cannot-start-with-whitespace#comments</comments>
		<pubDate>Thu, 01 Apr 2010 11:43:32 +0000</pubDate>
		<dc:creator>radu</dc:creator>
				<category><![CDATA[ExtJS Components]]></category>
		<category><![CDATA[utilities]]></category>
		<category><![CDATA[overriding]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[textfield]]></category>

		<guid isPermaLink="false">http://www.jslog.com/?p=192</guid>
		<description><![CDATA[Recently I needed a text field in ExtJS that doesn&#8217;t allow user input to start with space. So I thought it would be useful for others as well. I chose to override the original Ext.form.TextField and make all the textfields in the application have this behaviour.
Here is the code for this:

(function(){
    //put [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I needed a text field in ExtJS that doesn&#8217;t allow user input to start with space. So I thought it would be useful for others as well. I chose to override the original Ext.form.TextField and make all the textfields in the application have this behaviour.</p>
<p>Here is the code for this:</p>
<pre class="prettyprint">
(function(){
    //put all the code in an anonymous function to hide the local variables from the global namespace

    //methods that will be overriden - keep the original
    var originalFilterKeys = Ext.form.TextField.prototype.filterKeys;
    var originalInitEvents = Ext.form.TextField.prototype.initEvents;

    Ext.override(Ext.form.TextField,{

        // private
        filterKeys : function(e){
            var res = originalFilterKeys.apply(this, arguments);

            var cc = String.fromCharCode(e.getCharCode());

            //if the caret is in the first position, and the typed character
            //was space, stop the event
            if (cc == ' ' &#038;&#038; (this.getCaretPos(this.el.dom) == 0) ){
                e.stopEvent()
            }

            //the case when the text is selected and the user presses space
            if (cc == ' ' &#038;&#038; this.getSelectedText() == this.getValue()){
                //clear value of the text field
                e.stopEvent();
                this.setValue('');
            }

            return res; //return original result
        },

        /**
         * @return String the selected text or '' if none
         */
        getSelectedText: function(){
            var dom = this.el.dom;
            var selected = (dom.value).substring(this.getSelectionStart(), this.getSelectionEnd());

            return selected;
        },

        getSelectionStart: function(){
            var input = this.el.dom
            if (input.setSelectionRange){ // Mozilla
                return input.selectionStart;
            } else if (document.selection) { // IE
                var pos, textRange = document.selection.createRange().duplicate();

                if (textRange.text.length > 0) { // selection is not collapsed
                    pos = input.value.indexOf(textRange.text);
                } else { // selection is collapsed
                    pos = 0;
                }

                return pos;
            }
            return 0;
        },

        getSelectionEnd: function() {
            var input = this.el.dom
            if (input.setSelectionRange){ // Mozilla
                return input.selectionEnd;
            } else if (document.selection) { // IE
                var selectedRange = document.selection.createRange().duplicate();
                if (selectedRange.text.length > 0){
                    selectedRange.moveStart("character", -input.value.length);
                }
                return selectedRange.text.length;
            }

            return 0;
        },

        /**
         * @return int - the current index of the caret
         */
        getCaretPos: function() {
            var input = this.el.dom;
            var pos = 0;
            if (input.createTextRange) {
                var range = document.selection.createRange().duplicate();
                range.moveStart('textedit',-1);
                pos = range.text.length;
            } else if (input.setSelectionRange) {
                pos = input.selectionEnd;
            }
            return pos;
        },

        // private
        initEvents : function(){
            this.maskRe = new RegExp('.*'); //I just needed a reg exp to match all characters
            //as filterKeys method is only called if the textfield has a 'maskRe' property
            return originalInitEvents.call(this);
        }
    })

})()
</pre>
<p>Hope it helps! Enjoy the code. If you have any questions, let me know!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jslog.com/extjs-textfield-that-cannot-start-with-whitespace/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Google Closure Advanced Compilation</title>
		<link>http://www.jslog.com/google-closure-advanced-compilation</link>
		<comments>http://www.jslog.com/google-closure-advanced-compilation#comments</comments>
		<pubDate>Sun, 21 Mar 2010 21:24:10 +0000</pubDate>
		<dc:creator>radu</dc:creator>
				<category><![CDATA[Google Closure]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[utilities]]></category>
		<category><![CDATA[js code optimization]]></category>
		<category><![CDATA[obfuscation]]></category>

		<guid isPermaLink="false">http://www.jslog.com/?p=171</guid>
		<description><![CDATA[As I have promised in this post, I am giving a review of the ADVANCED_OPTIMIZATIONS option in Google Closure JavaScript Compiler.
Beyond simply shortening variable names, Closure Compiler with ADVANCED_OPTIMIZATIONS, does three other important steps:

aggresive renaming &#8211; not only renaming local variables and functions, but it renames GLOBAL variables and functions. In this way, it can [...]]]></description>
			<content:encoded><![CDATA[<p>As I have promised in <a href="http://www.jslog.com/using-google-closure-compiler">this</a> post, I am giving a review of the <code>ADVANCED_OPTIMIZATIONS</code> option in Google Closure JavaScript Compiler.</p>
<p>Beyond simply shortening variable names, Closure Compiler with ADVANCED_OPTIMIZATIONS, does three other important steps:</p>
<ul>
<li><b>aggresive renaming</b> &#8211; not only renaming local variables and functions, but it renames GLOBAL variables and functions. In this way, it can ruin your public API</li>
<li><b>dead code removal</b> &#8211; it removes functions you are not using and segments of unreachable code. This can be fine for some apps, but it is definitely risky for JavaScript libraries, that expose some functions which are supposed to be called only by client code.</li>
<li><b>function inlining</b> &#8211; inserting the function&#8217;s body instead of the function call, where appropriate</li>
</ul>
<p>So it is true that without some additional work, the ADVANCED_OPTIMIZATIONS option will just ruin your code and your public API. Of course the solutions are at hand, but the question is if they worth the effort.
</p>
<p><span id="more-171"></span></p>
<p>
<h3>Keep your public API</h3>
<p>If you provide ONLY the code below to Google Compiler, it produces <b>empty</b> output:</p>
<pre class="prettyprint">
function hello(name){
    alert("Hello " + name);
}
</pre>
<p>What? Empty output? Well&#8230; yes, as you never call your function. Instead, for the next code: </p>
<pre class="prettyprint">
function hello(name){
    alert("Hello " + name);
}
hello('jslog');
</pre>
<p>it produces the following output:</p>
<pre class="prettyprint">
alert("Hello jslog");
</pre>
<p>This is smart! But we want to preserve our API (by the way, in the tutorial for Google Closure Compiler Advanced Optimizations, <a href="http://code.google.com/closure/compiler/docs/api-tutorial3.html">Google says on this page</a> that the <code>hello</code> function is preserved, while it is NOT &#8211; see section <a href="http://code.google.com/closure/compiler/docs/api-tutorial3.html#removal">Removal of code you want to keep</a> and try the code online at <a href="http://closure-compiler.appspot.com/home">Closure Compiler UI Tool</a>)
</p>
<p>
So if the <code>hello</code> method above would be part of the public API, it would break third parties using it. Google proposes a solution for this: export the public objects/functions into the global namespace using the <code>window</code> object:</p>
<pre class="prettyprint">
function hello(name){
    alert("Hello " + name);
}
hello('jslog');
window['hello'] = hello;

//and the output is:
function a(b){alert("Hello "+b)}a("jslog");window.hello=a;
//so the hello function is kept as a property on the global window object
</pre>
<p>Instead, if you use:</p>
<pre class="prettyprint">
window.hello = hello;
</pre>
<p>you get </p>
<pre class="prettyprint">
function b(c){alert("Hello "+c)}b("jslog");window.a=b;
</pre>
<p>which is surely not what you want. So make sure you use the <code>window['public_name']</code> notation. You should also standardize the way you access properties in your objects, either using the array notation, or the dotted notation, otherwise the compiler could be mislead by a mix of the two. But sometimes we just need to use both, as properties may be automatically generated at runtime.
</p>
<p>Other problems with the <b>Google Closure Compiler</b> <code>ADVANCED_OPTIMIZATIONS</code> are separately compiling blocks of code with dependencies to external JavaScript. The solution for this is </p>
<ul>
<li>using either <b>exports</b> like the above or with the <code>goog.exportSymbol()</code> or</li>
<li>using extern files specifically provided as a compilation option</li>
</ul>
<p>In any case, I think this is just a bit too clumsy. </p>
<p>Moreover, having a class and export all its properties/functions is quite a job to to if your app is already a large one. Just have a short example:</p>
<pre class="prettyprint">
MyClass = function(name) {
  this.myName = name;
};
MyClass.prototype.myMethod = function() {
  alert(this.myName);
};
window['MyClass'] = MyClass; // <-- Constructor
MyClass.prototype['myMethod'] = MyClass.prototype.myMethod; <-- export mechanism

//the above compiles to
MyClass=function(a){this.b=a};MyClass.prototype.a=function(){alert(this.b)};window.MyClass=MyClass;MyClass.prototype.myMethod=MyClass.prototype.a;
</pre>
</p>
<p>
<h3>Conclusions</h3>
<p>After this short overview of the <code>ADVANCED_OPTIMIZATIONS</code> flag, I really think most people won't need it. If you already have a large library, having it compiled with advanced optimizations would be a total nightmare, as it would require a review of all public methods and properties and additional work for each. And the gain? Just a few kilobytes. I have tried compiling <b>ExtJS Core with advanced optimizations and got aprox 62 KB</b>, while with <b>simple optimizations it is 74 KB</b>. Not very well for the amount of effort it would require, in my opinion. </p>
<p>But if you still think advanced optimizations is for you, you are probably wanting to optimize a lot, and you should first start seaching for other ways to optimize - first, make sure you combine all your js code into one file. It's better to have one js file of 100KB rather than have 10 files each of 5 KB. So make sure you are doing every other possible optimization before moving to the advanced optimizations flag.</p>
<p>After all, it's up to you to decide if it's worth the effort!
</p>
<p>PS: You can follow me on twitter <a href="http://twitter.com/extjslog">@extjslog</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jslog.com/google-closure-advanced-compilation/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Follow me on twitter</title>
		<link>http://www.jslog.com/follow-me-on-twitter</link>
		<comments>http://www.jslog.com/follow-me-on-twitter#comments</comments>
		<pubDate>Thu, 11 Mar 2010 07:35:45 +0000</pubDate>
		<dc:creator>radu</dc:creator>
				<category><![CDATA[News]]></category>

		<guid isPermaLink="false">http://www.jslog.com/?p=182</guid>
		<description><![CDATA[Follow me on twitter @extjslog. I will be tweeting on JavaScript, ExtJS, jQuery and other web 2.0 things.
PS: I am preparing the promised post on Google Closure Compiler ADVANCED_OPTIMIZATIONS.
]]></description>
			<content:encoded><![CDATA[<p>Follow me on twitter <a href="http://twitter.com/extjslog">@extjslog</a>. I will be tweeting on JavaScript, ExtJS, jQuery and other web 2.0 things.</p>
<p>PS: I am preparing the promised post on Google Closure Compiler ADVANCED_OPTIMIZATIONS.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jslog.com/follow-me-on-twitter/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick tip: use &#8220;scope&#8221; config option</title>
		<link>http://www.jslog.com/use-scope-config-option-quick-tip</link>
		<comments>http://www.jslog.com/use-scope-config-option-quick-tip#comments</comments>
		<pubDate>Wed, 24 Feb 2010 20:53:22 +0000</pubDate>
		<dc:creator>radu</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[quick tips]]></category>
		<category><![CDATA[ExtJS events]]></category>
		<category><![CDATA[function scope]]></category>
		<category><![CDATA[functions]]></category>

		<guid isPermaLink="false">http://www.jslog.com/?p=159</guid>
		<description><![CDATA[You should make use of the scope config option in components
.

in Ajax calls
var MyPanel = Ext.extend(Ext.Panel, {
    doSave: function(){
	Ext.Ajax.request({
	    url: 'your_url',
	    params: ....
	    success: function(response){
		response = Ext.decode(response.responseText);
		this.onSuccess(response)
	    },
	    scope: this //the scope in which the success callback [...]]]></description>
			<content:encoded><![CDATA[<h2>You should make use of the <strong>scope</strong> config option in components</h2>
<p>.</p>
<ul>
<li>in Ajax calls
<pre class="prettyprint">var MyPanel = Ext.extend(Ext.Panel, {
    doSave: function(){
	Ext.Ajax.request({
	    url: 'your_url',
	    params: ....
	    success: function(response){
		response = Ext.decode(response.responseText);
		this.onSuccess(response)
	    },
	    scope: this //the scope in which the success callback is called
	})
    },
    onSuccess: function(){ .... }
}</pre>
<p>In this example, specifying the scope is very useful. By default, the success callback on Ajax calls is executed with the scope being the browser &#8216;window&#8217; object, which is not very useful. In the code above, we execute the success callback in the &#8216;this&#8217; scope, &#8216;this&#8217; being the instance of <b>MyPanel</b> which executes the <b>doSave</b> method. This is why we can safely call <b><code>this.onSuccess(response)</code></b>, as &#8216;this&#8217; is a MyPanel object, which has the onSuccess method.<br /> I find the scope config property very useful, so even though specifying the scope of a function is very natural in JavaScript, the fact that ExtJS made it so natural and easy deserves being noted. Well done ExtJS!
</li>
<li>in Buttons
<pre class="prettyprint">{
    xtype: 'button',
    text: 'Save',
    handler: function(){
	//do something on pressing the button
    },
    scope: myScope //scope of the handler
}</pre>
</li>
<li>with Stores
<pre class="prettyprint">new Ext.data.Store({
    //...other config options
    autoLoad: {
	callback: function(){ ... },
	scope: aScope //for the callback function after loading the store
    }
})</pre>
</li>
<li>in listeners
<pre class="prettyprint">new Ext.Panel({
    listeners: {
	scope: window, //the scope of all listeners in this config
	show: function(){ ... },
	afterrender: function(){ ...this is 'window' }
    }
})</pre>
</li>
<li>in <a href='http://www.extjs.com/deploy/dev/docs/?class=Ext.Action'>actions</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.jslog.com/use-scope-config-option-quick-tip/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick tips on ExtJS and JavaScript</title>
		<link>http://www.jslog.com/quick-tips-on-extjs-and-javascript</link>
		<comments>http://www.jslog.com/quick-tips-on-extjs-and-javascript#comments</comments>
		<pubDate>Thu, 18 Feb 2010 19:45:04 +0000</pubDate>
		<dc:creator>radu</dc:creator>
				<category><![CDATA[ExtJS Components]]></category>
		<category><![CDATA[quick tips]]></category>
		<category><![CDATA[utilities]]></category>
		<category><![CDATA[ExtJS]]></category>

		<guid isPermaLink="false">http://www.jslog.com/?p=147</guid>
		<description><![CDATA[Tips on JavaScript and ExtJS: using the ExtJS ref config option on panels and other components.]]></description>
			<content:encoded><![CDATA[<p>I will usually try to post a major and well documented <b>article</b> on this blog <b>every week</b>. But during the week, I will also have smaller tips, just a few lines short, about small things/improvements that can make your life better using JavaScript and ExtJS.</p>
<p>Here is the first one:</p>
<p>
<h2>Use the <b>ref</b> config option in ExtJS</h2>
<p><span id="more-147"></span></p>
<pre class="prettyprint">

var win = new Ext.Window({
    layout: 'fit',
    width: 300,
    height: 200,
    title: 'my window',
    items: [{
            <b>ref</b>: 'panel',
            xtype: 'panel', layout: 'form',
            frame: true, defaults: {xtype: 'textfield'},
            items: [
                {<b>ref</b>: '../nameField', fieldLabel: 'Name'},
                {<b>ref</b>: 'age', fieldLabel: 'Age'}
            ]
    }]
});

win.show();
//so now, with the above ref options, you can do:
win.nameField.setValue('name here');
win.panel.age.setValue(20);
</pre>
<p>Notice in the example above that setting ref <b>age</b> config puts a reference &#8220;age&#8221; in the panel containing the text field, while puting a ref <b>../nameField</b> sets a &#8220;nameField&#8221; reference on the component one more level up, that is, the containing window. In this way, you can navigate many levels, each &#8220;/&#8221; navigating one more level upwards.<br />
In this next example, I introduce another level of nesting, by artificially adding another panel, in order to illustrate the navigation with multiple slashes.</p>
<pre class="prettyprint">

var win = new Ext.Window({
    layout: 'fit',
    width: 300,
    height: 200,
    title: 'my window',
    items: [{
            ref: 'panel',
            xtype: 'panel', layout: 'form',
            frame: true, defaults: {xtype: 'textfield'},
            items: [

                {
                     xtype: 'panel', fieldLabel: 'Name', layout: 'fit',
                     items: [{xtype: 'textfield', ref: '//nameField'}]
                     //notice above, two slashes, which puts
                     //nameField reference on the containing window (two levels)
                },
                {ref: 'age', fieldLabel: 'Age'}
            ]
    }]
});

win.show();
win.nameField.setValue('name here');
win.panel.age.setValue(20);
</pre>
<p>Please see <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Component&#038;member=ref">Ext.Component &#8220;ref&#8221; reference</a> from the Ext API.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jslog.com/quick-tips-on-extjs-and-javascript/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;Live&#8221; event in ExtJS</title>
		<link>http://www.jslog.com/live-event-in-extjs</link>
		<comments>http://www.jslog.com/live-event-in-extjs#comments</comments>
		<pubDate>Mon, 08 Feb 2010 21:45:38 +0000</pubDate>
		<dc:creator>radu</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[utilities]]></category>
		<category><![CDATA[ExtJS events]]></category>
		<category><![CDATA[live event]]></category>

		<guid isPermaLink="false">http://www.jslog.com/?p=121</guid>
		<description><![CDATA[A quick intro to the live event in ExtJS, using delegates. It is similar to the jQuery live event, but much more powerful. This article provides a quick and useful insight into it.]]></description>
			<content:encoded><![CDATA[<p>jQuery is a nice JavaScript library, we all know it. But not many of us are familiar with ExtJS. As I have now been working with both, I needed some time to adapt to the change from jQuery to ExtJS and rediscover how things are done the easiest way with both libraries.</p>
<p>One of the things I really liked about jQuery was the <a href="http://api.jquery.com/live/">&#8220;live&#8221; event</a>.<br />
The jQuery documentation explains it very straightforward: </p>
<blockquote><p>[with a live event you] <b>attach a handler to the event for all elements which match the current selector, now or in the future</b></p></blockquote>
<p><span id="more-121"></span><br />
I wanted to have something similar in ExtJS, and, no surprise, Ext has it, but it&#8217;s not very obvious for a newcomer.</p>
<p>
In jQuery you can easily say:</p>
<pre class="prettyprint">
$('p').live('click', function(){
    // do something on paragraph click
})
</pre>
<p>As it turns out, the &#8220;live&#8221; event in ExtJS is even more powerful and customizable.<br />
In ExtJS, the equivalent of the above is:</p>
<pre class="prettyprint">
Ext.getBody().on('click', function(event, target){
        // do something on paragraph click
    }, null, {
        delegate: 'p'
    })
</pre>
</p>
<p>
For more options and configuration parameters, see <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Element" target="_blank">Ext.Element::addListener API</a> (Ext.Element.on() is a shorthand for the Ext.Element.addListener() method)
</p>
<p>As can easily be seen, you can add live events not only to the <b>body</b> element, but to any element.</p>
<pre class="prettyprint">
Ext.get('header').on('click', function(){
           //only handle anchors with the "menu" css class,
           //which are in the element with id="header"
     }, this /* the scope */, {
         delegate: 'a.menu'
    })
</pre>
<p>You can further distinguish between the target elements in the event callback</p>
<pre class="prettyprint">
Ext.get('header').on('click', function(e,target){
         //an anchor with class="menu" has been clicked in
         //an element with id="header"

         // Ext.Element.is(selector) tests the current
         // item for the given selector

         // target is of type HtmlElement, not Ext.Element,
         // so wrap in Ext.get()
         if (Ext.get(target).is('.item')){
             // do smth special with anchors with "item" class
         }
     }, this /* the scope */, {
         delegate: 'a.menu'
    })
</pre>
</p>
<p>You can see a <a href="http://www.jslog.com/demos/live_event.html" target="_blank">live demo here</a>. Thanks!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jslog.com/live-event-in-extjs/feed</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Google won&#8217;t support IE6</title>
		<link>http://www.jslog.com/google-wont-support-ie6</link>
		<comments>http://www.jslog.com/google-wont-support-ie6#comments</comments>
		<pubDate>Sat, 30 Jan 2010 09:09:53 +0000</pubDate>
		<dc:creator>radu</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[browsers]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[ie6]]></category>

		<guid isPermaLink="false">http://www.jslog.com/?p=123</guid>
		<description><![CDATA[This is a good news for all web developers. As I am using Google Apps, I have just received an email from Google stating that they will not support IE6 any longer in their apps. Well&#8230; finally a big player had the courage to make IE6 history! To give you a bit more detail about [...]]]></description>
			<content:encoded><![CDATA[<p>This is a good news for all web developers. As I am using Google Apps, I have just received an email from <strong>Google</strong> stating that they <strong>will not support IE6</strong> any longer in their apps. Well&#8230; finally a big player had the courage to make IE6 history! To give you a bit more detail about what Google is going to do, here is a quote from their email:</p>
<blockquote><p>Over the course of 2010, we will be phasing out support for Microsoft Internet Explorer 6.0 as well as other older browsers that are not supported by their own manufacturers.</p>
<p>We plan to begin phasing out support of these older browsers on the Google Docs suite and the Google Sites editor on March 1, 2010.  After that point, certain functionality within these applications may have higher latency and may not work correctly in these older browsers. Later in 2010, we will start to phase out support for these browsers for Google Mail and Google Calendar.</p>
<p>Google Apps will continue to support Internet Explorer 7.0 and above, Firefox 3.0 and above, Google Chrome 4.0 and above, and Safari 3.0 and above.</p></blockquote>
<p>We will certainly not miss you, IE6!<br />
Waiting for comments from happy developers!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jslog.com/google-wont-support-ie6/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
