0

I am trying to attach the same jQuery and JSON ASP.NET MVC3 Method to two different <select> elements:

<select id="StartYear">
<option value="">Select Year</option>
<option value="2000">2000</option>
<option value="2001">2001</option>
</select>

<select id="StartMonth">
<option value="">Select Month</option>
</select>

Same applies for <select> elements with ids "EndYear" and "EndMonth".

I want to attach to both "Start Year" and "End Year" the same jQuery function:

$('[id$="Year"]').change(function () {
        var selectedYear = $(this).val();
        var selectedId = $(this).attr('id')
        if (selectedYear != null && selectedYear != '') {
            $.getJSON('@Url.Action("Months")', { year: selectedYear }, function (months) {
                var monthsSelect = $('#StartMonth');
                if (selectedId == 'EndYear') {
                    monthsSelect = $('#EndMonth');
                }
                monthsSelect.empty();
                daysSelect.prepend("<option text='-- select month --' value='' selected='selected'></option>");
                $.each(months, function (index, month) {
                    monthsSelect.append($('<option/>', {
                        value: month.value,
                        text: month.text
                    }));
                });
            });
        }
    });

However, this code does not work. I debugged it with Bugzilla and I found out that this condition (selectedId == 'EndYear') breaks the function. The variable selectedId is in the closure scope but I don't know how to bring it inside the function scope. Otherwise I don't know what it cna be the cause. Keep in mind that without that condition the code was working (of course just with #StartMonth)

3
  • 1
    How does it break? Does it give any error? Commented Oct 29, 2012 at 23:14
  • What's the selectedId outside of the getJSON method? (so, console.log($(this).attr('id')); after the assignment? ) Commented Oct 29, 2012 at 23:25
  • thanks! before it gives StartDate then undefined Commented Oct 29, 2012 at 23:43

1 Answer 1

2

If I correctly understand your problem the variable selectedId can do be accessed inside of success handler of $.getJSON, but the value of the variable can be already changed by another change event.

For example if two change events will be stated in short time interval from for example "#EndYear" and "#StartYear" then could be the following

  1. change events for "#EndYear" will be triggered
  2. selectedId variable will be set to "EndYear"
  3. first $.getJSON will be started
  4. change events for "#StartYear" will be triggered
  5. selectedId variable will be set to "StartYear"
  6. second $.getJSON will be started
  7. first $.getJSON will be finished and the value of selectedId variable will be "StartYear" inside of the success handler
  8. second $.getJSON will be finished and the value of selectedId variable will be "StartYear" inside of the success handler

So I think that you need just need to have different instances of selectedId variable to use the value which was before the $.getJSON took place. You can implement that in different way. It seems the most native for me to replace $.getJSON to $.ajax and to use context parameter of $.ajax. The code could be about the following

$('[id$="Year"]').change(function () {
    var selectedYear = $(this).val();
    var selectedId = $(this).attr('id')
    if (selectedYear != null && selectedYear != '') {
        //$.getJSON('@Url.Action("Months")', {year: selectedYear}, function(months){
        $.ajax({
            url: '@Url.Action("Months")',
            dataType: 'json',
            data: { year: selectedYear },
            context: {selectedId: selectedId},
            success: function (months) {
                var selectedId = this.selectedId; // get from context
                ....
            }
        });
    }
});
Sign up to request clarification or add additional context in comments.

3 Comments

thanks Oleg, my problem is much easier. I don not understand why selectedId before the $.getJSON is equal to "StartDate" or "EndDate" and inside the function is undefined
@CiccioMiami: You are welcome! In any way what I suggest is to save the value of the selectedId in new object which you will access inside of success callback. In the case you will be sure that you will have unchanged value of selectedId inside of success callback.
@CiccioMiami: I have another idea which can be the reason of your problem: the event bubbling or some effect based on it. If you register change event on the element then all changes of the children follow calling of the change event handler. So you could have probably more changes of selectedId which you though. I recommend you to include console.log inside of the event handler and analyse the results. You will probably see when selectedId variable will be reset to undefined (when $(this).attr('id') return undefined).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.