PDA

View Full Version : [3.0] Ext.ux.data.GoogleProxy



fdupont
7 Sep 2009, 10:41 AM
This is my first extension, so feel free to improve it :) .

This is a DataProxy which read queries from a Google API AjaxSearch (http://code.google.com/intl/fr/apis/ajaxsearch/) object.
It supports paging, start value, limit value but not result sorting (due to technical limitation).

It feeds a store with records which have theses fields (names are explicit) :


id
content
title
titleNoFormatting
url
cacheUrl
visibleUrl
unescapedUrl


Here is the code :



Ext.ns('Ext.ux.data');

Ext.ux.data.GoogleProxy = function(){
var api = {};
api[Ext.data.Api.actions.read] = true;
Ext.ux.data.GoogleProxy.superclass.constructor.call(this, {
api: api
});
};

Ext.extend(Ext.ux.data.GoogleProxy, Ext.data.DataProxy, {
doRequest : function(action, rs, params, reader, cb, scope, arg) {
// Callback crafting
if(!this.cb || params.query != this.cb.query)
{
this.googleObj = new google.search.WebSearch();
this.cb = null;
}

this.cb = this.cb || {
method: (this.api[action]) ? this.api[action]['method'] : undefined,
request: {
callback : cb,
scope : scope,
arg : arg
},
buffer: [],
nbPages: 0,
reader: reader,
callback : this.createCallback(action, rs),
scope: this
};
this.cb.arg = arg;

var g = this.googleObj;
if(this.cb.nbPages == 8)
{
// If we already have results, we just keep it
this.onRead(Ext.data.Api.actions.read, this.cb, []);
} else {
// Go on for the query !
g.setResultSetSize(google.search.Search.LARGE_RESULTSET);
g.setSearchCompleteCallback(this, this.cb.callback, [this.cb, action, rs]);
g.execute(params.query);
}
},

createCallback : function(action, rs) {
return function(o, success, response) {
if (!success) {
if (action === Ext.data.Api.actions.read) {
// @deprecated: fire loadexception for backwards compat.
this.fireEvent('loadexception', this, o, response);
}
this.fireEvent('exception', this, 'response', action, o, response);
o.request.callback.call(o.request.scope, null, o.request.arg, false);
return;
}
if (action === Ext.data.Api.actions.read) {
this.onRead(action, o, response);
}
}
},

onRead : function(action, o, response) {
var g = this.googleObj;

// If Google API does not complete successfully, so do we.
if(g.completionStatus != 200)
{
this.fireEvent('exception', this, 'response', action, o, response, e);
o.request.callback.call(o.request.scope, null, o.request.arg, false);
return;
}

// Just buffering data unless we already have 8 pages of 8 items (Google API limitation)
if(o.nbPages < 8)
{
o.nbPages++;
// Routine to craft standard array results from Google API results
var response = g.results;
var result;
try {
for(var i = 0; i < response.length; i++)
{
var r = [];
var f = o.reader.meta.fields;
var s = g.results[i];
for(var j =0; j < f.length; j++)
{
if(f[j].name == 'id') r.push(i + (g.cursor.currentPageIndex * 8));
if(f[j].name == 'content') r.push(s.content);
if(f[j].name == 'title') r.push(s.title);
if(f[j].name == 'titleNoFormatting') r.push(s.titleNoFormatting);
if(f[j].name == 'url') r.push(s.url);
if(f[j].name == 'cacheUrl') r.push(s.cacheUrl);
if(f[j].name == 'visibleUrl') r.push(s.visibleUrl);
if(f[j].name == 'unescapedUrl') r.push(s.unescapedUrl);
}
o.buffer.push(r);
}
// Load next page unless we already read the last one
if(o.nbPages < 8)
{
g.gotoPage(o.nbPages);
return true;
}
} catch(e) {
this.fireEvent('exception', this, 'response', action, o, response, e);
o.request.callback.call(o.request.scope, null, o.request.arg, false);
return;
}
}
// Finally, load results into the store
var b = o.buffer;
o.arg.params.start = o.arg.params.start || 0;
o.arg.params.limit = o.arg.params.limit || o.buffer.length;
result = o.reader.readRecords(b.slice(o.arg.params.start, o.arg.params.start + o.arg.params.limit));
result.totalRecords = o.buffer.length;
this.fireEvent('load', this, o, o.arg);
o.request.callback.call(o.request.scope, result, o.arg, true);
},

destroy: function(){
// Some memory clearing
this.googleObj.clearAllResults()
this.googleObj.cancelSearch()
Ext.ux.data.GoogleProxy.superclass.destroy.call(this);
}
});

And the exemple is here : http://www.kafe-in.net/extjs/ext.ux.data.googleproxy.html (may be laggy some times).

I just tested it on Firefox 3.5, so it may be bugged with other browsers (IE, Opera, etc.)