views:

412

answers:

2

I have the following html that renders within an ASP.NET Repeater:

<div class="divDE-item" onclick="addFilter(this);">
  <span class="spnKey">Some key</span>
  <div>1234</div>
</div>

I realize that having an onclick on the outer div may not be the most graceful jQuery-centric approach. However, considering my situation, it works well.

Here is my addFilter() function:

function addFilter(oDiv) {
  $(document).ready(function() {
    // Get and set the prefix text for the label. i.e. "Key = "
    sDEName = $(oDiv).find("span").text();
    $('#<%= lblDEName.ClientID %>').text(sDEName + " = ");

    // Get the actual filter text value. i.e. "1234"
    // sFilter = $(oDiv).text();
    var sFilter = $(oDiv).filter(function() {
        var filtered = $(this).not(".spnKey");
        return filtered
    });

    $('#<%= txtValue.ClientID %>').val(sFilter);
  });
}

The goal is for the output to appear like this (with 1234 being the value of a textbox):

Some key = 1234

However, the output I'm getting is: Some key = Some key 1234

+3  A: 

You don't need to call filter.

You can simply write $('div:not(.spnKey)', oDiv).text().

To answer your question, you're using filter and not wrong. The filter method returns a jQuery object containing some of the elements in the one you call it on. (Not their children). To use it this way, you should call $(oDiv).children().filter(...).

The not method is the opposite of filter, and returns the elements in the jQuery object that don't match a selector of function. You could therefore also write $(oDiv).children().not('.spnKey').

SLaks
That worked! Thank you for the correction and example, very well put.
Clay
+2  A: 

It seems like you're going about this completely the wrong way. Try this -- have your repeater spit out code as normal:

<div class="divDE-item">
  <span class="spnKey">Some key</span>
  <div>1234</div>
</div>

And use the following javascript to grab the value:

$(document).ready(function() {
  $("div.divDE-item").click(function() { 
     $thisElement = $(this);
     var thisValue = $($thisElement).children("div").text();
     $('#<%= txtValue.ClientID %>').val(thisValue);
  });
});

This way it will apply that click event to every instance of that (I'm guessing repeated) div that appears in the DOM pre-render. Should be a bit more lightweight as well.

Plan B
I agree completely, and I tried that approach at first. I wasn't successful in getting the click event to fire. Perhaps it has something to do with the Repeater being within a ListView, all of which is within an UpdatePanel. The UpdatePanel being the likely culprit. So, I went with this admittedly less desirable approach with the onclick method. I'm all ears, though, for doing this the right way. Thanks for the feedback.
Clay
@Clay: Did you try $("div.divDE-item").live("click", function() { ...
Plan B
@Plan B: Very nice, that worked. I have not gotten around to checking out the new live() method. Thanks again!
Clay
@Clay: No problem. `live()` isn't really a new method, and its a bit confusing in concept but can be very useful. I just think of it as an event binder to objects that may appear in the DOM *after* $(document).ready()
Plan B