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.sort; 018 019import org.apache.wicket.core.util.string.CssUtils; 020import org.apache.wicket.markup.ComponentTag; 021import org.apache.wicket.markup.html.border.Border; 022import org.apache.wicket.util.string.Strings; 023 024/** 025 * A component that wraps markup with an OrderByLink. This has the advantage of being able to add 026 * the attribute modifier to the wrapping element as opposed to the link, so that it can be attached 027 * to <th> or any other element. 028 * 029 * For example: 030 * 031 * <th wicket:id="order-by-border">Heading</th> 032 * 033 * @param <S> 034 * the type of the sorting parameter 035 * @author Igor Vaynberg ( ivaynberg ) 036 * 037 */ 038public class OrderByBorder<S> extends Border 039{ 040 private static final long serialVersionUID = 1L; 041 042 public static final String SORT_ASCENDING_CSS_CLASS_KEY = CssUtils.key(OrderByLink.class, "ascending"); 043 044 public static final String SORT_DESCENDING_CSS_CLASS_KEY = CssUtils.key(OrderByLink.class, "descending"); 045 046 public static final String SORT_NONE_CSS_CLASS_KEY = CssUtils.key(OrderByLink.class, "none"); 047 048 private final ISortStateLocator<S> stateLocator; 049 050 private final S property; 051 052 /** 053 * @param id 054 * see 055 * {@link OrderByLink#OrderByLink(java.lang.String, java.lang.Object, org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortStateLocator) } 056 * @param property 057 * see 058 * {@link OrderByLink#OrderByLink(java.lang.String, java.lang.Object, org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortStateLocator) } 059 * @param stateLocator 060 * see 061 * {@link OrderByLink#OrderByLink(java.lang.String, java.lang.Object, org.apache.wicket.extensions.markup.html.repeater.data.sort.ISortStateLocator) } 062 */ 063 public OrderByBorder(final String id, final S property, 064 final ISortStateLocator<S> stateLocator) 065 { 066 super(id); 067 068 this.stateLocator = stateLocator; 069 this.property = property; 070 071 OrderByLink<S> link = newOrderByLink("orderByLink", property, stateLocator); 072 addToBorder(link); 073 } 074 075 /** 076 * create new sort order toggling link 077 * 078 * @param id 079 * component id 080 * @param property 081 * sort property 082 * @param stateLocator 083 * sort state locator 084 * @return link 085 */ 086 protected OrderByLink<S> newOrderByLink(final String id, final S property, 087 final ISortStateLocator<S> stateLocator) 088 { 089 return new OrderByLink<S>(id, property, stateLocator) 090 { 091 private static final long serialVersionUID = 1L; 092 093 @Override 094 protected void onSortChanged() 095 { 096 OrderByBorder.this.onSortChanged(); 097 } 098 }; 099 } 100 101 /** 102 * This method is a hook for subclasses to perform an action after sort has changed 103 */ 104 protected void onSortChanged() 105 { 106 // noop 107 } 108 109 @Override 110 public void onComponentTag(final ComponentTag tag) 111 { 112 super.onComponentTag(tag); 113 114 final ISortState<S> sortState = stateLocator.getSortState(); 115 116 SortOrder dir = sortState.getPropertySortOrder(property); 117 String cssClass; 118 if (dir == SortOrder.ASCENDING) 119 { 120 cssClass = getString(SORT_ASCENDING_CSS_CLASS_KEY); 121 } 122 else if (dir == SortOrder.DESCENDING) 123 { 124 cssClass = getString(SORT_DESCENDING_CSS_CLASS_KEY); 125 } 126 else 127 { 128 cssClass = getString(SORT_NONE_CSS_CLASS_KEY); 129 } 130 131 if (!Strings.isEmpty(cssClass)) 132 { 133 tag.append("class", cssClass, " "); 134 } 135 136 } 137 138}