JoeAB
JoeAB

Reputation: 53

How to update the model for a CheckBoxMultipleChoice?

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

Answers (1)

martin-g
martin-g

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

Related Questions