
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 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 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.
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 NamespaceNow let us create the controller. If you haven’t created the controller yet, click this link, to learn the procedure to create a Controller
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);
}
}
}
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 NamespaceI 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 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.
