ageoff
ageoff

Reputation: 2828

Get the table from cell data

So this should be pretty simple, but it seems to be making me stumble. I have a drop down in a cell in a table. When that value is changed, I call a javascript function and pass that drop down in the function. How do i get the table from that? example code:

<table><tr>
<td>DATA</td>
<td><select id='leadState' onChange='updateData(this)'><option selected='selected' value='new'>New</option><option value='old'>Contacted</option></select></td>
</tr>
</table>

javascript:

function updateData(select) {
    var table = select.parentNode.parentNode.parentNode;
    var row = select.parentNode.parentNode;
    var cell = select.parentNode;
}

Why does this not return the table properly?

Upvotes: 0

Views: 2514

Answers (2)

David Thomas
David Thomas

Reputation: 253308

Because you've forgotten about the tbody element (which is optional, but most, if not all, browsers add to the table to wrap the tr elements. Try another parentNode:

function updateData(select) {
                // select -> td  -> tr      -> tbody   -> table
    var table = select.parentNode.parentNode.parentNode.parentNode;
    var row = select.parentNode.parentNode;
    var cell = select.parentNode;
}

JS Fiddle demo.

And you really don't have to traverse the table for every variable:

function updateData(select) {
    var td = select.parentNode,
        tr = td.parentNode,
        tbody = tr.parentNode,
        table = tbody.parentNode;
}

JS Fiddle demo.

Assuming you'd like to stick with plain JavaScript, and would prefer not to manually iterate through the DOM while retrieving elements, here's a simple plain-JavaScript implementation of closest():

HTMLElement.prototype.closest = function (selector) {
    var self = this.length ? this[0] : this;
    while (self.tagName.toLowerCase() !== selector.toLowerCase() && self.tagName.toLowerCase() !== 'body') {
        self = self.parentNode;
    }
    return self.tagName.toLowerCase() == 'body' ? this : self;
}

function updateData(select) {
    var td = select.closest('td'),
        tr = select.closest('tr'),
        table = select.closest('table');
    console.log(td, tr, table);
}

JS Fiddle demo.

Upvotes: 1

relic
relic

Reputation: 1692

David Thomas's answer is probably the best answer. Although if you have jQuery on your page, you could also use the 'closest()' function.

$(select).closest('table')

That would account for browsers that automatically add the tbody container, AND browsers that don't.

Upvotes: 1

Related Questions