ASP.NET MVC 'Create' Action in Bootstrap Modal to Update Index from separate view/controller

995 Views Asked by At

I have a View/Controller called "Reviews" in this I want a bootstrap modal pop-up that shows the 'Create' action from the 'ReviewChecklist' controller. This all displays correctly, but I need to submit this post to save the checklist data to the database. Doing this causes it to crash out and render the wrong page instead of just closing the modal pop-up.

I also have the index of 'ReviewChecklist' rendered above so this should ideally update too.

Not sure if I've approached this something completely wrong or got something not quite right, thanks in advance.

'Review' View

<div class="form-group">
            @{
                Html.RenderAction("Index", "ReviewChecklists", new { reviewId = Model.Id, viewOnly = false });
            }

            <button type="button" class="btn btn-primary" data-toggle="modal" data-target="#checklistModal">
                Launch demo modal
            </button>
            <div class="modal fade" id="checklistModal" tabindex="-1" role="dialog" aria-labelledby="checklistModalLabel" aria-hidden="true">
                <div class="modal-dialog" role="document">
                    <div class="modal-content">
                        <div class="modal-header">
                            <h5 class="modal-title" id="checklistModalLabel">Review Checklist</h5>
                            <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                <span aria-hidden="true">&times;</span>
                            </button>
                        </div>
                        @using (Html.BeginForm("Create", "ReviewChecklistsController", FormMethod.Post, new {Id = "checklistForm" }))
                        {
                            <div class="modal-body">
                                @{Html.RenderAction("Create", "ReviewChecklists", new { reviewId = Model.Id });}
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
                                <button type="submit" class="btn btn-success">Save Checklist</button>
                            </div>
                        }
                    </div>
                </div>
            </div>
        </div>

'ReviewChecklist' Controller:

[HttpPost]
//[ValidateAntiForgeryToken] Causes issues with the modal dialog
        public async Task<ActionResult> Create([Bind(Include = "Id,ReviewId,ChecklistId,Status")] ReviewChecklist[] reviewChecklist)
        {
            foreach (ReviewChecklist item in reviewChecklist)
            {
                db.ReviewChecklists.Add(item);
            }
            await db.SaveChangesAsync();
            return PartialView();
            //return RedirectToAction("Create", "Reviews", new { reviewId = reviewChecklist[0].ReviewId });
        }

Script code:

If you need anything else please comment :)

// prepare the form when the DOM is ready 
$(document).ready(function () { 
    alert('setting up form');
    var options = { 
        beforeSubmit:  showRequest,  // pre-submit callback 
        success: showResponse,  // post-submit callback 
        error: handleError
    }; 

    // bind form using 'ajaxForm'
    $('#checklistForm').ajaxForm(options); /// give your create form an ID
    alert('form setup complete');
}); 

// pre-submit callback 
function showRequest(formData, jqForm, options) { 
  //// things you can do before form submit like loaders
    alert('showRequest');
    return true;
} 

// post-submit callback 
function showResponse(responseText, statusText, xhr, $form)  { 
 //// things you can do after the response 
    alert('showResponse');
    alert(responseText);
  if(responseText == 1)
   $("#checklistModal").modal("hide");
   /// show toast or somthing for saving data successfully
} 

function handleError(xhr, textStatus, error) {
    alert('error');
    alert(textStatus);
}

The jQuery.Form plugin has been added via Nuget and added to the bundles like this:

bundles.Add(new ScriptBundle("~/bundles/jqueryform").Include(
                    "~/Scripts/jquery.form*"));

and then referenced in the _Layout.cshtml like so

@Scripts.Render("~/bundles/jqueryform")

The issue I am now facing is that after the submit is done, it does not close the modal, instead just renders all the source code of the page? I also do not see the alerts for showRequest or showResponse but the alerts of form setup displayed are shown.

1

There are 1 best solutions below

13
On BEST ANSWER

1. Keep HTML as it is except give Id to create from. Ensure it is also not nested in any other forms.

2. Include this library in your layout from here (also available as a Nuget package)

It's a jQuery Form Plugin allows you to easily and unobtrusively upgrade HTML forms to use AJAX.

3.Controller

    [HttpPost]
    //[ValidateAntiForgeryToken] Causes issues with the modal dialog
    public async Task<ActionResult> Create([Bind(Include = 
       "Id,ReviewId,ChecklistId,Status")] ReviewChecklist[] reviewChecklist)
    {
        foreach (ReviewChecklist item in reviewChecklist)
        {
            db.ReviewChecklists.Add(item);
        }
        await db.SaveChangesAsync();

        return Json(1, JsonRequestBeahvaoir.AllowGet); /// return 1 or 0 or as per requirements or anything, the response you can handle in jQuery showResponse() method later.
    }

4.Script

// prepare the form when the DOM is ready 
  $(document).ready(function() { 
     var options = { 
           beforeSubmit:  showRequest,  // pre-submit callback 
           success:       showResponse  // post-submit callback 
     }; 
     // bind form using 'ajaxForm' 
     $('#myForm1').ajaxForm(options); /// give your create form an ID
  });     

// pre-submit callback 
  function showRequest(formData, jqForm, options) { 
      // things you can do before form submit like loaders
      return true; 
    } 

 // post-submit callback 
  function showResponse(responseText, statusText, xhr, $form)  { 
     // things you can do after the response 
      if(responseText == 1)
       $("#checklistModal").modal("hide");
       // show toast or somthing for saving data successfully
    }