DavidB
DavidB

Reputation: 301

Updating Data in Table from AJAX Call

EDIT: OK, so I got it to call the Partial View _GridView by changing my return statement to return PartialView("_GridView", model); but it won't update the table with my data. I've traced it and it it's sending the correct model and iterating through the table with the correct data and the AJAX call is successful, but the data is still the same data. Any ideas anyone?

I have two partial views in a view. One that has a few dropdownlists that I'm using as filters and the other is a table that displays database info:

My View:

@model IEnumerable<PPL.Models.GridPart>

@{
    ViewBag.Title = "Index";


}



<h2>Index</h2>




<div id="dropDownsDiv">
    @Html.Partial("_DropDownsView", Model)
</div>


<div id="theGrid">
    @Html.Partial("_GridView", Model)
</div>

Partial View _GridView:

@model IEnumerable<PPL.Models.GridPart>

@{
    ViewBag.Title = "_GridView";
}
<div id="theGrid">
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Category)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Type)
        </th>
        <th>
            @*@Html.DisplayNameFor(model => model.PartNum)*@
            Part #
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Status)
        </th>        
        <th>
            @Html.DisplayNameFor(model => model.REL)
        </th>


    </tr>

    @foreach (var item in Model)
    {
        <tr>
            <td>
                @Html.DisplayFor(modelItem => item.Category)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.Type)
            </td>
            <td>
                @Html.DisplayFor(modelItem => item.PartNum)
            </td>
            <td bgcolor="#@Html.DisplayFor(modelItem => item.StatusColor)">
                @Html.DisplayFor(modelItem => item.Status)
            </td>
            <td bgcolor="#@Html.DisplayFor(modelItem => item.RELColor)">
                @Html.DisplayFor(modelItem => item.REL)
            </td>


        </tr>

    }


</table>

Partial View _DropDownsView:

@{
    ViewBag.Title = "_DropDownsView";


}

<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>


<script type="text/javascript">
    // assuming you're using jQuery

    $(document).ready(function () {
        $("#Categories").change(function () {

            //alert("I'm here!");

            //Update typeDropDown
            $.ajax({
                url: '/Part/Myajaxcall',
                type: 'POST',
                datatype: 'json',
                data: { id: $("#Categories").val() },
                success: function (data) {
                    $('#typeDropDown option[value!="0"]').remove()                    
                    $.each(data, function (i, item) {
                        $('#typeDropDown').append('<option value="' + item.DescriptorID + '">' + item.pplType + '</option>');                                                
                    });                   
                },
                error: function(jqXHR, textStatus, errorThrown){
                    alert(errorThrown);
                }
            });



            //Update Data Grid
            $.ajax({
                url: '/Part/updateGrid',
                type: 'POST',
                datatype: 'json',
                data: { id: $("#Categories").val() },
                success: function (data) {
                    alert("Got it!");
                },
                error: function (jqXHR, textStatus, errorThrown) {
                    alert(errorThrown);
                }
            });




        });
    });



</script>


Category:  @Html.DropDownList("Categories", "          ") 

Type: <select id="typeDropDown"><option value="0"></option></select>

Manufacturer: @Html.DropDownList("Manufacturers", "          ") 

What I'm trying to accomplish is when an item is selected from the Categories drop down list, I want to first update the second drop down list via AJAX (which is working) and next, I want to update the table with my data.

Here's my Controller:

public class PartController : Controller
    {
        private PartContext db = new PartContext();


        //
        // GET: /Part/

        public ActionResult Index()
        {


            //Use LINQ to query DB & Get all of the parts
            //Join PPLPart & PPLDescriptor Tables
            var myParts = from p in db.Parts
                          join d in db.Descriptors on p.DescriptorID equals d.DescriptorID
                          select new
                          {
                              Category = d.DescriptorDesc,
                              TypeCol = p.PPLType,
                              PartNumber = p.PartNum,
                              Status = p.PPLStatus,
                              StatusColor = p.PPLStatusBGColor,
                              REL = p.RELStatus,
                              RELColor = p.RELStatusBGColor
                          };

            //Drop the parts into a List            
            List<GridPart> pl = new List<GridPart>();

            foreach (var m in myParts)
            {
                GridPart gp = new GridPart();
                gp.Category = m.Category;
                gp.Type = m.TypeCol;
                gp.PartNum = m.PartNumber;
                gp.Status = m.Status;
                gp.StatusColor = m.StatusColor;
                gp.REL = m.REL;
                gp.RELColor = m.RELColor;

                pl.Add(gp);
            }

            var model = pl;


            //Pass info for Categories drop-down
            ViewBag.Categories = new SelectList(db.Descriptors, "DescriptorID", "DescriptorDesc");

            //Pass info for Manufacturer drop-down
            ViewBag.Manufacturers = new SelectList(db.Manufacturers, "ManufacturerID", "ManufacturerName");




            //Pass off to View
            return View(model);
        }


        [HttpPost]
        public ActionResult updateGrid(string id)
        {
            int intID = Convert.ToInt32(id);

            //Use LINQ to query DB & Get all of the parts
            //Join PPLPart & PPLDescriptor Tables
            var myParts = from p in db.Parts
                          join d in db.Descriptors on p.DescriptorID equals d.DescriptorID
                          where d.DescriptorID == intID
                          select new
                          {
                              Category = d.DescriptorDesc,
                              TypeCol = p.PPLType,
                              PartNumber = p.PartNum,
                              Status = p.PPLStatus,
                              StatusColor = p.PPLStatusBGColor,
                              REL = p.RELStatus,
                              RELColor = p.RELStatusBGColor
                          };

            //Drop the parts into a List            
            List<GridPart> pl = new List<GridPart>();

            foreach (var m in myParts)
            {
                GridPart gp = new GridPart();
                gp.Category = m.Category;
                gp.Type = m.TypeCol;
                gp.PartNum = m.PartNumber;
                gp.Status = m.Status;
                gp.StatusColor = m.StatusColor;
                gp.REL = m.REL;
                gp.RELColor = m.RELColor;

                pl.Add(gp);
            }

            var model = pl;



            return PartialView(model);
        }


        [HttpPost]
        public JsonResult Myajaxcall(string id)
        {

            int intID = Convert.ToInt32(id);

            var types = from c in db.Types
                             where c.DescriptorID == intID
                             select new { did = c.DescriptorID, pType = c.pplType };

            List<PPLType> typesList = new List<PPLType>();

            foreach (var t in types)
            {
                PPLType p = new PPLType();
                p.DescriptorID = t.did;
                p.pplType = t.pType;

                typesList.Add(p);
            }



            //string command = "EXEC dbo.pr_PPLDescriptor_list";
            //List<int> results = db.Database.SqlQuery(int, command, null);


            return Json(typesList, JsonRequestBehavior.AllowGet);
        }

    }

