You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by sv...@apache.org on 2018/12/06 20:31:24 UTC
[04/14] wicket git commit: WICKET-6587 CheckBoxSelector allow dynamic
list of CheckBoxes
WICKET-6587 CheckBoxSelector allow dynamic list of CheckBoxes
this closes #292 and closes #293
Project: http://git-wip-us.apache.org/repos/asf/wicket/repo
Commit: http://git-wip-us.apache.org/repos/asf/wicket/commit/7b025aba
Tree: http://git-wip-us.apache.org/repos/asf/wicket/tree/7b025aba
Diff: http://git-wip-us.apache.org/repos/asf/wicket/diff/7b025aba
Branch: refs/heads/WICKET-6563
Commit: 7b025aba9886787c2c707b046f39657f2939afb8
Parents: b5c6a8d
Author: Sven Meier <sv...@apache.org>
Authored: Tue Nov 27 11:14:24 2018 +0100
Committer: Sven Meier <sv...@apache.org>
Committed: Tue Nov 27 11:52:02 2018 +0100
----------------------------------------------------------------------
.../markup/html/form/CheckBoxSelector.java | 74 ++++++-
.../wicket/markup/html/form/CheckSelector.js | 4 +-
.../examples/compref/CheckBoxSelectorPage.html | 93 ++++----
.../examples/compref/CheckBoxSelectorPage.java | 221 ++++++++++++-------
4 files changed, 263 insertions(+), 129 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/wicket/blob/7b025aba/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxSelector.java
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxSelector.java b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxSelector.java
index acea40d..83ae73d 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxSelector.java
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckBoxSelector.java
@@ -16,10 +16,14 @@
*/
package org.apache.wicket.markup.html.form;
-import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
import org.apache.wicket.Component;
-
+import org.apache.wicket.behavior.Behavior;
+import org.apache.wicket.markup.html.WebMarkupContainer;
/**
* A Javascript-based "Select All" checkbox component that works with a loose collection of
@@ -33,31 +37,63 @@ public class CheckBoxSelector extends AbstractCheckSelector
{
private static final long serialVersionUID = 1L;
+ private final Set<CheckBox> connectedCheckBoxes = new HashSet<>();
+
+ private final Behavior cleanup = new Behavior()
+ {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void onRemove(Component component)
+ {
+ connectedCheckBoxes.remove(component);
+ component.remove(this);
+ }
+ };
+
/**
- * Javascript array literal containing the markup IDs of the checkboxes we want to
- * check/uncheck. Example: "['foo', 'bar', 'baz']". Generated by
- * JavascriptUtils.buildMarkupIdJSArrayLiteral().
+ * @param id
+ * The component ID
+ *
+ * @see CheckBoxSelector#getCheckBoxes()
*/
- private final String checkBoxIdArrayLiteral;
+ public CheckBoxSelector(String id)
+ {
+ super(id);
+ }
/**
* @param id
* The component ID
* @param boxes
- * The CheckBoxes this selector will control.
+ * checkBoxes this selector will control
*/
public CheckBoxSelector(String id, CheckBox... boxes)
{
super(id);
- checkBoxIdArrayLiteral = buildMarkupIdJSArrayLiteral(Arrays.asList(boxes));
+ for (CheckBox box : boxes)
+ {
+ connectedCheckBoxes.add(box);
+ box.add(cleanup);
+ }
}
@Override
protected CharSequence getFindCheckboxesFunction()
{
return String.format("Wicket.CheckboxSelector.getCheckboxesFunction(%s)",
- checkBoxIdArrayLiteral);
+ buildMarkupIdJSArrayLiteral(getCheckBoxes()));
+ }
+
+ /**
+ * Override this method to control a dynamic collection of {@link CheckBox}es.
+ *
+ * @return by default returns the checkBoxes passed to the constructor
+ */
+ protected Iterable<? extends CheckBox> getCheckBoxes()
+ {
+ return connectedCheckBoxes;
}
/**
@@ -68,7 +104,7 @@ public class CheckBoxSelector extends AbstractCheckSelector
* The components whose IDs we need
* @return a properly formatted JS array literal
*/
- private String buildMarkupIdJSArrayLiteral(final Iterable<? extends Component> components)
+ private String buildMarkupIdJSArrayLiteral(final Iterable<? extends CheckBox> components)
{
StringBuilder buf = new StringBuilder();
buf.append('[');
@@ -76,7 +112,6 @@ public class CheckBoxSelector extends AbstractCheckSelector
{
for (Component component : components)
{
- component.setOutputMarkupId(true);
buf.append('\'').append(component.getMarkupId()).append("', ");
}
buf.delete(buf.length() - 2, buf.length());
@@ -85,4 +120,21 @@ public class CheckBoxSelector extends AbstractCheckSelector
return buf.toString();
}
+ /**
+ * Utility method to collect all {@link CheckBox}es inside a container.
+ *
+ * @param container
+ * container with checkBoxes
+ * @return all contained checkBoxes
+ */
+ public static final Iterable<CheckBox> collectCheckBoxes(WebMarkupContainer container)
+ {
+ List<CheckBox> checkBoxes = new ArrayList<>();
+
+ container.<CheckBox, Void> visitChildren(CheckBox.class, (child, visit) -> {
+ checkBoxes.add(child);
+ });
+
+ return checkBoxes;
+ }
}
http://git-wip-us.apache.org/repos/asf/wicket/blob/7b025aba/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckSelector.js
----------------------------------------------------------------------
diff --git a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckSelector.js b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckSelector.js
index 66f2e19..5c0bce1 100644
--- a/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckSelector.js
+++ b/wicket-core/src/main/java/org/apache/wicket/markup/html/form/CheckSelector.js
@@ -145,7 +145,9 @@
for (var i = 0; i < checkBoxIDs.length; i++) {
var checkBox = document.getElementById(checkBoxIDs[i]);
- result.push(checkBox);
+ if (checkBox) {
+ result.push(checkBox);
+ }
}
return result;
};
http://git-wip-us.apache.org/repos/asf/wicket/blob/7b025aba/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckBoxSelectorPage.html
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckBoxSelectorPage.html b/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckBoxSelectorPage.html
index 434d8c6..703fef7 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckBoxSelectorPage.html
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckBoxSelectorPage.html
@@ -1,41 +1,52 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
- <head>
- <title>Wicket Examples - component reference</title>
- </head>
- <body>
- <wicket:extend>
-
- <h1>wicket.markup.html.form.CheckGroup</h1>
- <wicket:link><a href="Index.html">[back to the reference]</a></wicket:link>
-
- <p>
- A CheckBoxSelector selects and deselects all Check components under the same CheckGroup as itself
- </p>
- <p>
- <form wicket:id="form">
- CheckGroup:<br/>
- <div wicket:id="checkgroup">
- <input type="checkbox" wicket:id="check1"/> 1
- <input type="checkbox" wicket:id="check2"/> 2
- <input type="checkbox" wicket:id="check3"/> 3
- <input type="checkbox" wicket:id="check4"/> 4
- <input type="checkbox" wicket:id="groupSelector"/> select all
- </div>
- <input type="checkbox" wicket:id="groupSelectorOutside"/> select all (outside group)
- <hr/>
- CheckboxMultipleChoice:
- <div wicket:id="choice"/>
- <input type="checkbox" wicket:id="choiceSelector"/> select all
- <hr/>
- Loose Checkboxes:
- <input type="checkbox" wicket:id="looseCheck1"/> 1
- <input type="checkbox" wicket:id="looseCheck2"/> 2
- <input type="checkbox" wicket:id="looseCheck3"/> 3
- <input type="checkbox" wicket:id="looseCheck4"/> 4
- <input type="checkbox" wicket:id="looseSelector"/> select all
- </form>
- </p>
- </wicket:extend>
-</body>
-</html>
+<?xml version="1.0" encoding="UTF-8"?>
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:wicket="http://wicket.apache.org">
+ <head>
+ <title>Wicket Examples - component reference</title>
+ </head>
+ <body>
+ <wicket:extend>
+
+ <h1>wicket.markup.html.form.CheckGroup</h1>
+ <wicket:link><a href="Index.html">[back to the reference]</a></wicket:link>
+
+ <p>
+ A CheckBoxSelector selects and deselects all Check components under the same CheckGroup as itself
+ </p>
+ <p>
+ <form wicket:id="form">
+ CheckGroup:<br/>
+ <div wicket:id="checkgroup">
+ <input type="checkbox" wicket:id="check1"/> 1
+ <input type="checkbox" wicket:id="check2"/> 2
+ <input type="checkbox" wicket:id="check3"/> 3
+ <input type="checkbox" wicket:id="check4"/> 4
+ <input type="checkbox" wicket:id="groupSelector"/> select all
+ </div>
+ <input type="checkbox" wicket:id="groupSelectorOutside"/> select all (outside group)
+ <hr/>
+ CheckboxMultipleChoice:
+ <div wicket:id="choice"/>
+ <input type="checkbox" wicket:id="choiceSelector"/> select all
+ <hr/>
+ Loose Checkboxes:
+ <input type="checkbox" wicket:id="looseCheck1"/> 1
+ <input type="checkbox" wicket:id="looseCheck2"/> 2
+ <input type="checkbox" wicket:id="looseCheck3"/> 3
+ <input type="checkbox" wicket:id="looseCheck4"/> 4
+ <input type="checkbox" wicket:id="looseSelector"/> select all
+
+ <hr/>
+ Extensible Selector:
+ <ul>
+ <li wicket:id="list">
+ <input type="checkbox" wicket:id="check"/><wicket:label for="check"/>
+ </li>
+ </ul>
+ <input type="checkbox" wicket:id="extensibleSelector"/> select all
+ <input type="submit" value="add a choice" wicket:id="addChoice"/>
+ <input type="submit" value="remove a choice" wicket:id="removeChoice"/>
+ </form>
+ </p>
+ </wicket:extend>
+</body>
+</html>
http://git-wip-us.apache.org/repos/asf/wicket/blob/7b025aba/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckBoxSelectorPage.java
----------------------------------------------------------------------
diff --git a/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckBoxSelectorPage.java b/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckBoxSelectorPage.java
index aa1bcd9..aab653d 100644
--- a/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckBoxSelectorPage.java
+++ b/wicket-examples/src/main/java/org/apache/wicket/examples/compref/CheckBoxSelectorPage.java
@@ -1,76 +1,145 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.wicket.examples.compref;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import org.apache.wicket.examples.WicketExamplePage;
-import org.apache.wicket.markup.html.form.Check;
-import org.apache.wicket.markup.html.form.CheckBox;
-import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice;
-import org.apache.wicket.markup.html.form.CheckBoxSelector;
-import org.apache.wicket.markup.html.form.CheckGroup;
-import org.apache.wicket.markup.html.form.CheckGroupSelector;
-import org.apache.wicket.markup.html.form.CheckboxMultipleChoiceSelector;
-import org.apache.wicket.markup.html.form.Form;
-import org.apache.wicket.model.Model;
-import org.apache.wicket.request.mapper.parameter.PageParameters;
-
-/**
- * An example page for {@link CheckBoxSelector}
- */
-public class CheckBoxSelectorPage extends WicketExamplePage
-{
- private static final long serialVersionUID = 1L;
-
- /**
- * Constructor
- *
- * @param parameters
- * Page parameters
- */
- public CheckBoxSelectorPage(final PageParameters parameters)
- {
- super(parameters);
-
- final Form<?> form = new Form<>("form");
- add(form);
- final CheckGroup<Integer> checkgroup = new CheckGroup<>("checkgroup", Arrays.asList(
- 1, 2, 3, 4));
- form.add(checkgroup);
- checkgroup.add(new Check<>("check1", Model.of(1)));
- checkgroup.add(new Check<>("check2", Model.of(2)));
- checkgroup.add(new Check<>("check3", Model.of(3)));
- checkgroup.add(new Check<>("check4", Model.of(4)));
- // one selector inside the checkgroup...
- checkgroup.add(new CheckGroupSelector("groupSelector"));
-
- // ...and one selector outside the checkgroup
- form.add(new CheckGroupSelector("groupSelectorOutside", checkgroup));
- final CheckBoxMultipleChoice<Integer> choice = new CheckBoxMultipleChoice<>(
- "choice", Model.ofList(new ArrayList<>()), Arrays.asList(1, 2, 3, 4));
- form.add(choice);
- form.add(new CheckboxMultipleChoiceSelector("choiceSelector", choice));
- final CheckBox loose1 = new CheckBox("looseCheck1", Model.of(Boolean.FALSE));
- final CheckBox loose2 = new CheckBox("looseCheck2", Model.of(Boolean.FALSE));
- final CheckBox loose3 = new CheckBox("looseCheck3", Model.of(Boolean.FALSE));
- final CheckBox loose4 = new CheckBox("looseCheck4", Model.of(Boolean.FALSE));
- form.add(loose1, loose2, loose3, loose4);
- form.add(new CheckBoxSelector("looseSelector", loose1, loose2, loose3, loose4));
- }
-}
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.wicket.examples.compref;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.wicket.examples.WicketExamplePage;
+import org.apache.wicket.markup.html.form.Button;
+import org.apache.wicket.markup.html.form.Check;
+import org.apache.wicket.markup.html.form.CheckBox;
+import org.apache.wicket.markup.html.form.CheckBoxMultipleChoice;
+import org.apache.wicket.markup.html.form.CheckBoxSelector;
+import org.apache.wicket.markup.html.form.CheckGroup;
+import org.apache.wicket.markup.html.form.CheckGroupSelector;
+import org.apache.wicket.markup.html.form.CheckboxMultipleChoiceSelector;
+import org.apache.wicket.markup.html.form.Form;
+import org.apache.wicket.markup.html.list.ListItem;
+import org.apache.wicket.markup.html.list.ListView;
+import org.apache.wicket.model.Model;
+import org.apache.wicket.request.mapper.parameter.PageParameters;
+
+/**
+ * An example page for {@link CheckBoxSelector}
+ */
+public class CheckBoxSelectorPage extends WicketExamplePage
+{
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Constructor
+ *
+ * @param parameters
+ * Page parameters
+ */
+ public CheckBoxSelectorPage(final PageParameters parameters)
+ {
+ super(parameters);
+
+ final Form<?> form = new Form<>("form");
+ add(form);
+ final CheckGroup<Integer> checkgroup = new CheckGroup<>("checkgroup", Arrays.asList(
+ 1, 2, 3, 4));
+ form.add(checkgroup);
+ checkgroup.add(new Check<>("check1", Model.of(1)));
+ checkgroup.add(new Check<>("check2", Model.of(2)));
+ checkgroup.add(new Check<>("check3", Model.of(3)));
+ checkgroup.add(new Check<>("check4", Model.of(4)));
+ // one selector inside the checkgroup...
+ checkgroup.add(new CheckGroupSelector("groupSelector"));
+
+ // ...and one selector outside the checkgroup
+ form.add(new CheckGroupSelector("groupSelectorOutside", checkgroup));
+
+ final CheckBoxMultipleChoice<Integer> choice = new CheckBoxMultipleChoice<>(
+ "choice", Model.ofList(new ArrayList<>()), Arrays.asList(1, 2, 3, 4));
+ form.add(choice);
+ form.add(new CheckboxMultipleChoiceSelector("choiceSelector", choice));
+
+ final CheckBox loose1 = new CheckBox("looseCheck1", Model.of(Boolean.FALSE));
+ final CheckBox loose2 = new CheckBox("looseCheck2", Model.of(Boolean.FALSE));
+ final CheckBox loose3 = new CheckBox("looseCheck3", Model.of(Boolean.FALSE));
+ final CheckBox loose4 = new CheckBox("looseCheck4", Model.of(Boolean.FALSE));
+ form.add(loose1, loose2, loose3, loose4);
+ form.add(new CheckBoxSelector("looseSelector", loose1, loose2, loose3, loose4));
+
+ // and one which will get more choices later
+ final List<Integer> extensibleChoices = new ArrayList<>(Arrays.asList(1, 2, 3));
+ final Set<Integer> selected = new HashSet<>();
+ final ListView<Integer> listView = new ListView<Integer>("list", extensibleChoices) {
+ @Override
+ protected void populateItem(final ListItem<Integer> item) {
+ final CheckBox check = new CheckBox("check", new Model<Boolean>() {
+ @Override
+ public Boolean getObject() {
+ return selected.contains(item.getModelObject());
+ }
+
+ @Override
+ public void setObject(Boolean object) {
+ if (object) {
+ selected.add(item.getModelObject());
+ } else {
+ selected.remove(item.getModelObject());
+ }
+ }
+ });
+ check.setLabel(() -> item.getModelObject().toString());
+ item.add(check);
+ }
+ };
+ listView.setReuseItems(true);
+ form.add(listView);
+ form.add(new Button("addChoice") {
+ @Override
+ public void onSubmit() {
+ extensibleChoices.add(extensibleChoices.get(extensibleChoices.size() - 1) + 1);
+ }
+ });
+ form.add(new Button("removeChoice") {
+
+ @Override
+ protected void onConfigure()
+ {
+ super.onConfigure();
+
+ setEnabled(extensibleChoices.size() > 1);
+ }
+
+ public void onSubmit()
+ {
+
+ Integer integer = extensibleChoices.get(extensibleChoices.size() - 1);
+ extensibleChoices.remove(integer);
+ selected.remove(integer);
+ }
+ });
+
+ final CheckBoxSelector extensibleSelector = new CheckBoxSelector("extensibleSelector") {
+ @Override
+ protected Iterable<? extends CheckBox> getCheckBoxes()
+ {
+ return collectCheckBoxes(listView);
+ }
+ };
+ form.add(extensibleSelector);
+ }
+}