PDA

View Full Version : Beta 2: Remote Filtering Grid with Paging



nstokoe
12 Jan 2012, 12:10 PM
Hello everyone.

I am trying to implement a grid which uses remote filtering of columns with paging. Previous 2.x showcases contained an example of this exact situation but the 3.0 beta 2 showcase's example of remote filtering does not include paging. I tried to extend that example (http://sencha.com/examples-dev/#ExamplePlace:remotefiltergrid) to use a toolbar for paging, but the bind method for Toolbar only takes a loader of type PagingLoader<PagingLoadConfig,?> and will not work with PagingLoader<FilterPagingLoadConfig, ?>.

Anyone know how to get both remote filtering and paging working together using the same loader?

binarious
27 Jan 2012, 1:06 AM
Hello,

any new insights? We have the same problem, too.

nstokoe
27 Jan 2012, 8:25 AM
None yet.

Surprised this functionality isn't available since it was clearly possible in 2.x.

Colin Alworth
27 Jan 2012, 1:23 PM
Sorry about the delay in getting to this post.

I see no reason why this shouldn't work, except for the generics issue preventing passing in an otherwise valid PagingLoader to the toolbar. Try casting the loader when you pass it in, something like

toolbar.bind((PagingLoader)loader);
This will emit a warning about an unsafe, raw cast, but will serve as a temporary workaround

From 2.x we have made a number of generics fixes, but I see there are still a few places that need some attention. Thanks for bringing this up, and let me know how the workaround goes - we will update this thread when there is a better fix.

binarious
30 Jan 2012, 7:14 AM
I tried casting the PagingLoader<FilterPagingLoadConfig, PagingLoadResult<...>> to just raw PagingLoader as you described. After that I get the following ClassCastException:



Caused by: java.lang.ClassCastException: com.sencha.gxt.data.shared.loader.PagingLoadConfigBean cannot be cast to com.sencha.gxt.data.shared.loader.FilterPagingLoadConfig
at com.sencha.gxt.widget.core.client.grid.filters.AbstractGridFilters.handleBeforeLaod(AbstractGridFilters.java:363)
at com.sencha.gxt.widget.core.client.grid.filters.AbstractGridFilters$LoaderHandler.onBeforeLoad(AbstractGridFilters.java:94)
at com.sencha.gxt.data.shared.loader.BeforeLoadEvent.dispatch(BeforeLoadEvent.java:95)
at com.sencha.gxt.data.shared.loader.BeforeLoadEvent.dispatch(BeforeLoadEvent.java:1)
at com.google.gwt.event.shared.GwtEvent.dispatch(GwtEvent.java:1)
at com.google.web.bindery.event.shared.EventBus.dispatchEvent(EventBus.java:40)
at com.google.web.bindery.event.shared.SimpleEventBus.doFire(SimpleEventBus.java:193)
at com.google.web.bindery.event.shared.SimpleEventBus.fireEvent(SimpleEventBus.java:88)
at com.google.gwt.event.shared.SimpleEventBus.fireEvent(SimpleEventBus.java:52)
at com.google.gwt.event.shared.EventBus.castFireEvent(EventBus.java:67)
at com.google.gwt.event.shared.SimpleEventBus.fireEvent(SimpleEventBus.java:57)
at com.sencha.gxt.data.shared.loader.Loader.fireEvent(Loader.java:197)
at com.sencha.gxt.data.shared.loader.Loader.load(Loader.java:171)
at com.sencha.gxt.data.shared.loader.Loader.load(Loader.java:158)
at de.kdo.gxt.framework.client.user.UserRightController$1$1.execute(UserRightController.java:107)
at com.google.gwt.core.client.impl.SchedulerImpl$Task$.executeScheduled$(SchedulerImpl.java:50)
at com.google.gwt.core.client.impl.SchedulerImpl.runScheduledTasks(SchedulerImpl.java:228)
at com.google.gwt.core.client.impl.SchedulerImpl.flushPostEventPumpCommands(SchedulerImpl.java:388)
at com.google.gwt.core.client.impl.SchedulerImpl$Flusher.execute(SchedulerImpl.java:78)
at com.google.gwt.core.client.impl.SchedulerImpl.execute(SchedulerImpl.java:138)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessagesWhileWaitingForReturn(BrowserChannelServer.java:337)
at com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:218)
at com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
at com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:561)
at com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:269)
at com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
at com.google.gwt.core.client.impl.Impl.apply(Impl.java)
at com.google.gwt.core.client.impl.Impl.entry0(Impl.java:213)
at sun.reflect.GeneratedMethodAccessor54.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
at com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
at com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:172)
at com.google.gwt.dev.shell.BrowserChannelServer.reactToMessages(BrowserChannelServer.java:292)
at com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:546)
at com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:363)
at java.lang.Thread.run(Thread.java:662)


excerp of the implementation:


// Store
store = new ListStore<UserDTO>(props.key());


loader = new KdoCrudLoader(service, (ListStore) store);




// Toolbar zum Blättern
final PagingToolBar toolBar = new PagingToolBar(5);
toolBar.getElement().getStyle().setProperty("borderBottom", "none");
toolBar.bind((PagingLoader) loader);


