views:

144

answers:

5

I have the following snippet of code (I'm using jQuery 1.4.2):

$.post('/Ads/GetAdStatsRow/', { 'ad_id': id }, function(result) {
    $('#edit_ads_form tbody').prepend(result);
    $(result).find('td.select-ad input').attr('checked','checked').click();
});

Assume that the post works correctly and returns a correct pre-built <tr> with some <td>s. Here's the weirdness: the $(result).find() line finds the correct input (which is a checkbox, as it's the only input in the cell) and runs the chained click() function correctly, but it REFUSES to set the box as checked, which I need to happen.

Here's a crazy twist, too... when I get super specific and change the $(result).find() line to this (the id of the checkbox):

$('#ad_' + id).click();

It checks the box, but doesn't run the click() function! If I set it to

$('#ad_' + id).attr('checked','checked').click();

it runs the click function as though the box were checked, but the box remains unchecked, and if I do

$('#ad_' + id).click().attr('checked','checked');

it does nothing at all.

What in the world could be the matter with this? I'm running out of hair....

Thanks!

EDIT

Here's how I set my click event in the $(function()) call:

$('td.select-ad input').live('click',AdPreview.selectAd);

It works as is for all the other checkboxes, and the newly-added checkbox does indeed work if clicked by hand.

EDIT 2

After some digging I discovered that this:

$('#ad_' + id).click();

actually does call my click function in addition to checking the box. However, when the click function is called (I've already checked to make sure that input is the correct checkbox and it is),

var input = $(this);
console.log(input.is(':checked'));

the log returns false, even though the box is actually checked! GAH WTF

+2  A: 

http://www.electrictoolbox.com/check-uncheck-checkbox-jquery/

jQuery (or the browser's DOM? I forget) expect a true or false value for the "checked" attribute, despite the fact that in HTML-source-land it's "checked='checked'".

HTH.

Brendan Kidwell
i use `.attr('checked','checked')` in probably 100 locations throughout my code and it works as expected...
Jason
I believe browsers actually just look for the presence of the attribute and don't care about its value at all.
notJim
A: 

Isn't doing $(result).find('td.select-ad input').attr('checked','checked').click(); going to check it (.attr('checked','checked')) and then uncheck it by clicking (.click())?

Forgive me if there's something I'm missing, but I'm fairly certain that's it. That's why $('#ad_' + id).click(); works, but your other examples don't.

notJim
i thought that too... but why won't it stay ticked?
Jason
When you do the `click()` call, it unticks the box. It's ticking it, then unticking it. What if you instead did `$(result).find('td.select-ad input').click();` (remove the `.attr('checked','checked')` part).
notJim
when i do that, nothing happens at all.
Jason
What's in your click handler? It's possible there is something like preventDefault, or return false that's preventing it from getting checked.
notJim
there is no preventDefault or return false
Jason
+1  A: 

I suspect what is happening here is that the Click is actually unticking the checkbox. That is because the Find method is, as you say, returning the checkbox.

Try removing the click call.

Here's some sample code

<html>
    <head>
        <script src="http://code.jquery.com/jquery-1.4.2.min.js"&gt;&lt;/script&gt;
    </head>

    <body>

        <script type="text/javascript">
            function clicked() {
                console.log('clicked');
            }

            $(document).ready(function() {

                var result = '<tr><td><input type="checkbox" id="chkbx" onclick="clicked()" /></td></tr>';

                $('#edit_ads_form tbody').prepend(result);

                $('#edit_ads_form tbody').find("input").click();
            });
        </script>

        <table id="edit_ads_form">
        <tbody>

        </tbody>
        </table>
    </body>
</html>
Jonathan
i did... nothing happens
Jason
I've added some code, shows the checkbox getting checked and the click event firing.
Jonathan
+3  A: 

I think it's because you're doing your find on some html which isn't in the DOM.

$.post('/Ads/GetAdStatsRow/', { 'ad_id': id }, function(result) {
    // the "result" html is copied into the DOM
    $('#edit_ads_form tbody').prepend(result);

    // now you're doing a find on some HTML which isn't in the DOM.
    $(result).find('td.select-ad input').attr('checked','checked').click();
});

That explains why doing the specific stuff works, to an extent. Here are the individual problems:

$('#ad_' + id).click();

This will click the box (making it get checked), but there are no events attached to it.

$('#ad_' + id).attr('checked','checked').click();

This sets the attribute to checked, and then clicks it, unchecking it straight away.

nickf
this makes sense... however i have the checkbox click event set with `live('click')` earlier in the doc. shouldn't it run?
Jason
I think one reason why `$(result)..click()` is not doing anything as `live` handlers listen to events that bubble up to the DOM document, but `$(result)` contains nodes detached from the DOM.
Anurag
+1  A: 

I figured it out, thank you to all who put me on the right track. Here's what I had to do:

First, rather than wiring my checkboxes to run on click(), I updated them to run on change(). After I did this, I used the following line in place of the other:

$('#ad_' + id).click().change();

and everything works now! The checkbox stays checked and the correct function is called.

Thanks again everyone!

Jason
good catch.. click handler is called before the checkbox value gets updated, and change handler is called after the value gets updated, but the change handler will not be called when programmatically firing a click.
Anurag