I added two Ajax*.javas to make ajax happy.
and changed the final onClick method to non-final. because AjaxOrderByLink have to override it.  ( perhaps I should not do it this way)
And I added another ListSortStateLocator to wrapper a simple List as a ISortStateLocator, then PageableListView/ListView can use  AjaxOrderByLink too .


The original example is like this:

 SortableContactDataProvider dp = new SortableContactDataProvider();
 final DataView dataView = new DataView("oir", dp)
......
datacontainer.add(new OrderByBorder("orderByFirstName", "firstName", dp)
                {
                        protected void onSortChanged()
                        {
                                dataView.setCurrentPage(0);
                        }
                });

now use ajax is as simple as this :

datacontainer.add(new AjaxOrderByBorder("orderByFirstName", "firstName", dp, dataView)
                {
                        protected void onSortChanged()
                        {
                                dataView.setCurrentPage(0);
                        }
                });


and also, to sort a PageableListView :   // borrowed by PageablePage example

 WebMarkupContainer datacontainer = new WebMarkupContainer("data");
                datacontainer.setOutputMarkupId(true);
                add(datacontainer);

                final List list = Arrays.asList(names);
                ISortStateLocator ssl = new ListSortStateLocator(list){
                    protected void sortList(List list,String name, int order){
                        // because I'm lazy, here I just reverse the list.
                        Collections.reverse(list);
                    }
                };

                final PageableListView listview = new PageableListView("rows", list, 10)
                {
                        protected void populateItem(ListItem item)
                        {
                                item.add(new Label("name", item.getModelObjectAsString()));
                        }
                };

                datacontainer.add(listview);

                datacontainer.add(new AjaxOrderByBorder("orderByName", "name", ssl, listview)
                {
                        protected void onSortChanged()
                        {
                                listview.setCurrentPage(0);
                        }
                });


On 6/11/06, Igor Vaynberg <[EMAIL PROTECTED]> wrote:
i checked this into 2.0 trunk earlier today, but im having trouble backporting to 1.2

see DefaultAjaxFallbackDatatable

only supports sorting so far, when i have time i will take a look at your paging patch.

-Igor



On 6/10/06, lu dongping < [EMAIL PROTECTED]> wrote:
I'll try to fix this.


On 6/10/06, Igor Vaynberg < [EMAIL PROTECTED]> wrote:
yep, we dont have support for that yet. datatable and friends were built way before we had ajax support. what we need to do is create an ajaxified order by link and create factory on the headerstoolbar to generate links just like the tabbedpanel does.

this is a bit of work and i dont know if someone has the time to do it right now.

you can either create a bug for it and we will get to it when we can, or do the refactor yourself and provide us with a patch.

i know martijn is interested in working on this but i am unsure about his availability.

-Igor


On 6/9/06, Stefan Kanev < [EMAIL PROTECTED]> wrote:
Hi. Is there a quick way to implement the sorting of the DataTable with AJAX, or should I go rewriting everything from the OrderByLink to the HeadersToolbar?



_______________________________________________
Wicket-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-user






_______________________________________________
Wicket-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-user






_______________________________________________
Wicket-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-user






_______________________________________________
Wicket-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-user



/*
 * $Id: OrderByBorder.java 3345 2005-12-05 08:29:28Z ivaynberg $
 * $Revision: 3345 $
 * $Date: 2005-12-05 16:29:28 +0800 (Mon, 05 Dec 2005) $
 *
 * ====================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wicket.extensions.markup.html.repeater.data.sort;

import wicket.ajax.IAjaxCallDecorator;
import wicket.markup.html.border.Border;
import wicket.markup.html.navigation.paging.IPageable;

/**
 * A component that wraps markup with an OrderByLink. This has the advantage of
 * being able to add the attribute modifier to the wrapping element as opposed
 * to the link, so that it can be attached to &lt;th&gt; or any other element.
 * 
 * For example:
 * 
 * &lt;th wicket:id="order-by-border"&gt;Heading&lt;/th&gt;
 * 
 * 
 * @author Igor Vaynberg ( ivaynberg )
 * 
 */
