I can subclass it of course, but because HtmlDataTable (in createDataModel
method) checks if the DataModel is an instance of SortableDataModel, it will
actually wrap my extended BaseSortableModel into a SortableModel, that will
not use my custom defined comparator.
I would expect that HtmlDataTable to use only BaseSortableModel and every
time a column header link is clicked to notify me by which column the data
to be sorted.
Or maybe I got it wrong. Could you explain in few words how would you
implement a custom sortable model starting from BaseSortableModel?
Thanks.
Catalin
Mike Kienenberger wrote:
>
> It was left that way to provide identical backward compatible behavior.
>
> However, you should be able to subclass (or use) BaseSortableModel
> instead of the default sortable model.
>
> On 11/27/07, CatalinPetrisor <[EMAIL PROTECTED]> wrote:
>>
>> That's a very good idea. However, in the latest svn sources the
>> HtmlDataTable
>> component still uses SortableModel class to set the current sort column.
>> Wouldn't be normal to use BaseSortableModel class to allow extensibility?
>>
>> Thanks.
>>
>>
>> Mike Kienenberger wrote:
>> >
>> > As a first step in this process, I've separated SortableDataModel into
>> > SortableDataModel (current behavior, final, subclass of
>> > BaseSortableDataModel) and BaseSortableDataModel (extendable, works on
>> > Comparators).
>> >
>> > I tested all of the simple examples involving dataTable at one point,
>> > but it's possible that something may have slipped by me that I didn't
>> > notice.
>> >
>> >
>> > On 3/14/07, Mike Kienenberger <[EMAIL PROTECTED]> wrote:
>> >> I took a look at SortableModel and t:dataTable sorting again last
>> >> night. My requirements in most cases are to simply specify a sort
>> >> order in the page code, not to allow end-users to manipulate the sort
>> >> order. From what I can tell, there's no easy way to do this. I
>> >> documented the most effective method I could find on the wiki under a
>> >> "static sorting" subheading, but even that method leaves unnecessary
>> >> links in the column headers.
>> >>
>> >> At the same time, I looked into what it would take to make sorting
>> >> cleaner and more user-friendly.
>> >>
>> >> I came up with a subclass of extended dataTable and a replacement
>> >> SortableModel that did what I wanted for the most part:
>> >>
>> >> <my:sortableDataTable
>> >> preserveDataModel="true"
>> >> value="#{bean.carList}"
>> >> var="car"
>> >> >
>> >> <f:facet name="comparator">
>> >> <my:propertyComparator
>> >> property="style.color"
>> >> descending="true" />
>> >> </f:facet>
>> >> </my:sortableDataTable>
>> >>
>> >> This is based in part on reusing my components for sorting selectItem
>> >> lists. For some reason, couldn't make this work without using
>> >> preserveDataModel. [Strangely enough, doing the same thing with the
>> >> current t:dataTable sort attributes didn't require preserveDataModel.]
>> >>
>> >> In any case, a comparator component can be any UIComponent that
>> >> implements a ComparatorSource interface (ie, public Comparator
>> >> getComparator()), which provides a great deal of flexibility.
>> >>
>> >> The propertyComparator implementation basically does the same thing as
>> >> the internal guts of the current SortableModel, but is pluggable. I
>> >> used beanutils in my comparator rather than EL to process the property
>> >> expression, which also eliminates the "rowObjectGet" hack. An "EL
>> >> comparator" could be implemented if the EL processing features were
>> >> needed.
>> >>
>> >> I think it would be worthwhile to replace the current SortableModel
>> >> with a more generic pluggable one. A good start would be to pull all
>> >> of the property-resolving/comparison out of it, and stick it into a
>> >> comparator like I did. setSortCriteria(List criteria) appears to be
>> >> misnomer since only the first item in the list is used -- using a
>> >> comparator would also solve that issue as you can create
>> >> MultipleComparator that takes a list of other comparators and goes
>> >> through them in order.
>> >>
>> >> Following is what DataTable looks like to make this work. Note that
>> >> this doesn't handle the current sorting options.
>> >>
>> >> protected DataModel createDataModel()
>> >> {
>> >> DataModel dataModel = super.createDataModel();
>> >>
>> >> UIComponent comparatorUIComponent = getComparator();
>> >> Comparator comparator = null;
>> >> if (null != comparatorUIComponent)
>> >> {
>> >> if (comparatorUIComponent instanceof ComparatorSource)
>> >> {
>> >> comparator =
>> >> ((ComparatorSource)comparatorUIComponent).getComparator();
>> >> }
>> >> else
>> >> {
>> >> // TODO: need log error instead
>> >> throw new
>> RuntimeException("comparatorUIComponent
>> >> should
>> >> implement ComparatorSource");
>> >> }
>> >> }
>> >>
>> >> boolean isSortable = null != comparator;
>> >>
>> >> if (isSortable)
>> >> {
>> >> if (!(dataModel instanceof BaseSortableModel))
>> >> {
>> >> dataModel = new BaseSortableModel(dataModel);
>> >> }
>> >>
>> >> ((BaseSortableModel)dataModel).setComparator(comparator);
>> >> }
>> >>
>> >> return dataModel;
>> >> }
>> >>
>> >> After stripping out the comparator stuff from SortableModel, these are
>> >> the major changes:
>> >>
>> >> public void setComparator(Comparator _comparator) {
>> >> this._comparator = _comparator;
>> >> _sort();
>> >> }
>> >>
>> >>
>> >> private void _sort()
>> >> {
>> >> if (null == _comparator)
>> >> {
>> >> // restore unsorted order:
>> >> _baseIndicesList = _sortedIndicesList = null;
>> >> return;
>> >> }
>> >>
>> >> //TODO: support -1 for rowCount:
>> >> int sz = getRowCount();
>> >> if ((_baseIndicesList == null) || (_baseIndicesList.size() !=
>> >> sz))
>> >> {
>> >> // we do not want to mutate the original data.
>> >> // however, instead of copying the data and sorting the
>> copy,
>> >> // we will create a list of indices into the original
>> data,
>> >> and
>> >> // sort the indices. This way, when certain rows are made
>> >> current
>> >> // in this Collection, we can make them current in the
>> >> underlying
>> >> // DataModel as well.
>> >> _baseIndicesList = new IntList(sz);
>> >> }
>> >>
>> >> final int rowIndex = _model.getRowIndex();
>> >>
>> >> _model.setRowIndex(0);
>> >> // Make sure the model has that row 0! (It could be empty.)
>> >> if (_model.isRowAvailable())
>> >> {
>> >> Collections.sort(_baseIndicesList, new
>> >> RowDataComparator(_comparator, _model));
>> >> _sortedIndicesList = null;
>> >> }
>> >>
>> >> _model.setRowIndex(rowIndex);
>> >> }
>> >>
>> >> protected class RowDataComparator implements Comparator
>> >> {
>> >> private Comparator dataComparator = null;
>> >> private DataModel dataModel = null;
>> >>
>> >> public RowDataComparator(Comparator comparator,
>> DataModel
>> >> model)
>> >> {
>> >> this.dataComparator = comparator;
>> >> this.dataModel = model;
>> >> }
>> >>
>> >> public int compare(Object arg1, Object arg2) {
>> >> Integer r1 = (Integer)arg1;
>> >> Integer r2 = (Integer)arg2;
>> >> dataModel.setRowIndex(r1.intValue());
>> >> Object rowData1 = _model.getRowData();
>> >> dataModel.setRowIndex(r2.intValue());
>> >> Object rowData2 = _model.getRowData();
>> >>
>> >> return dataComparator.compare(rowData1, rowData2);
>> >> }
>> >> }
>> >>
>> >>
>> >> Also, here's how I'd like to improve t:selectItems. I've had a custom
>> >> subclass of f:selectItems of this working for awhile. Notice how we
>> >> can reuse the same propertyComparator component. This particular
>> >> implementation can take a list of comparator children and implicitly
>> >> wraps them in a MultipleComparator. That's not really possible with
>> >> a dataTable facet, so we'd want to provide a MultipleComparator
>> >> component.
>> >>
>> >> <my:orderedSelectItems value="#{bean.carList}">
>> >> <my:propertyComparator
>> >> property="style.color"
>> >> descending="false" />
>> >> </my:orderedSelectItems>
>> >>
>> >
>> >
>>
>> --
>> View this message in context:
>> http://www.nabble.com/SortableModel-and-t%3AdataTable-changes-improvements-tf3403639.html#a13967432
>> Sent from the My Faces - Dev mailing list archive at Nabble.com.
>>
>>
>
>
--
View this message in context:
http://www.nabble.com/SortableModel-and-t%3AdataTable-changes-improvements-tf3403639.html#a13976924
Sent from the My Faces - Dev mailing list archive at Nabble.com.