How to make jQuery Ajax Call from a WebGrid in MVC using C# and Vb.Net

← PrevNext →

jQuery Ajax provides methods that allow web applications to send and receive data Asynchronously, without refreshing the page. If your application is on MVC framework, you can still use Ajax methods efficiently to send or receive data from server. Here in this post, I am sharing an example on how to make a jQuery Ajax call (the GET method) from an MVC WebGrid to extract more data based on the row value, from the controller. The example code is both in C# and in Vb.Net.

Make jQuery Ajax from an MVC WebGrid

This post is the second post in the WebGrid series. I have previously shared a post explaining how to create a WebGrid in MVC from scratch for both C# and VB programmers. If you have come directly to this post, then I would recommend, please check the previous post’s code. Since the example, here extends the code and procedures from the previous post.

Here’s what I am doing. I have two tables in my SQL Server database. I’ll extract data from the master table, that is dbo.Products and bind the data to the WebGrid. I want to extract more (misc.) details, based on the WebGrid’s selected row value, by making an Ajax call to server, which will fetch data from the details table called dbo. ProductDetails.

The Database

The example here uses data from two tables, a Master table and Details table. I have created the Product Master table here. Now lets create the product details table.

Create db.ProductDetails table in SQL Server
CREATE TABLE [dbo].[ProductDetails](
    [Product_ID] [int] NULL,
    [Brand] [varchar](100) NULL,
    [Price] [numeric](18, 2) NULL,
    [Availability] [varchar](10) NULL,
    [Quantity] [int] NULL
)

Add few rows of data to the table.

INSERT INTO ProductDetails (Product_ID, Brand, Price, Availability, Quantity)
VALUES (1, 'Natrag', 20, 'In Stock', 110),
    (2, 'Mono', 15, 'In Stock', 200),
    (3, 'Elxin', 17.5, 'In Stock', 121),
    (4, 'Parcc', 275, 'In Stock', 10),
    (5, 'Smart', 22, 'In Stock', 87),
    (6, 'Doms', 40, 'In Stock', 11),
    (7, 'X-Presso', 175, 'In Stock', 65)

Once your database is ready, create your MVC project for WebGrid.

