PDA

View Full Version : Insert/delete record to Grid and PagingToolbar



VictorSmirnov
9 Jun 2008, 12:27 PM
When I add or delete records in a EditorGridPanel corresponding PagingToolbar is not updated.

I've dug around and found the following:
1. PagingToolbar does not listen for the add and remove events from it's store. So it does not know, when, for instance, new record is added.
2. PagingToolbar invokes store's getTotalCount method to calculate number of pages.
This method just return totalLength property (from server response) which is updated only when data is reloaded, is not it?

This all is rather sophisticated ;) Like in my case, Store actualy stores only records for the currently shown page. So, when I delete record I need to load additional one to fill empty position.

After all I found the following behaviour:
1. Reload store when record is deleted.
2. When record is inserted do the following: reload (and show to user) the page of the store which contains our new record. This is sophisticated too, but can be done.

Is there any better solution for this?

I think, that I'm not the first, who faced this. I looked through existing samples. This question is avoided.

Many thanks for your time and suggestions!

oddy
3 Aug 2009, 12:45 AM
Guys, is this issue ignored intentionally?

oddy
3 Aug 2009, 5:08 AM
Why item number in the pager doesn't change it's value on add/remove in the store?

VictorSmirnov
3 Aug 2009, 7:51 AM
Hi oddy!

The question is - why pager should change when we add/remove in the store?

Let's look at source code (version 3.0, almost the same with 2.2) file "src\widgets\PagingToolbar.js" function "bindStore : function(store, initial){".
We can see, that we listen to events 'beforeload', 'load' and 'exception'.
None of these events is fired when we add or remove row from the story.
This is why PagingToolbar will ignore these changes.

The other question is what to do when we add/remove row?
May be we need to reflect this and update counter. What to do with new records?

If interested I can try to write a patch for this. There might be two group of changes:
1. Store should update totalLength property when adding/removing records.
2. PagingToolbar should listent to corresponding store events and update counter.
It seems to be so minor that no serious developer wants do bother with it :)

Let me know, what behavior you expect. I think I can write a patch for this.

Regards, Victor

oddy
4 Aug 2009, 2:55 AM
Hi oddy!

The question is - why pager should change when we add/remove in the store?

Let's look at source code (version 3.0, almost the same with 2.2) file "src\widgets\PagingToolbar.js" function "bindStore : function(store, initial){".
We can see, that we listen to events 'beforeload', 'load' and 'exception'.
None of these events is fired when we add or remove row from the story.
This is why PagingToolbar will ignore these changes.

The question is clear and simple - why the pager doesn't change it's value when it's binded source is changed. Look at it as if you where a user. "As design" or "because events are not fired" is not an explanation.



The other question is what to do when we add/remove row?
May be we need to reflect this and update counter. What to do with new records?

If interested I can try to write a patch for this. There might be two group of changes:
1. Store should update totalLength property when adding/removing records.

I think that there is no sense to update totalLength every time I add/remove records from the store.


2. PagingToolbar should listent to corresponding store events and update counter.

Yep :) But don't bother about it if you don't need it for yourself. What I'm trying is to get an answer from support team. Any answer will do. I don't remember the case when their explanations were bad.

Animal
4 Aug 2009, 3:07 AM
I don't understand your point.

What do you want to happen when you add a record locally to the Store which is not in the database, but just added into the local page?

VictorSmirnov
4 Aug 2009, 3:36 AM
Hi!

I think I understand the problem:) Let's discuss the scenario.
1. User loads list of items into grid.
2. User creates new item.
2.1. New item is saved to server. There is no need to reload all list to reflect this change. Yes really :) (In general server should return newly inserted item, cause some logic might be implemented on server. For instance, JS application should get id from server. But for now it's not important)
2.2. We (application developer) don't reload the store but just insert new item into the store after save is completed.
3. User should see that total number of items has changed and number of show items has changed. Well, I think so. But this does not happen. This can be seen on several examples for PagingToolbar.

It's really not obvious for me what to do in this scenario. For instance, user selected first 10 record with respect to sorting (server side sorting). Then he inserts new record and what should happen? He sees 11 records? And what should happen if he presses next button? Should he see records from 11 to 20 or from 12 to 21? If we reload all grid from server on new record insertion, it might happen that user does not see his record, cause it's on another screen.

I think it's hard to have general solution for this.
For instance, we might insert new record at the beginning of the list, select it, remove last record and increase total record counter. But it's a meter of taste. One can say that this is absolutely wrong and suggest another scenario :)

Regards,
Victor

Animal
4 Aug 2009, 3:46 AM
New item saved to the server?

So the response from that save operation must be used to update the Toolbar in some way?

I think we are in agreement here. I don't see how that could be automated.

oddy
4 Aug 2009, 3:51 AM
I don't understand your point.

What do you want to happen when you add a record locally to the Store which is not in the database, but just added into the local page?
Look. PagingToolbar uses some store to reflect it's state. Not the state of the database. Generally it'll look like this: you have a grid and a pager binded to one store. You add/remove some records to/from the store and it's expected from the pager to reflect current state of the store. Hope my point is clear now.

Animal
4 Aug 2009, 3:53 AM
As mud.

It's displaying "Page 45 of 1452"

You add a record locally, and what do you want to happen? Please explain what you want to happen!

oddy
4 Aug 2009, 4:14 AM
As mud.

It's displaying "Page 45 of 1452"

You add a record locally, and what do you want to happen? Please explain what you want to happen!

Nope, pager displays record count in the store, so it's "Displaying 1 - 50 of 1500".
And when I add one record, I need to have this: "Displaying 1 - 50 of 1501".

Animal
4 Aug 2009, 4:20 AM
There are not 1501 records to page through. There are 1500 records to page through.

You have added one locally to the Store.

VictorSmirnov
4 Aug 2009, 4:25 AM
Nope, pager displays record count in the store, so it's "Displaying 1 - 50 of 1500".
And when I add one record, I need to have this: "Displaying 1 - 50 of 1501".
Great! :)

