1

I have question about how to bind data from controller. This is the idea: I have list of data in datatable. I need to delete 1 data from datatable. I'm using ajax post to call actionresult in controller and send the model. And my controller will delete the data, and return the model to view.

Here is my viewmodels:

public class SampleHeaderViewModels
{
    [Display(Name = "ID")]
    public int intID { get; set; }

    [Display(Name = "Field 1")]
    public string txtField1 { get; set; }

    [Display(Name = "Field 2")]
    public string txtField2 { get; set; }
}

public class SampleDetailViewModels
{
    [Display(Name = "ID")]
    public int intID { get; set; }

    [Display(Name = "Line")]
    public int intLine { get; set; }

    [Display(Name = "Detail 1")]
    public string txtDetail1 { get; set; }

    [Display(Name = "Detail 2")]
    public string txtDetail2 { get; set; }
}

public class SampleViewModels
{
    public SampleHeaderViewModels Header { get; set; }
    public List<SampleDetailViewModels> Detail { get; set; }

    public SampleViewModels()
    {
        Header = new SampleHeaderViewModels();
        Detail = new List<SampleDetailViewModels>();
    }
}

And this is my View:

<div class="row">
    <div class="block">
        <div class="block-content controls">
            <div class="col-md-6">
                <div class="row-form">
                    <div class="col-md-4">
                        @Html.LabelFor(m => m.Header.txtField1, htmlAttributes: new { @class = "control-label" })
                    </div>
                    <div class="col-md-8">
                        @Html.HiddenFor(m => m.Header.intID)
                        @Html.TextBoxFor(m => m.Header.txtField1, htmlAttributes: new { @class = "form-control" })
                    </div>
                </div>
                <div class="row-form">
                    <div class="col-md-4">
                        @Html.LabelFor(m => m.Header.txtField2, htmlAttributes: new { @class = "control-label" })
                    </div>
                    <div class="col-md-8">
                        @Html.TextBoxFor(m => m.Header.txtField2, htmlAttributes: new { @class = "form-control" })
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<div class="row">
    <div class="block">
        <div class="block-content controls">
            <div class="col-md-12">
                <div class="row-form">
                    <table id="tbDataTable" class="table table-bordered">
                        <thead>
                            <tr>
                                <td>

                                </td>
                                <td>
                                    @Html.LabelFor(m => m.Detail.FirstOrDefault().intLine)
                                </td>
                                <td>
                                    @Html.LabelFor(m => m.Detail.FirstOrDefault().txtDetail1)
                                </td>
                                <td>
                                    @Html.LabelFor(m => m.Detail.FirstOrDefault().txtDetail2)
                                </td>
                            </tr>
                        </thead>
                        <tbody>
                            @if (Model.Detail != null)
                            {
                                for (int x = 0; x <= Model.Detail.Count - 1; x++)
                                {
                                    <tr>
                                        <td>
                                            <button type="button" class="btn btn-primary" onclick="return DeleteDetail('@Model.Detail[x].intLine');">Delete</button>
                                        </td>
                                        <td>
                                            @Html.DisplayFor(m => @Model.Detail[x].intLine)
                                            @Html.HiddenFor(m => @Model.Detail[x].intLine)
                                        </td>
                                        <td>
                                            @Html.DisplayFor(m => @Model.Detail[x].txtDetail1)
                                            @Html.HiddenFor(m => @Model.Detail[x].txtDetail1)
                                        </td>
                                        <td>
                                            @Html.DisplayFor(m => @Model.Detail[x].txtDetail2)
                                            @Html.HiddenFor(m => @Model.Detail[x].txtDetail2)
                                        </td>
                                    </tr>
                                }
                            }
                    </table>
                </div>
                <div class="row-form">
                    <div class="col-md-2">
                        <button type="button" id="btnAddDetail" class="btn btn-info">Add Detail</button>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

This is my Javascript:

