Column order generated dynamically by front-end (for colReorder)

Issue #52 resolved
David Wasylciw created an issue

Similar to the solution in PR15, there are a few situations where I'm trying to reuse the same server side DataTablesView, but with different column ordering on the end user page. I've found that for this to work I need to redefine order_columns each time which is a pain.

If there was anyway that DataTablesView could pick up the column orders from the GET string, either based on the name or data fields it would be quite helpful in this situation. This way it's also much easier for the front-end folks to change around column ordering without needing backend changes. Not sure if that PR is the best way, but it seems like the only way at this point in time.

Based on one at least one datatables.net forums posting (at the very end), the author seems to think this is how users can easily find the column names for sorting. A dynamic solution like this is also required if the user has colReorder enabled as it changes the column index that gets sent for sorting.

In my particular case, I've overrode prepare_results and some of the names there don't match the sort field names I would need to use so I will need to restructure that, but that's something that can be dealt with or documented as a gotcha.

Comments (5)

  1. Maciej Wisniowski repo owner

    @dwasyl do you think something like that can be used (in this case it is for get_columns, but possibly same thing can be used for get_order_columns - unless there is other way to define which columns should be used for ordering):

        def get_columns(self):
            """ Returns the list of columns that are returned in the result set
            """
            if self.columns:
                return self.columns
            # try to get columns from the request using the data['name'] attribute, eg.:
            # columnDefs: [
            #             {
            #                 name: 'username',
            #                 targets: [0]
            #             },
            #             {
            #                 name: 'email',
            #                 targets: [1]
            #             }
            #         ],
            columns = []
            column_no = 0
            column_key = 'columns[{0}][name]'.format(column_no)
            while column_key in self._querydict:
                column_name = self._querydict.get(column_key)
                if column_name == '':
                    raise Exception('self.columns is not defined and there is no \'name\' defined in columns definition!')
                columns.append(column_name)
                column_no += 1
                column_key = 'columns[{0}][name]'.format(column_no)
            return columns
    
  2. David Wasylciw reporter

    @pigletto I think this works well. The only decision point is whether to use the name or data field. Personally, it's a bit of a toss either way, but in theory it should match up to the data column directly so the user doesn't need to set the name field (and seemed to be the author's intent). But, using the name field also provides a bit more flexibility.

    Other than that I think the approach above is good. There should be a note somewhere that if someone does define columns that it will fail with reorderable columns.

    For get_order_columns, the same code would work, except the script should test for the orderable property being true, and otherwise overriding the column name with a blank string.

    So long as get_columns and get_order_columns use the same source for column names it will be alright.

  3. Log in to comment