views:

639

answers:

7

I've got HTML code that roughly looks like this:

<li id="someid-11">

<img src="..." alt="alt" />
<h2><a href="somelink"> sometext </a>
    <span><a class="editcontent" href="?action=editme">Edit</a></span>
</h2>
<div id="11" class="content">
 <!-- // content goes here -->
 <div class="bottom_of_entry"> </div>

</li>

I'm using the a.editcontent to activate an edit-in-place method on div.content. My current selector looks like this

jQuery('a.editcontent').bind('click', (function(){
 jQuery(this).parent('span').parent('h2').next('.content').trigger('edit');
}

It works, but its ugly. There must be some better way to do that, right?

+1  A: 

You can probably use xpath to get from the A to the DIV in one go?

Edit: Apparently xpath selectors are no more in jquery (thanks to the guy in the comments for pointing this out)

benlumley
haven't xpath selectors been removed from the more recent versions of jQuery?
Wayne Austin
What's xpath ? :) (googling it now)
yoavf
oh ... looks like they have been removed yes!
benlumley
+2  A: 

Would it not be better to store the id in the link, then on your hander, find the content div by id, and do your trigger? That way you're not tied to a specific hierarchy.

Sprintstar
+4  A: 

I think using some meta-attributes would be a better solution.

<li id="someid-11">

<img src="..." alt="alt" />
<h2><a href="somelink"> sometext </a>
    <span><a rel="11" class="editcontent" href="?action=editme">Edit</a></span>
</h2>
<div id="11" class="content">
 <!-- // content goes here -->
 <div class="bottom_of_entry"> </div>

</li>

(Added the rel="11" to the link)

And then in JavaScript:

$( 'a.editcontent' ).click(function()
{   
    $( '#' + $(this).attr( 'rel' )).trigger( 'edit' );
});
okoman
note that this will break (X)HTML validation since "11" is not a valid value for rel. (you decide how important that is for yourself). In any case, you can't have an id which starts with a number - that will break in IE. prefix it with an arbitrary string of letters.
nickf
+1  A: 

Out of my head:

$("a.editcontent").click(function(){
    $(this).parents("h2").slice(0, 1).next(".content").trigger("edit");
});
svinto
instead of .parents("h2").slice(0, 1), it'd be easier and more efficient to do .parents("h2:first")
nickf
+1  A: 

I agree with Sprintstart

var clickHandler = function (link) {
     $(link.data.action).trigger("edit");
}

$('a.editconent').bind('click', {action:'.content'}, clickHander);

Then you can be much more target about the jQuery statement which fires the edit event.

Matt Goddard
+2  A: 

I recommended the Sprintstar Solution. but if you don't like it, use this:

$("a.editcontent").click(function(){
    $(this).parents("h2").next(".content").trigger("edit");
});

If you have more that one "h2":

$("a.editcontent").click(function(){
    $(this).parents("h2:first").next(".content").trigger("edit");
});
Ata
I'd recommend that you always be as specific as possible in your queries. If you want the first h2 ancestor, then always specify h2:first. It will let the search loop stop as soon as one is found, and is clearer for future coders who now know that you're definitely always working with one element.
nickf
A: 

I think its hard to read because you're having to go up from one element back down to another. If you reference both from a common container, those paths will seem more meaningful.

var listitem11 = $("#someid-11");

listitem11.find('a.editcontent').bind('click'), (function(){
     listitem11.find('.content').trigger('edit');
}

Now I suspect you have multiple list items to deal with, and in that case you'll need an enclosing loop where you didn't need one before. Still I think that puts you ahead.

Frank Schwieterman