Displaying rendered data in server side filtering

Displaying rendered data in server side filtering

coolboyjulescoolboyjules Posts: 19Questions: 6Answers: 1

Hi everyone,

I've implemented server side filtering using individual drop downs and I've created render functions for my data to format it for the user as in https://datatables.net/examples/api/multi_filter_select.html. The issue I'm having is that the filter drop downs still display the raw data as opposed to using the render functions I've made. Can I call these render functions in my initComplete function?

` initComplete: function () {
var api = this.api();

                        api.columns()
                            .indexes()
                            .flatten()
                            .each(function (i) {
                                var column = api.column(i);
                                var select = $('<select><option value=""></option></select>')
                                    .appendTo($(column.footer()).empty())
                                    .on('change',
                                        function () {
                                            column
                                                .search(this.value)
                                                .draw();
                                        });

                                column.data()
                                    .unique()
                                    .sort()
                                    .each(function (d) {
                                        select.append('<option value="' + d + '">' + d + '</option>');
                                    });
                            });
                    },`

So that it uses my render functions like this one?

{ "name": "Frequency", "data": "Frequency", "render": function (data, type, row) { debugger; if (type === 'display') { return data + 'm'; } return data; } }

Thanks for your help.

This question has an accepted answers - jump to answer

Answers

  • coolboyjulescoolboyjules Posts: 19Questions: 6Answers: 1

    Here's a picture of what I'm trying to achieve.

    I feel like it has to be something simple in this snippet...

    column.data() .unique() .sort() .each(function (d) { select.append('<option value="' + d + '">' + d + '</option>'); });

  • DirceuNazarethDirceuNazareth Posts: 44Questions: 1Answers: 12

    I was looking the documentation of each() and look like it return the original data inside of it (value, index). If that is the case you need re-formatting the data.
    var number = d + 'm'; //like your render function above
    <option value="' + number + '">' + number + '</option>

  • coolboyjulescoolboyjules Posts: 19Questions: 6Answers: 1

    Yes I suppose that would work but the issue is that each column is formatted differently. I wouldn't be able to use the each() api anymore and would have to copy a lot of code. I'm just wondering if there is any way to call my render functions I've made in my column definitions.

  • DirceuNazarethDirceuNazareth Posts: 44Questions: 1Answers: 12

    are you using the original data for something?
    If not, you can just remove the type conditional.
    That will modify your data, for whatever use, if I am not wrong.

    { 
       "name": "Frequency", 
       "data": "Frequency", 
       "render": function (data, type, row) { 
            return data + 'm'; 
         }
    }
    
  • coolboyjulescoolboyjules Posts: 19Questions: 6Answers: 1

    Hmm. Yes I am. I need to use the original data for sorting and filtering server side. I tried removing the type conditional and I still get the data without the + 'm' in your example :neutral:

  • DirceuNazarethDirceuNazareth Posts: 44Questions: 1Answers: 12

    Sorry, I think I cannot help you so...

    Well, you can always create a function to format the data, and apply it on the $.each and render...

    But I guess do the formatting just once will be more productive and faster.

  • coolboyjulescoolboyjules Posts: 19Questions: 6Answers: 1
    edited September 2016

    Thanks for trying Dirceu. I do know the workaround but it will be messy and fragile (creating the function in another file and doing like a case statement in the each() function.

    Anyways, I feel like this must be a common thing. Lots of people do this stuff server side. I could honestly be doing something really silly. I just want to access the render function i defined in my columns declaration :(

  • DirceuNazarethDirceuNazareth Posts: 44Questions: 1Answers: 12

    Well that you have access, if you know the integer relative to the column object.

    if the column is the 3rd (arrays start from 0, so your integer would be 2), for instance:

    var settings = yourDataTable.settings()[0];
    var renderFunction = settings.aoColumns[2]["mRender"]
    
  • coolboyjulescoolboyjules Posts: 19Questions: 6Answers: 1
    edited September 2016

    Turns out this works

    var settings = this.fnSettings();
    var renderFunction = settings.aoColumns[2]["mRender"];
    
  • DirceuNazarethDirceuNazareth Posts: 44Questions: 1Answers: 12
    Answer ✓

    Oh! ok, it is inside of initComplete callback.
    In this case, this callback accept "initComplete": function(settings, json).
    So you can try (if we are using same version):

    initComplete: function(settings, json) {`
    
    //code before...
    
    //since your are using render I just did a check if render is there (they should be the same, because mRender is a fallBack for previous version of DT)
    var renderFunction = settings.aoColumns[2]["render"] ? settings.aoColumns[2]["render"] : settings.aoColumns[2]["mrender"];
    
    //code after...
    
    }
    
  • coolboyjulescoolboyjules Posts: 19Questions: 6Answers: 1

    OK so I've figured it out. Dirceu was super helpful! Thank you! The settings object is key. So for anyone else trying to do this. You can access your settings object in your initComplete function like so:

    initComplete: function() {
                                var api = this.api();
                                var settings = this.fnSettings();
    

    And if you're following the example I gave in the top link, you'll want to get the render function for the current column like so:

     initComplete: function() {
                                var api = this.api();
                                var settings = this.fnSettings();
    
                                api.columns()
                                    .indexes()
                                    .flatten()
                                    .each(function (i) {
                                        var renderFunction = settings.aoColumns[i]["mRender"];
    

    And to format your dropdown, all you have to do is this:

     column.data()
                                            .unique()
                                            .sort()
                                            .each(function (d) {
                                                if (renderFunction == null) {
                                                    select.append('<option value="' + d + '">' + d + '</option>');
                                                } else {
                                                    debugger;
                                                    select.append('<option value="' + d + '">' + renderFunction(d,'display',null) + '</option>');
                                                }
                                            });
    

    Where I've changed the delegate in the each() function to first check if the renderFunction for this column is null and then otherwise use it to format the value.

This discussion has been closed.