3

I want to upload partial view data without reloading the html. i have used Json to get the data but I think there is some issues in Script. The Success part is not executing.

  [HttpPost]
        public JsonResult HorseTracker(ClsHorseTracker model)
        {
            try
            {
                if (ModelState.IsValid)
                {

                  horseTrackerDetails.InsertUpdateHorseTracker(model);
                    }
                                        }
                return Json(model, JsonRequestBehavior.AllowGet);
            }
            catch
            {
                return Json(new { success = false });
            }
        }

 [ChildActionOnly]
        public PartialViewResult HorseTrackerDetails()
        {
            return PartialView("_pHorseTrackerDetails", horseTrackerDetails.HorseTrackerList());
        }

Main View

 @using (Html.BeginForm("HorseTracker", "HorseTracker", FormMethod.Post, new { id = "CreateForm" }))
        {
            <div class="panel panel-default" style="font-size:12px;">

                <div class="panel-body">
                    <div class="form-group">    

                        @Html.TextBoxFor(m => m.HorseName)

                        @Html.DropDownListFor(m => m.HorseTypeName, Model.HorseTypeList)

                    </div>
                    <input type="submit" value="Save" class="btn btn-primary pull-right" />
                </div>
            </div>

        }

    </div>
    <div id="partial" class="col-md-8">
        @Html.Action("HorseTrackerDetails", "HorseTracker")
    </div>

Partial View

  <table class="table">
                <tr>

                    <th>
                        @Html.DisplayNameFor(model => model.HorseName)
                    </th>

                    <th>
                        @Html.DisplayName("Type")
                    </th>


                </tr>

                @foreach (var item in Model)
                {
                    <tr>

                        <td>
                            @item.HorseName
                        </td>

                        <td>
                            @item.HorseTypeName
                        </td>
</tr>
</table>

Script

  $(document).ready(function () {
            var url = '@Url.Action("HorseTracker", "HorseTracker")';
            $('#CreateForm').submit(function () {

                  if (!$(this).valid()) {
                    return;
                   }
                 $.post(url,$(this).serialize(), function (response) {
                     if (response.success) {
                         debugger;
                         $('#partial').html(response);
                     }
                     else {
                         var message = response.message;
                         alert(message);
                      }
                });
                   return false;
               })
        })
13
  • 1
    You're returning model (ClsHorseTracker) but not includes success response, hence if (response.success) always returns false. You need to add something like success = true in return Json part. Commented Aug 10, 2018 at 7:10
  • @TetsuyaYamamoto, now $('#partial').html(response); executes but still do not see changes in the form unless I refresh the page. Commented Aug 10, 2018 at 7:18
  • Check if response returns proper HTML partial page response. If it returns something other than HTML markups, you should know why the response is not rendered properly. Commented Aug 10, 2018 at 7:20
  • @TetsuyaYamamoto, When I mousehover on html, it doesnot show markup. But response contains data inside. Where I am doing wrong.Please guide me. Commented Aug 10, 2018 at 7:25
  • Well, you should use return PartialView instead of return Json on successful result with viewmodel - you only need to check if the request fails with success = false exist as response. Commented Aug 10, 2018 at 7:28

2 Answers 2

3

Unless you are changing the values of you model properties is the POST method, then there is no reason to return the model (or a partial view). You can simply append a new row to the table based on the values in your form.

Your controller method should be

[HttpPost]
public JsonResult HorseTracker(ClsHorseTracker model)
{
    try
    {
        if (ModelState.IsValid)
        {
              horseTrackerDetails.InsertUpdateHorseTracker(model);
              return Json(new { success = true});
        }
        // see notes below
    }
    catch
    {
        return Json(new { message = "your error message" });
    }
}

Then modify the script to

var url = '@Url.Action("HorseTracker", "HorseTracker")';
$('#CreateForm').submit(function () {
    if (!$(this).valid()) {
        return;
    }
    var name = $('#HorseName').val();
    var type = $('#HorseTypeName').find('option:selected').text()

    $.post(url, $(this).serialize(), function (response) {
        if (response.success) {
            var row = $('<tr></tr>');
            row.append($('<td></td>').text(name));
            row.append($('<td></td>').text(type));
            $('.table').append(row);
        } else if (response.message) {
            alert(response.message);
        }
    });
    return false;
})

Notes

If ModelState is not valid, then you should return a list of ModelState errors, so that you can update the corresponding element generated by @Html.ValidationMessageFor(...); To do that you can use

var errors = ModelState.Keys.Where(k => ModelState[k].Errors.Count > 0).Select(k => new { propertyName = k, errorMessage = ModelState[k].Errors[0].ErrorMessage });
return Json( new { errors = errors });

and then add a else if (response.errors) { // update the error messages } block of code in the success callback

If would be better to render the <table> with <thead> and <tbody> elements and give the <tbody> an id attribute and use that as the selector to add the new row

Sign up to request clarification or add additional context in comments.

5 Comments

Currently for var name = $('#HorseName'); giving [object Object]
One more thing to ask, as main is providing criteria and based on that criteria, more than 2 fields are inserting in the database. In that case,if I want to display more than only these 2 fields then can I use like var sire = $('#Sire').val();
Yes. And then you just append more <td> element to to row based on your form controls
Thank you so much. Solved my problem. Can you please tell me difference between this approach $('#partial').html(response); and var row = $('<tr></tr>'); appending the data. Which one is good for which circumstances?
$('#partial').html(response); means you need to return a partial view from the controller method (and in your case, that would be a partial view based on IEnumerable<T> that generates your table). In you case, that is unnecessary, since all you need to do is add one new row to the table, and you already have all the necessary information in the view to do that (i.e. based on the form controls)
1

Sounds like you're not include response.success in JSON response, hence it always returns false and $('#partial').html(response) never executes. You should use PartialView for success response like this:

public ActionResult HorseTracker(ClsHorseTracker model)
{
    try
    {
        if (ModelState.IsValid)
        {
            horseTrackerDetails.InsertUpdateHorseTracker(model);
        }
        return PartialView("_pHorseTrackerDetails", model)
    }
    catch
    {
        return Json(new { success = false, message = "Your message here" });
    }
}

And then change your AJAX POST to retrieve HTML response as given below:

$.post(url, $(this).serialize(), function (response) {
    if (response.success == false) {
        var message = response.message;
        alert(message);
    }
    else {
        debugger;
        $('#partial').html(response);
    }
});

If you want to returning viewmodel contents with result status instead, you must append HTML table rows and cell elements manually with $.each:

Controller

public ActionResult HorseTracker(ClsHorseTracker model)
{
    try
    {
        if (ModelState.IsValid)
        {
            horseTrackerDetails.InsertUpdateHorseTracker(model);
        }
        return Json(new { success = true, data = model });
    }
    catch
    {
        return Json(new { success = false, message = "Your message here" });
    }
}

jQuery

$.post(url,$(this).serialize(), function (response) {
    if (response.success) {
        debugger;
            $.each(response.data, function(i, item) {
                var row = $('<tr>');
                row.append($('<td>').text(item.HorseName), $('<td>').text(item.HorseTypeName));
            });
            $('#table').append(row);
    }
    else {
        var message = response.message;
        alert(message);
    }
});

1 Comment

Your first approach gives error The model item passed into the dictionary is of type 'ClsHorseTracker', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[ClsHorseTracker]'.`

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.