ASP.NET AJAX & ExtJS 4 Grid (3)

Read Previous Example First!

In this example, we’ll be returning additional data to our ExtJS4 data store, which is passed from ASP.NET over AJAX in XML format. It’s common to show grid row count in the form title, as well as something else in the header, such as final SQL or LDAP query used by your ASP.NET AJAX script (WebMethod).

Combine this with ExtJS4 buffered grid’s ability to only render 50 HTML rows with infinite scrolling, this makes  the stock ExtJS4 gridpanel an extremely powerful application in its own right, very good at running large data queries.  On a decent computer with decent Internet connection this will smoke the traditional buffered grid, which ajax back on every scroll.


First, we’ll modify our store and add a messageProperty attribute to the proxie’s reader. This will let us encode some data in JSON on the server and pass anything we want, along with our search results.

// Store
Ext.create('Ext.data.Store',{
	model: 'MyOrg.model.SearchResult'
	, proxy: Ext.create('MyOrg.proxy.MSAjaxProxy', {
		url: 'Default-UMRA.aspx/Search'
		, reader: {
			type: 'xml'
			, root: 'matches'
			, record: 'match'
			, messageProperty: 'jsonData'
		}
		, extraParams: { query: 'Param to C#' }
	}) // eo proxy
})

Here’s the corresponding changes to our XML in ASP.NET:

/// <summary>
/// Returns XML  matches/match[id,name]
/// </summary>
/// <param name="query">Search query</param>
[WebMethod(EnableSession = true)]
[ScriptMethod(ResponseFormat=ResponseFormat.Xml,UseHttpGet = false,XmlSerializeString = false)]
public static XmlDocument Search( string query )
{
	XmlDocument doc = new XmlDocument();
	using (XmlWriter writer = doc.CreateNavigator().AppendChild())
	{
		writer.WriteStartDocument();
		writer.WriteStartElement("matches");
 
		// Some postback JSON data { LDAPFilter: '...', MoreData: '...' }
		Dictionary<string,object> JSONData = new Dictionary<string,object>();
		JSONData["LDAPFilter"] = "(&(sAMAccountName=*))";
		JSONData["MoreData"] = "Another var could be DateTime, etc.";
		string XMLData = new System.Web.Script.Serialization.JavaScriptSerializer().Serialize(JSONData);
		writer.WriteElementString("jsonData", XMLData);
 
		for (int i = 0; i < 100; i++)
		{
			writer.WriteStartElement("match");
 
			writer.WriteElementString("id", i);
			writer.WriteElementString("name", "Number " + i);
 
			writer.WriteEndElement(); // eo match
		}
 
		writer.WriteEndElement(); // eo matches
		writer.WriteEndDocument();
	}
 
	return doc;
}

For the finale – the prefetch event! Note that our store will now hold only 50 records.  The entire data set will be stored in store’s “prefetchData” attribute, which is where we can get the row count from.

var grid = Ext.create('Ext.grid.Panel', {
	xtype: 'grid'
	, columns: [
		{ header: 'ID', dataIndex: 'id' }
		, { header: 'Name', dataIndex: 'name' }
	]
	, store: Ext.create('Ext.data.Store',{
		model: ...
		, proxy: ...
		, listeners: {
			// After the store is loaded
			'prefetch': function(store, records, isSuccess, operation) {
				// Get our response JSON
				var json = Ext.JSON.decode(operation.resultSet.message)
					, LDAPFilter = msg.LDAPFilter
					, MoreData = msg.MoreData
					, rowCount = store.prefetchData.length;
 
				// Put row count in title
				grid.setTitle( grid.title + ' (' + rowCount + ')' );
 
				// Add header
				grid.addDocked({xtype: 'toolbar', items: [
					'LDAP Filter: ' + LDAPFilter
				] });
			}
		} // eo listeners
		// Infinite scrolling
		, pageSize: 50
		, buffered: true
		, purgePageCount: 0
	}) // eo store
	// Infinite scrolling
	, verticalScroller: { xtype: 'paginggridscroller', activePrefetch: false }
	, invalidateScrollerOnRefresh: false
	, viewConfig: { trackOver: false }
});
 
// Load ALL remote data, but display only so much
grid.store.guaranteeRange(0,49);
VN:F [1.9.22_1171]
Rating: 8.3/10 (6 votes cast)
ASP.NET AJAX & ExtJS 4 Grid (3), 8.3 out of 10 based on 6 ratings

One thought on “ASP.NET AJAX & ExtJS 4 Grid (3)”

Leave a Reply

Your email address will not be published. Required fields are marked *

* Copy This Password *

* Type Or Paste Password Here *