<?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>Fusioncube &#187; javascript</title>
	<atom:link href="http://www.fusioncube.net/index.php/category/javascript/feed" rel="self" type="application/rss+xml" />
	<link>http://www.fusioncube.net</link>
	<description>The online journey of a technophile, by Steve Brownlee</description>
	<lastBuildDate>Tue, 31 Aug 2010 13:34:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Sencha ExtJS 3.3 Beta Announced</title>
		<link>http://www.fusioncube.net/index.php/sencha-extjs-3-3-beta-announced</link>
		<comments>http://www.fusioncube.net/index.php/sencha-extjs-3-3-beta-announced#comments</comments>
		<pubDate>Fri, 30 Jul 2010 13:08:08 +0000</pubDate>
		<dc:creator>Steve Brownlee</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Sencha]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[actioncolumn]]></category>
		<category><![CDATA[beta]]></category>
		<category><![CDATA[calendar]]></category>
		<category><![CDATA[event handler]]></category>
		<category><![CDATA[pivotgrid]]></category>

		<guid isPermaLink="false">http://www.fusioncube.net/index.php/sencha-extjs-3-3-beta-announced</guid>
		<description><![CDATA[I was browsing around the Sencha site this morning and saw that they announced the beta release of 3.3 which includes two major new components: PivotGrids Calendar While those will garner much attention, the ugly stepchild mentioned at the bottom of the press release is also very cool. The ActionColumn allows you to put icons [...]]]></description>
			<content:encoded><![CDATA[<p>I was browsing around the Sencha site this morning and saw that they <a href="http://www.sencha.com/blog/2010/07/28/announcing-ext-js-3-3-beta-pivotgrids-calendars-and-more/" target="_blank">announced the beta release of 3.3</a> which includes two major new components: </p>
<ul>
<li><a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/pivotgrid/simple.html" target="_blank">PivotGrids</a> </li>
<li><a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/calendar/index.html" target="_blank">Calendar</a> </li>
</ul>
<p>While those will garner much attention, the ugly stepchild mentioned at the bottom of the <a href="http://www.sencha.com/blog/2010/07/28/announcing-ext-js-3-3-beta-pivotgrids-calendars-and-more/" target="_blank">press release</a> is also very cool. The <a href="http://www.sencha.com/deploy/ext-3.3-beta1-6976/examples/grid/array-grid.html" target="_blank">ActionColumn</a> allows you to put icons inside a grid with an accompanying event handler.</p>
<p>This is something we use quite a bit in Flex, and its addition to ExtJS is exciting.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fusioncube.net/index.php/sencha-extjs-3-3-beta-announced/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sencha ExtJS: Allow users to find without searching in a ComboBox</title>
		<link>http://www.fusioncube.net/index.php/sencha-extjs-allow-users-to-find-without-searching-in-a-combobox</link>
		<comments>http://www.fusioncube.net/index.php/sencha-extjs-allow-users-to-find-without-searching-in-a-combobox#comments</comments>
		<pubDate>Wed, 21 Jul 2010 14:23:10 +0000</pubDate>
		<dc:creator>Steve Brownlee</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[cancel query]]></category>
		<category><![CDATA[ComboBox]]></category>
		<category><![CDATA[enableKeyEvents]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[keypress]]></category>

		<guid isPermaLink="false">http://www.fusioncube.net/?p=929</guid>
		<description><![CDATA[In an ExtJS ComboBox, it’s fairly easy to implement a search feature where given the user’s entry, you can return a list of possible matches. I outline this mechanism in Sencha ExtJS: Simple Autocomplete Example. However, recent user feedback was, “If I know the unit I’m looking for, why can’t I just type it in [...]]]></description>
			<content:encoded><![CDATA[<p>In an ExtJS ComboBox, it’s fairly easy to implement a search feature where given the user’s entry, you can return a list of possible matches. I outline this mechanism in <a href="http://www.fusioncube.net/index.php/ext-simple-autocomplete-example" target="_blank">Sencha ExtJS: Simple Autocomplete Example</a>.</p>
<p>However, recent user feedback was, “If I know the unit I’m looking for, why can’t I just type it in and hit ENTER and skip the whole search feature to find the one I need?”</p>
<p>Doh.</p>
<p>Yes, I was making the users wait – even if for 1 second – for a list of possible matches to be displayed, when 90% of the time they know which one they want to open.</p>
<p>Luckily, I was able to briefly look at the documentation for ComboBox and find out how to accomplish this. You need to set the enableKeyEvents config property to true, and then hook into the keypress event and check for the user pressing the ENTER (or RETURN) key. When the ENTER key is pressed, prevent the query from being executed, and open the item the user entered.</p>
<pre class="code"><code>var WidgetSearch = new Ext.form.ComboBox({
    minChars:           3,
    loadingText:        '',
    itemSelector:       'div.search-item',
    triggerClass:       'x-form-search-trigger',
    applyTo:            'search-field',
    <strong>enableKeyEvents:  true,</strong>
    store: new Ext.data.Store({
        proxy: new Ext.data.HttpProxy({url: 'widgets.cfm'}),
        reader: new Ext.data.JsonReader({
            root:           'data',
            totalProperty:  'recordcount'
        }, [
            {name: 'widget_number', type: 'string'},
            {name: 'widget_name', type: 'string'}
        ])
    }),
    tpl: new Ext.XTemplate(
        '&lt;tpl for="."&gt;&lt;div class="search-item"&gt;',
            '{widget_number} - {widget_name}',
        '&lt;/div&gt;&lt;/tpl&gt;'
    ),
    onSelect: function(record){
        document.location.href = 'displayWidgetDetails.cfm&amp;amp;wid=' + record.data.widget_number;
    },
    listeners:
    {
        // Hook into the keypress event to detect if the user pressed the ENTER key
        keypress: function(comboBox, e){
            if (e.getCharCode() == e.ENTER) {
                // Prevent the default query action since the user
                // believes she has entered a proper widget number
                comboBox.on('beforequery', function(q){q.cancel=true;},this);

                // Redirect browser to widget detail view
                document.location.href = 'displayWidgetDetails.cfm&amp;amp;wid=' + WidgetSearch.getValue();
            }
        }
    }
});</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.fusioncube.net/index.php/sencha-extjs-allow-users-to-find-without-searching-in-a-combobox/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Managing dirty rows in a Sencha ExtJS EditorGridPanel</title>
		<link>http://www.fusioncube.net/index.php/managing-dirty-rows-in-a-sencha-extjs-editorgridpanel</link>
		<comments>http://www.fusioncube.net/index.php/managing-dirty-rows-in-a-sencha-extjs-editorgridpanel#comments</comments>
		<pubDate>Tue, 20 Jul 2010 20:07:21 +0000</pubDate>
		<dc:creator>Steve Brownlee</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[datagrid]]></category>
		<category><![CDATA[dirty data]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://www.fusioncube.net/index.php/managing-dirty-rows-in-a-sencha-extjs-editorgridpanel</guid>
		<description><![CDATA[A Sencha ExtJS EditorGridPanel automatically visually marks a cell as dirty when a user modifies the value, but that’s it. If you want to know if a row is dirty and take an action based upon that knowledge, you’re on your own. Since I needed this functionality, I took a stab at it today, and [...]]]></description>
			<content:encoded><![CDATA[<p>A Sencha ExtJS EditorGridPanel automatically visually marks a cell as dirty when a user modifies the value, but that’s it. If you want to know if a row is dirty and take an action based upon that knowledge, you’re on your own.</p>
<p>Since I needed this functionality, I took a stab at it today, and here’s my simplistic example of how to do it.</p>
<p>First, I create a global variable named editedRow which will get updated when the afteredit event is fired on the GridPanel.</p>
<pre class="code"><code>var editedRow;

var AutoGrid = new Ext.grid.EditorGridPanel({
    // Properties clipped for article;
    // view example for full code
});

// After any field is edited, make the row dirty
AutoGrid.on('afteredit', function(){
    if (!editedRow){
        editedRow = AutoGrid.getSelectionModel().getSelections();
    }
}, this);</code></pre>
<p>Now that I’ve stored which row is dirty, every time the user clicks on another cell, I check a) there is a dirty row, and b) if the active row is the dirty row.</p>
<pre class="code"><code>// Any time the user mouse downs on a cell,
// check to see if there are any dirty rows
AutoGrid.on('cellmousedown', checkForChanges, this);

function checkForChanges(){
    if (!editedRow){
        return true;      // No dirty rows
    } else {
        var selectedRow = AutoGrid.getSelectionModel().getSelections();
        var selectedRecord = selectedRow[0].data;
        var editedRecord;

        editedRecord = editedRow[0].data;

        if (selectedRecord.model != editedRecord.model){
            // Alert the user to save changes
            // See example for full code
        }
    }
}</code></pre>
<p>Then if there is a dirty row, I can prompt the user and ask it to save its changes before editing another row.</p>
<p><a href="http://www.fusioncube.net/examples/dirtyRow.html" target="_blank">View Dirty Row Example</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fusioncube.net/index.php/managing-dirty-rows-in-a-sencha-extjs-editorgridpanel/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sencha ExtJS ComboBox.selectedValue() equivalent for DataGrid</title>
		<link>http://www.fusioncube.net/index.php/sencha-extjs-combobox-selectedvalue-equivalent-for-datagrid</link>
		<comments>http://www.fusioncube.net/index.php/sencha-extjs-combobox-selectedvalue-equivalent-for-datagrid#comments</comments>
		<pubDate>Tue, 20 Jul 2010 15:39:30 +0000</pubDate>
		<dc:creator>Steve Brownlee</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Sencha]]></category>
		<category><![CDATA[ComboBox]]></category>
		<category><![CDATA[datagrid]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[renderer]]></category>
		<category><![CDATA[selectedValue]]></category>

		<guid isPermaLink="false">http://www.fusioncube.net/index.php/sencha-extjs-combobox-selectedvalue-equivalent-for-datagrid</guid>
		<description><![CDATA[Man this took a long time to figure out. Ok, inside a Sencha ExtJS DataGrid, I have assigned a ComboBox as the editor for one of the columns populated with its own Store of items. I’ve got a ColdFusion Component returning a query object, which is then converted into JSON with the ajaxCFC class. var [...]]]></description>
			<content:encoded><![CDATA[<p>Man this took a long time to figure out.</p>
<p>Ok, inside a Sencha ExtJS DataGrid, I have assigned a ComboBox as the editor for one of the columns populated with its own Store of items. I’ve got a ColdFusion Component returning a query object, which is then converted into JSON with the <a href="http://www.fusioncube.net/index.php/invoking-coldspring-bean-with-ajaxcfc" target="_blank">ajaxCFC</a> class.</p>
<pre class="code"><code>var ItemCode = Ext.data.Record.create([
       {name: 'item_id', type: 'int'}
       {name: 'item_code', type: 'string'}
]);

var ItemCodesStore = new Ext.data.Store({
    autoLoad:false,
    proxy: new Ext.data.MemoryProxy(),
    reader: new Ext.data.JsonReader({ root: 'data'; }, ItemCode)
});

// Snippet from ColumnModel of DataGrid
header: 'Code',
dataIndex: 'existingCode',
width: 70,
editor: new Ext.form.ComboBox({
   mode: 'local',
   displayField: 'item_code',
   valueField: 'item_id',
   store: ItemCodesStore
})
</code></pre>
<p>This is straightforward code. The column represents the <em>existingCode</em> value in the DataGrid&#8217;s store, and when the user clicks on an individual cell, a ComboBox is rendered with possible values stored in ItemCodesStore. </p>
<p>My problem is that I want the <em>item_code</em> value displayed at all times. By default, when a user selects an item from the ComboBox, the <em>item_id</em> value will be displayed, because even though I have set <em>displayField:&#8217;item_code&#8217;</em> in the ComboBox, the DataGrid has no knowledge of this, and always shows the valueField.</p>
<p>What I had to do was write a custom renderer for that column that does a search in the ItemCodes store for a matching <em>item_id</em> and return the <em>item_code</em> to be rendered instead.</p>
<pre class="code"><code>function CodeRenderer(val){
    var matching = ItemCodesStore.queryBy(
                      function(rec,id){
                         return rec.item_id == val;
                      });
    return (matching.items[0]) ? matching.items[0].data.item_code : '';
};

// Snippet from ColumnModel of DataGrid
header: 'Code',
dataIndex: 'existingCode',
width: 70,
<strong>renderer: CodeRenderer,</strong>
editor: new Ext.form.ComboBox({
   mode: 'local',
   displayField: 'item_code',
   valueField: 'item_id',
   store: ItemCodesStore
})</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.fusioncube.net/index.php/sencha-extjs-combobox-selectedvalue-equivalent-for-datagrid/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Fixing the Worst Hack of my Career</title>
		<link>http://www.fusioncube.net/index.php/fixing-the-worst-hack-of-my-career</link>
		<comments>http://www.fusioncube.net/index.php/fixing-the-worst-hack-of-my-career#comments</comments>
		<pubDate>Tue, 20 Jul 2010 13:35:42 +0000</pubDate>
		<dc:creator>Steve Brownlee</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[dom]]></category>
		<category><![CDATA[hack]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[rendering]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://www.fusioncube.net/index.php/fixing-the-worst-hack-of-my-career</guid>
		<description><![CDATA[Several years ago, I designed and developed an application whose scope was far greater than the business folks imagined. Therefore, the timeline was far more compressed than I would have liked. I cut a lot of corners in that project in order to get it out in time, but there was only one hack that [...]]]></description>
			<content:encoded><![CDATA[<p>Several years ago, I designed and developed an application whose scope was far greater than the business folks imagined. Therefore, the timeline was far more compressed than I would have liked.</p>
<p>I cut a lot of corners in that project in order to get it out in time, but there was only one hack that has haunted me since I reluctantly pushed it into production: I returned a large HTML string from an AJAX call and inserted it directly into the DOM.</p>
<p>It was far easier, at the time, to simply loop through the highly complex query structures in my class and build the HTML structure there rather than build a JSON string and use a JavaScript parsing class to build the HTML on the browser.</p>
<p>Well, in a little twist of fate, there was an update scheduled for this application; and this time I had some extra time as the release date got pushed back a couple of weeks. Using that to my advantage, I finally was able to fine-tune that entire mechanism, including:</p>
<li><font color="#444640">Passing a vastly more compressed JSON string back to the interaction layer.</font> </li>
<li><font color="#444640">Using a new HTMLRender class in JavaScript to parse the JSON, and then build and insert the HTML into the DOM.</font> </li>
<li><font color="#444640">Reduced the number of hits on the database by retrieving all information in one, massive query instead of dozens of smaller ones.</font> </li>
<li>Increased the usage of Sencha ExtJS in the layout to make it more attractive.</li>
<p><font color="#4c4c4c">All in all, this particular section of the application now executes about 70% faster, is less resource intensive on the database, and is easier to use.</font></p>
<p><font color="#4c4c4c">It’s a big monkey off my back. Not to mention that I always enjoy going back to code from previous projects and seeing how I can improve upon it since I’m always learning new tricks.</font></p>
<li>
</li>
]]></content:encoded>
			<wfw:commentRss>http://www.fusioncube.net/index.php/fixing-the-worst-hack-of-my-career/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating a Sencha ExtJS paging bar for a DataGrid</title>
		<link>http://www.fusioncube.net/index.php/creating-a-sencha-extjs-paging-bar-for-a-datagrid</link>
		<comments>http://www.fusioncube.net/index.php/creating-a-sencha-extjs-paging-bar-for-a-datagrid#comments</comments>
		<pubDate>Wed, 23 Jun 2010 15:09:15 +0000</pubDate>
		<dc:creator>Steve Brownlee</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[Sencha]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[recommended]]></category>
		<category><![CDATA[datagrid]]></category>
		<category><![CDATA[pagination]]></category>
		<category><![CDATA[pagingbar]]></category>

		<guid isPermaLink="false">http://www.fusioncube.net/index.php/creating-a-sencha-extjs-paging-bar-for-a-datagrid</guid>
		<description><![CDATA[True to my promise over the years, anytime it takes me significant mental and time resources to discover how to accomplish a development task that I think others might find useful, I will share the process. I’ve got an app in which users need access to a dataset that is larger than 10k records. Pagination [...]]]></description>
			<content:encoded><![CDATA[<p>True to my promise over the years, anytime it takes me significant mental and time resources to discover how to accomplish a development task that I think others might find useful, I will share the process.</p>
<p>I’ve got an app in which users need access to a dataset that is larger than 10k records. Pagination to the rescue (plus a search feature which I covered in my <a href="http://www.fusioncube.net/index.php/replacing-data-in-extjs-grid-store" target="_blank">Replacing data in Sencha ExtJS grid store</a> article).&#160; I’m giving the users the option of paging through the results 100 at a time if they so wish.</p>
<p>It ended up being simple to accomplish after scouring through the documentation and looking at related articles throughout the Web.</p>
<p>First you need to have a script that returns sets of 100 results. In my case, I have a ColdFusion Component that does a CFQUERY on the table. I simply pass in the number from which I want to start my resultset and it returns the next 100 rows. Convert your query to a JSON string using serializeJSON() in ColdFusion, or any method you wish.</p>
<p>Next, I created a ColdFusion page that accepts a <em>start</em> parameter – which is sent from the PagingBar object in ExtJS – and passes that along to the CFC. The resulting JSON string simply gets output.</p>
<pre class="code"><code>&lt;cfsetting enablecfoutputonly="true"&gt;

&lt;cfparam default="" name="start"&gt;

&lt;cfscript&gt;
providers = application.widget.framework.getBean('Insurance').listInsurance(startRecord=start);
writeOutput(insurers);
&lt;/cfscript&gt;

&lt;cfsetting enablecfoutputonly="false"&gt;</code></pre>
<p>Next, create a Store object with this page as its proxy, and a JsonReader to parse the results.</p>
<pre class="code"><code>var Insurer = Ext.data.Record.create([
       {name: 'col1', type: 'int'},
       {name: 'col2', type: 'string'},
       {name: 'col3', type: 'string'},
       {name: 'col4', type: 'int'}
]);

var InsurerStore = new Ext.data.Store({
    proxy: new Ext.data.HttpProxy({url: 'liveQueries/insurance.cfm'}),
    reader: new Ext.data.JsonReader({ root: 'data', totalProperty:'totalRecords' }, Insurer)
});</code></pre>
<p>Now you can create your PagingBar object with the Store object you created as its datastore.</p>
<pre class="code"><code>var PagingBar = new Ext.PagingToolbar({
    pageSize: 100,
    store: InsurerStore,
    displayInfo: true,
    displayMsg: 'Displaying topics {0} - {1} of {2}',
    emptyMsg: 'No insurers to display'
});</code></pre>
<p>Lastly, attach your PagingBar to a DataGrid object with the <em>bbar</em> property. You also have the option of performing an initial search to show the first 100 record to the user by default. To do this, just call the load() event on your Store (shown below).</p>
<pre class="code"><code>var InsurerGrid = new Ext.grid.GridPanel({
   store             : InsurerStore,
   sm                : new Ext.grid.RowSelectionModel({singleSelect:true}),
   cm                : InsurerColumnModel,
   renderTo          : 'insurer-grid',
   frame             : true,
   bbar              : PagingBar
});

InsurerStore.load({params:{start:0, limit:100}});</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.fusioncube.net/index.php/creating-a-sencha-extjs-paging-bar-for-a-datagrid/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sencha ExtJS Drag &amp; Drop Target Detection</title>
		<link>http://www.fusioncube.net/index.php/extjs-drag-drop-target-detection</link>
		<comments>http://www.fusioncube.net/index.php/extjs-drag-drop-target-detection#comments</comments>
		<pubDate>Tue, 15 Jun 2010 13:49:45 +0000</pubDate>
		<dc:creator>Steve Brownlee</dc:creator>
				<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[recommended]]></category>
		<category><![CDATA[drag and drop]]></category>
		<category><![CDATA[findRowIndex]]></category>
		<category><![CDATA[notifyDrop]]></category>
		<category><![CDATA[Sencha]]></category>
		<category><![CDATA[target element]]></category>

		<guid isPermaLink="false">http://www.fusioncube.net/index.php/extjs-drag-drop-target-detection</guid>
		<description><![CDATA[I wanted to enhance the experience on one of my applications a bit since we’re doing a release in a few weeks. I took the opportunity to implement some more ExtJS awesomeness on many of the tools inside the application, and on one in particular, users are able to create 1-1 mappings between two sets [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to enhance the experience on one of my applications a bit since we’re doing a release in a few weeks. I took the opportunity to implement some more ExtJS awesomeness on many of the tools inside the application, and on one in particular, users are able to create 1-1 mappings between two sets of data.</p>
<p>I decided to tinker around with the drag &amp; drop capabilities of ExtJS and originally had the user click a button, which created a window, into which the user could drag an item from each data set and create the mapping. It worked very well and was a much better interaction than the previous version.</p>
<p>I showed it to a colleague, and he actually thought of a way to make it better. Why not simply allow the user to click and drag an item from one grid to the item on the other grid to which she wanted to map it? Even better. However, when I started to think about the code I would need, I couldn’t think of how to determine which item in the “drop” data grid was the actual target.</p>
<p>Let’s say you have automobiles in one grid, and colors in another. You could let the user drag a color from the second grid onto a specific model of vehicle on the first, but the trick is determining onto which model the user dropped the color.</p>
<p><a href="http://www.fusioncube.net/wp-content/uploads/2010/06/clip_image001.png"><img title="clip_image001" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="404" alt="clip_image001" src="http://www.fusioncube.net/wp-content/uploads/2010/06/clip_image001_thumb.png" width="505" border="0" /></a></p>
<p>If I was able to detect the model, I could then show a new window with the requested mapping so that the user could verify her choice.</p>
<p><a href="http://www.fusioncube.net/wp-content/uploads/2010/06/clip_image0015.png"><img title="clip_image001[5]" style="border-top-width: 0px; display: inline; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="257" alt="clip_image001[5]" src="http://www.fusioncube.net/wp-content/uploads/2010/06/clip_image0015_thumb.png" width="493" border="0" /></a></p>
<p>After some digging around, I discovered that the Grid object’s view has a <em>findRowIndex()</em> method which accepts an Element as an argument. Since the <em>notifyDrop</em> event provides the e.target() property, that was all I needed. I could get the row index, and then retrieve the corresponding item from the data store.</p>
<pre class="code"><code>// Determine the row on which the color was dropped
targetRow = TargetGrid.getView().findRowIndex(e.target);
targetDataItem = TargetGrid.store.data.items[targetRow];</code></pre>
<p>You can check out the sample code that shows how to determine the target grid element on my <a href="http://www.fusioncube.net/examples/ddTarget.html" target="_blank">Drag &amp; Drop Target Detection</a> example page.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fusioncube.net/index.php/extjs-drag-drop-target-detection/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Replacing data in Sencha ExtJS grid store</title>
		<link>http://www.fusioncube.net/index.php/replacing-data-in-extjs-grid-store</link>
		<comments>http://www.fusioncube.net/index.php/replacing-data-in-extjs-grid-store#comments</comments>
		<pubDate>Fri, 21 May 2010 03:47:15 +0000</pubDate>
		<dc:creator>Steve Brownlee</dc:creator>
				<category><![CDATA[ComboBox]]></category>
		<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[GridPanel]]></category>
		<category><![CDATA[data]]></category>
		<category><![CDATA[Sencha]]></category>
		<category><![CDATA[Store]]></category>

		<guid isPermaLink="false">http://www.fusioncube.net/?p=877</guid>
		<description><![CDATA[I&#8217;ve got a data grid in one of my applications that is paginated because the underlying data set is over 9700 records in size. As I&#8217;ve said in previous articles, pagination is an annoying design pattern, but a necessary evil nonetheless. To make it easier on my users, I put a Ext.form.ComboBox in the toolbar [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve got a data grid in one of my applications that is paginated because the underlying data set is over 9700 records in size. As I&#8217;ve said in previous articles, pagination is an annoying design pattern, but a necessary evil nonetheless.</p>
<p>To make it easier on my users, I put a Ext.form.ComboBox in the toolbar of the grid which can be used by the users to search for records. The problem I was having was twofold:</p>
<ol>
<li>The ComboBox has one Ext.data.Store and the data grid has another one that is used to display the default, first 100 records in the table. </li>
<li>The ComboBox displays its results in a list beneath itself by default, but I wanted the results displayed in the grid. </li>
</ol>
<p>The second problem was easy enough to solve. When the list is shown it raises the <em>expand</em> event, so I capture that and immediately close it again with the <em>collapse()</em> method.</p>
<p>However, having the data grid, in essence, be able to display the contents of two different Stores was a bit more problematic since Ext.grid.GridPanel doesn&#8217;t have a setStore() method (which, I suppose, I could have implemented). My solution was to copy the contents of the search results into the store used by the GridPanel. This way, the user can still page the entire data set if she so wishes, but search results will override the Store when it is done.</p>
<pre class="code"><code>// Create the data store for all things found with the search bar with each row represented by a Thing
var ProviderSearchStore = new Ext.data.Store({
    proxy: new Ext.data.HttpProxy({url: 'liveQueries/searchForStuff.cfm'}),
    reader: new Ext.data.JsonReader({ root:'data',totalProperty:'recordcount'}, Thing)
});

// Since the grid is using the ProviderStore, when the store for the
// search feature is populated, clear out the grid's store and populate
// it with the records retrieved in the search
SearchStore.on('load',
    function()
    {
        var allRecords = SearchStore.getRange();
        DefaultStore.removeAll();
        DefaultStore.add(allRecords);
    });

/*
 * When the list of results is shown, immediately collapse it since we're
 * showing the results in the grid
 */
combo.on('expand', function(){ combo.collapse(); });

// Create the data store for all insurers with each row represented by an Insurer
var DefaultStore = new Ext.data.Store({
    proxy: new Ext.data.HttpProxy({url: 'liveQueries/getStuff.cfm'}),
    reader: new Ext.data.JsonReader({ root:'data', totalProperty:'totalRecords' }, Thing)
});

// Create the grid to show insurers
var grid = new Ext.grid.GridPanel({
    store: DefaultStore,
    renderTo: 'grid-div',
    title:'Stuff',
    frame:true,
	bbar: PagingBar,
	tbar:[
            {text:'Search for insurer'},
            new Ext.Toolbar.Spacer(),
	    ProviderSearch
    ]
});</code></pre>
<p>Here&#8217;s what the final control looks like. As you see, I searched for &#8216;ZA&#8217;, which returned only one result, which is now shown in the grid. Below, you can see that the original data set is still being stored in the paging toolbar&#8217;s data store, so just by clicking the refresh button, the first 100 rows in the table will be displayed again.</p>
<p><a href="http://www.fusioncube.net/wp-content/uploads/2010/05/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.fusioncube.net/wp-content/uploads/2010/05/image_thumb1.png" width="598" height="362" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.fusioncube.net/index.php/replacing-data-in-extjs-grid-store/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Scrolling pagination in Sencha ExtJS</title>
		<link>http://www.fusioncube.net/index.php/scrolling-pagination-in-ext</link>
		<comments>http://www.fusioncube.net/index.php/scrolling-pagination-in-ext#comments</comments>
		<pubDate>Thu, 20 May 2010 21:12:59 +0000</pubDate>
		<dc:creator>Steve Brownlee</dc:creator>
				<category><![CDATA[Ext]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[paging]]></category>
		<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[pagination]]></category>
		<category><![CDATA[scrolling]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://www.fusioncube.net/?p=871</guid>
		<description><![CDATA[This is mainly for my own information retrieval, but perhaps it might be useful to another Javascript developer out there who is using ExtJS. I’ve got a list of several thousand insurance plans I need to display to the users of one of my applications. I originally implemented a standard Ext.PagingToolbar to add to the [...]]]></description>
			<content:encoded><![CDATA[<p>This is mainly for my own information retrieval, but perhaps it might be useful to another Javascript developer out there who is using ExtJS.</p>
<p>I’ve got a list of several thousand insurance plans I need to display to the users of one of my applications. I originally implemented a standard Ext.PagingToolbar to add to the footer of my data grid, but I’ve never been a fan of that navigation pattern, and I suspect that my users wouldn’t be either.</p>
<p>I then thought of sites like Google Reader that automatically retrieves the next set of records as soon as it detects that you’ve scrolled to a certain place in the reading element. A quick trip to my friend Google uncovered an <a href="http://www.codeproject.com/KB/ajax/AjaxScrollingPagination.aspx" target="_blank">article on The Code Project by Jason Witty</a> that provided an example of just this technique.</p>
<p>A quick adaptation to my application provided a working example:</p>
<pre class="code"><code>var emptyData;

// Set default scroll variables.
var currentpos = 0;
var currentpage = 1;

// Set constants.
//itemsperpage: number of records that appear on each page of content.
var itemsperpage = 100;

// Number of pages of content to fetch when offset reached.
var pagestofetch = 1;

// Number of pixel interval to fire handler request. You'll need to adjust this value
// depending on the location and size of your data grid
var scrolloffset = 1800;
var scrolloffsetinterval = 1800;

// Create the column model to display only the data needed for the users
var InsurerColumnModel = new Ext.grid.ColumnModel([{
       id:'col1',
       header: "Abbreviation",
       dataIndex: 'col1',
       width: 120
    },{
       id:'col2',
       header: "Name",
       dataIndex: 'col2',
       width: 240
    },{
       id:'col3',
       header: Group",
       dataIndex: 'col3',
       width: 120
    }
]);

// Create a JSON Store to hold the data elements
var ScrollingProviderStore = new Ext.data.JsonStore({
	data:     emptyData,
	root:     'data',
	fields:   Insurer
});

// Create the grid to display each insurer
var InsurerGrid = new Ext.grid.GridPanel({
    store: ScrollingProviderStore,
    sm: new Ext.grid.RowSelectionModel({singleSelect:true}),
    cm: InsurerColumnModel,
    renderTo: 'insurer-display-grid',
    stripeRows: true,
    width:'auto',
    height:350,
    autoScroll: true,
    autoExpandColumn:'col2',
    title:'Insurance Plans',
    frame:true
});

// Create an event listener for when the user scrolls the grid
InsurerGrid.addListener('bodyscroll',scrollListener);

// Fires when grid is scrolled
function scrollListener(scrollLeft, scrollTop){
    // Only handle scroll downs past highest position.
    if ( scrollTop &gt; currentpos )
    {
        // Check if we should get more data
        if ( scrollTop &gt;  scrolloffset )
        {
            // Store current grid scroll state.
            var state = InsurerGrid.getView().getScrollState();

            // Adjust scroll offset
            scrolloffset = scrollTop + scrolloffsetinterval;

            // Adjust current page
            currentpage = currentpage + 1;

            $.AjaxCFC({
	        url: "ajaxCFC/ajax.cfc",
	        factory: "application.framework",
	        bean: "Insurance",
	        method: "listProviders",
	        data: { 'start': currentpage },
	        timeout:30000,
	        useDefaultErrorHandler: false,
	        success: function(result) {
	            var insurers = eval("(" + result + ")");
	            ScrollingProviderStore.loadData(insurers,true);

                    // Restore the scrollbar state back to where the user
                    // triggered the load.
                    InsurerGrid.getView().restoreScroll(state);
	        },
                error: function(results) {
	            Ext.MessageBox.alert("Failed", "Failed to retrieve insurers. Please try again.");
	        }
	   });
        }

        currentpos=scrollTop;
    }
};</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://www.fusioncube.net/index.php/scrolling-pagination-in-ext/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Javascript argument collections within closures</title>
		<link>http://www.fusioncube.net/index.php/javascript-argument-collections-within-closures</link>
		<comments>http://www.fusioncube.net/index.php/javascript-argument-collections-within-closures#comments</comments>
		<pubDate>Thu, 17 Sep 2009 20:03:26 +0000</pubDate>
		<dc:creator>Steve Brownlee</dc:creator>
				<category><![CDATA[Ext]]></category>
		<category><![CDATA[ajaxCFC]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[closures]]></category>
		<category><![CDATA[ExtJS]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[message box]]></category>
		<category><![CDATA[Sencha]]></category>

		<guid isPermaLink="false">http://www.fusioncube.net/?p=653</guid>
		<description><![CDATA[I have to say, it&#8217;s been a refreshing break to work on one of our older apps that was written pre-Flex. Working on my old jQuery/ExtJS Javascript code has been fun and I&#8217;ve been able to add some new tricks I&#8217;ve learned in the last year and a half. One little tidbit that I thought [...]]]></description>
			<content:encoded><![CDATA[<p>I have to say, it&#8217;s been a refreshing break to work on one of our older apps that was written pre-Flex.  Working on my old jQuery/ExtJS Javascript code has been fun and I&#8217;ve been able to add some new tricks I&#8217;ve learned in the last year and a half.</p>
<p>One little tidbit that I thought I&#8217;d pass along is a simple trick that most Javascript developers know how to do, but may trip up someone just getting into advanced Javascript development with some of the major libraries out there.</p>
<p>Knowing the proper scope of your Javascript variables is a task that everyone who&#8217;s worked with the language knows is important.  Using libraries like jQuery and ExtJS make it a bit tricker.  An example is when you want to pass an entire argument collection from one function to another and then use that argument collection inside a closure for, say, an ExtJS MessageBox.</p>
<p>At first, you may have the desire to simply pass the argument array from the first function to the second.</p>
<pre class="code"><code>function confirm(one, two, three, four) {
    Ext.MessageBox.show({
        title: 'Confirmation',
        msg: 'Please confirm that you want to delete this.',
        buttons: Ext.MessageBox.YESNO,
        fn: function (btn) {
           if(btn == 'yes') doAction(arguments);
        }
    });
}

function doAction(one, two, three, four) {
    $.AjaxCFC({
        url: "com/acme/Widget.cfc",
        method: "delete",
        data: { 'one':one,
                'two':two,
                'three':three,
                'four':four
        }
    });
}</code></pre>
<p>But the execution block that actually calls the doAction() method in within a closure inside the main confirm() method. What this means is that the argument array actually contains the arguments for that anonymous function to handle the button click on the confirmation message.</p>
<p>What you need to do is preserve the arguments collection in a variable scoped to the confirm() method &#8211; which is available to the closure (one of the strengths of Javascript) &#8211; which can then be passed to the doAction() method.</p>
<p>You then use the apply() method on the function (the apply() method allows you to pass the arguments array) and pass that holding variable.</p>
<pre class="code"><code>function confirm(one, two, three, four) {
    var args = arguments;

    Ext.MessageBox.show({
        title: 'Confirmation',
        msg: 'Please confirm that you want to delete this.',
        buttons: Ext.MessageBox.YESNO,
        fn: function (btn) {
           if(btn == 'yes') doAction.apply(this, args);
        }
    });
}

function doAction() {
    var args = arguments;

    $.AjaxCFC({
        url: "com/acme/Widget.cfc",
        method: "delete",
        data: { 'one':args[0],
                'two':args[1],
                'three':args[2],
                'four':args[3]
        }
    });
}</code></pre>
<p>Javascript is such a beautiful and powerful language.  I have to say I&#8217;ve missed working with it.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fusioncube.net/index.php/javascript-argument-collections-within-closures/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