public class AjaxOrderByBorder extends Border
{
	private static final long serialVersionUID = 1L;

	/**
	 * @param id
	 *            see
	 *            [EMAIL PROTECTED] OrderByLink#OrderByLink(String, String, ISortStateLocator, OrderByLink.ICssProvider) }
	 * @param property
	 *            see
	 *            [EMAIL PROTECTED] OrderByLink#OrderByLink(String, String, ISortStateLocator, OrderByLink.ICssProvider) }
	 * @param stateLocator
	 *            see
	 *            [EMAIL PROTECTED] OrderByLink#OrderByLink(String, String, ISortStateLocator, OrderByLink.ICssProvider) }
	 * @param cssProvider
	 *            see
	 *            [EMAIL PROTECTED] OrderByLink#OrderByLink(String, String, ISortStateLocator, OrderByLink.ICssProvider) }
	 */
	public AjaxOrderByBorder(String id, String property, ISortStateLocator stateLocator,
			OrderByLink.ICssProvider cssProvider)
	{
		this(id,property,stateLocator,cssProvider,null);
	}
	public AjaxOrderByBorder(String id, String property, ISortStateLocator stateLocator, OrderByLink.ICssProvider cssProvider, final IPageable pageable)
	{
		super(id);
		AjaxOrderByLink link = new AjaxOrderByLink("orderByLink", property, stateLocator,
				OrderByLink.VoidCssProvider.getInstance(),pageable,getLinkAjaxCallDecorator()) {
			
			private static final long serialVersionUID = 1L;

			protected void onSortChanged()
			{
				AjaxOrderByBorder.this.onSortChanged();
			}
		};
		add(link);
		add(new OrderByLink.CssModifier(link, cssProvider));
	}        

	/**
	 * This method is a hook for subclasses to perform an action after sort has
	 * changed
	 */
	protected void onSortChanged()
	{
		// noop
	}

	/**
	 * @param id
	 *            see
	 *            [EMAIL PROTECTED] OrderByLink#OrderByLink(String, String, ISortStateLocator)}
	 * @param property
	 *            see
	 *            [EMAIL PROTECTED] OrderByLink#OrderByLink(String, String, ISortStateLocator)}
	 * @param stateLocator
	 *            see
	 *            [EMAIL PROTECTED] OrderByLink#OrderByLink(String, String, ISortStateLocator)}
	 */
	public AjaxOrderByBorder(String id, String property, ISortStateLocator stateLocator)
	{
		this(id, property, stateLocator, OrderByLink.DefaultCssProvider.getInstance());
	}
	public AjaxOrderByBorder(String id, String property, ISortStateLocator stateLocator, final IPageable pageable)
	{
		this(id, property, stateLocator, OrderByLink.DefaultCssProvider.getInstance(),pageable);
	}

        protected IAjaxCallDecorator getLinkAjaxCallDecorator()
	{
		return null;
	}
}





/*
 * $Id: OrderByLink.java 5046 2006-03-21 01:33:42Z joco01 $
 * $Revision: 5046 $
 * $Date: 2006-03-21 09:33:42 +0800 (Tue, 21 Mar 2006) $
 *
 * ====================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wicket.extensions.markup.html.repeater.data.sort;

import java.io.Serializable;

import wicket.AttributeModifier;
import wicket.Component;
import wicket.ajax.AjaxRequestTarget;
import wicket.ajax.IAjaxCallDecorator;
import wicket.ajax.markup.html.IAjaxLink;
import wicket.ajax.markup.html.navigation.paging.AjaxPagingNavigationBehavior;
import wicket.markup.html.link.Link;
import wicket.markup.html.navigation.paging.IPageable;
import wicket.model.AbstractModel;
import wicket.model.IModel;
import wicket.util.lang.Objects;
import wicket.version.undo.Change;

/**
 * A component that represents a sort header. When the link is clicked it will
 * toggle the state of a sortable property within the sort state object.
 * 
 * @author Phil Kulak
 * @author Igor Vaynberg (ivaynberg)
 */
