GXT Grid filtering a store - java

I understand that in GXT 3.0 grids are pulling their data from a store (in my case a list store). I am trying to implement a search function to help filter through some of the results in the grid dynamically. However, I am having trouble determining the best method to do this. I have considered doing this server side by modifying the source file..but ultimately I just want to toggle the displaying of a row if it doesn't contain a desired string. Any suggestions for how to best approach this?

You can try using store filter to toggle displaying row that contains the string you desired. Here is the example code:
ListStore<YourModelData> listStore = new ListStore<YourModelData>(yourPropertiesObject.key());
StoreFilter<YourModelData> sf = new StoreFilter<YourModelData>() {
#Override
public boolean select(Store<YourModelData> store, YourModelData parent,
YourModelData item) {
return item.contains("some-string");
}
};
listStore.addFilter(sf);

Related

Adding/creating a click event for rows to a Vaadin Grid with SelectionMode.MULTI?

I am trying to create a small application where I have various file locations stored in a Vaadin grid, the grid currently only shows two columns - ID and File Name, and I would like to see as a notification the file location too whenever I click on a row.
Meaning, every time I click a row from the grid I would like it to show me the location, using Notification.show(), like that:
(Please ignore the <b></b>s, they are irrelevant.)
As my grids selection model is MULTI, per default the click listener cannot register which row it is clicked on and selecting the row via checkbox is not what I want to have the data displayed. Simply, I would like to get the item for every row I click and have the location displayed as a notification.
So far, I found a solution for a similar issue but it deals with columns and the rows in Vaadin grids are rather different from what I am used to.
public static <T> void addColumnClickListener(Grid<T> grid, Consumer<Column<T>> listener)
{
String expression = "function(){const col=element.getEventContext(event).column;return col ? col.id : '';}()";
grid.getElement().addEventListener("click", e ->
{
String colId = e.getEventData().getString(expression);
Optional<Column<T>> column = grid.getColumns().stream().filter(col -> colId.equals(col.getId().get())).findFirst();
column.ifPresent(listener);
}
).addEventData(expression);
}
And I am to call the function like that:
addColumnClickListener(grid, column -> Notification.show("fubar"));
This code snippet is from the Vaadin forums and I do not quite understand it. The string expression seems to be that it contains possible JavaScript code and the rest overrides the type of the column. (I think, I really do not understand this snippet fully)
Is there any way to do something similar to the snippet above but for rows?
You can do this with an ItemClickListener on the Grid:
grid.addItemClickListener(item -> {
Notification.show(String.format("File location: %s", item.getLocation()));
});

Google Maps Cluster Customization (Adding text to Cluster Item)

