PDA

View Full Version : How to handle GridFilters on server side correctly?



genobis
31 Aug 2010, 4:20 AM
Hello everyone!

I've found concept of grid filters very promising and started playing with it. Although I had no problems of getting them to work on client side:


GridFilters filters=new GridFilters();
filters.addFilter(new StringFilter("test")); //of course there is a column with corresponding data index
grid.addPlugin(filters);

The filter is visible at column header context menu, but that would be all. Generated URL contains no useful data - there is something like
filters=[com.extjs.gxt.ui.client.data.BaseStringFilterConfig@2c0] which obviously is a result of BaseStringFilterConfig.toString() (or, more accurately, an ArrayList converted to String). Am I doing something wrong?

I'm using HttProxy, JsonPagingLoadResultReader and BasePagingLoader to obtain data. I also made sure, that loader always uses an instance of BaseFilterPagingLoadConfig. GXT version is 2.2 RC. Any advices, please?

sven
31 Aug 2010, 4:31 AM
The HttpProxy cannot handle complex loadconfigs. You need to extend HttpProxy and override the generateUrl method.

genobis
31 Aug 2010, 4:42 AM
Understood. Thank you, in that case it seems to be the best thing I can do right now.

But I have one more idea: if BaseFilterConfig.toString() returned RpcMap.toString() (I mean the map from BaseModelData), the data would be sent correctly. Of course it would still be up to developer to parse it and handle on server side, but at least no data would be lost that way. Or, if that's not possible, it would be good to mention somewhere in HttpProxy api that not all load configs will work with it. Otherwise you can expect more lost souls like me, I'm afraid ;)

pletrox
6 Sep 2010, 7:55 AM
Understood. Thank you, in that case it seems to be the best thing I can do right now.

Did it worked out for you? Can you perhaps give a sample implementation of the overridden generateUrl?

Thanks!
Peter

genobis
9 Sep 2010, 11:43 PM
@pletrox - sorry, I've just read your message. Overriding generateUrl method is, in fact, rather simple thing. The tough part is intepreting it on the server side ;) I'm not finished with it yet, still considering switching to RpcProxy. Anyway, you asked for overriden generateUrl, so here you are:



@Override
protected String generateUrl(Object loadConfig) {
StringBuffer sb = new StringBuffer();
if (loadConfig instanceof ModelData) {
Map<String, Object> map = ((ModelData) loadConfig).getProperties();
for (String key : map.keySet()) {
sb.append("&" + key + "=" + escape(objToString(map.get(key))));
}
}
if (sb.length() > 0) {
return sb.substring(1, sb.length());
}
return sb.toString();
}

protected static String objToString(final Object o) {
if(o instanceof List) {
StringBuilder sb=new StringBuilder();
sb.append("[");
Iterator iterator=((List)o).listIterator();

while(iterator.hasNext()) {
final Object item=iterator.next();
sb.append(objToString(item));
if(iterator.hasNext()) {
sb.append(",");
}
}
sb.append("]");
return sb.toString();
}
else if(o instanceof ModelData) {
Map<String,Object> map=((ModelData)o).getProperties();
return map.toString();
}
else if(o!=null) {
return o.toString();
}
else {
return null;
}
}

protected static native String escape(String data) /*-{
return window.escape(data);
}-*/;


I've been playing with some regular expression to parse it on server, but results are still not satisfying for me. Still, if you are interested...

So if string is:

[{a="r1", b="s2"}, {c="t3"}, { key="value" }]
(Map.toString() does not return values in "", but this can be done quite easily if needed - if you are going to use the first piece of code just don't use map.toString(), but write all entries in key="value" format).
and you have the following code:


Pattern pattern=Pattern.compile(".*?((\\{\\s*((([a-zA-Z0-9]+\\s*\\=\\s*\\\".+?\\\")(\\s*\\,\\s*)?)+)\\s*\\})(\\,\\s*)?).*?");
Matcher matcher=pattern.matcher(string);

while(matcher.find()) {
System.out.println(matcher.group(3));
}
you should get something like

a="r1", b="s2"
c="t3"
key="value"
...which you can parse again, this time back into the map. An expression similar to the first one should do the job. If you think it's overcomplicated... well, I agree, that's why I'm still not sure if it's worth that :)

Hope this helps.
Kind regards,
Tom