public class AjaxOrderByLink extends OrderByLink implements IAjaxLink
{
	private static final long serialVersionUID = 1L;


	/**
	 * Constructor.
	 * 
	 * @param id
	 *            the component id of the link
	 * @param property
	 *            the name of the sortable property this link represents. this
	 *            value will be used as parameter for sort state object methods.
	 *            sort state object will be located via the stateLocator
	 *            argument.
	 * @param stateLocator
	 *            locator used to locate sort state object that this will use to
	 *            read/write state of sorted properties
	 */
	public AjaxOrderByLink(String id, String property, ISortStateLocator stateLocator)
	{
		this(id, property, stateLocator, DefaultCssProvider.getInstance());
	}
        public AjaxOrderByLink(String id, String property, ISortStateLocator stateLocator,final IPageable pageable, final IAjaxCallDecorator ajaxCallDecorator)
        {
            this(id,property,stateLocator, DefaultCssProvider.getInstance() , pageable, ajaxCallDecorator);
        }

	/**
	 * Constructor.
	 * 
	 * @param id
	 *            the component id of the link
	 * @param property
	 *            the name of the sortable property this link represents. this
	 *            value will be used as parameter for sort state object methods.
	 *            sort state object will be located via the stateLocator
	 *            argument.
	 * @param stateLocator
	 *            locator used to locate sort state object that this will use to
	 *            read/write state of sorted properties
	 * @param cssProvider
	 *            CSS provider that will be used generate the value of class
	 *            attribute for this link
	 * 
	 * @see OrderByLink.ICssProvider
	 * 
	 */
	public AjaxOrderByLink(String id, String property, ISortStateLocator stateLocator,
			ICssProvider cssProvider)
	{
		this(id,property, stateLocator, cssProvider,null,null);
	}

        public AjaxOrderByLink(String id, String property, ISortStateLocator stateLocator,
			ICssProvider cssProvider,final IPageable pageable, final IAjaxCallDecorator ajaxCallDecorator)
	{
		super(id,property, stateLocator, cssProvider);
                add(new AjaxPagingNavigationBehavior(this, pageable, "onclick",ajaxCallDecorator));
		setOutputMarkupId(true);
	}
        
        public void onClick()
	{
                onClick(null);
		// We do not need to redirect
		setRedirect(false);

		// Return the the current page.
		setResponsePage(getPage());
                
	}
        
        public void onClick(final AjaxRequestTarget target) {
            sort();
            onSortChanged();
        }


}





package wicket.extensions.markup.html.repeater.data.sort;

import java.util.Collections;
import java.util.List;
import wicket.markup.html.list.ListView;

/**
 * this class is used to wrapper List to ISortStateLocator .
 * then PageableListView with the same List can be sorted.
 */
public abstract class ListSortStateLocator implements ISortStateLocator{
    
    private final List list ;
    
    /** Creates a new instance of SortableListView */
    public ListSortStateLocator(List list) {
        this.list = list;
    }
    
    /**
     * sort List by name.
     * @param list List to be sorted
     * @param name the property name ordered by
     * @param order asc or desc
     */
    protected abstract void sortList(List list, String name, int order);
    
    private ISortState state = new ISortState(){
        int order = ISortState.ASCENDING;
        
        public void setPropertySortOrder(String name, int order) {
            this.order = order;
            sortList(list,name,order);
        }
        
        public int getPropertySortOrder(String name) {
            return order;
        }
        
    };
    
    public ISortState getSortState() {
        return state;
    }
    
    public void setSortState(ISortState iSortState) {
        state = iSortState;
    }
    
}





