0

I want to make a page which displays which Users of my website have the current "Role". Each users have a set of Roles, and a Role is affected to 0 ~ n users.

I'm displaying a basic list with Users's name, and a checkbox for each User. And then a submit button.
When the form is submitted, it will delete the Role from the selected Users.

Most of the time, it's working fine. But there is a problem if the DB' data changed between the page loading and the form submit.

If we are into this situation, it deletes the role from the wrong user!

I've tried different ways, and right now I'm using something like this :

import java.util.LinkedList;
import java.util.List;

import org.apache.wicket.markup.html.WebPage;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.form.Button;
import org.apache.wicket.markup.html.form.CheckBox;
import org.apache.wicket.markup.html.form.StatelessForm;
import org.apache.wicket.markup.html.list.AbstractItem;
import org.apache.wicket.markup.repeater.RepeatingView;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.request.mapper.parameter.PageParameters;


public class Test extends WebPage {
    private static final long serialVersionUID = 1L;


    /**
     * An item used to link the checkbox to the Database Object
     */
    public static class Item {
        private boolean selected = false;
        private int num;

        public Item(final int num) { this.num = num; }
        public final boolean isSelected() { return selected; }
        public final int getNum() { return num; }
        public final void setSelected(boolean selected) { this.selected = selected; }
        public final void setNum(int num) { this.num = num; }
    }



    public Test(final PageParameters params) {
        // This list will hold items we display
        final List<Item> values = new LinkedList<Item>();

        // Our stateless form
        final StatelessForm<Void> form = new StatelessForm<Void>("form") {
            private static final long serialVersionUID = 1L;

            @Override
            protected void onSubmit() {
                // On submit, we check our items to see which ones are selected
                String toDelete = "";

                for (final Item it : values) {
                    if (it.selected) {
                        toDelete += it.getNum() + ", ";
                    }
                }

                System.out.println(toDelete);
            }
        };
        add(form);

        form.add(new Button("submit"));

        // We retrieve our data from the Database
        final List<Integer> things = getFromDatabase();

        // We print them
        final RepeatingView rp = new RepeatingView("li");
        form.add(rp);

        for (int num : things) {
            final AbstractItem item = new AbstractItem(rp.newChildId());
            rp.add(item);

            // We create our holder
            final Item it = new Item(num);
            values.add(it);

            item.add(new Label("name", num));

            // We use the property of our holder as model
            item.add(new CheckBox("checkbox", new PropertyModel<Boolean>(it, "selected")));
        }
    }



    /**
     * Simulate a fetch from the database by swapping our data at each requests
     */
    public static int num = 0;

    private static List<Integer> getFromDatabase() {
        final List<Integer> list = new LinkedList<Integer>();

        if (num++ %2 == 0) {
            list.add(1);
            list.add(2);
        }
        else {
            list.add(2);
            list.add(1);
        }

        return list;
    }
}

and :

<body>
    <form wicket:id="form">
    <ul>
        <li wicket:id="li">
            <span wicket:id="name"></span>
            <input type="checkbox" wicket:id="checkbox" />
        </li>
    </ul>
    <input type="submit" valud="submit" wicket:id="submit" />
    </form>
</body>

I'm simulating a changing DB by swapping values each time the page is requested.

And what happens is that if I select "1" and press submit, it says that it'll delete "2"!

I understand why, but I've no idea how to fix it.

The best way to fix it would be to have something like this:

<input type="checkbox" name="toDelete[]" value="<the_id>" />
<input type="checkbox" name="toDelete[]" value="<the_id>" />
etc.

But I've no idea how to do it with Wicket, and I can't find anything on the Internet =/

So yeah.. any examples / ideas?

Tiller
  • 436
  • 1
  • 4
  • 22
  • Hi Tiller, have you looked at wicket examples tables, lists and repeating views on wicket-library.com/wicket-examples-6.0.x/index.html ?That's a good starting point(look at repeaters section). I found it useful to download wicket examples (from wicket home page) and run them on your machine. That way you can step through the code and understand how the examples work. – Lucas T Nov 29 '13 at 08:29
  • They're using almost only statefull pages :) – Tiller Nov 29 '13 at 09:43
  • How about using an unique identifier (like the primary key) of the row you want to delete instead of the list index for 'num'? – Nicktar Nov 29 '13 at 15:11
  • Yes, I wanted to ask, but I did not want to assume anything. What is num referring to? – Lucas T Nov 30 '13 at 12:05
  • I should have made the example simplier. Num is actually my unique id :) But anyway, don't my problem. I just fixed doing a good-old form, without the Wicket's implementation. – Tiller Dec 01 '13 at 19:50
  • 1
    You are not using any IModel-s to wrap the data. Wicket is constructing the page and serializing everything within the page, also your data. Page constructor is called usually only once, so the data will not be updated. Wrap the data is LoadableDetachableModel, so you can updtate it. – mrak Dec 02 '13 at 14:13

0 Answers0