0

I'm using Visual Studio 2010 / C# 4.0 / MVC 3 / Razor / jQuery 1.5.1 / Google Chrome 21.0.1180.83 m / Windows 7 Enterprise

Here is my exact code with non-salient things (well what I think is non-salient) commented out.

Basically I'm creating an <input /> element and am trying to bind a change event to it if the user changes its value, but the event doesn't seem to be binding. When I look at the elements in Google Chrome (Ctrl + Shift + J), I do not see anything under "Event Listeners."

<script type="text/javascript" src="/scripts/jquery-1.5.1.js"></script>

<script type="text/javascript">

$(function () {
// ...

    $('#StoredProcedureName').change(function () {
        // ...

        var parameters = $('#parameters');  // <table id="parameters"></table>

        $.getJSON('@Url.Action(/* */)', {
            // ...
        }, function (data) {
            parameters.empty();
            // ...
            $.each(data, function (k, v) {
                // ...
                parameters.
                    append($('<tr />').
                        // ... Other <td /> elements
                        append($('<td />').
                            append($('<input />').
                                // ...
                                change(function () {
                                    alert("here2"); // This alert isn't happening.
                                }).
                                addClass('testClass'). // This class is showing up though.
                                // ...
                            )
                        )
                    );
            });

            // ...
        });
    });

    // ...
});

</script>

When I make a test MVC website and do this, it seems to work. This is so puzzling.

<!DOCTYPE html>

<html>
<head>
    <title></title>

    <script type="text/javascript" src="../../Scripts/jquery-1.5.1.js"></script>

    <script type="text/javascript">
        $(function () {
            $("#a").append(
                $("<input />").change(function () {
                    alert("here1");
                }).attr('value', 'text')
            );
            $("#b").change(function () {
                alert("here2");
            });
        });
    </script>
</head>
<body>
    <div id="a">
    </div>
    <input id="b" />
</body>
</html>

Can anyone tell me why my first alert isn't being executed, in spite of the <input /> element showing up, with the proper class?

Edit:

The table is being created, along with the input element:

Screenshot of Chrome inspector

Jesus is Lord
  • 14,971
  • 11
  • 66
  • 97
  • This definitely sounds like the jQuery library isn't loading properly - Are you sure your site is running from the root of the webserver (not `/MyApp/`) ? If not, your jQuery path will be incorrect. Look in the "Net" tab and see if you can see the library loading correctly – Basic Aug 24 '12 at 10:49
  • Could you link your orginal html page as well? I'm not seeing a textbox with id StoredProcedureName, maybe it's called SPNAME or you made a typo? – Kristof Aug 24 '12 at 10:52
  • @Basic: The jQuery library is generating the ``. I do not see errors from `$` being invalid in the console. I'm not sure what you mean by the net tab - in Chrome? – Jesus is Lord Aug 24 '12 at 10:56
  • @Kristof: Later in my page I have: `
    Select a Stored Procedure: @Html.DropDownList("StoredProcedureName", Enumerable.Empty())
    `. It's there. The table is being built. `` and `` elements are appearing. The `` element is there. It's just when I change it, the alert isn't happening. And there isn't an event in the Event Listeners when I inspect the generated element in Chrome.
    – Jesus is Lord Aug 24 '12 at 10:58
  • @WordsLikeJared The Ctrl-Shift-J panel has a "Network" tab which shows all resources downloaded for that page. That said, I hadn't realised some jQuery was working so I'm probably wrong. – Basic Aug 24 '12 at 11:05
  • You might have done this already, but just in case. There are no javascript errors reported right? All bets are off if there are errors on the page. – Jason Dam Aug 25 '12 at 05:22
  • @JasonDam There were no errors like that. I figured it out, though -- my answer explains briefly if you're interested. – Jesus is Lord Aug 27 '12 at 13:14

3 Answers3

0

Can you try it without the table elements?

I am just wondering about how you are doing this:

append($('<tr />')

I would expect that to be a closed table row, and likewise with the

append($('<td />')

Have a look at this example for table building

Add table row in jQuery

Community
  • 1
  • 1
Justin Harvey
  • 14,446
  • 2
  • 27
  • 30
  • I'm building my table similar to the highest answer on that question, except I am not doing `.find('tbody')`. I can try that. Hang on. – Jesus is Lord Aug 24 '12 at 10:55
  • What I was getting at is that youi are using closed table tags rather than ....... So unless I have missed something I am not sure your input will actually be in the intended place. – Justin Harvey Aug 24 '12 at 11:02
  • I'm not sure I understand -- I thought `
    ` in a selector is the same as `
    ` ? See the image I uploaded in my question -- it shows the input element appearing. So I think it's in the intended place, if I understand you correctly?
    – Jesus is Lord Aug 24 '12 at 11:09
  • Yeah, just seen your image, so I think the structure looks ok, its puzzling. – Justin Harvey Aug 24 '12 at 11:10
  • Sorry, I added something I then realised was irrelevant and couldn't find a way to delete it. – Justin Harvey Aug 24 '12 at 11:49
0

personally i would try to add a class to the input field and use jqueries Live() function in stead of normal binding.
You can bind the onclick to all input's with class foo.
Info about Live here

if you don't like the live could you try not doing the .change binding immediatly but call an extra jquery selector on it's id like you did in your working example?

Kristof
  • 3,267
  • 1
  • 20
  • 30
0

Feel free to edit this with an explanation. But basically inside my code I was sorting the table elements like so:

var options = parameters.children();
options.sort(function (a, b) {
    if (a.text > b.text) return 1;
    else if (a.text < b.text) return -1;
    else return 0
});
parameters.empty().append(options);

Removing this (I'm not sure why I had it) did the trick.

Jesus is Lord
  • 14,971
  • 11
  • 66
  • 97