Any help would be greatly appreciated.

Upvotes: 1

Views: 19409

Answers (2)

Amila
Amila

Reputation: 3816

your solution is correct.

few things to mention where you can improve your solution. As you are only getting data for the table and for the dropdown and not changing anything in the database, you can do a get request.

And it seems your Index action and UpdateGrid uses the same code and therefor you can use a single action and return different results.

within your index action, you can use Request.IsAjaxRequest() to check weather the request is made through ajax.

    [HttpGet]
    public ActionResult Index(string id)
    {
        //create a predicate and default it to true
        Expression<Func<Descriptor, bool>> predicate = d => true;

        if(Request.IsAjaxRequest())
        {
            //when an ajax request is made, convert the id to int
            int intID = Convert.ToInt32(id);
            //overwrite the predicate with your condition and use it in the where clause
            predicate = d => d.DescriptorID == intID
        }

        //Use LINQ to query DB & Get all of the parts
        //Join PPLPart & PPLDescriptor Tables
        var myParts = from p in db.Parts
                      join d in db.Descriptors on p.DescriptorID equals d.DescriptorID
                      where predicate
                      select new
                      {
                          Category = d.DescriptorDesc,
                          TypeCol = p.PPLType,
                          PartNumber = p.PartNum,
                          Status = p.PPLStatus,
                          StatusColor = p.PPLStatusBGColor,
                          REL = p.RELStatus,
                          RELColor = p.RELStatusBGColor
                      };

        //Drop the parts into a List            
        List<GridPart> pl = new List<GridPart>();

        foreach (var m in myParts)
        {
            GridPart gp = new GridPart();
            gp.Category = m.Category;
            gp.Type = m.TypeCol;
            gp.PartNum = m.PartNumber;
            gp.Status = m.Status;
            gp.StatusColor = m.StatusColor;
            gp.REL = m.REL;
            gp.RELColor = m.RELColor;

            pl.Add(gp);
        }

        var model = pl;

        if(Request.IsAjaxRequest())
        {
            return PartialView(model);
        }
        else
        {
            //Pass info for Categories drop-down
            ViewBag.Categories = new SelectList(db.Descriptors, "DescriptorID", "DescriptorDesc");

            //Pass info for Manufacturer drop-down
            ViewBag.Manufacturers = new SelectList(db.Manufacturers, "ManufacturerID", "ManufacturerName");

            //Pass off to View
            return View(model);
        }
    }

Now your ajax call has to be changed as follows

//Update Data Grid
        $.ajax({
            url: '/Part/Index',
            type: 'GET',
            datatype: 'json',
            data: { id: $("#Categories").val() },
            success: function (data) {
                $('#theGrid').html(data);
            },
            error: function (jqXHR, textStatus, errorThrown) {
                alert(errorThrown);
            }
        });

hope this helps.

Upvotes: 2

DavidB
DavidB

Reputation: 301

OK, I got it. So, as stated above, to pass the new model via AJAX to the partial view I updated my action result's return to:

return PartialView("_GridView", model);

Need to return a partial view and pass in the name of the partial view you're passing to as the first parameter and the model you want to pass as the second parameter.

Then, to refresh the data in the table of data in the partial view, I added this to my AJAX:

$('#theGrid').html(data);

Basically, this is what updates the div that contains the table.

Thanks everyone for all of your comments. Hope this is helpful to someone else.

Upvotes: 3

Related Questions