function DeleteDetail(intLine)
    {
        debugger;
        
        var modelHeader = {
            "intID": $('#@Html.IdFor(m => m.Header.intID)').val(),
            "txtField1": $('#@Html.IdFor(m => m.Header.txtField1)').val(),
            "txtField2": $('#@Html.IdFor(m => m.Header.txtField2)').val(),
        };

        var modelDetail = @Html.Raw(JsonConvert.SerializeObject(Model.Detail));

        $.ajax({
            url: '/Sample/DeleteDetail',
            type: 'POST',
            datatype: 'JSON',
            contentType: 'application/json',
            data: JSON.stringify(
                {
                    objHeader : modelHeader,
                    objDetail : modelDetail,
                    intLine : intLine
                }),
            cache: false,
            success: function (data) {
                @*window.location.replace('@Url.Action("Detail")');*@
                },
            error: function (data) {
                console.log(data);
            }
        });
    }

And this is my controller:

[HttpPost]
    public ActionResult DeleteDetail(SampleHeaderViewModels objHeader, List<SampleDetailViewModels> objDetail, int intLine)
    {
        objDetail.Remove(objDetail.Where(m => m.intLine == intLine).FirstOrDefault());

        SampleViewModels obj = new SampleViewModels();
        obj.Header = objHeader;
        obj.Detail = objDetail;

        TempData["model"] = obj;

        return View("Index", obj);
    }

The question is: In my code, when I pressed "Delete" button in datatable, it will call function AJAX POST DeleteDetail in javascript. And it will send the Header model and Detail model to my Controller. And my controller will remove the selected row and return the model to View. And my View get the latest model. Which is 1 row already deleted. But it will not render the datatable. So the deleted data is still there. I'm trying using @url to post the page when the AJAX succeded, but still no luck. How to force the datatable to bind the latest model?

Thanks.

Edited:

I'm trying to refresh the data without refresh the page. Just refresh the datatable.

Here is my Controller:

public ActionResult DeleteDetail(SampleHeaderViewModels objHeader, List<SampleDetailViewModels> objDetail, int intLine)
    {
        objDetail.Remove(objDetail.Where(m => m.intLine == intLine).FirstOrDefault());

        SampleViewModels obj = new SampleViewModels();
        obj.Header = objHeader;
        obj.Detail = objDetail;

        TempData["model"] = obj;

        var json = JsonConvert.SerializeObject( new {detail = obj.Detail});

        return Content(json, "application/json");
    }

And this is my Javascript:

function DeleteDetail(intLine)
    {
        debugger;
        var modelHeader = {
            "intID": $('#@Html.IdFor(m => m.Header.intID)').val(),
            "txtField1": $('#@Html.IdFor(m => m.Header.txtField1)').val(),
            "txtField2": $('#@Html.IdFor(m => m.Header.txtField2)').val(),
        };

        var modelDetail = @Html.Raw(JsonConvert.SerializeObject(Model.Detail));

        $.ajax({
            url: '/Sample/DeleteDetail',
            type: 'POST',
            datatype: 'JSON',
            contentType: 'application/json',
            data: JSON.stringify(
                {
                    objHeader : modelHeader,
                    objDetail : modelDetail,
                    intLine : intLine
                }),
            cache: false,
            success: function (data) {
                debugger;

                table = $("#tbDataTable").dataTable();
                oSettings = table.fnSettings();

                table.fnClearTable(this);

                for (var i=0; i < data.detail.length; i++)
                {
                    table.oApi._fnAddData(oSettings, data.detail[i]);
                    //this part always send error DataTables warning: table id=tbDataTable - Requested unknown parameter '0' for row 0.
                }

                oSettings.aiDisplay = oSettings.aiDisplayMaster.slice();
                table.fnDraw();

                },
            error: function (data) {
                console.log(data);
            }
        });
    }

But it send me an error DataTables warning: table id=tbDataTable - Requested unknown parameter '0' for row 0. The view and view model is still same like the first question. Please help me.