1: Example
This picture represents a group of clusters(the ones that have the text in the middle) and a cluster Item, which is only one item of a specific type.
What I'm trying to achieve is that on a cluster item, I want to add some text, for example "1", which represents that is only a cluster item, therefore there is only one item in there.
I managed to get the text working on the group of clusters but not on the cluster item.
The code that does the trick in my case it's this one:
String place = item.getPlaceName();
if (place.length() > 12)
place = place.substring(0, 10) + "..";
placeAddressAndLocation.setText(place);
Now I am not aware where should I place the exact code for the cluster item.
In the example found on google dev(which is the one I'm also following), there are a couple of methods for these
protected void onBeforeClusterItemRendered
protected void onClusterItemRendered
Tried adding the code on both of the methods, but it doesn't do anything. Any suggestions? Thanks!
If you want to use onBeforeClusterItemRendered, you can try with this answer.
So in the onBeforeClusterItemRendered method, you can set the attributes of markerOptions.
You might want to try to set the title, snippet or icon of the markerOptions, you can read the documentation of the markerOptions.

Return list of checked checkboxes from Javascript to Wicket

I am trying to make a filter for a searchfield where a number of checkboxes can be checked to choose what people want to search. I am currently trying to do this with the CheckGroup component but as I do not have a submit button I do not know how I can retrieve the latest checked objects. One thought of doing it was using Javascript, to call a function in Javascript and retrieve all the checkboxes like that. I currently have the following code in Wicket. So my question would be how to do this and if it is possible to not do this with Javascript. I have tried using AjaxFormChoiceComponentBehaviour and that works but since it does a post whenever a checkbox is checked, I think JS would be a better option.
public Filter(String id) {
super(id);
form = new Form("filterform");
types = resultItemHandlerPool.getTypes();
checkGroup = new CheckGroup<Class<?>>("checkGroup", new PropertyModel<Collection<Class<?>>>(this,"types"));
ListView typesListview = new ListView<Class<?>>("typesList", new PropertyModel<List<? extends Class<?>>>(this,"types")) {
#Override
protected void populateItem(final ListItem<Class<?>> item) {
item.add(new Check<Class<?>>("check", item.getModel()));
item.add(new Label("className", item.getModelObject().getSimpleName()));
}
};
typesListview.setReuseItems(true);
checkGroup.add(typesListview);
form.add(checkGroup);
add(form);
}
public List<Class<?>> getSearchableTypes() {
return types;
}
Thanks and kind regards,
Merlijn
You say you want to do the search server side. So, the server needs to know which items are checked in order to do the search.
Just use a plain old form for the searchfield (including checkboxes) and make it so that after entering the search-value the user posts the form. That way, the serverside code will receive the search value and the list of checked checkboxes and will know exactly what to search for.
AjaxFormChoiceComponentBehaviour does indeed update the server side Checkgroup after every click with an ajax post. If you only need to know the value of the Checkgroup after posting the search value, just don't use the AjaxFormChoiceComponentBehaviour and submit the form. Both a normal form submit and an ajax submit will work here.

Alternatives for switch statement

I am developing an Wicket application. But my question is not really Wicket related. In that app I have a horizontal menu. This menu is created by few links. On clicking the link you will be navigated to some page. Now based on the page you are currently viewing the css class attribute of the link of the menu will be changed to "selected". This is the description of the problem.
Now I am solving this problem by using a integer value. The value is saved in the session and it is updated when any one link has been clicked. Based on that saved value, which link will be "selected", will be determined at runtime.
I am implementing this in following way:
//On link click I set a number in session
public void onClick() {
session.setValue(1);// or 2 or 3
}
When the menu is created I switch between the value and modify the css class, as follows:
switch(session.getValue){
case 1: add css to home;
case 2: add css to profile;
// and so on.
}
I was wondering that is this the only right way to do it? Or there some other better techniques or design patterns exist which can help me to achieve this in better way?
Store the menu items in an array (or an ArrayList):
items[0] = home
items[1] = profile
And use the index of the array as menu identifier. When you receive the selected menu itentifier, retrieve the corresponding item with
items[selectedItem]
You could also use a Map if the identifiers are not numbers, or don't go from 0 to N.
For a start, use an enum or static constants instead of magic numbers (1, 2, 3).
The Visitor Pattern is commonly used to avoid this sort of switching. You might not want to implement the full pattern in your case, but it's worth knowning. JB Nizet's answer may be more practical in your situation.
See https://en.wikipedia.org/wiki/Visitor_pattern
These SO questions might give you some ideas, too
Java visitor pattern instead of instanceof switch
Java Enums - Switch statements vs Visitor Pattern on Enums - Performance benefits?
I have implemented it using EnumMap and an Enum type as its key. I have defined an Enum:
public enum NavigationStatus {
HOME,
PROFILE;
}
In session I set the value of the current navigation as:
private NavigationStatus activeUserNavigationStatus;
public NavigationStatus getActiveUserNavigationStatus() {
return activeUserNavigationStatus;
}
public void setActiveUserNavigationStatus(NavigationStatus activeUserNavigationStatus) {
this.activeUserNavigationStatus = activeUserNavigationStatus;
}
Primarily I set it to: setActiveUserNavigationStatus(NavigationStatus.HOME);
Now where the menu is building I created an EnumMap:
EnumMap<NavigationStatus, Component[]> menuMap = new EnumMap<NavigationStatus, Component[]>(NavigationStatus.class);
And added elements to it, as:
menuMap.put(NavigationStatus.HOME, new Component[] { homeContainer, home });
And also on click methods of the links I set the status value:
public void onClick() {
session.setActiveUserNavigationStatus(NavigationStatus.PROFILE);
}
Last of all I checked the current value from the session and set the css class accordingly:
Component[] menuComponents = menuMap.get(getSession().getActiveUserNavigationStatus());
menuComponents[0].add(new AttributeAppender("class", new Model<Serializable>(" active")));
menuComponents[1].add(new AttributeAppender("class", new Model<Serializable>(" active")));
This is without switch statement and combines the idea of JB Nizet's ArrayList index and Oli Charlesworth's Enum.
Thank you.

Wicket ListView not refreshing

I am taking my first steps with Apache Wicket and ran into the following problem. I have a ListView that displays a "delete" link right next to its entries. When the delete link is clicked, the entity represented by the list item is deleted from the database but the list itself does not get updated until I reload the page manually in the browser.
IModel<List<SampleEntity>> sampleEntityListModel = new LoadableDetachableModel<List<SampleEntity>>() {
#Override
protected List<SampleEntity> load() {
return mSampleEntityBA.findAll();
}
};
mListview = new ListView<SampleEntity>("listview", sampleEntityListModel) {
#Override
protected void populateItem(final ListItem<SampleEntity> item) {
item.add(new Label("listlabel", new PropertyModel<String>(item.getModelObject(),
"text")));
item.add(new Link<SampleEntity>("deleteLink", item.getModel()) {
#Override
public void onClick() {
mSampleEntityBA.delete(item.getModelObject());
}
});
}
};
When onClick called, item.getModelObject() pulls from the sampleEntityListModel which in turn calls mSampleEntityBA.findAll(). The model object of sampleEntityListModel will be cached for the duration on the request cycle (until it is detached - which is usually what you want) and is not aware of the call to delete().
In order to refresh the sampleEntityListModel, add a sampleEntityListModel.detach() call just after the delete (sampleEntityListModel must be made final, but this will not cause any extra state to be serialized). This will cause the model to fetch a fresh set of data when the list view is rendered later in the request cycle.
You probably want an AjaxLink instead of that Link, and then you have to make the list refresh, using the tactics described here, possibly adjusting a bit for the fact that the wiki has Wicket 1.3 code instead of 1.4.
But you might also be better off with a different repeater, such as a RefreshingView or a DataView. There are some examples of assorted repeaters here. While none of them are exactly what you're looking for, looking at that code might help.
looks like the problem is that your mSampleEntityBA.findAll(); is returning incorrect data. hard to help without seeing more code.
on a different note, you should really be using DataView when working with database-backed lists.
You might also want to check out JQGrid from the wiQuery project instead of DataView.

Categories