And what should be done with newly inserted record? I suppose it should be:
"Displaying 1 - 51 of 1501"
Or after inserting new record you suppose to remove some other record from the store, so that there will be 50 records in a grid.

The funny thing happens when you remove record :) It should display
"Displaying 1 - 49 of 1499"
Unless you load one more record from server.

Is this exactly what you expect Pager to do?
When you insert new record - show "Displaying 1 - 51 of 1501"
And when you remove record - show "Displaying 1 - 49 of 1499"


And yes, there is one more important thing. If you insert record to the store and don't send this information to server then after you reload page you will loose this new record and it will be again 1500 records. But with Ext 3.0 you can setup store to save changes to server automatically and we might not think about this supposing that new record will be inserted into DB (for instance) in the background by associated proxy object.

Condor
4 Aug 2009, 4:25 AM
As Animal pointed out:
For remote paging you would not add a record locally. You would send a request to the server to add a record and reload the store after that.

For local paging (using my PagingStore extension) it's almost identical. You add the record to the store and reload it (to re-paginate and update the toolbar).

Animal
4 Aug 2009, 4:26 AM
Nope, pager displays record count in the store, so it's "Displaying 1 - 50 of 1500".
And when I add one record, I need to have this: "Displaying 1 - 50 of 1501".

And it displays both pages and Records:

http://i131.photobucket.com/albums/p286/TimeTrialAnimal/pagingtoolbar.jpg

oddy
4 Aug 2009, 4:27 AM
There are not 1501 records to page through. There are 1500 records to page through.

You have added one locally to the Store.
Consider this example:
I have a grid with 10 records. Pager shows me: "Displaying records 1 - 10 of 10"
I add one record to the grid. I see 11 records. And what shows me pager? Right. It lies me about 10 records: "Displaying records 1 - 10 of 10"

Animal
4 Aug 2009, 4:29 AM
It's actually worse than that Victor.

Imaging you are on page 56 of 1664

if you add a Record, there's no reason why it should be in this page of a server paged GridPanel, depending on the "ORDER BY" clause of your query.

It might end up in reality being inserted after your current page in which case the Paging Toolbar should not be updated.

Or before the current page.... wo shat should happen in this case?

No. The only reliable way is to refresh the page after database update.

oddy
4 Aug 2009, 4:29 AM
As Animal pointed out:
For remote paging you would not add a record locally. You would send a request to the server to add a record and reload the store after that.
But I don't want to reload the store after I commit changes. It means I should load all that bunch of records again.

Animal
4 Aug 2009, 4:30 AM
You are missing the point oddy.

Yuo might add 400 records locally. So then what happens when you do "Next Page".

They're local. They are "phantom" records.

oddy
4 Aug 2009, 4:34 AM
Why can't I do this:


Ext.override(Ext.PagingToolbar, {
initComponent: Ext.PagingToolbar.prototype.initComponent.createSequence(function(){
this.store.on('add', this.onStoreAdd, this);
this.store.on('remove', this.onStoreRemove, this);
this.on('change', this.setTotalCount, this);
})
, setTotalCount: function(){
this.totalCount = this.store.getTotalCount();
}
, onStoreAdd: function(store, rs, index){
this.totalCount += rs.length;
this.updateState(store.getCount(), this.totalCount);
}
, onStoreRemove: function(store, r, index){
this.totalCount--;
this.updateState(store.getCount(), this.totalCount);
}
, updateState : function(count, totalCount){
if (this.displayItem){
var msg = count == 0
? this.emptyMsg
: String.format(this.displayMsg, this.cursor+1, this.cursor+count, totalCount);
this.displayItem.setText(msg);
}
}
, totalCount : 0
});


What's wrong with this approach?

oddy
4 Aug 2009, 4:36 AM
You are missing the point oddy.

Yuo might add 400 records locally. So then what happens when you do "Next Page".

They're local. They are "phantom" records.
Can we check phantom property of the added/removed records? I mean, if I want to update paging toolbar only on a remotely added records, can we check phantom property?

natiishyn
21 Jan 2014, 6:30 AM
Hello.
I have the same issue, but I'm using ExtJS 4.1.
For the first time, after page is loaded I download data to grid and then I want to work with it locally. I can add records to the grid and manually delete them.
When I add record, I push it to server, but I don't want to load all the data to grig from server. I load data from store and add there a new record, so in grid I can see one more, but on paging toolbar info is not changing. Same with deleting.
When I try to delete one record, I manually delete it from store (I checked store), but text in pagination is previous. I can see changes on store and on grid, but text in pagination tool is like it was before deleting.
So how can I refresh that text manually?