This is a solution about updating listView by filtering with text input.
1-First you need to create 2 classes :
I-FilterAjaxEvent II-OnChangeUpdate
I-FilterAjaxEvent
public class FilterAjaxEvent {
private AjaxRequestTarget target;
private String input;
public FilterAjaxEvent(AjaxRequestTarget target, String input) {
super();
this.target = target;
this.input = input;
}
public FilterAjaxEvent() {
super();
}
public AjaxRequestTarget getTarget() {
return target;
}
public void setTarget(AjaxRequestTarget target) {
this.target = target;
}
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
}
II-OnChangeUpdate
public class OnChangeUpdate extends OnChangeAjaxBehavior{
IModel<String> filterModel;
public OnChangeUpdate(IModel<String> filterModel) {
super();
this.filterModel=filterModel;
}
@Override
protected void onUpdate(AjaxRequestTarget target) {
String input=filterModel.getObject();
this.getComponent().send(this.getComponent().getPage(), Broadcast.DEPTH,
new FilterAjaxEvent(target, input));
}
public IModel<String> getFilterModel() {
return filterModel;
}
public void setFilterModel(IModel<String> filterModel) {
this.filterModel = filterModel;
}
}
2-Then in the HomePage Class you need to declare :
IModel<String> filterModel;
WebMarkupContainer wmc;
IModel<List<User>> filterList;
3-Then in the constructor of the Form Class you need to initialize :
filterModel=Model.of("");
wmc=new WebMarkupContainer("container");
// This is myListView which I want to update
listViewUsers=new Data("list-of-users",Model.ofList(listOfUsers));
//This is my List which I want to display after filtering
filterList=new FiltredListModel(Model.ofList(listOfUsers));
4-In the overrided onInitialize method of the Form Class you have to add :
inputField.add(new OnChangeUpdate(filterModel));
add(inputField);
add(wmc);
wmc.add(listViewUsers);// This is myListView which I want to update
wmc.setOutputMarkupId(true);
5-Create FilterListModel class to filter the first List by checking the existence of each character :
public class FiltredListModel implements IModel<List<User>> {
private IModel<List<User>> listModel;
public FiltredListModel(IModel<List<User>> listModel) {
this.listModel = listModel;
}
@Override
public List<User> getObject() {
if (filterModel.getObject() != null && filterModel.getObject() != "") {
return listModel.getObject().stream()
.filter(c->c.getFirstName().toUpperCase().contains(filterModel.getObject().toUpperCase())
|| c.getLastName().toUpperCase().contains(filterModel.getObject().toUpperCase()))
.collect(Collectors.toList());
}
return listModel.getObject();
}
}
6-Finally you have to catch the event while changing the filter input, so you should create overrided method onEvent in the HomePage class :
@Override
public void onEvent(@Nullable IEvent event) {
super.onEvent(event);
if (event.getPayload() instanceof FilterAjaxEvent) {
FilterAjaxEvent filterAjaxEvent = (FilterAjaxEvent) event.getPayload();
filterModel.setObject(filterAjaxEvent.getInput());
String filter=filterModel.getObject();
if(filter!=null || filter!="") {
listViewUsers.setList(filterList.getObject());
}
filterAjaxEvent.getTarget().add(get("container"));
}
}
Trying many solutions (OnChangeAjaxBehavior, AjaxRequestTarget ,AjaxLink) but this is the simple one and easy to understand.