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?