As promised previously today I am going write about adding remote pagination functionality with GXT Grid which was one of most demanded one from my readers. In my previous blog I have described in detail how you can load data from a remote data store and show them in GXT Grid. In this writing the same Comments entity and CommentModel are used to represent data. You will find the code of these classes here.
At first in the implementation of your GWT RPC Service add a method to load all the comments from the data store.
public List<Commentmodel> getAllComment() { List<Commentmodel> commentList = new ArrayList<Commentmodel>(); PersistenceManager pm = PMF.get().getPersistenceManager(); try { String query = "select from " + Comments.class.getName()+" order by postedDate desc"; List<Comments> list = (List<Comments>) pm.newQuery(query).execute(); if (!list.isEmpty()) { for (Comments c : list) { //convert from entity object to DTO commentList.add(CommentConverter.entityToModel(c)); } } }catch (Exception ex) {} finally { pm.close(); } return commentList; }
Now add a method public PagingLoadResult<Commentmodel> getComments(PagingLoadConfig config) in your service which takes a PagingLoadConfig object to determine the limit and offset value of the request and returns the desired list for the paging loader. Here is the implementation of the method.
@Override public PagingLoadResult<Commentmodel> getComments(PagingLoadConfig config) { //comments is a private variable of the service implementation class //private List<Commentmodel> comments; comments = getAllComment(); //get all the comments from the data store //and sort this list according to sorting info if (config.getSortInfo().getSortField() != null) { final String sortField = config.getSortInfo().getSortField(); if (sortField != null) { Collections.sort(comments, config.getSortInfo().getSortDir().comparator(new Comparator<Commentmodel>() { public int compare(CommentModel c1, CommentModel c2) { if (sortField.equals("comments")) { return c1.getComments().compareTo(c2.getComments()); } else if (sortField.equals("postedBy")) { return c1.getPostedBy().compareTo(c2.getPostedBy()); } else if (sortField.equals("postedDate")) { return c1.getStartingDate().compareTo(c2.getStartingDate()); } return 0; } })); } } //Create a sublist and add data to list according //to the limit and offset value of the config ArrayList<Commentmodel> sublist = new ArrayList<Commentmodel>(); int start = config.getOffset(); int limit = comments.size(); if (config.getLimit() > 0) { limit = Math.min(start + config.getLimit(), limit); } for (int i = config.getOffset(); i < limit; i++) { sublist.add(comments.get(i)); } return new BasePagingLoadResult<Commentmodel> (sublist, config.getOffset(), comments.size()); }
Your server side coding is done. Let's come to client side coding and see how to use this service to add remote pagination functionality with GXT Grid.
First create a RpcProxy object, proxy to make RPC call using the load configuration. With the proxy object create a PagingLoader, loader which is required to load page enabled set of data and enable the remote sorting attribute of the loader.
RpcProxy<PagingLoadResult<CommentModel>> proxy = new RpcProxy<PagingLoadResult<CommentModel>>() { @Override public void load(Object loadConfig, AsyncCallback<PagingLoadResult<CommentModel>> callback) { Gxtexamplegalary.greetingService.getComments( (PagingLoadConfig) loadConfig, callback); } }; // loader final PagingLoader<PagingLoadResult<ModelData>> loader = new BasePagingLoader<PagingLoadResult<ModelData>>( proxy); loader.setRemoteSort(true);
Now use this loader to create a ListStore of CommentModel and bind the loader with a PagingToolBar.
ListStore<CommentModel> commentList = new ListStore<CommentModel>(loader); final PagingToolBar toolBar = new PagingToolBar(3); toolBar.bind(loader);
Create a List of ColumnConfig and a ColumnModel from the ColumnConfig list.
List<ColumnConfig> configs = new ArrayList<ColumnConfig>(); ColumnConfig column = new ColumnConfig(); column.setId("comments"); column.setHeader("Comments"); column.setWidth(200); configs.add(column); column = new ColumnConfig("postedBy", "Posted By", 150); column.setAlignment(HorizontalAlignment.LEFT); configs.add(column); column = new ColumnConfig("postedDate", "Posting Date", 100); column.setAlignment(HorizontalAlignment.RIGHT); column.setDateTimeFormat(DateTimeFormat.getShortDateFormat()); configs.add(column); ColumnModel cm = new ColumnModel(configs);
Finally create a Grid with the commentList and the column model. Add a Listener with the Grid to handle the remote pagination functionality. In the handleEvent method of the Listener first create a PagingLoadConfig, config and set offset, limit, sort field and sort direction value of the config. Then load data by the loader with this configuration.
final Grid<CommentModel> grid = new Grid<CommentModel>(commentList, cm); grid.setStateId("pagingGridExample"); grid.setStateful(true); grid.addListener(Events.Attach, new Listener<GridEvent<CommentModel>>() { public void handleEvent(GridEvent<CommentModel> be) { PagingLoadConfig config = new BasePagingLoadConfig(); config.setOffset(0); config.setLimit(3); Map<String, Object> state = grid.getState(); if (state.containsKey("offset")) { int offset = (Integer) state.get("offset"); int limit = (Integer) state.get("limit"); config.setOffset(offset); config.setLimit(limit); } if (state.containsKey("sortField")) { config.setSortField((String) state.get("sortField")); config.setSortDir(SortDir.valueOf((String) state .get("sortDir"))); } loader.load(config); } }); grid.setLoadMask(true); grid.setBorders(true); grid.setAutoExpandColumn("comments"); grid.setStyleAttribute("borderTop", "none"); grid.setStripeRows(true); ContentPanel cp = new ContentPanel(); cp.setBodyBorder(false); cp.setHeading("Grid with Pagination"); cp.setButtonAlign(HorizontalAlignment.CENTER); cp.setLayout(new FitLayout()); cp.setSize(700, 300); cp.add(grid); cp.setBottomComponent(toolBar); RootPanel.get().add(cp);
That's all for today. Enjoy GWT and GXT :-)
23 comments:
Simple question: how do you manage errors?
On a non-paged, you define your own callback with the onFailure method.
Here, the callback is provided by the framework.
How do you known that the load method has worked as expected? (I'm currently working on some errors when the session times out ...).
@bfabien: I use a client side exception class.
The class will be like this
public class ClientException extends Exception implements Serializable
{
private static final long serialVersionUID = 1L;
private String message = "";
public ClientException()
{
}
public ClientException(String message)
{
super(message);
this.message = message;
}
public ClientException(Throwable cause)
{
super(cause);
}
@Override
public String getMessage()
{
return message;
}
public void setMessage(String message)
{
this.message = message;
}
}
Hi Shams,
I'm new to GWT/GXT and have found your blog quite helpful... thanks! However, I don't quite understand how to use a client side exception class in this case and print out an error message if an error is encountered during the load. Could you give an example? Thank you in advance for your help!
Hi Shams, congrats for your work. I'm implementing a grid, but I have a problem here.
Look, I have a submit button, a grid and an export button (for export the grid to csv file). When I push the submit button, my grid is refreshed and the button is enabled just when the grid retrieves more than 1 model data (register).
But, I don't how to get the grid dataset count. I tried to get the loader count, but when I inspect this object the count is = 0 and same thing when I get the grid store count.
How can you get this dataset count?
Thanks =]
ListStore count should work
Thank you for this great and useful posts! :)
Hi Shams, this is a great post.
I need a help.
I need to pass some of my custom data, inside the BasePagingLoadResult, and hence I extended this class (BasePagingLoadResult), and wrote my own setter and getter method.
But in the client side, we are not implementing the AsyncCallback. I mean, I can retrieve my data in onSuccess() method, but here, we are creating a proxy and that proxy is being passed to the loader.
So, in such case, can you please suggest me, what should I do, to retrieve my custom data?
The class extending BaseModel which is attached to the grid cannot be used in the RPC call. If we try to use it we get the serialization exception stating that the serialization policy donot allow this type to be serialized.
So how should I handle this?
Thanks,
Madhur
@Madhur: If you are using any property of your own data type, make sure that your class is serializable. First try with only basic data type...
Hey Shams,
I had not included a default constructor in the serializable class.
Yes Madhur, default constructor is one of the requirement to make a class serializable.
Wondelful tutorial! keep on with the good stuff.
you are great Bro, by the way, what the purpose of this part of code String sortField = config.getSortInfo().getSortField();
thx
If you want to get sorted data, you need to use the sortField.
Hi can u kindly provide me with an info how can i use retrieved data into combobox in gxt.
for eg: i will have a form with textfields,the entered data will be added into the grid below the form.When i use to edit a row data i will click on the row and the data will be populated to text fields.The problem is i had a combobox in the form where i cant able to populate value onto combobox while editing.can u please provide me some suggestions.. thank u
Hi, I am newbie of GWT, and I am trying to learn by using your very helpful tutorials.
In this way, I was able to build a virtual phonebook. It is created by a recordset extracted from a mySQL database.
Subsequently, I add remote pagination to a Grid showing the list of contacts, adding filtering and checkboxes to select one or more contacts at the same time. I successfully added remote paging and filtering to Grid, but now I would like to add grouping. I tried to work with GroupStore object, but unsuccessfully. Is it possible? Could you help me? My private email is matteo.cacciola@gmail.com: if I can contact you privately, I should send my tentative code, since here I cannot
hi shams,
i make my own project according to this tutorial and i found this error : com.google.gwt.user.client.rpc.SerializationException: Type 'com.gxt.grid.client.Posting' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = com.gxt.grid.client.Posting@1fbea5e
my Posting.java :
public class Posting extends BaseModel{
private static final long serialVersionUID = 1L;
public Posting() {}
public Posting(int idd, String name){
set("idd", idd);
set("name", name);
}
public String getIdd() {
return (String) get("idd");
}
public void setIdd(int idd) {
set("idd", idd);
}
public String getName() {
return (String) get("name");
}
public void setName(String name) {
set("name", name);
}
i've got that error when execute new BasePagingLoadResult(sublist, config.getOffset(),posts.size());
any advice to solve this thing?
thanks before.
Thanks For Your Tutorial..
Perfectly working..
To find out how to manage errors, check out this link (I've tested it myself - it works!)
Hi Ahimsa,
in serviceImpl,
use ModdelData as ur PagingLoader object
public PagingLoadResult getQuestionnaireDatas(PagingLoadConfig config, String region) throws SessionExpiredException
{
try
{
ApprovalData result = new ApprovalData();
ListStore questionnaireDatas = null;
result = delegate.getQuestionnaireApproval(getSessionContext().getUser().getUserId(), region);
if(result != null && result.getQuestionnaires() != null && result.getQuestionnaires().size() > 0)
{
questionnaireDatas = new ListStore<>();
questionnaireDatas.add(result.getQuestionnaires());
//Collections.sort(result.getQuestionnaires(), new QuestionnaireData());
}
ArrayList sublist = new ArrayList();
int start = config.getOffset();
int limit = questionnaireDatas.getModels().size();
if (config.getLimit() > 0)
{
limit = Math.min(start + config.getLimit(), limit);
}
for (int i = config.getOffset(); i < limit; i++)
{
sublist.add(questionnaireDatas.getModels().get(i));
}
return new BasePagingLoadResult(sublist, config.getOffset(), questionnaireDatas.getModels().size());
}
catch(SessionExpiredException ex)
{
throw new SessionExpiredException();
}
catch (Exception e)
{
TECH_LOG.error("error",e);
}
return null;
}
Hello, I'm new to java, and I can't resolve BasePagingLoadResult, witch package I've to choose?
Hey
I have problem with pagination in GXT 3.1.1 in comboBox under IE 10
When I click next, previous, last, first button pagination values hiddes
This is similar problem:
http://www.sencha.com/forum/showthread.php?144219-GXT-2.2.4-Combobox-with-paging-loader-popup-disappear-problem
Can you saw this problem in your experience?
Post a Comment