1

I've got a drop down list that filters a table. I want the drop down list to repopulate every time the table has been filtered to only show the remaining (unique) items. Currently I have the following function

    function rePopulateSelectList(column, control) {
//wipe the previous drop down
    $('#' + control).find('option').remove();
//
    $('#adminTable tr').each(function () {
         $.unique($(this).find('td:eq(' + column + ')')).each(function () {
            var columnText = $(this).text();
            $('#' + control).append('<option value="' + columnText + '">' + columnText + '</option>');
        });
    });
}

the drop down is being repopulated (on the select.change() event) but I'm ending up with at least twice as many drop down options, none of which are unique

cookee89
  • 144
  • 12
  • What is "unique item" in your meaning? – Regent Sep 12 '14 at 09:29
  • I'm trying to get a collection of unique td's from my table, i.e. by comparing the text() property only. I'm now assuming that the unique comparison won't work as each td is in a different tr – cookee89 Sep 12 '14 at 09:44
  • How [$.unique](http://api.jquery.com/jquery.unique/) works you can see in [fiddle](http://jsfiddle.net/x9n2fyh4/). – Regent Sep 12 '14 at 10:19

2 Answers2

1

Try the code below. $.unique does not give you unique tr by comparing text inside in td.

function rePopulateSelectList(column, control) {

    var $control = $('#' + control);

    //wipe the previous drop down
    $control.find('option').remove();

    $('#adminTable tr').each(function () {

        var columnText = $(this).find('td:eq(' + column + ')').text();

        if ($control.find("option[value='" + columnText + "']").length > 0) {
            return;
        }

        $control.append('<option value="' + columnText + '">' + columnText + '</option>');

    });
}
Mihir
  • 419
  • 3
  • 10
  • 1
    By the way, `'td:eq(' + column + ')'` returns single `td`. It makes no sense to use `find('td:eq(' + column + ')').each()`... – Regent Sep 12 '14 at 09:43
  • +1 Now it looks good for me, even though on your place I will put `$control.append` inside `if` (changing `> 0` to `== 0`, of course) to make code shorter and easier. – Regent Sep 12 '14 at 11:51
  • Inverted condition helps reduce nesting level, habit of using [R#](http://stackoverflow.com/questions/268132/invert-if-statement-to-reduce-nesting). ;-) – Mihir Sep 12 '14 at 12:09
1

It seems you may have a few issues in your code. Passing in a column index assumes you want only one column's values? Try something like this:

function rePopulateSelectList(columnIndex, select) {
    $('#' + select + ' option').remove();

    var control = $('#' + select), values = [];
    $('#adminTable tr').each(function () {
        var cell = $(this).find('td:eq(' + columnIndex + ')'),
            text = cell.text();

        if (values.indexOf(text) == -1) {
            values.push(text);
            control.append('<option value="' + text + '">' + text + '</option>');
        }
    });
}
DvS
  • 1,025
  • 6
  • 11
  • +1 It looks correct for me too. And one thing I would simplify: `cell` is used only to get its text. So it can be simplified to `var text = $(this).find('td:eq(' + columnIndex + ')').text();` – Regent Sep 12 '14 at 11:55
  • Yes, you're right. I included 'cell' only to make it clear what the code is doing. – DvS Sep 12 '14 at 12:25
  • this looks more like it, indexOf(text) == -1 is the bit of gold i needed. Thanks very much – cookee89 Sep 12 '14 at 12:57