Sean
Sean

Reputation: 517

How to update Parent form from a Modal

I have a modal form that updates a client's address once the "save" button is clicked. I want to use a AJAX call to update the Model's data once the modal form is closed. It would then redirect back to the parent form from which the modal form was called (Index.cshtml). The AJAX call is successfully retrieving the updated modal form's data via the textboxes but it always throws an error.

TL;DR: Want to close a modal form, redirect to parent form and update the text displayed there.

Please see below for my code snippets:

Controller

[ValidateInput(false), HttpPost]
public JsonResult UpdateClientDetails(Client newClientDetails)
{
    _clientService.UpdateClient(newClientDetails);

    return Json(newClientDetails);
}

$('.btn-update-client').click(function (e) {
        var id = $(this).val();
        $('#updateClientModal .modal-content').load('/client/UpdateClientDetails/' + id);
        $('#updateClientModal').modal('show');
});

View (Index.cshtml)

<div class="panel-body">
    <label>Client Id: <span id="ClientId">@id</span></label>
    <address>
        <span id="Address1">@client.Address1</span>, <span id="Address2">@client.Address2</span><br>
        <span id="City">@client.City</span>, <span id="Province">@client.Province</span><br>
        <span id="PostalCode">@client.PostalCode</span><br>
        <abbr title="Phone">P:</abbr> <span id="PhoneNumber">@client.PhoneNumber</span>
    </address>
    <div><button value="@id" type="button" class="btn btn-primary btn-update-client">Change</button></div>
</div>

__

Controller Method

public ActionResult Index()
{
    return View(_clientService.GetClientList());
}

Modal Form

@model Client
@using ProductManager.Models

<div class="modal-header">
<h4 class="modal-title" id="exampleModalLabel">@Model.Name - ID: @Model.Id</h4>
</div>
@{
    var attributes = new Dictionary<string, object>();
    attributes.Add("class", "form-horizontal");
}
@using (Html.BeginForm("UpdateClientDetails", "Client", FormMethod.Post, attributes))
{
<div class="modal-body">
    <div class="form-group">
        <label for="clientAddress1" class="col-xs-3 control-label">Address 1</label>
            <div class="col-xs-9">
                <input type="text" class="form-control" id="clientAddress1" name="Address1" value="@Model.Address1">
            </div>
    </div>
    <div class="form-group">
        <label for="clientAddress2" class="col-xs-3 control-label">Address 2</label>
            <div class="col-xs-9">
                <input type="text" class="form-control" id="clientAddress2" name="Address2" value="@Model.Address2">
            </div>
    </div>
    <div class="form-group">
        <label for="clientCity" class="col-xs-3 control-label">City</label>
            <div class="col-xs-9">
                <input type="text" class="form-control" id="clientCity" name="City" value="@Model.City">
            </div>
    </div>
    <div class="form-group">
        <label for="clientProvince" class="col-xs-3 control-label">Province</label>
            <div class="col-xs-9">
                @Html.DropDownListFor(model => model.Province, (IEnumerable<SelectListItem>)ViewBag.ProvinceList, new { @class = "form-control", @id = "clientProvince" })
            </div>
    </div>
    <div class="form-group">
        <label for="clientPostalCode" class="col-xs-3 control-label">Postal Code</label>
            <div class="col-xs-9">
                <input type="text" class="form-control" id="clientPostalCode" name="PostalCode" value="@Model.PostalCode">
            </div>
    </div>
    <div class="form-group">
        <label for="clientPhoneNumber" class="col-xs-3 control-label">Phone #</label>
            <div class="col-xs-9">
                <input type="text" class="form-control" id="clientPhoneNumber" name="PhoneNumber" value="@Model.PhoneNumber">
            </div>
    </div>
    <div>
        <input type="hidden" id="clientName" name="Name" value="@Model.Name">
    </div>
    <div>
        <input type="hidden" id="clientID" name="Id" value="@Model.Id">
    </div>
</div>
<div class="modal-footer">
    <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
    <button type="submit" class="btn btn-primary">Save changes</button>
</div>
}

<script type="text/javascript">
    $('.btn-primary').click(function () {
        $.ajax({
            type: 'POST',
            data: getModelData(),
            dataType: 'json',
            success: function (data) {

                $("#Address1").text(data.Address1);
                $("#Address2").text(data.Address2);
                $("#City").text(data.City);
                $("#Province").text(data.Province);
                $("#PostalCode").text(data.PostalCode);
                $("#PhoneNumber").text(data.PhoneNumber);
            },
            error: function () {
                alert("Error occured!");
            }
        });

        function getModelData() {
            var dataToSubmit = {
                Address1: $("#clientAddress1").val(),
                Address2: $("#clientAddress2").val(),
                City: $("#clientCity").val(),
                Province: $("#clientProvince").val(),
                PostalCode: $("#clientPostalCode").val(),
                PhoneNumber: $("#clientPhoneNumber").val()
            };

            return dataToSubmit;
        }
    });
</script>

After clicking the "Save" button on my modal form, it redirects to http://localhost:6969/Client/UpdateClientDetails/1234 with the following string:

{"Address1":"38 Lesmill Rd","Address2":"Suite 1",
 "City":"Toronto","Province":"ON","PostalCode":"M3B 2T5",
 "PhoneNumber":"(416) 445-4504","Id":2827,"Name":"Advisor Centric"}

Upvotes: 2

Views: 2480

Answers (1)

anthonysmothers
anthonysmothers

Reputation: 307

If you are being redirected when you click the save function, it could be due to a few reasons. The below snippet should solve your problems.

$(document).on('click', '.btn-primary', function (event) {
    event.preventDefault();
    $.ajax({
        type: 'POST',
        data: getModelData(),
        dataType: 'json',
        success: function (data) {
            $("#Address1").text(data.Address1);
            $("#Address2").text(data.Address2);
            $("#City").text(data.City);
            $("#Province").text(data.Province);
            $("#PostalCode").text(data.PostalCode);
            $("#PhoneNumber").text(data.PhoneNumber);
        },
        error: function () {
            alert("Error occurred!");
        }
    });

    function getModelData() {
        var dataToSubmit = {
            Address1: $("#clientAddress1").val(),
            Address2: $("#clientAddress2").val(),
            City: $("#clientCity").val(),
            Province: $("#clientProvince").val(),
            PostalCode: $("#clientPostalCode").val(),
            PhoneNumber: $("#clientPhoneNumber").val()
        };
        return dataToSubmit;
    }
});

Changes to snippet explained:

  1. Instead of using the jQuery click method, I have updated this to use the on method. This will allow us to attach an event to the btn-primary class even if it is loaded after the dom has been rendered.
  2. We are now passing in the event object into the method. This allows us to prevent any default behavior that is expected, for example submitting the form traditionally. This is accomplished with the event.preventDefault() method.

Upvotes: 2

Related Questions