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.