PDA

View Full Version : proxy param start doesn't work



Bob Wilson
21 Jun 2012, 7:39 AM
Hi all,

I'm trying to change the "start" param of my Ajax proxy, but nothing is changed when I check the Chrome Network Debugger.

Here is the simple piece of code :



jsonReader = Ext.create('Ext.data.reader.Json', {
id: 'id',
root: 'viewentry',
totalProperty: '@toplevelentries',
fields:
[
{name:'@position', mapping:'@position'},
{name:'@unid', mapping:'@unid'},
{name:'@description', mapping:'entrydata[0].text[0]'}
]
});

var proxy = Ext.create('Ext.data.proxy.Ajax', {
url: 'http://192.168.1.2/iCore.nsf/lookupResourcesByName?ReadViewEntries&outputformat=JSON',
start: 1,
reader: jsonReader
});

myDataStore = Ext.create('Ext.data.Store', {
proxy: proxy,
fields: ['@position', '@unid', '@description'],
autoLoad: true
});
console.log(myDataStore);


Whatever the start param I put, Chrome show me this request, with a start : 0



ReadViewEntries:

outputformat:
JSON
_dc:
1340292354962
page:
1
start:
0
limitIndex:
25


Is it a bug ?

skirtle
21 Jun 2012, 12:11 PM
I don't believe that Ajax proxy has a start config option.

The start parameter is part of the paging mechanism of the store and is mapped to the configured startParam in the proxy. Do a quick search for start in this file to see how it works:

http://docs.sencha.com/ext-js/4-1/source/Server.html#Ext-data-proxy-Server

Bob Wilson
21 Jun 2012, 8:29 PM
This is the mistake ! Thank you !!!
There is only a startParam, which is, in fact, not the same at all...

As a lot of people helped me on this forum, here is my small contribution, with a minimal working example to demonstrate how to use IBM LOTUS DOMINO VIEWS to fill EXTJS 4.1 GRIDS.

You can find some info on the forums, but nothing really 'packaged', and often with deprecated methods of Ext3 (and previous versions...)

I hope it will save a lot of time to people like me that got a headacke with those field mapping rules and this ***** start param (I finally found the answer in a very old post of Jack Slocum. Thank you Jack) :



// DOMINO VIEW to EXT GRID
//
// The minimal example using json and readviewentries
// Use the following URL syntax to output your view :
// http://domain/database/view?ReadViewEntries&outputformat=JSON


var proxy = Ext.create('Ext.data.proxy.Ajax', {
url: './lookupResourcesText?ReadViewEntries&outputformat=JSON', // Your view
startParam: 'start',
limitParam: 'count', // Map Domino limit parameter
reader: {
type: 'json',
root: 'viewentry',
totalProperty: '@toplevelentries'
}
});

myDataStore = Ext.create('Ext.data.Store', {
proxy: proxy,
fields: [
// Retrieve position in the view
{name: 'a', mapping: '@position'},

// Retrieve document unid for further processing
{name: 'b', mapping: '@unid'},

// retrieve column 0 data.
// Use entrydata[1].text[0] to retrieve column 1, and so on...
{name: 'c', mapping: 'entrydata[0].text[0]'}
],
});

var grid = Ext.create('Ext.grid.GridPanel', {
renderTo:'example',
store:myDataStore,
columns:[
// For the columns data, use the field names as defined in the proxy
// For the example, I've used a, b, c...
{header: "id", width: 100, sortable:'true', resizable: false, dataIndex: 'a'},
{header: "name", width: 220, resizable: false, dataIndex: 'b'},
{header: "description", width: 220, resizable: false, dataIndex: 'c'}
],
bbar:[
{
text: 'Load data',
scale: 'large',
handler: function() {

myDataStore.load({
scope: this,

// !!! BE CAREFUL, start param is 1-based
// ...and NOT 0-based !!!
// A start param with 0 will NOT return any document
start: 1,


// Retrieve only 20 documents
limit: 20,

callback: function(records, operation, success) {
// Do something brilliant here
}
});


}
}
]
});


Enjoy ! :D

skirtle
21 Jun 2012, 8:42 PM
Passing the start parameter into the load call is a bit fragile. Personally I would subclass the proxy and make the necessary overrides in there to tweak the request parameters based on the operation. That way paging will work reliably no matter how the requests are initiated.

Bob Wilson
21 Jun 2012, 8:53 PM
I've tried this but my ExtJS level is too low to handle things correctly.

In a previous try, I've indirect my code as you suggest with a Ext.data.Operation object, but, when I've called the operation with the proxy.read(myOperation) method, the grid didn't update as it does when I'm using the store.load method.

I'm sure it's possible to do as you said, but I didn't find how to update my grid once the poxy.read is finished.

Any advice ?

Bob Wilson
21 Jun 2012, 9:23 PM
After a few catch & tries, I've seen that I don't need to call proxy.read(operation).
I can directly use the store.load(operation) and that's it.

ingo.hefti
28 Jun 2012, 1:35 AM
After a few catch & tries, I've seen that I don't need to call proxy.read(operation). I can directly use the store.load(operation) and that's it.
Does your previous sample reflect your latest findings? Thanks!