9
  • Reload your datatable after success deleted record Commented Apr 27, 2017 at 17:34
  • I have read about reload datatable from server side. But I have no luck. Maybe I don't understand the concept. Could you help me with all my code above? Commented Apr 27, 2017 at 22:13
  • Are you using jquery datatable plugin ?? Commented Apr 28, 2017 at 2:24
  • Yes i do. But I don't really understand how to rebind th datatable Commented Apr 28, 2017 at 5:38
  • You are using strongly type modal binding to show listing, you need to reload your page after successfully deleted record Commented Apr 28, 2017 at 5:40

3 Answers 3

1

Action Method return true if you successfully deleted a record from database other wise return false:

 public ActionResult DeleteDetail(SampleHeaderViewModels objHeader, 
  List<SampleDetailViewModels> objDetail, int intLine)
  {
     ...
  ...
  db.SaveChanges();
  return Json(new { Success = true; });
  }

Reload the current page in success method of ajax ,

  success: function (data) {

  if(data.Success) {
   // reload you page through javacript/jquery
        window.location.reload();

        //location.reload(true);
    }
Sign up to request clarification or add additional context in comments.

15 Comments

Is there any way to refresh the table without refresh the page?
Its depend on how you are loading listing on the page if you are using strongly type then you have to reload your page. if you are loading the listing through ajax OR any jquery plugin like datatable jquery plugin. then its doesn't reload the page.
If I convert objDetail as JSON and I return it, can I bind the datatable without refresh the page?
Yes , You just need to reload/refresh the datatable . No need relaod page
|
0

Jquery:

<script>
    var Display;

    $(document).ready(function () {

        $('#ProductTable').DataTable();

        Display = function () {
            var URL = '@Url.Action("GetProductsData", "Product")';

            oTable = $('#ProductTable').DataTable({
                dom: 'Bfrtip',
                "bPaginate": false,
                buttons: [
                    'excel', 'pdf', 'print'
                ],
                "processing": false,
                "serverSide": false,
                "bSort": false,
                "searching": true,
                "sAjaxSource": URL,
                "pageLength": 10,
                "bDestroy": true,
                "bLengthChange": true,
                "scrollX": true,
                "scrollY": ($(window).height() - 200),
                "pagingType": "full_numbers",
                "sEmptyTable": "Loading data from server",
                "fnServerData": function (sSource, aoData, fnCallback) {

                    $.ajax({
                        "dataType": 'json',
                        "type": "POST",
                        "url": sSource,
                        "data": aoData,
                        "success": fnCallback
                    });
                },
                "columns": [
                                  {

                                      "sWidth": "5%",
                                      "bSortable": true,
                                      "sClass": "TextCenter ID",
                                      "visible": false,
                                      "render": function (data, type, row, meta) {
                                          return (row[0])
                                      }
                                  },
                                  {

                                      "sWidth": "5%",
                                      "sClass": "rightalign ",
                                      "render": function (data, type, row, meta) {
                                          return (row[1])
                                      }
                                  },
                                   {

                                       "sWidth": "10%",
                                       "sClass": "rightalign TA_C",
                                       "render": function (data, type, row, meta) {
                                           return (row[2])
                                       }
                                   },

                                  {
                                      "swidth": "5%",
                                      "sclass": "TextCenter Action",
                                      "render": function (data, type, row, meta) {
                                          return '<button class="btn btn-primary fa fa-check-square"  title="Edit" onclick="editdata(' + row[0] + ',\'' + row[1] + '\',' + row[2] + ')"></button>' +
                                      '<button class="btn btn-danger glyphicon glyphicon-trash" title="Delete"  onclick="deletedata(' + row[0] + ')" style="margin-left: 10px;"></button>';

                                          }
                                  }


                ], "fnInitComplete": function (oSetting, json) {

                }
            });
        }



        Display();

        $("#btninsert").click(function () {


            var fdata = new FormData();

            fdata.append("id","0");
            fdata.append("pname",$("#txtpname").val());
            fdata.append("pprice", $("#txtpprice").val());


            $.ajax({
                url: '@Url.Action("InupProduct", "Product")',
                type: "POST",
                contentType: false, // Not to set any content header
                processData: false, // Not to process data
                data: fdata,
                success: function (result) {
                    if (result == 1) {

                        swal("Successfully Product Inserted!", "", "success", {
                            button: "Close",
                        });

                        clear();
                        Display();
                    }
                    else {

                        swal("Product Not Inserted!", "", "error", {
                            button: "Close",
                        });
                    }

                },
                error: function (err) {
                    alert(err.statusText);
                }
            });

        });


        $("#btnupdate").click(function () {
            var fdata = new FormData();

            fdata.append("id", $("#hdnID").val());
            fdata.append("pname", $("#txtuppname").val());
            fdata.append("pprice", $("#txtuppprice").val());


            $.ajax({
                url: '@Url.Action("InupProduct", "Product")',
                type: "POST",
                contentType: false, // Not to set any content header
                processData: false, // Not to process data
                data: fdata,
                success: function (result) {
                    if (result == 1) {

                        swal("Successfully Product Updated!", "", "success", {
                            button: "Close",
                        });
                        clear();
                        Display();
                        $('#mmd').modal('hide');

                    }
                    else {
                        swal("Product Not Updated!", "", "error", {
                            button: "Close",
                        });
                    }

                },
                error: function (err) {
                    alert(err.statusText);
                }
            });
        });

        function clear() {
            $("#txtpname").val("");
            $("#txtpprice").val("");
        }
    });

    function deletedata(ID) {
        bootbox.confirm({
            title: "Please Confirm",
            message: "Are you sure to delete this record.",
            buttons: {
                cancel: {
                    label: '<i class="fa fa-times"></i> Cancel'
                },
                confirm: {
                    label: '<i class="fa fa-check"></i> Confirm'
                }
            },
            callback: function (result) {
                if (result == true) {
                    var data = { "ID": ID };
                    $.ajax({
                        url: '@Url.Action("deleteRecord", "Product")',
                        type: "POST",
                        contentType: "application/json; charset=utf-8",
                        data: JSON.stringify(data),
                        dataType: "json",
                        success: function (response) {

                            if (response == 1) {
                                swal("Successfully Product Deleted!", "", "success", {
                                    button: "Close",
                                });

                                    Display();


                            }
                            else {
                                swal("Product Not Deleted!", "", "error", {
                                    button: "Close",
                                });

                            }
                        }
                    });
                }
            }
        });
    }

    function editdata(pid,pname,price)
    {

        $("#hdnID").val(pid);
        $("#txtuppprice").val(price);
        $("#txtuppname").val(pname);
        $('#mmd').modal();          
    }
</script>

<style>
    .dataTables_scrollBody{
            position: relative;
overflow: auto;
margin-top: -5%;
width: 100%;
height: 502px;
    }
</style>

Comments

0
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>


<script src="https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js"></script>
<script src="https://cdn.datatables.net/1.10.16/js/dataTables.bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootbox.js/4.4.0/bootbox.min.js"></script>
<script src="https://unpkg.com/[email protected]/dist/sweetalert.min.js"></script>

Controller: public JsonResult GetProductsData(){ var alldata = dbobj.products.ToList();

        var result = from x in alldata
                     select new[]
                     {
                            Convert.ToString(x.pid),
                            Convert.ToString(x.pname),
                            Convert.ToString(x.pprice)

                     };


        return Json(new
        {
            aaData = result
        },
      JsonRequestBehavior.AllowGet);

    }


    public JsonResult deleteRecord(int ID)
    {
        try
        {
            var data = dbobj.products.Where(x => x.pid == ID).FirstOrDefault();
            dbobj.products.Remove(data);
            dbobj.SaveChanges();
            return Json(1, JsonRequestBehavior.AllowGet);
        }
        catch (Exception ex)
        {
            return Json(0, JsonRequestBehavior.AllowGet);
        }
    }

}

1 Comment

Please add some explanation to this answer, makes this answer better.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.