create view v as select eid,name from emp union select 0,'select' where 1=2
create view v as select eid,name from emp where eid>100 with check option
create view v as select eid,name from emp where eid>100 with check option
App_Start
as described at this blog.<redirect
firstRequestOnly="false"
mobileHomePageUrl="~/mobile/default.aspx"
timeout="20"
devicesFile="~/App_Data/Devices.dat"
mobilePagesRegex="mobile">
</redirect>
Category
, Product
and DataRepository
.public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
}
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public string ProductDescription { get; set; }
public Category ProductCategory { get; set; }
}
public class DataRepository
{
public List<Product> GetProducts()
{
List<Product> products = new List<Product>{
new Product () { ProductId = 1, ProductName = "Nokia Lumia 625",
ProductDescription = "A mid-range Lumia with a focus of
combining 4G with a large display (4.7 inch, the first time
on a Lumia), yet keeping the price in a low and affordable range",
ProductCategory = new Category () { CategoryId = 1, CategoryName = "Phones"}},
new Product () { ProductId = 2, ProductName = "Nokia Lumia 925",
ProductDescription = "A thinner, lighter, partially aluminium
re-skin of the Lumia 920, designed to broaden the appeal of the 92x range.
It is a compromise between Lumia 920 and Lumia 928 features-wise.",
ProductCategory = new Category () { CategoryId = 1, CategoryName = "Phones"}},
new Product () {ProductId = 3, ProductName = "ThinkPad X1 Carbon Ultrabook",
ProductDescription = "At less than 1.4 kg, the X1 Carbon Ultrabook™
brings a new level of quality to the ThinkPad legacy of high standards
and innovation. A carbon fiber roll cage with reinforcement
throughout makes this system ultralight, ultradurable,
and highly portable. Stay unplugged all day, but when needed,
boost your battery up to 80% capacity in just 35 minutes.",
ProductCategory = new Category () {CategoryId = 2, CategoryName = "Computers"}},
new Product () {ProductId = 4, ProductName = "ThinkPad X230 Laptop",
ProductDescription = "Tough, slim and light,
the 12.5 inch ThinkPad X230 elevates the business laptop to a new level
with its vivid IPS display, purer sound and peerless keyboard ergonomics.
Start faster, resume faster and charge your battery less,
giving you more time to strive for success.",
ProductCategory = new Category () {CategoryId = 2, CategoryName = "Computers"}},
new Product () {ProductId = 5, ProductName = "Programming ASP.NET MVC 4",
ProductDescription = "Get up and running with ASP.NET MVC 4,
and learn how to build modern server-side web applications.
This guide helps you understand how the framework performs,
and shows you how to use various features to solve many real-world
development scenarios you’re likely to face.",
ProductCategory = new Category () {CategoryId = 3, CategoryName = "Books"}},
new Product () {ProductId = 6, ProductName = "Pro ASP.NET MVC 4",
ProductDescription = "In this fourth edition,
the core model-view-controller (MVC) architectural concepts are not
simply explained or discussed in isolation, but are demonstrated in action.
You’ll work through an extended tutorial to create a working e-commerce
web application that combines ASP.NET MVC with the latest
C# language features and unit-testing best practices.",
ProductCategory = new Category () {CategoryId = 3, CategoryName = "Book"}}
};
return products;
}
public List<Category> GetCategories()
{
return new List<Category> {
new Category () { CategoryId = 1, CategoryName = "Phones"},
new Category () {CategoryId = 2, CategoryName = "Computers"},
new Category () { CategoryId = 3, CategoryName = "Books"}
};
}
}
For the sake of simplicity, we are using hardcoded data in Repository for demo purposes. In real time application, Repository is supposed to do CRUD operations by communication persistent data source like SQL Server, XML or whatever. For this demo, now our model and repository are ready for use.Category
and Product
model to "Category wise Products" page. To know more about ViewModel
, Please visit "ViewModel
" section of this article. Now add a “ViewModels” folder in project by right clicking at project > Add > New Folder as shown below:ProductCategoryVM
” and add the following code in it:
public class ProductCategoryVM
{
public int SelectedCategoryId = -1;
public List<Category> AllCategories { get; set; }
public List<Product> AllProducts { get; set; }
}
ProductController
” as shown below:ProductController
class and add the appropriate namespaces as needed:
DataRepository _repository = new DataRepository();
public ActionResult AllProducts()
{
List<Product> productModel = new List<Product>();
productModel = _repository.GetProducts();
return View(productModel);
}
public ActionResult CategoryWiseProducts()
{
ProductCategoryVM vm = new ProductCategoryVM();
vm.AllCategories = _repository.GetCategories();
vm.AllProducts = _repository.GetProducts();
return View(vm);
}
ProductController
, right click on “AllProducts
” action method and from menu, select “Add View”. You will get a popup as below fill the details shown here and click OK. <h2>All Products</h2>
<p>@Html.ActionLink("Create New", "Create") </p>
Add a new the table (in place of deleted “Create New” action link) as shown below: <table >
<tr>
<td style="width:20%; text-align:left;">
<h2>All Products</h2>
</td>
<td style="width:90%; text-align:right;">
@Html.ActionLink("Category wise Products",
"CategoryWiseProducts", "",
new { style = "font-size:20px; background-color:lightblue;" })
</td>
</tr>
</table>
Now, update the existing table to display products detail. First, update the table header code as following:<tr>
<th>Name
</th>
<th>Description
</th>
</tr>
And delete the code for below Action links in Product
Table as we will not implement anything for those:<td>
@Html.ActionLink("Edit", "Edit", new { id=item.ProductId }) |
@Html.ActionLink("Details", "Details", new { id=item.ProductId }) |
@Html.ActionLink("Delete", "Delete", new { id=item.ProductId })
</td>
ProductController
, right click on “CategoryWiseProducts
” action method and from menu select “Add View”. This time we will get a popup as below fill the details shown here (we will go for empty View so uncheck the checkbox for "Create a strongly-typed view") and click OK.@model ShopOnline.ViewModels.ProductCategoryVM
@{
ViewBag.Title = "Category wise Products";
SelectList cat = new SelectList(Model.AllCategories, "CategoryId", "CategoryName");
}
<h2>Category wise Products</h2>
<br />
<table>
<tr>
<td style="font-size: 16px;">Select a Category:
</td>
<td>
@Html.DropDownListFor(m => m.SelectedCategoryId, cat,
"Select Category", new { style = "width:200px; font-size:16px;" })
</td>
</tr>
</table>
<table>
<tbody id="tblProductData">
</tbody>
</table>
<script>
$("#SelectedCategoryId").change(function () {
var selectedCategory = $(this).val().trim();
var allProducts = @Html.Raw(Json.Encode(Model.AllProducts));
$('#tblProductData').empty();
var headers = '<tr><th>Name</th><th>Description</th></tr>';
var elements = "";
for (var i = 0; i < allProducts.length; i++) {
if(allProducts[i].ProductCategory.CategoryId == selectedCategory)
elements = elements + '<tr><td>' +
allProducts[i].ProductName + '</td><td>' +
allProducts[i].ProductDescription + '</td></tr>';
}
if (elements != "")
$('#tblProductData').append(headers + elements);
});
</script>
_Layout
page under Views > shared folder, change the location of the following line:
@Scripts.Render("~/bundles/jquery")
By default, it is at the bottom, put it in head
of layout page. Delete unnecessary links and code, finally it should look like:<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title - My ASP.NET MVC Application</title>
<meta name="viewport" content="width=device-width" />
@Scripts.Render("~/bundles/jquery")
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")
</head>
<body>
<header>
<div class="content-wrapper">
<div class="float-center">
<nav>
<ul id="menu">
<li>@Html.ActionLink
("Home", "Index", "Home")</li>
<li>@Html.ActionLink("Products",
"AllProducts", "Product")</li>
</ul>
</nav>
</div>
</div>
</header>
<div id="body">
<section class="content-wrapper main-content clear-fix">
@RenderBody()
</section>
</div>
</body>
</html>
<h2>
tag of both “AllProducts.Mobile.cshtml” to "All Products : Mobile View" and similarly for “CategoryWiseProducts.Mobile.cshtml” to "Category Wise Product : Mobile View".RegisterRoute
method, change default route as:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Product",
action = "AllProducts", id = UrlParameter.Optional }
);
}
Install-Package jQuery.Mobile
You would get as shown in below screenshot:RegisterBundles
method, add the following code:bundles.Add(new ScriptBundle("~/bundles/Mobilejs").Include( "~/Scripts/jquery.mobile-1.*", "~/Scripts/jquery-1.*")); bundles.Add(new StyleBundle("~/Content/Mobilecss").Include( "~/Content/jquery.mobile.structure-1.4.0.min.css", "~/Content/jquery.mobile-1.4.0.css"));Here, we are creating two bundles: one having JavaScripts and the second one having all CSS to be used in mobile specific views. We will refer to those bundles in Mobile Specific layout page.
head
tag:
<meta charset="utf-8" /> <title>@ViewBag.Title – Mobile Application</title> <link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" /> <meta name="viewport" content="width=device-width" /> @Styles.Render("~/Content/Mobilecss") @Scripts.Render("~/bundles/Mobilejs") @Scripts.Render("~/bundles/modernizr")Here, we are referring to newly created bundles which we created in the above section.
body
tag, delete all existing code and write the following code:
<div data-role="page" data-theme="a"> <div data-role="header" data-position="fixed" data-theme="b"> <h1>@ViewBag.Title</h1> <div data-role="navbar" data-theme="a" data-iconpos="top"> <ul> <li><a href="@Url.Action("Index", "Home")" data-icon="home">Home</a></li> <li><a href="@Url.Action("AllProducts", "Product")" data-icon="check">Product</a></li> </ul> </div> </div> <div> @RenderSection("featured", false) @RenderBody() </div> </div>There are many amazing things with the above code. Focus on attributes like: data-role, data-position, data-theme, etc. and their values. They are attributes defined in jQuery mobile to provide shape and behavior to a
div
for specific use. The names and purposes are much correlated, it makes those self-explanatory. You can learn more about such attributes from jQuery Mobile demos here.@model IEnumerable<ShopOnline.Models.Product> @{ ViewBag.Title = "All Products"; } <div class="ui-grid-a"> <div class="ui-block-a"> <hgroup class="title"> <h1>@ViewBag.Title</h1> </hgroup> </div> <div class="ui-block-b"> <a class="ui-btn ui-btn" style="color:blue" data-role="button" href="@Url.Action("CategoryWiseProducts", "Product")">Category wise Products</a> </div> </div> @* Making collapsible set of all products using data-role*@ <div data-role="collapsible-set" data-inset="true"> @foreach (var item in Model) { <div data-role="collapsible"> <h3>@item.ProductName</h3> <ul data-role="listview" data-theme="a" data-divider-theme="a" > <li style="white-space:normal"> <h4>Detail:</h4> <div>@item.ProductDescription</div> </li> </ul> </div> } </div>Here, first we are creating a Grid having title of page and a button to navigate to “CategoryWiseProducts.Mobile.cshtml” page. After that, we are creating a collapsible set of products detail. Here
<li style="white-space:normal">
is very critical code to make the text wrapable otherwise the detail text would not wrap as per the width of bowser screen. If you want to explore more about any attributes or look into possibilities (if you want to design in some other way), please visit jQuery Mobile - Demos and look into controls available there.@model ShopOnline.ViewModels.ProductCategoryVM
@{
ViewBag.Title = "Category wise Products";
SelectList cat = new SelectList(Model.AllCategories, "CategoryId", "CategoryName");
}
<h2>Category wise Products</h2>
<div class="ui-field-contain">
<select name="select-custom-1" id="categorySelect" data-native-menu="false">
<option value="0">Select a Category</option>
@foreach (var item in Model.AllCategories)
{
<option value="@item.CategoryId">@item.CategoryName</option>
}
</select>
</div>
<div id="tblProductData"></div>
<script>
$("#categorySelect").change(function () {
var selectedCategory = $(this).val().trim();
var allProducts = @Html.Raw(Json.Encode(Model.AllProducts));
$('#tblProductData').empty();
var frontheaders = '<div data-role="collapsible-set" data-inset="true">';
var backheaders = '</div>';
var elements = '';
for (var i = 0; i < allProducts.length; i++) {
if(allProducts[i].ProductCategory.CategoryId == selectedCategory)
elements = elements + '<div data-role="collapsible"> <h3>' +
allProducts[i].ProductName + '</h3> <ul data-role="listview"
data-theme="a" data-divider-theme="a"> <li style="white-space:normal">
<h4>Detail:</h4> <div>' +
allProducts[i].ProductDescription + '</div> </li> </ul> </div>';
}
if (elements != '')
{ var data = frontheaders + elements + backheaders
$('#tblProductData').append(data).trigger('create');
}
});
</script>
Here, first we are creating a select box having all categories. On selection of a category, we are adding products data in tblProductData div
under selected category using JavaScript.