Hi
I have a request to change the behaviour of the sorting feature on our grids.
What the user would like is to have the following behaviour:
rather than having to press shift click.
What would be the recommended approach to achieve this?
Regards
Aidan
Hi Aidan,
You can use the firstSortDirection property and then handle the columnSorting event. The whole code will look like this:
features: [ { name: "Sorting", firstSortDirection: "descending", columnSorting: function (evt, ui) { if((ui.owner.option("firstSortDirection") == ui.direction) && ui.owner.grid.dataSource.settings.sorting.expressions.length != 0) { ui.owner.clearSorting(); return false; } } }
This code will execute when user tries to sort a column for third time as the provided scenario. The clearSorting method removes the current sorting(for all sorted columns) and updates the UI.
Please be aware that this will only work for 15.1. Let me know if you use lower version of IgniteUI so that I can modify my code accordingly.
Hi Hristo,
Thanks for the reply.
Sorry forgot to add the platform info, we are on 14.2 with plan to move to 15.1 but not immediately. If you have a solution for 14.2 that would be great.
Hello,
This should work for 14.2:
columnSorting: function (evt, ui) { if((ui.owner.option("firstSortDirection") == ui.direction) && ui.owner.grid.dataSource.settings.sorting.expressions.length != 0) { var i, se = [], exprs = ui.owner.grid.dataSource.settings.sorting.expressions; for (i = 0; i < exprs.length; i++) { se.push(exprs[i].fieldName) } for (i = 0; i < se.length; i++) { ui.owner.unsortColumn(se[i], undefined) } return false; }}
Please test it in your app and let me know if you have further questions, I will be glad to help.
If you wish to sort and unsort the columns programmatically and preserve the class details, you can use the following. We built a custom UNDO and REDO functionality into the grid and we have two methods to achieve that functionality. Excuse the terrible formatting.
var _sortColumn = function (fieldName, direction) { $(.selector).igGridSorting("sortColumn", fieldName, direction); var colIndex; $.each($(.selector).igGrid("option", "columns"), function (idx) { if (fieldName === this.key) { colIndex = idx; return false; } }); var sorting = $(.selector).data("igGridSorting"), sortStyles = sorting.css, activeHeader; activeHeader = $(.selector).igGrid("headersTable").find("th").eq(colIndex); activeHeader.addClass(direction === "asc" ? sortStyles.ascendingColumnHeader : sortStyles.descendingColumnHeader); activeHeader.addClass(sortStyles.sortableColumnHeaderActive); sorting._currentActiveHeader = activeHeader; $(.selector).find("tr td:nth-child(" + (colIndex + 1) + ")").addClass(direction === "asc" ? sortStyles.ascendingColumn : sortStyles.descendingColumn); }; var _unsortColumn = function () { $(.selector).data("igGrid").dataSource.settings.sorting.expressions.clear(); // step 1 var settings = $(.selector).data("igGridSorting"); var header = $.grep(settings._headers, function (column) { return column.header[0].id === id + '_' + settings._curColKey; }); var columnSetting = $.grep(settings.options.columnSettings, function (columnSetting) { return columnSetting.columnKey === settings._curColKey; }); delete columnSetting[0].currentSortDirection; // step 2 var mode = settings.options.mode; settings.options.mode = "multi"; // step 3 $(.selector).igGridSorting("unsortColumn", header[0].index, header[0].header); // step 4 settings.options.mode = mode; // step 5 $(.selector).igGrid("dataBind"); // step 6 };
Hi,
Thank you for sharing your solution with the other community members ! It is a nice workaround for the sorting mode limiatation. You can also use the suggested above expressions.clear() method if having a column always sorted breaks your scenario in some way.
Please let me know if I may be of any further assistance to you.
Thanks for the update.
In the meantime I adopted your code and this is what I have working now. Posting it so others coming across this post can compare and contrast.
We have a column that is always sorted descending by default, this played well since it allowed the unsort to become a resort on that default column and the CSS and visual clues worked nicely of us.
features: [{ name: 'Sorting', type: 'remote', mode: 'single', applySortedColumnCss: false, // remove default sort background color but leave visual clue in header columnSorting: function (evt, ui) { if ((ui.owner.option("firstSortDirection") == ui.direction) && ui.owner.grid.dataSource.settings.sorting.expressions.length != 0) { if (ui.owner.grid.dataSource.settings.sorting.expressions[0].fieldName == ui.columnKey && ui.columnKey != "NameOfYourDefaultSortedColumn") { // our grid has a default sort column so sort by it in order to remove current sort. $(gridElement).igGridSorting("sortColumn", "NameOfYourDefaultSortedColumn", "descending"); return false; } } return true; }}]
Thanks again for your help.
Hello Aidan,
I missed to say that the suggested will work only for multi mode sorting and you are using single mode. This is why I modified my code and now it looks like:
columnSorting: function (evt, ui) { if((ui.owner.option("firstSortDirection") == ui.direction) && ui.owner.grid.dataSource.settings.sorting.expressions.length != 0) { ui.owner.grid.dataSource.settings.sorting.expressions.clear(); ui.owner.grid.dataBind(); $(".ui-iggrid-indicatorcontainer").hide() return false; }}
Please find the attached file that you can run and see if this is the behavior you want.
Unfortunately this doesn't work.
When I asked the question the grid in question had a mode of "multi", so I assumed that was part of the reason the code didn't work.
Since then, the multiple sort requirement was been dropped so I retried this code with a grid with mode = single but it still fails.
1. On the third click (back to firstSortDirection), the unsort does not occur and further clicking has no effect.
2. Clicking on a new / different column heading has no effect but the header gets the "sorted" background color, and the previous column retains its "sorted" background color.