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;
018
019import java.util.Iterator;
020import java.util.LinkedList;
021import java.util.List;
022
023import org.apache.wicket.AttributeModifier;
024import org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortStateLocator;
025import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;
026import org.apache.wicket.extensions.markup.html.repeater.data.table.DataTable.CssAttributeBehavior;
027import org.apache.wicket.markup.html.WebMarkupContainer;
028import org.apache.wicket.markup.repeater.Item;
029import org.apache.wicket.markup.repeater.RefreshingView;
030import org.apache.wicket.model.IModel;
031import org.apache.wicket.model.Model;
032
033
034/**
035 * Toolbars that displays column headers. If the column is sortable a sortable header will be
036 * displayed.
037 * 
038 * @param <S>
039 *            the type of the sorting parameter
040 * @see DefaultDataTable
041 * 
042 * @author Igor Vaynberg (ivaynberg)
043 * 
044 */
045public class HeadersToolbar<S> extends AbstractToolbar
046{
047        private static final long serialVersionUID = 1L;
048
049        /**
050         * Constructor
051         * 
052         * @param <T>
053         *            the column data type
054         * @param table
055         *            data table this toolbar will be attached to
056         * @param stateLocator
057         *            locator for the ISortState implementation used by sortable headers
058         */
059        public <T> HeadersToolbar(final DataTable<T, S> table, final ISortStateLocator<S> stateLocator)
060        {
061                super(table);
062
063                RefreshingView<IColumn<T, S>> headers = new RefreshingView<IColumn<T, S>>("headers")
064                {
065                        private static final long serialVersionUID = 1L;
066
067                        @Override
068                        protected Iterator<IModel<IColumn<T, S>>> getItemModels()
069                        {
070                                List<IModel<IColumn<T, S>>> columnsModels = new LinkedList<>();
071
072                                for (IColumn<T, S> column : table.getColumns())
073                                {
074                                        columnsModels.add(Model.of(column));
075                                }
076
077                                return columnsModels.iterator();
078                        }
079
080                        @Override
081                        protected void populateItem(Item<IColumn<T, S>> item)
082                        {
083                                final IColumn<T, S> column = item.getModelObject();
084
085                                WebMarkupContainer header;
086
087                                if (column.isSortable())
088                                {
089                                        header = newSortableHeader("header", column.getSortProperty(), stateLocator);
090                                }
091                                else
092                                {
093                                        header = new WebMarkupContainer("header");
094                                }
095
096                                if (column instanceof IStyledColumn)
097                                {
098                                        CssAttributeBehavior cssAttributeBehavior = new DataTable.CssAttributeBehavior()
099                                        {
100                                                private static final long serialVersionUID = 1L;
101
102                                                @Override
103                                                protected String getCssClass()
104                                                {
105                                                        return ((IStyledColumn<?, S>)column).getCssClass();
106                                                }
107                                        };
108
109                                        header.add(cssAttributeBehavior);
110                                }
111
112                                if (column.getHeaderColspan() > 1) {
113                                        header.add(AttributeModifier.replace("colspan", column.getHeaderColspan()));
114                                        header.add(AttributeModifier.replace("scope", "colgroup"));
115                                } else {
116                                        header.add(AttributeModifier.replace("scope", "col"));
117                                }
118
119                                if (column.getHeaderRowspan() > 1) {
120                                        header.add(AttributeModifier.replace("rowspan", column.getHeaderRowspan()));
121                                }
122
123                                item.add(header);
124                                item.setRenderBodyOnly(true);
125                                header.add(column.getHeader("label"));
126                        }
127                };
128                add(headers);
129        }
130
131        /**
132         * Factory method for sortable header components. A sortable header component must have id of
133         * <code>headerId</code> and conform to markup specified in <code>HeadersToolbar.html</code>
134         * 
135         * @param headerId
136         *            header component id
137         * @param property
138         *            property this header represents
139         * @param locator
140         *            sort state locator
141         * @return created header component
142         */
143        protected WebMarkupContainer newSortableHeader(final String headerId, final S property,
144                final ISortStateLocator<S> locator)
145        {
146                return new OrderByBorder<S>(headerId, property, locator)
147                {
148                        private static final long serialVersionUID = 1L;
149
150                        @Override
151                        protected void onSortChanged()
152                        {
153                                getTable().setCurrentPage(0);
154                        }
155                };
156        }
157}