JQuery .bind only works for the first control

advertisements

I've read similarly titled questions on here, but the behavior they are experiencing is not quite the same. Please do not link to similar questions, this issue is subtly different if you read carefully.

I have these controls which are created dynamically. They don't have hard-coded IDs.

For each one of these controls, I want a script to fire whenever the value is changed. The controls are all dropdowns. Here is my code-behind for when the page is loaded:

foreach (string param in hasDependencies.Keys)
{
    ScriptManager.RegisterStartupScript(this, GetType(), "onChange", "$('#MainContent_JenkinsField_" + param + "').on('change', function(){" + dynamicScript + "});", true);
}

The first control which enters this loop works perfectly. If I change the value of the dropdown, the script executes as expected every time. For whichever control enters this loop first, every time I change its dropdown value the script fires and executes perfectly.

However, the other controls do not fire the script. The script is not executed at all when I change the value of the other dropdowns, they do not even attempt to execute the script.

When I debug, I can see that every control is in fact going into this loop, and I can tell that it is the right ID for the control, but no matter what the first control is bound and the others are not. I also tried "on" and "change" instead of "bind," no difference.

I'm sure people will want to see the script itself, however the problem can be isolated to the C# code. There is nothing in the JS console, and nothing under the markup on the page in developer tools worth seeing, just a bunch of hard-coded sensitive unrelated information that I obviously cannot share. This problem can be isolated to the C# code, because even if I replace dynamicScript with something very simple (e.g., a simple alert) it only works for the first control.


Adding this as an answer (to clarify my comment), since putting it in a comment would be difficult. If it doesn't solve it, let me know and I'll remove it.

This code:

foreach (string param in hasDependencies.Keys)
{
    ScriptManager.RegisterStartupScript(this, GetType(), "onChange", "$('#MainContent_JenkinsField_" + param + "').on('change', function(){" + dynamicScript + "});", true);
}

This part is adding an event listener (listen for change and do something), not a function call (do something on change):

"$('#MainContent_JenkinsField_" + param + "').on('change', function(){" + dynamicScript + "});"

It should be

foreach (string param in hasDependencies.Keys)
{
    ScriptManager.RegisterStartupScript(this, GetType(), "onChange", dynamicScript, true);
}

or

foreach (string param in hasDependencies.Keys)
{
    ScriptManager.RegisterStartupScript(this, GetType(), "onChange", "function(){"+dynamicScript+"}", true);
}

So that it runs your dynamic script onchange instead of just adding another change event listener.

Does that make sense?

On a side note For future reference, writing code like this $('#MainContent_JenkinsField_[redacted]') may confuse your issue further for people trying to help, since [] can be part of a jQuery selector. If taken literally, that selector would look for an element with an ID of MainContent_JenkinsField_ that has an attribute named redacted. I hope the brackets were just to show where you removed the param, and the real selector looks something like this:$('#MainContent_JenkinsField_yourParam')