Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JQuery - Callback Dropdownlist load

I need to select a value from a Dropdownlist after it has been loaded:

EDIT: In the script associated with the View I have:

//Dropdown cascade call when trigger is called and fill councilDropdown:
$("#districtDropdown").cascade({
    url: "/Address/ListCouncilByDistrict",
    paramName: "districtId",
    firstOption: 'Selecione o Concelho...',
    childSelect: $("#councilDropdown")
});

$("#PostalCode").keyup(function () {
loadPTPostalCode();
});

$("#PostalCodeExtension").keyup(function () {
    loadPTPostalCode();
});


function loadPTPostalCode()
{
  if ($("#PostalCode").val() >= 1000) {
    $.ajax({
        url: '/Address/GetPTPostalCode',
        type: "POST",
        dataType: "json",
        data: { postalCode: $("#PostalCode").val(), postalCodeExtension: $("#PostalCodeExtension").val() },
        success: function (data) {
            if (data != null) {
                $("#districtDropdown").val(data.PTDistrict_Id); // Set the Dropdown value
                $('#districtDropdown').trigger('change'); // Trigger (force the dropdown to load

                // *** This is done to soon, the dropdownlist of the Councils is not all loaded yet ***
                $("#councilDropdown").val(data.PTCouncil_Id);
            }
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
            alert(textStatus)
        }
    });
}

}

EDIT: The View

@model Heelp.ViewModels.AddressPTViewModel

<h2>Create</h2>

@using (Ajax.BeginForm(MVC.Address.CreateAddressPT(), new AjaxOptions { OnSuccess = "showLoginConfirmationResultMessage" }, new { @id = "AddressForm" }))
{
@Html.AntiForgeryToken()

<div class="address1">
    @Html.LabelFor(model => model.Address1)
    @Html.TextBoxFor(model => model.Address1)
    @Html.ValidationMessageFor(model => model.Address1)
</div>
<div class="address2">
    @Html.TextBoxFor(model => model.Address2)
    @Html.ValidationMessageFor(model => model.Address2)
</div>
<div class="city">
    @Html.LabelFor(model => model.City)
    @Html.TextBoxFor(model => model.City)
    @Html.ValidationMessageFor(model => model.City)
</div>
<div class="postalCode">
    @Html.DisplayNameFor(m => m.PostalCode)
    @Html.TextBoxFor(m => m.PostalCode, new { @Value = "" })
    @Html.ValidationMessageFor(m => m.PostalCode)
</div>
<div class="postalCodeExtension">
    @Html.LabelFor(model => model.PostalCodeExtension)
    @Html.TextBoxFor(model => model.PostalCodeExtension)
    @Html.ValidationMessageFor(m => m.PostalCodeExtension)
</div>
<div class="postalCodeCity">
    @Html.LabelFor(model => model.PostalCodeCity)
    @Html.TextBoxFor(model => model.PostalCodeCity)
    @Html.ValidationMessageFor(m => m.PostalCodeCity)
</div>
<div id="district">
    @Html.DisplayNameFor(m => m.PTDistrict_Id)
    @Html.DropDownListFor(m => m.PTDistrict_Id, Model.PTDistrictList, HeelpResources.PTDistrictViewDropDownListFirstRecord, new { id = "districtDropdown" })
    @Html.ValidationMessageFor(m => m.PTDistrict_Id)
</div>
<div id="council">
    @Html.DisplayNameFor(m => m.PTCouncil_Id)
    @Html.DropDownListFor(m => m.PTCouncil_Id, Model.PTCouncilList, HeelpResources.PTCouncilViewDropDownListFirstRecord, new { id = "councilDropdown" })
    @Html.ValidationMessageFor(m => m.PTCouncil_Id)
</div>
<p>
    <input type="submit" value="Create" />
</p>
}
<div>
 @Html.ActionLink("Back to List", "Index")
</div>

EDIT:

Cascade Function:

// Cascade function
(function ($) {
$.fn.cascade = function (options) {
    var defaults = {};
    var opts = $.extend(defaults, options);

    return this.each(function () {
        $(this).change(function () {
            var selectedValue = $(this).val();
            if (selectedValue == '') {
                opts.childSelect.empty();
                return;
            }
            var params = {};
            params[opts.paramName] = selectedValue;
            $.post(opts.url, params, function (items) {
                //$.getJSON(opts.url, params, function (items) {
                opts.childSelect.empty();
                if (opts.firstOption != "")
                    opts.childSelect.append(
                        $('<option/>')
                            .attr('value', '')
                            .text(opts.firstOption));
                $.each(items, function (index, item) {
                    // alert(opts.firstOption);
                    opts.childSelect.append(
                        $('<option/>')
                            .attr('value', item.Id)
                            .text(item.Name)
                    );
                });
            });
        });
    });
};
})(jQuery);

But when I do that, as the Dropdownlist is not still loaded, the val() is not there yet.

For example, if I put an alert message before, it works fine because it as time to load the dropdown.

How can I set the value of the council dropdown only after the dropdown is loaded?

like image 521
Patrick Avatar asked Jan 15 '23 06:01

Patrick


2 Answers

As your requirement "set the value of the council dropdown only after the dropdown is loaded".

You need perform synchronous Ajax request. You can specify the async option to be false to get a synchronous Ajax request.

$.ajax({
    url: '/Address/GetPTPostalCode',
    type: "POST",
    dataType: "json",
    data: { postalCode: $("#PostalCode").val(), postalCodeExtension: $("#PostalCodeExtension").val() },
    success: function (data) {
        if (data != null) {
            $("#districtDropdown").val(data.PTDistrict_Id); 
            $('#districtDropdown').trigger('change'); 

            // *** This is done to soon, the dropdownlist of the Councils is not all loaded yet ***
            $("#councilDropdown").val(data.PTCouncil_Id);
        }
    },
    async:   false
});
like image 119
YROjha Avatar answered Jan 16 '23 22:01

YROjha


I would update the cascade plugin to trigger an event when the ddl is updated.

(function ($) {
$.fn.cascade = function (options) {
    var defaults = {};
    var opts = $.extend(defaults, options);

    return this.each(function () {
        $(this).change(function () {
            // #### store reference to changed element for later ####
            var self = this,
                selectedValue = $(this).val();
            if (selectedValue == '') {
                opts.childSelect.empty();
                return;
            }
            var params = {};
            params[opts.paramName] = selectedValue;
            $.post(opts.url, params, function (items) {
                //$.getJSON(opts.url, params, function (items) {
                opts.childSelect.empty();
                if (opts.firstOption != "")
                    opts.childSelect.append(
                        $('<option/>')
                            .attr('value', '')
                            .text(opts.firstOption));
                $.each(items, function (index, item) {
                    // alert(opts.firstOption);
                    opts.childSelect.append(
                        $('<option/>')
                            .attr('value', item.Id)
                            .text(item.Name)
                    );
                });
                // #### Trigger event ####
                self.trigger("update");
            });
        });
    });
};
})(jQuery);

now you can bind to that:

    ...
    // *** #### fixed #### This is done to soon, the dropdownlist of the Councils is not all loaded yet ***
    $("#councilDropdown").on("updated",function(){
        $(this).val(data.PTCouncil_Id);
    });
}
like image 21
Kevin B Avatar answered Jan 16 '23 22:01

Kevin B