/*
 * $Id: OrderByLink.java 5046 2006-03-21 01:33:42Z joco01 $
 * $Revision: 5046 $
 * $Date: 2006-03-21 09:33:42 +0800 (Tue, 21 Mar 2006) $
 *
 * ====================================================================
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package wicket.extensions.markup.html.repeater.data.sort;

import java.io.Serializable;

import wicket.AttributeModifier;
import wicket.Component;
import wicket.markup.html.link.Link;
import wicket.model.AbstractModel;
import wicket.model.IModel;
import wicket.util.lang.Objects;
import wicket.version.undo.Change;

/**
 * A component that represents a sort header. When the link is clicked it will
 * toggle the state of a sortable property within the sort state object.
 * 
 * @author Phil Kulak
 * @author Igor Vaynberg (ivaynberg)
 */
public class OrderByLink extends Link
{
	private static final long serialVersionUID = 1L;

	/** sortable property */
	private String property;

	/** locator for sort state object */
	private ISortStateLocator stateLocator;

	/**
	 * Constructor.
	 * 
	 * @param id
	 *            the component id of the link
	 * @param property
	 *            the name of the sortable property this link represents. this
	 *            value will be used as parameter for sort state object methods.
	 *            sort state object will be located via the stateLocator
	 *            argument.
	 * @param stateLocator
	 *            locator used to locate sort state object that this will use to
	 *            read/write state of sorted properties
	 */
	public OrderByLink(String id, String property, ISortStateLocator stateLocator)
	{
		this(id, property, stateLocator, DefaultCssProvider.getInstance());
	}

	/**
	 * Constructor.
	 * 
	 * @param id
	 *            the component id of the link
	 * @param property
	 *            the name of the sortable property this link represents. this
	 *            value will be used as parameter for sort state object methods.
	 *            sort state object will be located via the stateLocator
	 *            argument.
	 * @param stateLocator
	 *            locator used to locate sort state object that this will use to
	 *            read/write state of sorted properties
	 * @param cssProvider
	 *            CSS provider that will be used generate the value of class
	 *            attribute for this link
	 * 
	 * @see OrderByLink.ICssProvider
	 * 
	 */
	public OrderByLink(String id, String property, ISortStateLocator stateLocator,
			ICssProvider cssProvider)
	{
		super(id);

		if (cssProvider == null)
		{
			throw new IllegalArgumentException("argument [cssProvider] cannot be null");
		}

		if (property == null)
		{
			throw new IllegalArgumentException("argument [sortProperty] cannot be null");
		}

		this.property = property;
		this.stateLocator = stateLocator;
		add(new CssModifier(this, cssProvider));
	}

	/**
	 * @see wicket.markup.html.link.Link
	 */
	public void onClick()
	{
		sort();
		onSortChanged();
	}

	/**
	 * This method is a hook for subclasses to perform an action after sort has
	 * changed
	 */
	protected void onSortChanged()
	{
		// noop
	}

	/**
	 * Re-sort data provider according to this link
	 * 
	 * @return this
	 */
	public final OrderByLink sort()
	{
		if (isVersioned())
		{
			// version the old state
			Change change = new SortStateChange();
			addStateChange(change);
		}

		ISortState state = stateLocator.getSortState();

		int oldDir = state.getPropertySortOrder(property);

		int newDir = ISortState.ASCENDING;

		if (oldDir == ISortState.ASCENDING)
		{
			newDir = ISortState.DESCENDING;
		}

		state.setPropertySortOrder(property, newDir);

		return this;
	}

	private final class SortStateChange extends Change
	{
		private static final long serialVersionUID = 1L;

		private final ISortState old = (ISortState)Objects.cloneModel(stateLocator.getSortState());

		/**
		 * @see wicket.version.undo.Change#undo()
		 */
		public void undo()
		{
			stateLocator.setSortState(old);
		}

		/**
		 * @see java.lang.Object#toString()
		 */
		public String toString()
		{
			return "[StateOrderChange old=" + old.toString() + "]";
		}
	}


