1

I have a bootstrap modal popup, with an ajax helper form on which I need to do some js validation prior to submitting. If validation fails, I'm showing some extra things on the form. If my validation passes I want to submit the form, and update a specific div with a PartialView. To do the validation, I'm calling a js function from a button on the form, and passing in the form. If my validation passes, I call the form's submit.

This works, but the PartialView displays full page, rather than in the target div. The form works properly and updates the target div when I submit directly from a submit input on the form instead of submitting from the js function.

How do I update my target div when submitting from js function?

See code:

function validateActionItem(sender) {
  var $formToSubmit = $(sender).closest('form');
  $formToSubmit.submit();
}


<div id="MyDivContainer" class="col-lg-12">
   @Html.Action("MyPartial", "MyController", new { ID = Model.ID })

<div class="modal fade" id="MyModal">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      @using (Ajax.BeginForm("MyAction", "MyController", 
        new { ID = Model.ID }, 
        new AjaxOptions { 
          UpdateTargetId = "MyDivContainer",
          OnSuccess = "closeModal()" 
        }, 
        new { @id = "MyForm"}))
      {
        <div class="modal-body">

        <!-- My form fields -->

        </div>
        <div class="modal-footer">
          <button class="btn btn-primary" role="button"
            type="button" onclick="validate($(this))">
            Validate Submit
          </button>     
        </div>
      }
    </div>
  </div>
</div>

My _Layout.cshtml contains...

@Scripts.Render("~/bundles/jquery")
     
    @Scripts.Render("~/bundles/jqueryval")

    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
        <script src="@Url.Content("~/Scripts/jquery.validate.js")" type="text/javascript"></script>
        <script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.js")" type="text/javascript"></script>

The MyAction action returns PartialView(model).

Can anyone point to what I'm doing wrong, and why my PartialView displays full page when submitting the form from javascript but properly updates the target div when I replace the button with a regular input submit on the form?

UPDATE

I have refactored the submit like so, but it's never getting called for some reason?

jQuery().ready(function () {
        $("#MyForm").submit(function (e) {

            $.ajax({
                url: "/MyController/MyAction",
                type: "POST",
                dataType: "html",
                contentType: false,
                data: $("#MyForm").serialize(),
                success: function (partialViewResult) {
                    closeModal();
                    $("#MyDivContainer").empty().append(partialViewResult);
                }

            });
        });
    });

UPDATE 2

I discovered that the jquery script must be after the modal popup in my cshtml, so now I'm reaching the submit event of my input button. However, I can't get to my controller action... the ajax call errors.

$("#MyForm").submit(function (e) {
        e.preventDefault();

        var id = $('#ID').val();
        alert("submit function called");
        alert("ID: " + id);

        $.ajax({
            url: "/MyController/MyAction",
            type: "POST",
            dataType: "html",
            data: { ID: (id)},
            error: alert("Error!")
        });
    });

I hit the "Error" alert, and don't know how to debug this to figure out what's wrong.

Brad
  • 323
  • 2
  • 13
  • Not related but you seem to be including the validation scripts twice (via the bundle, and the manual script tags) –  Sep 13 '17 at 21:18
  • And you should be doing this with a submit button and handling the `.submit()` event (and canceling it if your validation fails). Or simply using the `$.ajax()` methods rather than the obsolete `Ajax.BeginForm` –  Sep 13 '17 at 21:20
  • I've removed Ajax.Begin form and discovered that my script has to be placed AFTER the modal popup. So now I'm in the click event, but my $.ajax() is always reaching the error function. – Brad Sep 13 '17 at 23:40
  • For a start its `data: { ID: id },` (no parenthesis), and your also not doing anything in the `success` callback (as per your first update –  Sep 13 '17 at 23:44
  • And you should learn to use your browser tools to debug your code (e.g. inspect the response in the Network tab to see the details of the error) –  Sep 13 '17 at 23:45
  • The parentheses were in the example I followed. I removed the success callback for now. Right now I'd be happy to just hit my break point in the post action. Yeah, I don't know squat about debugging javascript... I don't do it often. Thank you for the hint. I've determined the ID parameter is null, but I have no idea why. I purposefully created an alert to show the value, and it's there. It just doesn't make it to the controller action. – Brad Sep 14 '17 at 00:03
  • For Chrome, start [here](https://developer.chrome.com/devtools). You should not be writing code until you know how to debug it –  Sep 14 '17 at 00:33
  • Track your ajax error [using](https://stackoverflow.com/questions/1637019/how-to-get-the-jquery-ajax-error-response-text) ..Does your controller action support POST? – gjijo Sep 14 '17 at 04:30
  • Yes. I have it posting now, but if I put an alert in the "error:" it still alerts... dunno why. – Brad Sep 14 '17 at 13:54

1 Answers1

0

I've got it working. Thanks everyone for the help. Here's the code:

For whatever reason, the script has to be placed after the modal popup markup.

<script type="text/javascript">
    $("#MyForm").submit(function (e) {
        e.preventDefault();

        //getting fields to be checked
        
        if //checking failed validations
        {
            //doing some things if val fails
        }
        else
        {
            var id = $('#ID').val();
            
            $.ajax({
                url: "/MyController/MyAction",
                type: "POST",
                dataType: "html",
                data: {ID: id},
                success: function (partialViewResult) {
                    closeMyModal();
                    $("#MyDivContainer").empty().append(partialViewResult);
                }
            });
        }
    });
</script>
Brad
  • 323
  • 2
  • 13