0

I have a page with multiple dropdown boxes. I want to make some dropdowns as ready only after the AJAX finish the dropdown content load and the default value selection.

So in each dropdown's Ajax function, I have

complete: function () {
        $("#Country").enable();
        $("#ORG_ID").enable();
        $('#Country option[value="@TempData["Country"]"]').prop('selected', true).change();
        $('#ORG_ID option[value="@TempData["ORG_ID"]"]').prop('selected', true).change();
        }

"@TempData["Country"]"] is an ASP.NET MVC Razor variable.

I hope after all the Ajax events are fired and completed, the JavaScript DOM can set the Country and ORG_ID field as ready only with the codes -

<script type="text/javascript">
    function pageLoad() {
      document.getElementById('Country').readOnly = true;
      document.getElementById('ORG_ID').readOnly = true;
    }
</script>

It is supposed that pageLoad or window.onload will be fired after AJAX's complete event is finished. But after pageLoad has been set the Ajax events still continue to fire for the changes. The readOnly can never be set for these fields.

What have I missed? Is there a more complete page load event than pageLoad or window.onload in Javescript?

Thanks

Update: The AJAX call is from

$(document).ready(function () {
  GetCountry();
}

The above AJAX function codes are in

function GetCountry() {
    $("#Country").disable();
    $("#ORG_ID").disable();

    $.ajax({
        type: 'POST',
        url: '@Url.Action("GetCountry/" + ViewBag.Id.ToString(), "RequestList")',
        data: { Direct: isDirect },
        success: function (data, textStatus, jqXHR) {
            if (textStatus != "success") {
                alert("There was an error processing your request.");
                return;
            }

            $.each(data, function (i, item) {
                $('#Country').append($('<option>').val(item.Id).text(item.Text));
            });
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert("There was an error processing your request.");
        },
        complete: function () {
            $("#Country").enable();
            $("#ORG_ID").enable();
            $('#Country option[value="@TempData["Country"]"]').prop('selected', true).change();
            }
    })
}
Don
  • 1,532
  • 4
  • 24
  • 47
  • Where does the AJAX calls occurs? Page load event has nothing to do with complete AJAX calls... – plalx Aug 24 '14 at 17:15
  • this cannot be done in the way you are doing, try to check tempdata values, is the value null or not? – DevWithSigns Aug 24 '14 at 17:16
  • you are missing ajax calls – DevWithSigns Aug 24 '14 at 17:17
  • @plalx and Usama, I edited to add more content. A lot of AJAX codes. I tried to simplify it here. – Don Aug 24 '14 at 17:26
  • @Don Well you over simplified things. We need to see how you load your data into selects and at which point you are trying to set the selected values. – plalx Aug 24 '14 at 19:05
  • @plalx I added more complete code for one Combobox AJAX loading – Don Aug 24 '14 at 21:07
  • @Usama, the tempdata values are not null at all. – Don Aug 24 '14 at 21:08
  • @don It should be working the way it's written. What's `$('#Country').prop('options').length` within `complete`? If it's `> 0` it means your options were correctly loaded, but your selector doesn't match any option. Btw, to set a select value you can simply do `$('#Country').val(someOptionValue)`. – plalx Aug 24 '14 at 22:44

2 Answers2

1

The first A in AJAX stand for asynchronous, which means nothing waits on it, including window.load or document.ready.

The lazy method is to make your ajax synchronous using the "async" setting in $.ajax(), but this will pause all code execution and file loading while it waits on each reply. Not good.

The proper way to do this would be to use $.when(). Here is the relevant example from that page.

$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).done(function( a1, a2 ) {
  // a1 and a2 are arguments resolved for the page1 and page2 ajax requests, respectively.
  // Each argument is an array with the following structure: [ data, statusText, jqXHR ]
  var data = a1[ 0 ] + a2[ 0 ]; // a1[ 0 ] = "Whip", a2[ 0 ] = " It"
  if ( /Whip It/.test( data ) ) {
    alert( "We got what we came for!" );
  }
});



EDIT:

Is this not what you're trying to do? Fire a function after all of your ajax calls have completed?

$(document).ready(function () {
  GetCountry();
});

function GetCountry() {
    $("#Country").disable();
    $("#ORG_ID").disable();

    $.when(
        $.ajax({ // box 1
            type: 'POST',
            url: '@Url.Action("GetCountry/" + ViewBag.Id.ToString(), "RequestList")',
            data: { Direct: isDirect },
            success: function (data, textStatus, jqXHR) {
                if (textStatus != "success") {
                    alert("There was an error processing your request.");
                    return;
                }

                $.each(data, function (i, item) {
                    $('#Country').append($('<option>').val(item.Id).text(item.Text));
                });
            },
            error: function (jqXHR, textStatus, errorThrown) {
                alert("There was an error processing your request.");
            },
            complete: function () {
                $("#Country").enable();
                $("#ORG_ID").enable();
                $('#Country option[value="@TempData["Country"]"]').prop('selected', true).change();
            }
        }),
        $.ajax({ // box 2
            type: 'POST',
            url: '@Url.Action("GetCountry/" + ViewBag.Id.ToString(), "RequestList")',
            data: { Direct: isDirect },
            success: function (data, textStatus, jqXHR) {
                if (textStatus != "success") {
                    alert("There was an error processing your request.");
                    return;
                }

                $.each(data, function (i, item) {
                    $('#Country').append($('<option>').val(item.Id).text(item.Text));
                });
            },
            error: function (jqXHR, textStatus, errorThrown) {
                alert("There was an error processing your request.");
            },
            complete: function () {
                $("#Country").enable();
                $("#ORG_ID").enable();
                $('#Country option[value="@TempData["Country"]"]').prop('selected', true).change();
            }
        })

    ).done(function(){
        // fires after the two ajax calls are done
        document.getElementById('Country').readOnly = true;
        document.getElementById('ORG_ID').readOnly = true;
    });
}
Clayton Leis
  • 1,288
  • 9
  • 20
  • Thanks. Your example is for downloading a link. It is a bit different from mine. Please see my GetCountry(). – Don Aug 24 '14 at 21:13
  • I tried to move $.when to Document.Ready block as $.when(GetCountry()).done(function(){...}); but it does not work. Do I have to make it contain $.ajax only? – Don Aug 25 '14 at 20:06
  • Yep. jQuery.when() only accepts parameters of type [Deffered](http://api.jquery.com/category/deferred-object/), which $.ajax() happens to return. – Clayton Leis Aug 25 '14 at 21:17
0

You need to add async:false.

if you Setting async to false means that the statement you are calling has to complete before the next statement in your function can be called. If you set async: true then that statement will begin it's execution and the next statement will be called regardless of whether the async statement has completed yet.

Please try this code

  $.ajax({
        type: 'POST',
        url: '@Url.Action("GetCountry/" + ViewBag.Id.ToString(), "RequestList")',
        async:false,
        data: { Direct: isDirect },
        success: function (data, textStatus, jqXHR) {
            if (textStatus != "success") {
                alert("There was an error processing your request.");
                return;
            }

            $.each(data, function (i, item) {
                $('#Country').append($('<option>').val(item.Id).text(item.Text));
            });
        },
        error: function (jqXHR, textStatus, errorThrown) {
            alert("There was an error processing your request.");
        },
        complete: function () {
            $("#Country").enable();
            $("#ORG_ID").enable();
            $('#Country option[value="@TempData["Country"]"]').prop('selected', true).change();
            }
    })
Community
  • 1
  • 1