JMO
JMO

Reputation: 103

Submit MVC Form Results to HttpPost method and display model in bootstrap modal

I've seen lots of examples on how to use an ActionLink in a form to call a method on the controller. When it hits that method it then returns a partial view within a bootstrap modal. What I would like to do though is have my form post the form results to the HttpPost method on my controller and from there then call the partial view to display the bootstrap modal. How can I do this?

Form View:

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { id = "ballotForm" }))
{
    @Html.AntiForgeryToken()
    @(Html.EditorFor(m => m.BallotViewModel, new ViewDataDictionary(ViewData)
    {
        TemplateInfo = new System.Web.Mvc.TemplateInfo
        {
            HtmlFieldPrefix = "BallotViewModel"
        }
    }))
    <button type="submit" class="btn btn-primary" data-target="#modal-container" data-toggle="modal">Vote Management Ballot</button>

Controller:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Index(HomeViewModel bModel)
{
    if (ModelState.IsValid)
    {
        return PartialView("ViewVoteConfirmation", bModel.BallotViewModel);
    }
}

_Layout:

<div id="modal-container" class="modal fade"
     tabindex="-1" role="dialog">
    <div class="modal-content">
    </div>
</div>
<script type="text/javascript">

$(function () {

    // Initalize modal dialog
    // attach modal-container bootstrap attributes to links with .modal-link class.
    // when a link is clicked with these attributes, bootstrap will display the href content in a modal dialog.
    $('body').on('click', '.modal-link', function (e) {
        e.preventDefault();
        $(this).attr('data-target', '#modal-container');
        $(this).attr('data-toggle', 'modal');
        //$.post($(this).attr("href"), function (data) {
            // got the result in data variable. do whatever you want now
            //may be reload the page
        //});
    });

    // Attach listener to .modal-close-btn's so that when the button is pressed the modal dialog disappears
    $('body').on('click', '.modal-close-btn', function () {
        $('#modal-container').modal('hide');
    });

    //clear modal cache, so that new content can be loaded
    $('#modal-container').on('hidden.bs.modal', function () {
        $(this).removeData('bs.modal');
    });

    $('#CancelModal').on('click', function () {
        return false;
    });
});
</script>

Upvotes: 1

Views: 2855

Answers (2)

JMO
JMO

Reputation: 103

Here is what actually worked:

I applied this code snippet to my layout page

$('#ballotForm').on('submit', function(e) {
e.preventDefault();

var data = $(this).serialize();
var url = $(this).attr('target');

$.post(url, data)
    .done(function(response, status, jqxhr){

        $('#modal-container').modal('show');
        $('#modal-container').on('show.bs.modal', function (event) {
            var modal = $(this);
            modal.find('.modal-body').html(response);
        });

    })
    .fail(function(jqxhr, status, error){ });

Initially it did not work. So as @Tieson suggested, I moved

$('#modal-container').modal('show');

down below

$('#modal-container').on('show.bs.modal', function (event) {
    var modal = $(this);
    modal.find('.modal-body').html(response);
 });

and that enabled the modal to fire. So the altered working snippet looks like this:

$('#ballotForm').on('submit', function(e) {
e.preventDefault();

var data = $(this).serialize();
var url = $(this).attr('target');

$.post(url, data)
    .done(function(response, status, jqxhr){

        $('#modal-container').on('show.bs.modal', function (event) {
            var modal = $(this);
            modal.find('.modal-body').html(response);
        });

        $('#modal-container').modal('show');

    })
    .fail(function(jqxhr, status, error){ });

});

Upvotes: 1

Tieson T.
Tieson T.

Reputation: 21191

Seems relatively straight-forward.

  1. Attach an eventhandler to the form's onsubmit event.
  2. Cancel the normal event (you don't want the page itself to issue the POST request).
  3. Serialize the form, so that you have some data to submit.
  4. Grab the form's target property, so you know where to issue your POST.
  5. Use jQuery's $.post function to issue an ajax request.
  6. Your response is going to be a partial HTML page. We want to inject that into the body of the modal.

You should have something like this:

$('#ballotForm').on('submit', function(e) {
    e.preventDefault();

    var data = $(this).serialize();
    var url = $(this).attr('target');

    $.post(url, data)
        .done(function(response, status, jqxhr){

            $('#modal-container').on('show.bs.modal', function (event) {
                var modal = $(this);
                modal.find('.modal-body').html(response);
            });

            $('#modal-container').modal('show');

        })
        .fail(function(jqxhr, status, error){ });

});

This assumes a sunny-day case. .done() handles all 2xx response codes, which doesn't necessarily mean your response is exactly what you wanted.

Upvotes: 0

Related Questions