	/**
	 * Uses the specified ICssProvider to add css class attributes to the link.
	 * 
	 * @author Igor Vaynberg ( ivaynberg )
	 * 
	 */
	public static class CssModifier extends AttributeModifier
	{
		private static final long serialVersionUID = 1L;


		/**
		 * @param link
		 *            the link this modifier is being added to
		 * @param provider
		 *            implementation of ICssProvider
		 */
		public CssModifier(final OrderByLink link, final ICssProvider provider)
		{
			super("class", true, new AbstractModel()
			{
				private static final long serialVersionUID = 1L;

				public IModel getNestedModel()
				{
					return null;
				}

				public Object getObject(Component component)
				{

					final ISortState sortState = link.stateLocator.getSortState();
					return provider.getClassAttributeValue(sortState, link.property);
				}

				public void setObject(Component component, Object object)
				{
					throw new UnsupportedOperationException();
				}

			});
		}


		/**
		 * @see wicket.AttributeModifier#isEnabled()
		 */
		public boolean isEnabled()
		{
			return getReplaceModel().getObject(null) != null;
		}


	};


	/**
	 * Interface used to generate values of css class attribute for the anchor
	 * tag If the generated value is null class attribute will not be added
	 * 
	 * @author igor
	 */
	public static interface ICssProvider extends Serializable
	{
		/**
		 * @param state
		 *            current sort state
		 * @param property
		 *            sort property represented by the [EMAIL PROTECTED] OrderByLink}
		 * @return the value of the "class" attribute for the given sort
		 *         state/sort property combination
		 */
		public String getClassAttributeValue(ISortState state, String property);
	}


	/**
	 * Easily constructible implementation of ICSSProvider
	 * 
	 * @author Igor Vaynberg (ivaynberg)
	 * 
	 */
	public static class CssProvider implements ICssProvider
	{
		private static final long serialVersionUID = 1L;

		private String ascending;

		private String descending;

		private String none;

		/**
		 * @param ascending
		 *            css class when sorting is ascending
		 * @param descending
		 *            css class when sorting is descending
		 * @param none
		 *            css class when not sorted
		 */
		public CssProvider(String ascending, String descending, String none)
		{
			this.ascending = ascending;
			this.descending = descending;
			this.none = none;
		}

		/**
		 * @see wicket.extensions.markup.html.repeater.data.sort.OrderByLink.ICssProvider#getClassAttributeValue(wicket.extensions.markup.html.repeater.data.sort.ISortState,
		 *      java.lang.String)
		 */
		public String getClassAttributeValue(ISortState state, String property)
		{
			int dir = state.getPropertySortOrder(property);
			if (dir == ISortState.ASCENDING)
			{
				return ascending;
			}
			else if (dir == ISortState.DESCENDING)
			{
				return descending;
			}
			else
			{
				return none;
			}
		}
	}

	/**
	 * Convineince implementation of ICssProvider that always returns a null and
	 * so never adds a class attribute
	 * 
	 * @author Igor Vaynberg ( ivaynberg )
	 */
	public static class VoidCssProvider extends CssProvider
	{
		private static final long serialVersionUID = 1L;

		private static ICssProvider instance = new VoidCssProvider();

		/**
		 * @return singleton instance
		 */
		public static ICssProvider getInstance()
		{
			return instance;
		}

		private VoidCssProvider()
		{
			super("", "", "");
		}
	}

	/**
	 * Default implementation of ICssProvider
	 * 
	 * @author Igor Vaynberg ( ivaynberg )
	 */
	public static class DefaultCssProvider extends CssProvider
	{
		private static final long serialVersionUID = 1L;

		private static DefaultCssProvider instance = new DefaultCssProvider();

		private DefaultCssProvider()
		{
			super("wicket_orderUp", "wicket_orderDown", "wicket_orderNone");
		}

		/**
		 * @return singleton instance
		 */
		public static DefaultCssProvider getInstance()
		{
			return instance;
		}
	}

}





_______________________________________________
Wicket-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/wicket-user

Reply via email to