001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.extensions.markup.html.repeater.data.table.filter;
018
019import java.util.LinkedList;
020import java.util.List;
021
022import org.apache.wicket.Component;
023import org.apache.wicket.behavior.Behavior;
024import org.apache.wicket.extensions.markup.html.repeater.data.table.AbstractToolbar;
025import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable;
026import org.apache.wicket.extensions.markup.html.repeater.data.table.IColumn;
027import org.apache.wicket.extensions.markup.html.repeater.data.table.IStyledColumn;
028import org.apache.wicket.markup.ComponentTag;
029import org.apache.wicket.markup.html.list.ListItem;
030import org.apache.wicket.markup.html.list.ListView;
031import org.apache.wicket.model.IModel;
032import org.apache.wicket.util.lang.Args;
033import org.apache.wicket.util.string.Strings;
034
035
036/**
037 * Toolbar that creates a form to hold form components used to filter data in the data table. Form
038 * components are provided by columns that implement IFilteredColumn.
039 * 
040 * @author Igor Vaynberg (ivaynberg)
041 */
042public class FilterToolbar extends AbstractToolbar
043{
044        private static final String FILTER_ID = "filter";
045        private static final long serialVersionUID = 1L;
046
047        /**
048         * Constructor
049         * 
050         * @param table
051         *            data table this toolbar will be added to
052         * @param form
053         *            the filter form
054         * @param <T>
055         *            the type of the DataTable's model object
056         * @param <S>
057         *            the type of the DataTable's sorting parameter
058         * @param <F>
059         *            the type of filter state object
060         * 
061         */
062        public <T, S, F> FilterToolbar(final DataTable<T, S> table, final FilterForm<F> form)
063        {
064                super(table);
065
066                Args.notNull(table, "table");
067                
068                IModel<List<IColumn<T, S>>> model = new IModel<>() {
069                        private static final long serialVersionUID = 1L;
070
071                        @Override
072                        public List<IColumn<T, S>> getObject() {
073                                return new LinkedList<>(table.getColumns());
074                        }
075                };
076
077                // populate the toolbar with components provided by filtered columns
078                ListView<IColumn<T, S>> filters = new ListView<>("filters", model)
079                {
080                        private static final long serialVersionUID = 1L;
081
082                        @Override
083                        protected void populateItem(ListItem<IColumn<T, S>> item)
084                        {
085                                final IColumn<T, S> col = item.getModelObject();
086                                item.setRenderBodyOnly(true);
087
088                                Component filter = null;
089
090                                if (col instanceof IFilteredColumn)
091                                {
092                                        IFilteredColumn<T, S> filteredCol = (IFilteredColumn<T, S>)col;
093                                        filter = filteredCol.getFilter(FILTER_ID, form);
094                                }
095
096                                if (filter == null)
097                                {
098                                        filter = new NoFilter(FILTER_ID);
099                                }
100                                else
101                                {
102                                        if (!filter.getId().equals(FILTER_ID))
103                                        {
104                                                throw new IllegalStateException(
105                                                        "filter component returned  with an invalid component id. invalid component id [" +
106                                                                filter.getId() +
107                                                                "] required component id [" +
108                                                                getId() +
109                                                                "] generating column [" + col + "] ");
110                                        }
111                                }
112
113                                if (col instanceof IStyledColumn)
114                                {
115                                        filter.add(new Behavior()
116                                        {
117                                                private static final long serialVersionUID = 1L;
118
119                                                /**
120                                                 * @see Behavior#onComponentTag(Component, ComponentTag)
121                                                 */
122                                                @Override
123                                                public void onComponentTag(final Component component, final ComponentTag tag)
124                                                {
125                                                        String className = ((IStyledColumn<?, S>)col).getCssClass();
126                                                        if (!Strings.isEmpty(className))
127                                                        {
128                                                                tag.append("class", className, " ");
129                                                        }
130                                                }
131                                        });
132                                }
133
134                                item.add(filter);
135                        }
136                };
137                filters.setReuseItems(true);
138
139                add(filters);
140        }
141
142        @Override
143        protected void onBeforeRender()
144        {
145                if (findParent(FilterForm.class) == null)
146                {
147                        throw new IllegalStateException("FilterToolbar must be contained within a FilterForm");
148                }
149                super.onBeforeRender();
150        }
151
152}