View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.client.ui.commons.markup.html.form;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  import org.apache.commons.lang3.tuple.MutablePair;
24  import org.apache.commons.lang3.tuple.Pair;
25  import org.apache.wicket.AttributeModifier;
26  import org.apache.wicket.ajax.AjaxRequestTarget;
27  import org.apache.wicket.ajax.markup.html.AjaxLink;
28  import org.apache.wicket.event.Broadcast;
29  import org.apache.wicket.extensions.markup.html.repeater.data.grid.ICellPopulator;
30  import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
31  import org.apache.wicket.markup.html.form.Form;
32  import org.apache.wicket.markup.html.form.IFormSubmitter;
33  import org.apache.wicket.markup.html.panel.Panel;
34  import org.apache.wicket.markup.repeater.Item;
35  import org.apache.wicket.model.IModel;
36  import org.apache.wicket.model.Model;
37  import org.wicketstuff.egrid.column.EditableGridActionsColumn;
38  import org.wicketstuff.egrid.column.EditableGridActionsPanel;
39  import org.wicketstuff.egrid.component.EditableDataTable;
40  import org.wicketstuff.egrid.model.GridOperationData;
41  import org.wicketstuff.egrid.model.OperationType;
42  import org.wicketstuff.egrid.provider.IEditableDataProvider;
43  import org.wicketstuff.egrid.toolbar.EditableGridHeadersToolbar;
44  import org.wicketstuff.egrid.toolbar.EditableGridNavigationToolbar;
45  
46  public class AjaxGrid<K, V, S> extends Panel {
47  
48      private static final long serialVersionUID = 1L;
49  
50      protected static class NonValidatingForm<T> extends Form<T> {
51  
52          protected static final long serialVersionUID = 1L;
53  
54          public NonValidatingForm(final String id) {
55              super(id);
56          }
57  
58          @Override
59          public void process(final IFormSubmitter submittingComponent) {
60              delegateSubmit(submittingComponent);
61          }
62      }
63  
64      protected EditableDataTable<Pair<K, V>, S> dataTable;
65  
66      public AjaxGrid(
67              final String id,
68              final List<? extends IColumn<Pair<K, V>, S>> columns,
69              final IEditableDataProvider<Pair<K, V>, S> dataProvider,
70              final long rowsPerPage) {
71  
72          super(id);
73  
74          List<IColumn<Pair<K, V>, S>> newCols = new ArrayList<>();
75          newCols.addAll(columns);
76          newCols.add(new AjaxGridActionsColumn<>(new Model<>("Actions")));
77  
78          dataTable = new EditableDataTable<>("dataTable", newCols, dataProvider, rowsPerPage, null) {
79  
80              protected static final long serialVersionUID = 1L;
81  
82              @Override
83              protected void onError(final AjaxRequestTarget target) {
84                  AjaxGrid.this.onError(target);
85              }
86  
87              @Override
88              protected Item<Pair<K, V>> newRowItem(final String id, final int index, final IModel<Pair<K, V>> model) {
89                  return super.newRowItem(id, index, model);
90              }
91          };
92  
93          dataTable.setOutputMarkupId(true);
94  
95          dataTable.addTopToolbar(new EditableGridNavigationToolbar(dataTable));
96          if (displayHeader()) {
97              dataTable.addTopToolbar(new EditableGridHeadersToolbar<>(dataTable, dataProvider));
98          }
99          if (displayAdd()) {
100             dataTable.addBottomToolbar(newAddBottomToolbar(dataTable, dataProvider));
101         }
102 
103         Form<Pair<K, V>> form = new NonValidatingForm<>("form");
104         form.setOutputMarkupId(true);
105         form.add(dataTable);
106         add(form);
107     }
108 
109     public AjaxGrid<K, V, S> setTableBodyCss(final String cssStyle) {
110         dataTable.setTableBodyCss(cssStyle);
111         return this;
112     }
113 
114     public AjaxGrid<K, V, S> setTableCss(final String cssStyle) {
115         dataTable.add(AttributeModifier.replace("class", cssStyle));
116         return this;
117     }
118 
119     protected EditableDataTable.RowItem<Pair<K, V>> newRowItem(
120             final String id, final int index, final IModel<Pair<K, V>> model) {
121 
122         return new EditableDataTable.RowItem<>(id, index, model);
123     }
124 
125     protected AjaxGridBottomToolbar<Pair<K, V>, S> newAddBottomToolbar(
126             final EditableDataTable<Pair<K, V>, S> dataTable,
127             final IEditableDataProvider<Pair<K, V>, S> dataProvider) {
128 
129         return new AjaxGridBottomToolbar<>(dataTable) {
130 
131             protected static final long serialVersionUID = 1L;
132 
133             @Override
134             protected Pair<K, V> newRowInstance() {
135                 return new MutablePair<>();
136             }
137 
138             @Override
139             protected void onAdd(final AjaxRequestTarget target, final Pair<K, V> newRow) {
140                 dataProvider.add(newRow);
141                 target.add(dataTable);
142                 AjaxGrid.this.onAdd(target, newRow);
143             }
144 
145             @Override
146             protected void onError(final AjaxRequestTarget target) {
147                 super.onError(target);
148                 AjaxGrid.this.onError(target);
149             }
150         };
151     }
152 
153     protected boolean allowDelete(final Item<Pair<K, V>> rowItem) {
154         return true;
155     }
156 
157     protected boolean displayHeader() {
158         return true;
159     }
160 
161     protected boolean displayAdd() {
162         return true;
163     }
164 
165     protected void onCancel(final AjaxRequestTarget target) {
166     }
167 
168     protected void onDelete(final AjaxRequestTarget target, final IModel<Pair<K, V>> rowModel) {
169     }
170 
171     protected void onSave(final AjaxRequestTarget target, final IModel<Pair<K, V>> rowModel) {
172     }
173 
174     protected void onError(final AjaxRequestTarget target) {
175     }
176 
177     protected void onAdd(final AjaxRequestTarget target, final Pair<K, V> newRow) {
178     }
179 
180     protected class AjaxGridActionsColumn<P, S> extends EditableGridActionsColumn<Pair<K, V>, S> {
181 
182         protected static final long serialVersionUID = 1L;
183 
184         public AjaxGridActionsColumn(final IModel<String> displayModel) {
185             super(displayModel);
186         }
187 
188         @Override
189         public void populateItem(
190                 final Item<ICellPopulator<Pair<K, V>>> item,
191                 final String componentId,
192                 final IModel<Pair<K, V>> rowModel) {
193 
194             item.add(new AjaxGridActionsPanel<>(componentId, item));
195         }
196 
197         @Override
198         protected void onError(final AjaxRequestTarget target, final IModel<Pair<K, V>> rowModel) {
199             AjaxGrid.this.onError(target);
200         }
201 
202         @Override
203         protected void onSave(final AjaxRequestTarget target, final IModel<Pair<K, V>> rowModel) {
204             AjaxGrid.this.onSave(target, rowModel);
205         }
206 
207         @Override
208         protected void onDelete(final AjaxRequestTarget target, final IModel<Pair<K, V>> rowModel) {
209             AjaxGrid.this.onDelete(target, rowModel);
210         }
211 
212         @Override
213         protected void onCancel(final AjaxRequestTarget target) {
214             AjaxGrid.this.onCancel(target);
215         }
216 
217         @Override
218         protected boolean allowDelete(final Item<Pair<K, V>> rowItem) {
219             return AjaxGrid.this.allowDelete(rowItem);
220         }
221     }
222 
223     protected class AjaxGridActionsPanel<T> extends EditableGridActionsPanel<Pair<K, V>> {
224 
225         private static final long serialVersionUID = -1239486389000098745L;
226 
227         private final Item<Pair<K, V>> rowItem;
228 
229         @SuppressWarnings("unchecked")
230         public AjaxGridActionsPanel(final String id, final Item<ICellPopulator<Pair<K, V>>> item) {
231             super(id, item);
232 
233             rowItem = item.findParent(Item.class);
234             addOrReplace(new AjaxLink<String>("delete") {
235 
236                 private static final long serialVersionUID = 1049203640150071039L;
237 
238                 @SuppressWarnings("unchecked")
239                 @Override
240                 public void onClick(final AjaxRequestTarget target) {
241                     EditableDataTable<?, ?> eventTarget = rowItem.findParent(EditableDataTable.class);
242                     send(getPage(), Broadcast.BREADTH, new GridOperationData<>(
243                             OperationType.DELETE, (T) rowItem.getDefaultModelObject(), eventTarget));
244                     target.add(eventTarget);
245                     onDelete(target);
246                 }
247 
248                 @Override
249                 public boolean isVisible() {
250                     return AjaxGridActionsPanel.this.allowDelete(rowItem);
251                 }
252             });
253         }
254 
255         @Override
256         protected void onSave(final AjaxRequestTarget target) {
257             AjaxGrid.this.onSave(target, rowItem.getModel());
258         }
259 
260         @Override
261         protected void onError(final AjaxRequestTarget target) {
262             AjaxGrid.this.onError(target);
263         }
264 
265         @Override
266         protected void onCancel(final AjaxRequestTarget target) {
267             AjaxGrid.this.onCancel(target);
268         }
269 
270         @Override
271         protected void onDelete(final AjaxRequestTarget target) {
272             AjaxGrid.this.onDelete(target, rowItem.getModel());
273         }
274     }
275 }