UserColumnConfig ucc = new UserColumnConfig(props);
ColumnModel<UserDTO> cm = new ColumnModel<UserDTO>((List) ucc.getList());


Grid<UserDTO> grid = new Grid<UserDTO>(store, cm) {
@Override
protected void onAfterFirstAttach() {
super.onAfterFirstAttach();
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
public void execute() {
loader.load();
}
});
}
};

GridFilters<UserDTO> filters = new GridFilters<UserDTO>(loader);
filters.initPlugin(grid);


KdoCrudLoader.java


public class KdoCrudLoader extends PagingLoader<FilterPagingLoadConfig, PagingLoadResult<KdoBaseDTO>> {

public KdoCrudLoader(
DataProxy<FilterPagingLoadConfig, PagingLoadResult<KdoBaseDTO>> proxy) {
super(proxy);


}

public KdoCrudLoader(KdoBaseCrudServiceAsync service, ListStore<KdoBaseDTO> store) {
this(new KdoCrudProxy(service));
setRemoteSort(true);

addLoadHandler(new LoadResultListStoreBinding<FilterPagingLoadConfig, KdoBaseDTO, PagingLoadResult<KdoBaseDTO>>(
store));
}


}


KdoCrudProxy.java


public class KdoCrudProxy extends RpcProxy<FilterPagingLoadConfig, PagingLoadResult<KdoBaseDTO>> {


private KdoBaseCrudServiceAsync service;

public KdoCrudProxy(KdoBaseCrudServiceAsync service) {
super();
this.service = service;
}

@Override
public void load(FilterPagingLoadConfig loadConfig,
AsyncCallback<PagingLoadResult<KdoBaseDTO>> callback) {
service.getAll(loadConfig, callback);

}


}


Maybe I'm just doing it wrong. Any ideas?

nstokoe
30 Jan 2012, 12:55 PM
The suggested workaround did not work for me either. I don't have a nice pretty stack trace since at this point I'm testing on a JBoss server and haven't determined the best way to handle client side logging. Any suggestions on that front would be greatly appreciated (in addition to other workarounds for the original problem as well :))

darrellmeyer
30 Jan 2012, 2:42 PM
The PagingLoader must override the newLoadConfig method and return a FilterLoadConfig instance. As in:


final PagingLoader<FilterPagingLoadConfig, PagingLoadResult<Stock>> remoteLoader = new PagingLoader<FilterPagingLoadConfig, PagingLoadResult<Stock>>(
proxy) {
@Override
protected FilterPagingLoadConfig newLoadConfig() {
return new FilterPagingLoadConfigBean();
}
};

darrellmeyer
30 Jan 2012, 2:44 PM
The bug with the bind method is now fixed in SVN. I also added paging to the remote filter grid example. You can see the current code here:

http://staging.sencha.com:8080/examples-dev/#ExamplePlace:remotefiltergrid

Without this change, you can still get paging to work by simple casting the loader in the bind method (as mentioned by colin). I tested this and it works before making the change to the toolbar.

binarious
31 Jan 2012, 5:26 AM
This works for me. Thank you for the fast response.

PhiLho
1 Feb 2012, 2:27 AM
[I] haven't determined the best way to handle client side logging. Any suggestions on that front would be greatly appreciated
GWT has some primitive logging facilities out of the box, and I started to use GWT-log (http://code.google.com/p/gwt-log/) for this, as it offers extra flexibility / features / nicer output.

rohdef
1 Feb 2012, 2:51 AM
GWT has some primitive logging facilities out of the box, and I started to use GWT-log (http://code.google.com/p/gwt-log/) for this, as it offers extra flexibility / features / nicer output.

I can confirm that GWT-log is quite useful. I'm especially fond of the div-logger, so I can see the logs in a panel my app, which I disable on deploy.

nstokoe
1 Feb 2012, 11:32 AM
Casting the loader as a PagingLoader seems to work. The one thing I'm missing how the server method for returning filtered, paged, and sorted results would look. Could you post a sample of the new getStocks method that works with the updated example?

Colin Alworth
12 Feb 2012, 5:22 PM
The server code will probably be pretty specific to your particular backend - any kind of database probably provides features to filter or sort that would be much faster than implementing your own in your app server.

To send back the results, they should be packaged in a PagingLoadResult when they get to the loader so it can see how much data is left, and inform the store, toolbar. The sample code you posted seems to indicate that there is some DataProxy<FilterPagingLoadConfig, PagingLoadResult<KdoBaseDTO>> instance called 'service' that is actually being passed into your loader, but I don't see where that is defined, or how it is getting the data.

If using RPC, return an instance of PagingLoadResultBean<KdoBaseDOT>, having set the data, totallength, and offset, either in the constructor or with setters. If using RequestFactory, you'll need to indicate a specific class to return - RF has some issues with generic data (check out the examples sources at http://www.sencha.com/examples-dev/#ExamplePlace:requestfactorygrid). Using JSON or XML, you'll just create a PagingLoadResult instance from the data sent back from the server (there are no paging examples of this, but http://www.sencha.com/examples-dev/#ExamplePlace:jsongrid should give you the right idea).