Bob Wilson
28 Jun 2012, 3:24 AM
No, I didn't update my example, but as you ask, here his my last work. It could be useful for some people.

I've built a reusable function to build a JsonStore from any notes view.
The column model is fairly (too) simple at the moment, but I don't have time to dig more for now.
I'm still praying everyday that Jack releases a great Ext.ND view using Ext 4.1 and fast JSON (instead of XML agent conversion), with search features, paging, sorting, grouping...

To retrieve data within grids, just use 'c1' for view column 1, 'c2' for column 2, and so on.
Use 'unid' to retrieve the document unique id.

Here is the function that builds my store.
Feel free to comment, and criticize also.



/**
* Build a json store from a domino view
*
* @param {String} targetView : The url of the target view
* @param {Integer} start : The start index to retrieve data
* @param {Integer} limit : The number of documents that should be returned
* @param {String} restricToCategory : The category to filter if required. Set it to null if not needed.
* @param {Integer} columns : The number of columns to extract from the view
*
* @return {Ext.data.JsonStore} A JSON store containing the view entries, directly usable in Ext grids
*
* TODO :
* Use DXL to build the column model automatically...
* Columns model is currently static, with :
* - a column 'unid'
* - N columns named 'c1' to 'cn', where n is the columns parameter
*/
function buildStore(targetView, start, limit, restrictToCategory, columns)
{

url = targetView + "?ReadViewEntries&outputformat=JSON";
if (restrictToCategory != null) url = url + '&restrictToCategory=' + restrictToCategory;

var columnsModel = [];
columnsModel[0] = {name: 'unid', mapping: '@unid'};
for (i = 1; i <= columns; i++)
{
newCol = {name: 'c'+i.toString(), mapping: 'entrydata[' + (i-1).toString() + '].text[0]'};
columnsModel.push(newCol);
}

var model = Ext.define('Ext.document',
{
extend: 'Ext.data.Model',
fields: columnsModel
})

var proxy = Ext.create('Ext.data.proxy.Ajax', {
url: url,
startParam: 'start',
limitParam: 'count',
reader: {
type: 'json',
root: 'viewentry',
totalProperty: '@toplevelentries'
}
});

newStore = Ext.create('Ext.data.Store', {
proxy: proxy,
model: model
});

var operation = Ext.create('Ext.data.Operation', {
action: 'read',
start: start,
limit : limit
});

newStore.load(operation);
return newStore;
}



And here is a grid example using this function.
I've added useful examples like :
- creating an action column to manipulate the document (edit, delete, etc...)
- handle the doubleclick on row
- setting a special CSS class on a row according to a column value (this one asked me a lot of time to figure out) :">

Enjoy :-)



myViewStore = buildStore('../lookupFormItems', 1, 1000, null, 5);


var fieldList = Ext.create('Ext.grid.GridPanel', {
store: myViewStore,
renderTo: Ext.getBody(),


columns:[
{
// Example of how to create an action button to edit the document
xtype: 'actioncolumn',
sortable: false,
resizable: false,
width: 50,
items: [
{
icon: '../ICON_32x32_Edit.png',
handler: function(grid, rowIndex, colIndex)
{
var rec = grid.getStore().getAt(rowIndex);
var unid = rec.get('unid');
var url = '../0/' + unid + '?editdocument';
document.location = url;
}
}]
},
{header: "UNID", flex: 1, dataIndex: 'unid'},
{header: "Column 1", flex: 1, dataIndex: 'c1'},
{header: "Column 2", flex: 1, dataIndex: 'c2'},
],


viewConfig: {
// Example of how to use a column content to highlight a grid row
// In the example below, we colorize the row with the CSS class 'RED' if the value of column 1 = 'URGENT'
getRowClass: function(record, index) {
var c = record.get('c1');
if (c == 'URGENT') return 'RED';
},

// Example of how to handle doubleclick on a row.
// In this example, it opens the clicked document in edit mode.
listeners: {
'itemdblclick': function(view, rec, node, index, e, options ) {
var unid = rec.get('unid');
var url = '../0/' + unid + '?editdocument';
document.location = url;
}
}
},
});

ingo.hefti
28 Jun 2012, 3:48 AM
Thanks a lot!! I'll give it a try a.s.a.p.!

ingo.hefti
1 Jul 2012, 3:43 AM
@Bob: your sample helped me a lot to get a working sample of accessing our domino server. As I like the MVC approach very much, I baked the code into an MVC app. Also I wanted to use paging (as domino does this very well with ReadViewEntries). Whilst implementing the ext paging toolbar I noticed two things:
clicking the FIRST PAGE button of the toolbar uses (again) a ZERO based START option... (already did a feature request to optimize that). So I had to override the loadPage() method of the store to correct this.
the paging toolbar uses the pageSize of the store for paging. So setting this in my store once will use it for the store load AND the paging.
Thanks again for your efforts!

skirtle
1 Jul 2012, 4:23 AM
To elaborate on my earlier suggestion:


