pavilion pavilion - 18 days ago 7
Ajax Question

Asp.net mvc updating dropdownlist in parent's page submitted by a modal popup

I have a main page that loads a partial view which is using


Html.BeginCollectionItem("employees")


because I am using a jQuery tab. (so the user can add more employee forms)

Inside of my Employee partial view has a dropdownlist for selecting country, and it also has a link that pops up a modal to add a new country. Here, what I want to do is, after submitting the modal and when it is closed, I would like the dropdownlist to be refreshed right away so that the user can see the new updated list.

How can this be done when the Id of dropdownlist is dynamically changed as the user adds more tab?

Company.cshtml:

@using (Html.BeginForm("Create", "CompanyForm", FormMethod.Post))
{
<p>Company Info</p>
@Html.EditorFor(m => m.companyName, new { htmlAttributes = new { @class = "form-control" } })

<div id="tabs">
<ul>
<li><a href="#tabs-employee">Employee 1</a> <span class="ui-icon ui-icon-close" role="presentation">Remove Tab</span></li>
</ul>
<div id="tabs-employee">
@Html.Action("Employee")
</div>
</div>
<button type="submit">Submit</button>
}

<script>
//tab codes...
</script>


Employee.cshtml:

<div class="editorRow">
@using (Html.BeginCollectionItem("employees"))
{
<!-- Dropdown-->
@Html.DropDownListFor(m => m.CountryId, (SelectList)ViewBag.CountryList, "-- Select --", new { @class = "form-control" })
<!-- Link-->
<a href="#" class="btn btn-info btn-md" data-toggle="modal" data-target="#countryModal">Add Country</a>
}
</div>

<!-- Modal -->
<div class="modal fade" id="countryModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="myModalLabel">Add Country</h4>
</div>
<div class="modal-body">
<div class="ajax-dynamic-get-data-form" />
</div>
</div>
</div>
</div>

<script>
$('#countryModal').on('show.bs.modal', function (event) {
var url='@Url.Action("NewEmployee")';
$.ajax({
type: "GET",
url: url,
data: JSON,
cache: false,
success: function (data) {
$('#countryModal').find('.ajax-dynamic-get-data-form').html(data);
},
error: function (err) {
console.log(err);
}
});
})
</script>


NewCountry.cshtml:

@{
Layout = null;
}

@using (Html.BeginForm("PostNewCountry", "CompanyForm", FormMethod.Post, new { id = "postOfferForm" }))
{

<label>Employee Name</label>
@Html.TextBoxFor(x => x.CountryName, new { @class = "form-control" })


<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-default">Save</button>
</div>
}

<script>
$("#postOfferForm").submit(function () {
$.ajax({
url: "/CompanyForm/PostNewCountry",
type: "POST",
data: $(this).serialize(),
datatype: "json",
success: function (response) {
if (response.status === "success") {
$('#countryModal').modal('hide');

} else {
alert(response.errorMessage);
$('#countryModal').modal('hide');
}
}
});
return false;
});
</script>


Edited

Another problem after Stephen gave me a hint to solve the above issue, is that the modal is only popping up in tab1. How can I also update the dropdownlist in all tabs?

Answer

You have a number of problems with your implementation.

First your generating duplicate scripts (in both your Employee.cshtml and NewCountry.cshtml partials), and these need to be moved to the main view so there is only one copy loaded.

In addition, it is only necessary to have one modal form for creating a new Country in the main view, and include a button in each Employee partial to open the modal (currently you just repeating a whole lot of unnecessary html and making unnecessary ajax calls to populate the modal form repeatedly - you can just include the form initially, or if you want to populate it using ajax, include a 'flag' that indicates if its been loaded or not so only one ajax call is made)

To update the dropdownlists with an option for the new Country you have added, give then a class name

@Html.DropDownListFor(m => m.CountryId, ... new { @class = "form-control country" })

Then in your ajax success callback update each existing dropdown. You have not indicated what your PostNewCountry() method returns, but assuming it returns just the ID of the new Country, then

success: function (response) {
    var name = $('#CountryName').val(); // assumes you have only one modal form
    var countries = $('.country');
    $.each(countries, function(index, item) {
        var option = $('<option></option>').val(response).text(name);
        $(this).append(option);
    }
}

Your second issue (the modal is only popping up in tab1) is as a result of all duplicate id attributes which is invalid html. This will be solved by having only one modal as noted above, but with your current implementation, you need to remove the id attributes and use class names instead. When you use id selectors in jQuery, it will only select the first one with that id, so neither $('#countryModal').on(..., and $("#postOfferForm").submit(... will work correctly.

Comments