1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.syncope.client.ui.commons.markup.html.form;
20
21 import java.util.List;
22 import org.apache.syncope.client.ui.commons.Constants;
23 import org.apache.syncope.client.ui.commons.ajax.markup.html.IndicatorAjaxSubmitLink;
24 import org.apache.syncope.client.ui.commons.pages.BaseWebPage;
25 import org.apache.wicket.ajax.AjaxRequestTarget;
26 import org.apache.wicket.markup.html.WebMarkupContainer;
27 import org.apache.wicket.markup.html.basic.Label;
28 import org.apache.wicket.markup.html.form.Form;
29 import org.apache.wicket.markup.html.list.ListItem;
30 import org.apache.wicket.markup.html.list.ListView;
31 import org.apache.wicket.markup.html.panel.Fragment;
32 import org.apache.wicket.markup.html.panel.Panel;
33 import org.apache.wicket.model.IModel;
34 import org.apache.wicket.model.ResourceModel;
35 import org.springframework.util.CollectionUtils;
36
37 public abstract class AbstractMultiPanel<INNER> extends AbstractFieldPanel<List<INNER>> {
38
39 private static final long serialVersionUID = -6322397761456513324L;
40
41 private final ListView<INNER> view;
42
43 private final WebMarkupContainer container;
44
45 private final Form<?> form;
46
47 public AbstractMultiPanel(
48 final String id,
49 final String name,
50 final IModel<List<INNER>> model) {
51
52 super(id, name, model);
53
54
55
56
57 container = new WebMarkupContainer("multiValueContainer");
58 container.setOutputMarkupId(true);
59 add(container);
60
61 form = new Form<>("innerForm");
62 form.setDefaultButton(null);
63 container.add(form);
64
65
66 view = new InnerView("view", name, model);
67
68 if (CollectionUtils.isEmpty(model.getObject())) {
69 form.addOrReplace(getNoDataFragment(model, name));
70 } else {
71 form.addOrReplace(getDataFragment());
72 }
73 }
74
75
76 public AbstractMultiPanel<INNER> setFormAsMultipart(final boolean multipart) {
77 form.setMultiPart(multipart);
78 return this;
79 }
80
81 private Fragment getNoDataFragment(final IModel<List<INNER>> model, final String label) {
82 Fragment fragment = new Fragment("content", "noDataFragment", AbstractMultiPanel.this);
83 fragment.add(new Label("field-label", new ResourceModel(label, label)));
84 fragment.add(getPlusFragment(model));
85 return fragment;
86 }
87
88 private Fragment getDataFragment() {
89 Fragment contentFragment = new Fragment("content", "dataFragment", AbstractMultiPanel.this);
90 contentFragment.add(view.setOutputMarkupId(true));
91 return contentFragment;
92 }
93
94 private Fragment getPlusFragment(final IModel<List<INNER>> model) {
95 IndicatorAjaxSubmitLink plus = new IndicatorAjaxSubmitLink("add") {
96
97 private static final long serialVersionUID = -7978723352517770644L;
98
99 @Override
100 protected void onSubmit(final AjaxRequestTarget target) {
101
102 model.getObject().add(newModelObject());
103
104 if (model.getObject().size() == 1) {
105 form.addOrReplace(getDataFragment());
106 }
107
108 target.add(container);
109 }
110
111 @Override
112 protected void onError(final AjaxRequestTarget target) {
113 sendError(getString(Constants.OPERATION_ERROR));
114 super.onError(target);
115 ((BaseWebPage) getPage()).getNotificationPanel().refresh(target);
116 }
117
118 };
119
120 Fragment fragment = new Fragment("panelPlus", "fragmentPlus", AbstractMultiPanel.this);
121 fragment.addOrReplace(plus);
122 fragment.setRenderBodyOnly(true);
123
124 return fragment;
125 }
126
127 public ListView<INNER> getView() {
128 return view;
129 }
130
131 @Override
132 public AbstractMultiPanel<INNER> setModelObject(final List<INNER> object) {
133 view.setModelObject(object);
134 return this;
135 }
136
137 protected abstract INNER newModelObject();
138
139 protected abstract void sendError(String message);
140
141 private final class InnerView extends ListView<INNER> {
142
143 private static final long serialVersionUID = -9180479401817023838L;
144
145 private final String label;
146
147 private final IModel<List<INNER>> model;
148
149 private InnerView(final String id, final String label, final IModel<List<INNER>> model) {
150 super(id, model);
151 this.label = label;
152 this.model = model;
153 }
154
155 @Override
156 protected void populateItem(final ListItem<INNER> item) {
157 Panel panel = getItemPanel(item);
158
159 item.add(panel.setRenderBodyOnly(true));
160
161 IndicatorAjaxSubmitLink minus = new IndicatorAjaxSubmitLink("drop") {
162
163 private static final long serialVersionUID = -7978723352517770644L;
164
165 @Override
166 protected void onSubmit(final AjaxRequestTarget target) {
167
168 model.getObject().remove(item.getModelObject());
169 clearInput(panel);
170
171 if (model.getObject().isEmpty()) {
172 form.addOrReplace(getNoDataFragment(model, label));
173 }
174
175 target.add(container);
176 }
177
178 @Override
179 protected void onError(final AjaxRequestTarget target) {
180 onSubmit(target);
181 }
182 };
183
184 item.add(minus);
185
186 Fragment fragment = item.getIndex() == model.getObject().size() - 1
187 ? getPlusFragment(model)
188 : new Fragment("panelPlus", "emptyFragment", AbstractMultiPanel.this);
189
190 item.add(fragment.setRenderBodyOnly(true));
191 }
192 }
193
194 protected abstract Panel getItemPanel(ListItem<INNER> item);
195
196 protected void clearInput(final Panel panel) {
197
198 }
199
200 @Override
201 public AbstractFieldPanel<List<INNER>> setReadOnly(final boolean readOnly) {
202 container.setEnabled(!readOnly);
203 return this;
204 }
205
206 public AbstractFieldPanel<List<INNER>> setFormReadOnly(final boolean readOnly) {
207 form.setEnabled(!readOnly);
208 return this;
209 }
210 }