3

I have a fairly simple dynamic html structure of a table that contains links and the possibility that it will contain a second table with links. I would like the change the html attribute for the links in the main table but not in the second.

My structure:

<table>
<tr><td><a href="www.google.com">link</a></td></tr>
<tr><td><a href="www.google.com">link</a></td></tr>
<tr><td><a href="www.google.com">link</a></td></tr>
<tr><td><a href="www.google.com">link</a></td></tr>
<tr><td><a href="www.google.com">link</a></td></tr>
<tr>
    <td>
        <table>
            <tr><td><a href="http://stackoverflow.com">link</a></td></tr>
            <tr><td><a href="http://stackoverflow.com">link</a></td></tr>
            <tr><td><a href="http://stackoverflow.com">link</a></td></tr>
        </table>
    </td>
</tr>

So for example, I would like to change all the hrefs of "www.google.com" to "www.foo.com". I am able to change the href attribute, but I am having issues with my selector b/c there are times where the second table will not exist.

My current selector looks like: $('table a').filter(':not(table:last a)')

I'm sure it is not the most effecient way to do it, but it was working till the possibility of no second table came into play.

1
  • 2
    How do you access the first table, is there an ID or an absolute reference you can use? Is so, should be easy by using the > in a selector to prevent traversing down the tree further than expected. Commented Jan 3, 2011 at 22:12

5 Answers 5

5

If your "main" table is not inside another table, you could do:

$('table a:not(table table a)')

or equivalently:

$('table a').not('table table a')

Update: Performance-wise, Patrick's answer is much better.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you guys for the great answers. Im going to accept this one. It works and I can't tell who answered first you or mririgo below. Also, performance should never be an issue with this, since it is being generated dynamically, the number of rows will never be above 25.
1

I think I'd rather do this:

$('table').slice( 0, -1 ).find( 'a' );

Find all the tables, then reduce the set to all but the last, and finally do a .find() for the <a> elements.

The reason is that I'm heavily biased toward valid CSS selectors so that querySelectorAll can be successfully utilized by jQuery.

3 Comments

@Felix: Just gave an update to explain why. The :first selector fits under the category of non-valid CSS selectors. Minor consideration if there's only two tables.
I see. Just thought it looks nicer ;) But you are right... thanks for the explanation.
@Felix: Agreed, and :first is probably a worthwhile compromise in this case.
0

You can do with your table's container.
If it's body:

$("body > table > tr > td > a")

Comments

0

Try using the child selector and giving the main table an ID (if it doesn't have one already) :

$('#maintable > tbody > tr > td > a')

Where #maintable is the ID of your main table.

Edit: You'll also want to add the <tbody> tag to the table (for the reasons indicated in the comments).

This uses basic CSS selectors on newer browsers and doesn't require any jQuery magic unless you're using an older browser.

3 Comments

Be careful with using > when it comes to <table> elements. Even though there's no <tbody>, most browsers will insert one, causing your selector to fail.
@patrick dw: Good point. In that case, a <tbody> could be added explicitly so that you know for sure that it's there, and then the selector would change to: $('#maintable > tbody > tr > td > a')
Yes, I'm fully in favor of the explicit inclusion of <tbody> to ensure consistency across browsers.
0

If you can change the dynamically-generated HTML you should really give each table an ID property:

<table id="table1"> ...
    <table id="table2"> ...
    </table>
</table>

Then your selectors can be simply

$('#table1').find('a')

This doesn't really answer your question, but this design is much more maintainable and easier to change.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.