Filtering rows with dropdown lists

Filtering rows with dropdown lists

ghendricghendric Posts: 13Questions: 5Answers: 0

Test case: https://codepen.io/george-hendrickson/pen/ExvOvre

I have a column that has dropdowns in each row that I want to filter with a drop down in the column header. I'm trying to build the header drop down based on the filtered values showing. This function builds the list but when it comes to dropdowns, i'm having trouble getting the values i need to build it. column.data().unique() gives me the actual value of the selected dropdown in the row but I need the text too. this.$('select option:selected') gives me the list of selected options but it gives it to me regardless of which column is building the header dropdown. Is there a better way to do this? This code seems to be a bit overkill and i need to get as much performance as i can out of this. Any help is greatly appreciated.

function BuildSelectList(column) {
    if (column.index() == 5) {
        debugger;
    }
    var selectSet = new Set();
    //Sort all the data in the column
    column.data().unique().sort().each(function (data, row) {
        var val = $('<div/>').html(data).text();
        if (null != data && data.toString().search("input") != -1) {
            // Get input values
            if ($(data).find("input:text").length > 0) {
                val = $(data).find("input:text").val();
            }
            // Get checkbox values
            if ($(data).find("input:checkbox").length > 0) {
                val = $(data).find("input:checkbox").val();
            }
        }
        if (val != "") {
            try {
                // Get selected values
                var s = data.search('selected=');
                if (s != -1) {
                    var len = $(data).find('option:selected').length;
                    if (len > 0)
                        val = $(data).find('option:selected').text();
                }
            } catch {
                val = '';
            }
            // Create list of values
            var vals = val.split('\n').filter(function (i) {
                return i;
            });
            vals.forEach(function (val) {
                if (val == '')
                    val = $(data).val('');
                if (typeof val === "undefined")
                    val = '';
                selectSet.add(val);
            });
            if (vals.length == 0) selectSet.add('');
        } else if (data != '') {
            $(data + ' :input').each(function () {
                if (this.value != undefined) {
                    if ((this.type == 'text' || this.type == 'search') && this.hidden == false) {
                        if (this.value != undefined) {
                            selectSet.add(this.value);
                        } else
                            selectSet.add('');
                    } else
                        selectSet.add(this.value);
                } else
                    selectSet.add('');
            })
        } else {
            selectSet.add('');
        }
    });
    return selectSet;
}

This question has an accepted answers - jump to answer

Answers

  • ghendricghendric Posts: 13Questions: 5Answers: 0

    ..also, the Search input doesn't seem to work with dropdown lists either. Even if I set the data-search attribute on the TD that is holding the dropdown.

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    This SO thread discusses how to get the text from a select element.

    For the searching on those fields, you'll need to create a custom filter - something like these here.

    Colin

  • ghendricghendric Posts: 13Questions: 5Answers: 0

    I can get the text from the select but the first part is building it from the data that is already showing in the grid. column.data() just gives me the actual integer value of the select that's in each row. The code in the function BuildSelectList is what builds the dropdown filter for each column. I could put something like this this.$('select option:selected').each(function (e) { selectSet.add($(this).text()); }) in that function but it gets called for every column while the initComplete is executing. Is there a way to get the selected text from column?

    column is coming from this.api.columns()

  • kthorngrenkthorngren Posts: 21,443Questions: 26Answers: 4,974

    Maybe it would be easier to build the select list from the statusData variable.

    Kevin

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    On top of Kevin's suggestion, if you use node() instead of 'data()`, then you can get the text value from there.

    Colin

  • ghendricghendric Posts: 13Questions: 5Answers: 0

    Well, I could use the statusData variable to build the list but I need to know which column is building the dropdown filter during the api.columns() loop. I'm trying to make the method that I have that builds the dropdown filter list generic so I can use it with other pages that use this grid without having to hard code something. Nodes() kind of works okay but not so much with columns that have "inputs" in them. I did kind of mess with to get it to build the dropdown filter but column.search doesn't find anything and neither does the Search input at the top of the grid for columns with dropdowns in them.

  • kthorngrenkthorngren Posts: 21,443Questions: 26Answers: 4,974
    Answer ✓

    Thanks for the example you provided but its got a lot going on. I decided to simplify the problem a bit for just the Status column.
    http://live.datatables.net/kafireqi/1/edit

    The orthogonal HTML5 data attributes are meant for DOM sourced table data. So they won't work for your case. Use columns.render instead.

    You need to keep up with the selected option. In my example it uses the display operation to show the select list. It uses the filter operation to set the selected option text for filtering. Otherwise it just returns the data - the selected option value. There is an event handler that runs when the option is changed. It updates the cell data and redraws the table. This updates the filter text.

    In initComplete I created a loop that shows how you can iterate the selects in the column to find the selected option. This should get you started to create your column search list.

    You probably need to do something similar with the inputs to keep the filter updated.

    Kevin

  • ghendricghendric Posts: 13Questions: 5Answers: 0

    Bingo! Kevin, that helped me figure it out! woohoo! lol.. I forgot about the "filter" thing in the render. I updated my test case if anyone wants to see it work. The dropdown filter works too.. and I used column.nodes() to build those lists. The only thing left is for that to build the list faster since in my real project I the datatable has a lot of columns and thousands of rows of data.

  • kthorngrenkthorngren Posts: 21,443Questions: 26Answers: 4,974

    One option might to get a list of all the options, from your statusData variable or from the first row of data. Then get the unique values from the column and build a new select list with the unique options.

    Kevin

Sign In or Register to comment.