The Model (C# Code)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace webgridSample.Models
{
    public class modelProducts
    {
        // PROPERTIES FOR PRODUCTS.
        public int ProductID { get; set; }
        public string ProductName { get; set; }
        public string Brand { get; set; }

        // PROPERTIES FOR PRODDUCT DETAILS.
        public decimal Price { get; set; }
        public string Availability { get; set; }
        public int Quantity { get; set; }
    }
}

If you have checked my previous post on Introduction to WebGrid in MVC, then you’ll see the Model had properties for the Product Master. In the above Model I have added few more properties (the last 3) for Product Details.

The Model (Visual Basic Code)
Option Explicit On

Namespace webgridSample.Models
    Public Class modelProducts

        ' PROPERTIES FOR PRODUCTS.
        Public Property ProductID() As Integer
            Get
                Return m_ProductID
            End Get
            Set(value As Integer)
                m_ProductID = value
            End Set
        End Property
        Private m_ProductID As Integer

        Public Property ProductName() As String
            Get
                Return m_ProductName
            End Get
            Set(value As String)
                m_ProductName = value
            End Set
        End Property
        Private m_ProductName As String

        Public Property Brand() As String
            Get
                Return m_Brand
            End Get
            Set(value As String)
                m_Brand = value
            End Set
        End Property
        Private m_Brand As String


        ' PROPERTIES FOR PRODUCT DETAILS.
        Public Property Price() As Decimal
            Get
                Return m_Price
            End Get
            Set(value As Decimal)
                m_Price = value
            End Set
        End Property
        Private m_Price As Decimal

        Public Property Availability() As String
            Get
                Return m_Availability
            End Get
            Set(value As String)
                m_Availability = value
            End Set
        End Property
        Private m_Availability As String

        Public Property Quantity() As Integer
            Get
                Return m_Quantity
            End Get
            Set(value As Integer)
                m_Quantity = value
            End Set
        End Property
        Private m_Quantity As String
    End Class
End Namespace
The Controller

Now let us create the controller. If you haven’t created the controller yet, click this link, to learn the procedure to create a Controller

Controller (C# Code)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using webgridSample.Models;
using System.Data.SqlClient;

namespace webgridSample.Controllers
{
    public class productsController : Controller
    {
        const string sConnString = "Data Source=DNA;Persist Security Info=False;" +
            "Initial Catalog=DNA_Classified;User Id=sa;Password=demo;Connect Timeout=30;";

        // LIST OBJECT WILL HOLD AND RETURN A LIST OF PRODUCTS.
        List<modelProducts> ourProducts = new List<modelProducts>();

        public ActionResult viewProducts(modelProducts list)
        {
            using (SqlConnection con = new SqlConnection(sConnString))
            {
                // QUERY THE TABLE FOR DATA.
                using (SqlCommand cmd = new SqlCommand("SELECT *FROM dbo.Product"))
                {
                    cmd.Connection = con;
                    con.Open();

                    SqlDataReader reader = cmd.ExecuteReader();

                    // POPULATE THE LIST WITH DATA.
                    while (reader.Read())
                    {
                        ourProducts.Add(new modelProducts
                        {
                            ProductID = Convert.ToInt32(reader["Product_ID"]),
                            ProductName = reader["ProductName"].ToString(),
                            Brand = reader["Brand"].ToString()
                        });
                    }

                    con.Close();
                }
            }

            return View(ourProducts);
        }

        List<modelProducts> prodDetails = new List<modelProducts>();

        [HttpGet()]
        public ActionResult getProductDetails(int id)
            // THE METHOD TO RECEIVE A REQUEST.
        {
            if (id != 0)
            {

                using (SqlConnection con = new SqlConnection(sConnString))
                {
                    using (SqlCommand cmd = new SqlCommand("SELECT *FROM dbo.ProductDetails WHERE Product_ID = " + id))
                    {
                        cmd.Connection = con;
                        con.Open();

                        SqlDataReader reader = cmd.ExecuteReader();

                        // POPULATE THE LIST WITH PRODUCT DETAILS.
                        while (reader.Read())
                        {
                            prodDetails.Add(new modelProducts
                            {
                                Price = Convert.ToInt32(reader["Price"]),
                                Brand = reader["Brand"].ToString(),
                                Availability = reader["Availability"].ToString(),
                                Quantity = Convert.ToInt32(reader["Quantity"])
                            });
                        }

                        con.Close();
                    }
                }
            }

            // RETURN DATA IN JSON FORMAT.
            return Json(new {
                list = prodDetails
            }, JsonRequestBehavior.AllowGet);
        }
    }
}
Controller (Visual Basic Code)
Option Explicit On
Imports webgridSample.webgridSample.Models
Imports System.Data.SqlClient

Namespace webgridSample
    Public Class productsController
        Inherits System.Web.Mvc.Controller

        Const sConnString As String = "Data Source=DNA;Persist Security Info=False;" & _
            "Initial Catalog=DNA_Classified;User Id=sa;Password=demo;Connect Timeout=30;"

        Dim ourProducts As New List(Of modelProducts)()

        Function viewProducts(list As modelProducts) As ActionResult
            Using con As SqlConnection = New SqlConnection(sConnString)
                Using cmd As SqlCommand = New SqlCommand("SELECT *FROM dbo.Product")
                    With cmd
                        .Connection = con
                        con.Open()

                        Dim reader As SqlDataReader = cmd.ExecuteReader()

                        ' POPULATE THE LIST WITH DATA.
                        While reader.Read()
                            ourProducts.Add(New modelProducts() With { _
                                .ProductID = reader("Product_ID").ToString(), _
                                .ProductName = reader("ProductName").ToString(), _
                                .Brand = reader("Brand").ToString() _
                             })
                        End While

                        con.Close()
                    End With
                End Using
            End Using

            Return View(ourProducts)
        End Function

        Dim prodDetails As New List(Of modelProducts)()

        ' THE METHOD TO RECEIVE A REQUEST.
        <HttpGet()>
        Public Function getProductDetails(ByVal id As Integer) As ActionResult
            If id <> 0 Then
                Using con As SqlConnection = New SqlConnection(sConnString)
                    Using cmd As SqlCommand = New SqlCommand("SELECT *FROM dbo.ProductDetails WHERE Product_ID = " & id)
                        cmd.Connection = con
                        con.Open()
                    
                        Dim reader As SqlDataReader = cmd.ExecuteReader()

                        ' POPULATE THE LIST WITH PRODUCT DETAILS.
                        While reader.Read()
                            prodDetails.Add(New modelProducts With { _
                                .Price = Convert.ToInt32(reader("Price")),
                                .Brand = reader("Brand").ToString(),
                                .Availability = reader("Availability").ToString(),
                                .Quantity = Convert.ToInt32(reader("Quantity"))})
                        End While

                        con.Close()
                    End Using
                End Using
            End If

            ' RETURN DATA IN JSON FORMAT.
            Return Json(New With {
                        Key .list = prodDetails
                        }, JsonRequestBehavior.AllowGet)
        End Function
    End Class
End Namespace
The View viewProducts.cshtml (C#)

I am creating an object of the WebGrid class. Now, this will allow me to design the grid by adding the Columns etc. using the GetHTML() method (@objGrid.GetHtml). I have also created a <style> tag with classes to add some style to the grid.

The most important section in this View is the last column (with no header). It has an Anchor link attached, with an onclick event that calls a JavaScript function named getProductDetails().

This function has the code to make the Ajax call to the Controller function. The function takes a parameter, which is the ID, the product id, from the first column.

If the Ajax call is success, that is, the controller has processed the request and returned a data in JSON format (see the controller above with [HttpGet()], then it show the data in a <div> element (id = “showDetails”).

@{
    ViewBag.Title = "Our Products Inventory";
    WebGrid objGrid = new WebGrid(Model, rowsPerPage:5, canSort:false);
}

@*ADD STYLE FOR THE GRID*@
<style>
    .grid {
        font: 17px Calibri;
        width: 400px; 
        background-color: #FFF; 
        border: solid 1px #CD6736;
    }
    .grid td, th {
        padding: 2px; 
        border: solid 1px #CD6736; 
        text-align: center; 
        text-transform: capitalize;
    }
    .grid-header {
        background-color: #CD6736;
        color: #FFF;
        text-align: left;
    }
    .grid-footer {
        color: #000;
        font: 17px Calibri;
        text-align: left;
    }
    .grid tr:hover {
        background: #FF0;
        color: #000;
    } 
    a {
        cursor:pointer;
        color: #1464F4;
    }
</style>

@*CREATE AND ADD COLUMNS TO THE WebGrid USING GetHTML() METHOD*@

@objGrid.GetHtml(
    columns: objGrid.Columns (
        objGrid.Column("ProductID", "Product ID"),
        objGrid.Column("ProductName", "Product Name"),
        objGrid.Column("Brand"),
        objGrid.Column(" ", format: (item) => Html.Raw("<a onclick='getProductDetails(" + item.ProductID + ")'>View More</a>")) 
            //ADD A COLUMN WITH A LINK THAT WILL CALL JAVASCRIPT getProductDetails() FUNCTION
    ),
    caption: "Products Inventory",
    tableStyle: "grid",
    headerStyle: "grid-header",
    footerStyle: "grid-footer"
)

@*jQuery CDN*@
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div id="showDetails"></div>            @*THE ELEMENT TO SHOW OTHER DETAILS*@

<script>
    function getProductDetails(id) {

        $.ajax({
            type: 'GET',
            url: 'https://localhost:20196/products/getProductDetails/' + id,
            success: function (data) {

                // CREATE A DIV ELEMENT TO SHOW THE EXTRACTED DATA. (SOURCE: https://www.encodedna.com/2013/07/dynamically-add-remove-textbox-control-using-jquery.htm) 
                var div = $(document.createElement('div')).css({
                    font: '13px Verdana',
                    padding: '5px', margin: '10px 0', width: '170px', border: '1px dashed #777'
                });

                // LOOP THROUGH EACH DATA AND APPEND IT TO THE DYNAMIC DIV.
                $.each(data, function (index, value) {
                    if (value[0] != undefined) {
                        $(div).append('<b>ID</b>: ' + id + '<br/ >' +
                            '<b>Brand</b>: ' + value[0].Brand + '<br/ >' +
                            '<b>Price</b>: ' + value[0].Price + '<br/ >' +
                            '<b>Quantity</b>: ' + value[0].Quantity + '<br/ >' +
                            '<b>Avalilability</b>: ' + value[0].Availability + '<br/ >');
                    }
                    else {
                        $(div).append('Details not Available');
                    }
                });

                $('#showDetails').empty().append(div);
            }
        });
    }
</script>
The View viewProducts.vbhtml (for Visual Basic)

The visual basic for the view is pretty much the same.

@Code
    ViewData("Title") = "Our Products Inventory"
    Dim objGrid As New WebGrid(Model, rowsPerPage:=5)
End Code

@objGrid.GetHtml(
    columns:=objGrid.Columns(
            objGrid.Column("ProductID"),
            objGrid.Column("ProductName", "Product Name"),
            objGrid.Column("Brand"),
            objGrid.Column(" ", , format:=@@<a onclick="getProductDetails(@item.ProductID)">View More</a>)
        ),
        caption:="Products Inventory"
    )

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<div id="showDetails"></div>

<script>
    function getProductDetails(id) {

        $.ajax({
            type: 'GET',
            url: 'https://localhost:13771/products/getProductDetails/' + id,
            success: function (data) {

                // CREATE A DIV ELEMENT TO SHOW THE EXTRACTED DATA. (SOURCE: https://www.encodedna.com/2013/07/dynamically-add-remove-textbox-control-using-jquery.htm)  
                var div = $(document.createElement('div')).css({
                    font: '13px Verdana',
                    padding: '5px', margin: '10px 0', width: '170px', border: '1px dashed #777'
                });

                // LOOP THROUGH EACH DATA AND APPEND IT TO THE DYNAMIC DIV.
                $.each(data, function (index, value) {
                    if (value[0] != undefined) {
                        $(div).append('<b>ID</b>: ' + id + '<br/ >' +
                            '<b>Brand</b>: ' + value[0].Brand + '<br/ >' +
                            '<b>Price</b>: ' + value[0].Price + '<br/ >' +
                            '<b>Quantity</b>: ' + value[0].Quantity + '<br/ >' +
                            '<b>Avalilability</b>: ' + value[0].Availability + '<br/ >');
                    }
                    else {
                        $(div).append('Details not Available');
                    }
                });

                $('#showDetails').empty().append(div);
            }
        });
    }
</script>

That’s it. This is just the tip of the iceberg, when discussing about WebGrid in Asp.Net MVC. You can do more than what I have shown in the examples above. I’ll write and share more useful codes and examples on WebGrid in the coming days.

Thanks for reading.

← PreviousNext →