Ext.define('MyApp.proxy.DominoProxy', {
alias: 'proxy.domino',
extend: 'Ext.data.proxy.Ajax',

limitParam: 'count',

getParams: function() {
var params = this.callParent(arguments);

params.start = (params.start || 0) + 1;

return params;
}
});

Doing this in the proxy removes the need to sprinkle changes around elsewhere. The store and operation should use zero-based start, it's a detail of the proxy to switch it to one-based when contacting the server.

To use it you'd then do something like:


var store = Ext.create('Ext.data.Store', {
proxy: {
type: 'domino',
reader: ...
}
});

If the reader's the same for all your proxy instances too then you could move that into the class definition but I'd advise setting it in the constructor to avoid reference sharing problems. e.g.:



Ext.define('MyApp.proxy.DominoProxy', {
...

constructor: function() {
this.reader = ...;

this.callParent(arguments);
},

...
});

Subclassing is your friend. Whenever you find yourself tempted to go write a helper function to build an object consider using a subclass instead.

Bob Wilson
1 Jul 2012, 6:45 AM
@skirtle

Thanks a lot for your time & good advices.


@ingo.hefti

Glad that my example could save you some time.

I didn't have time yet to investigate the paging system, but I'm sure I'll need it in a very close future, so, if you could post a working example of it, I'd be happy to have a look at it.

Maybe that, in the end, after collaboration & exchanges, we'll find a way to rebuild this "domino view killer feature" that everyone needs in the Domino community :D

Next step : sorting, grouping & searching !
I offer hot coffee at the finish line ! ~o)

Have a nice day.

ingo.hefti
1 Jul 2012, 7:54 AM
To elaborate on my earlier suggestion:


Ext.define('MyApp.proxy.DominoProxy', {
alias: 'proxy.domino',
extend: 'Ext.data.proxy.Ajax',

limitParam: 'count',

getParams: function() {
var params = this.callParent(arguments);

params.start = (params.start || 0) + 1;

return params;
}
});

Doing this in the proxy removes the need to sprinkle changes around elsewhere. The store and operation should use zero-based start, it's a detail of the proxy to switch it to one-based when contacting the server.

To use it you'd then do something like:


var store = Ext.create('Ext.data.Store', {
proxy: {
type: 'domino',
reader: ...
}
});
This one is even better - works like a charm!
It took me some time to understand, what you are doing...
Very elegant! Thank you skirtle.

ingo.hefti
1 Jul 2012, 8:01 AM
I didn't have time yet to investigate the paging system, but I'm sure I'll need it in a very close future, so, if you could post a working example of it, I'd be happy to have a look at it.
I'll prepare a working sample database.

wki01
17 Jul 2012, 2:20 AM
Does anyone have a working example with paging bar?
Thanks in advance.

Bob Wilson
31 Jul 2012, 1:37 PM
Hi ingo.hefti,

After my previous "trip" to re-invent the "Notes2ExtView" with Ext4 & JSON, I am at the point where I would need a paging system.

I have 2 solutions :
- do it myself :((
- asking for help :">

Would it be ok for you to post your working example ?

ingo.hefti
1 Aug 2012, 3:04 AM
Would it be ok for you to post your working example ?

Hi Bob
No problem - and apologies for the delay (but you know, just came back from summer holidays... :D).
Here is a link to a working Domino DB: https://dl.dropbox.com/u/8085058/SenchaForum/DIRECTORY.NSF

(https://dl.dropbox.com/u/8085058/SenchaForum/DIRECTORY.NSF)The main page to call is ".. /directory.nsf/notesviewpaging". The app itself is done the MVC way. All js files are within the "Resources\Files\a1.." section. You will need to adjust the CompanyList controller with a valid address for the database on your server.

This uses EXT JS V4.1. All resources were copied directly to the html directory on the server. The remaining files are within the database. There is a problem with the resources not being found because of the url pointing somewhere else (chrome console). You can solve this with a web site config within the server config (works fine for me). But the sample still works also without the resources. This is just cosmetics.

I also started playing with filtering the view and it's already working, somehow... But work in progress - not finished yet.

Hope this helps!
Ingo

Bob Wilson
1 Aug 2012, 10:23 AM
But... Could you also send your private key so I can decrypt the database :D

I think you've done a local copy without unchecking the 'encrypt' option...(:|

ingo.hefti
1 Aug 2012, 1:20 PM
I think you've done a local copy without unchecking the 'encrypt' option...(:|
How embarrassing - the beginners number one mistake - and that to me... :">

Has been fixed now - my apologies!

Bob Wilson
2 Aug 2012, 5:18 AM
Don't apologize for giving something nice ! :-)

I didn't have the time to inspect the code, yet.

I'm worrying a little bit about the next step which will be the categorized views.
They are a great added-value in reporting views (for example, sales by year & month, etc...), but I don't have any idea yet of how to handle this with grids, and it's even worst if we think about the combination of categorization + paging. Ouch.
I maybe should have a look at the Ext.nd code to see how Jake could handle this.
Short nights are coming... :((