Filtering rows with dropdown lists
Filtering rows with dropdown lists
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
..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.
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
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 thisthis.$('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 fromcolumn
?column
is coming fromthis.api.columns()
Maybe it would be easier to build the select list from the
statusData
variable.Kevin
On top of Kevin's suggestion, if you use
node()
instead of 'data()`, then you can get the text value from there.Colin
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.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 thefilter
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
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.
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