Reputation: 53
The ClassChoice
control inherits CheckBoxMultipleChoice
. It is a common control used on multiple pages with selections persisted in the session. The available choices are obtained from the database. An "All" checkbox is added when there is more than one data item. On some pages a selection change causes the page to be refreshed with new data. On other page the selections should change without a refresh.
My problem is that I need to control the "All" checkbox when other checkboxes change and to change all of the checkboxes when the "All" checkbox changes.
I tried to call updateModel()
to force a change but that did not work. How can I change the selections (the model
parameter) without refreshing the page?
This edited code does not show page refreshing.
public class ClassChoice<T> extends CheckBoxMultipleChoice
{
private static final long serialVersionUID = 1L;
@SpringBean
private ClassService classService;
List<EntityClassModel> selection;
EntityClassModel ecmAll;
static List<EntityClassModel> availableClasses;
public ClassChoice(..)
{
super("classcheckboxes");
setSuffix(" "); // sets checkbox separator and ensures inline display
ecmAll = (EntityClassModel) modelFactory.getNewClassModel();
ecmAll.setClassname("All");
// List of all classes associated with user
availableClasses = classService.getListOfClasses(..);
setClassChoices();
add( new AjaxFormChoiceComponentUpdatingBehavior()
{
private static final long serialVersionUID = 1L;
@Override
protected void onUpdate(AjaxRequestTarget target)
{
List<Integer> previousIDs = UserSession.get().getSelectedClassIDs();
if ((previousIDs.size() > 0) && ((previousIDs.size() + 1) >= availableClasses.size()))
{
// Was previously Select All
if (selection.get(selection.size() - 1) == ecmAll)
{
// Select All still selected, remove it
selection.remove(selection.size() - 1);
}
else
{
// Remove all selections
selection.clear();
}
}
else if (selection.size() > 0)
{
// Was none or some selected
if (selection.get(selection.size() - 1) == ecmAll)
{
// Select All, select all available
selection.clear();
selection.addAll(availableClasses);
}
else if ((selection.size() + 1) >= availableClasses.size())
{
// Is now full, add Select All
selection.add(ecmAll);
}
// else change but no special handling required
}
// else none are currently selected
UserSession.get().setSelectedClasses(selection);
// Generate a list of selected class IDs, excluding All
List<Integer> selectedIDs = new ArrayList<Integer>();
int copysize = selection.size();
if ((copysize > 0) && (selection.get(copysize - 1) == ecmAll))
{
copysize--;
}
for (int index = 0; index < copysize; index++)
{
selectedIDs.add(selection.get(index).getId());
}
UserSession.get().setSelectedClassIDs(selectedIDs);
// Update the selections on the page
updateModel();
}
});
Initialize();
}
@SuppressWarnings("unchecked")
protected void Initialize()
{
// Grabs already selected classes from UserSession
List<Integer> selectedIDs = UserSession.get().getSelectedClassIDs();
selection = classService.getClassesByClassIDs(selectedIDs);
if (selectedIDs.size() > 1)
{
if ((selectedIDs.size() + 1) >= availableClasses.size())
{
selection.add(ecmAll);
}
}
setModel(Model.ofList(selection));
// Configure the data and display
setChoiceRenderer(new ChoiceRenderer<EntityClassModel>("classname", "id"));
setOutputMarkupId(true);
}
@SuppressWarnings("unchecked")
public void setClassChoices()
{
// Adds 'All' option when there is more than one class
if (availableClasses.size() > 1)
{
availableClasses.add(ecmAll);
}
setChoices(availableClasses);
}
public List<EntityClassModel> getSelection()
{
return selection;
}
}
Upvotes: 0
Views: 246
Reputation: 17513
You have to use the AjaxRequestTarget to update the HTML element on the browser side. By adding/removing elements to selection
you change the model of ClassChoice
at the server side. At the bottom of AjaxFormChoiceComponentUpdatingBehavior#onUpdate() you should do target.add(this)
to tell Wicket to repaint this ClassChoice instance with its new selection/model.
Make sure you call setOutputMarkupId(true)
in its constructor because otherwise you won't be able to update it with Ajax.
Upvotes: 2