0

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?

bbusdriver
  • 1,577
  • 3
  • 26
  • 58
  • 1
    Are you wanting to add the new employee to all dropdownlists, or just the one on the 'current' tab? If the later, use class names and relative selectors (the value of `id` attribute is irrelevant) –  Nov 14 '16 at 23:10
  • Great. using class name works, but i just found that the modal is popping up only in Employee 1 tab. If I clicked on the new employee link in Employee 2 tab, the modal is shown in Employee 1 tab. I assume that it is related to this line? $('#employeeModal').find('.ajax-dynamic-get-data-form').html(data); – bbusdriver Nov 14 '16 at 23:42
  • I'm have difficulty understanding what your trying to do here. It seems your generating a form for a `Company` and want to be able to dynamically add new `Employee` objects (and edit any existing employees it may have) - in which case this makes no sense - why would you have a dropdownlist for the employees? –  Nov 14 '16 at 23:48
  • Your also duplicating scripts which is awful practice. –  Nov 14 '16 at 23:49
  • Aside from dropdownlist, can you see why the modal is popping up in only tab 1? – bbusdriver Nov 14 '16 at 23:58
  • Because you have duplicate (invalid) `id` attributes - `div class="modal fade" id="employeeModal" ... >` and (duplicated `$('#employeeModal').on(..` script only selects the first one –  Nov 15 '16 at 00:00
  • But none of this makes sense anyway. If your adding a new employee for the company, then you do not need any modal form or any ajax to submit their name (the `Employee.cshtml` view should include the textbox for their name) –  Nov 15 '16 at 00:02
  • Hmm. Okay. What would be the best way to prevent that? – bbusdriver Nov 15 '16 at 00:05
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/128104/discussion-between-stephen-muecke-and-pavilion). –  Nov 15 '16 at 00:05

1 Answers1

1

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.