I have problems in displaying page on how to include the prev and next link...
I am using ASP.Net MVC 4 using these codes:
VIEW:
<div class="pagination">
<ul>
#for (int i = 1; i <= ViewBag.PagesCount; i++)
{
<text>
<li>#Html.ActionLink(i.ToString(), "Index", new { pagee = i })</li>
</text>
}
</ul>
</div>
CONTROLLER:
int offset = 15;
int pagecount = ((pagee - 1) * offset);
int totalPages = 0;
int totalItems = 0;
try
{
totalItems = requestform.Count();
while (totalItems > 0)
{
totalItems -= 15;
totalPages++;
}
ViewBag.PagesCount = totalPages;
return View(requestform.Skip(pagecount).Take(offset).ToList());
}
catch
{
while (totalItems > 0)
{
totalItems -= 15;
totalPages++;
}
ViewBag.PagesCount = totalPages;
return View(requestform.Skip(pagecount).Take(offset).ToList());
}
Please help me with this.
What do you say about this little extension PagedList ?
To add paging to page, you'll start by installing the PagedList NuGet package. Then you'll make additional changes in the Index method and add paging links to the Index view
Please check this link
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application
I would recommend also PagedList just add it via NuGet package manager and then,
modify your controller to look like this:
public ActionResult Index(int? page)
{
var dbtable = db.DbTable.Include(s => s.ID).OrderBy(s => s.StyleName); //ensure records are sorted.
if (Request.HttpMethod != "GET")
{
page = 1;
}
int pageSize = 2;
int pageNumber = (page ?? 1);
return View(dbtable.ToPagedList(pageNumber, pageSize));
}
in view replace:
#model IEnumerable<MyMvcApplication.Models.dbtable>
with
#model PagedList.IPagedList<MyMvcApplication.Models.dbtable>
replace code that looks like
<th>
#Html.DisplayNameFor(model => model.ID)
</th>
with
<th>
#Html.DisplayNameFor(model => model.First().ID)
</th>
at the end of the page after the </table> tag add this:
<div>
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#if (Model.HasPreviousPage)
{
#Html.ActionLink("<<", "Index", new { page = 1})
#Html.Raw(" ");
#Html.ActionLink("< Prev", "Index", new {page = Model.PageNumber - 1})
}
else{
#:<<
#Html.Raw(" ");
#:< Prev
}
#if (Model.HasNextPage)
{
#Html.ActionLink("Next >", "Index", new {page = Model.PageNumber + 1})
#Html.Raw(" ");
#Html.ActionLink(">>", "Index", new {page = Model.PageCount})
}
else{
#:Next >
#Html.Raw(" ")
#:>>
}
</div>
recently i found with cool controls, tooltip, first, next, last, previous check this mvc 4 paging nuget package, demo web page
Related
We are trying to implement infinite scroll in data grid in an ASP.NET Core MVC application. Searched a lot but could not find a good solution. Has any one used infinite scroll in data grid in an ASP.NET Core MVC . If so can you provide any guidance
I faced the same problem. Here is my solution. It works on nearly any table:
InfinityScroll.js
function InfinitiySroll(iTable, iAction, iParams) {
this.table = iTable; // Reference to the table where data should be added
this.action = iAction; // Name of the conrtoller action
this.params = iParams; // Additional parameters to pass to the controller
this.loading = false; // true if asynchronous loading is in process
this.AddTableLines = function (firstItem) {
this.loading = true;
this.params.firstItem = firstItem;
// $("#footer").css("display", "block"); // show loading info
$.ajax({
type: 'POST',
url: self.action,
data: self.params,
dataType: "html"
})
.done(function (result) {
if (result) {
$("#" + self.table).append(result);
self.loading = false;
}
})
.fail(function (xhr, ajaxOptions, thrownError) {
console.log("Error in AddTableLines:", thrownError);
})
.always(function () {
// $("#footer").css("display", "none"); // hide loading info
});
}
var self = this;
window.onscroll = function (ev) {
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
//User is currently at the bottom of the page
if (!self.loading) {
var itemCount = $('#' + self.table + ' tr').length - 1;
self.AddTableLines(itemCount);
}
}
};
this.AddTableLines(0);
}
Here a from Visual Studio scaffold view - a little bit modified
TestData.cshtml
#model IEnumerable<Infinity_Scroll.Models.TestData>
#{
ViewData["Title"] = "TestData";
}
<h1>TestData</h1>
<table id="anyTable" class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Id)
</th>
<th>
#Html.DisplayNameFor(model => model.Field1)
</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
#section Scripts {
<script src="~/js/InfinitiySroll.js"></script>
<script>
var infinityScroll = new InfinitiySroll("anyTable", "/home/_TestData", { sortOrder: "ascending", searchString: "3" });
</script>
}
The generating of the table rows is moved into a PartialView:
_TestData.cshtml
#model IEnumerable<Infinity_Scroll.Models.TestData>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Field1)
</td>
</tr>
}
And here is the Controller part:
...
private const int BATCH_SIZE = 50;
public IActionResult TestData()
{
return View();
}
[HttpPost]
public IActionResult _TestData(string sortOrder, string searchString, int firstItem = 0)
{
List<TestData> testData = new List<TestData>();
// Generate test data
for (int i = 1; i < 500; i++)
{
testData.Add(new TestData() { Id = i, Field1 = "This is row " + i.ToString() });
}
// Sort and filter test data
IEnumerable<TestData> query;
if (sortOrder.ToLower() == "descending")
{
query = testData.OrderByDescending(m => m.Field1);
}
else
{
query = testData.OrderBy(m => m.Field1);
}
if (!String.IsNullOrEmpty(searchString)) query = query.Where(m => m.Field1.Contains(searchString));
// Extract a portion of data
var model = query.Skip(firstItem).Take(BATCH_SIZE).ToList();
if (model.Count() == 0) return StatusCode(204); // 204 := "No Content"
return PartialView(model);
}
The model:
TestData.cs
namespace Infinity_Scroll.Models
{
public class TestData
{
public int Id { get; set; }
public string Field1 { get; set; }
}
}
You can download a simple Visual Studio example here: https://github.com/ThomasBrockmann/InfinityScroll
My issue: the dropdownlistfor is not selecting the correct value of string when loading the page. Here is the code and view:
Surcharges.html
#model IEnumerable<IEnumerable<string>>
#{
ViewBag.Title = "Surcharge Management";
}
<div id="mainTitleDiv" class="mainTitle">
<span style="display:inline-block;">#ViewBag.Title</span>
</div>
<br />
<table class="table">
#{
int i = 0;
foreach (var surcharge in Model)
{
int j = 0;
<tr>
#foreach (var item in surcharge)
{
if (i == 0)
{
#:<th>#Html.DisplayFor(model => item)</th>
}
else
{
if (j == 0)
{
#:<th>#Html.DisplayFor(model => item)</th>
}
else
{
#:<td>
if (!string.IsNullOrEmpty(item) && (i == 2)) // Type
{
#Html.DropDownListFor(x => item, new List<SelectListItem>
{
new SelectListItem() {Text = "Fixed Amount", Value ="0"},
new SelectListItem() {Text = "Percentage", Value ="1"}
}, new { style = "width:100%; height:34px;" } )
}
else
{
#Html.EditorFor(model => item, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => item, "", new { #class = "text-danger" })
}
#:</td>
}
j++;
}
}
</tr>
i++;
}
}
AdminController.cs
public ActionResult Surcharges()
{
if (!User.Identity.IsAuthenticated)
{
return RedirectToAction("Login", "Account");
}
int userId = User.Identity.GetUserId<int>();
var query = db.Surcharges.Where(x => x.UserId == userId).OrderBy(x => x.Id).ToList();
IEnumerable<IEnumerable<string>> surcharges = Utility.Pivot<string>(Utility.GetSurchargeList(query));
return View(surcharges);
}
Surcharges page
Surcharge
S2 and D1 have the string value "1" and not selected by the dropdownlist.
What am I doing wrong ?
Do I need a model to post the data edited back to the server ?
What should the correct model look like ?
Thanks
Thanks, Stephen. My ASP.NET MVC project requirement is to design a page that looks like this image:
Surcharge Page
and my Surcharge table and data look like this:
Surcharge Table
What is your suggestion regarding the model that properly works and binds to the table ?
Is it better to use a grid with Edit and Delete buttons instead of the foreach table ?
I'm looking for the best model that actually allows each row to be edited and saved into the table (dropdownlist for the Type field).
I have my code working and sorting correctly but I am using ViewBag to do so. I would like to clean up my code and use ViewModel instead to sort my grid but I'm stumped in how to do so. Any help would be greatly appreciated. Thank you.
Model
public partial class Asset
{
public int AssetKey { get; set; }
public int ProductKey { get; set; }
public string InventoryOwner { get; set; }
public string SerialNumber { get; set; }
Controller
public class InventoryManagementController : Controller
{
private Orders db = new Orders();
public ActionResult Index(int? AssetNum, string keyword, string sortOrder, string currentFilter, int? page)
{
ViewBag.OwnerSort = sortOrder == "owner_asce" ? "owner_desc" : "owner_asce";
ViewBag.AssetSort = sortOrder == "asset_asce" ? "asset_desc" : "asset_asce";
ViewBag.SerialSort = sortOrder == "serialnum_asce" ? "serialnum_desc" : "serialnum_asce";
ViewBag.ProductSort = sortOrder == "product_asce" ? "product_desc" : "product_asce";
ViewBag.Keyword = keyword;
var records = from s in db.Assets select s;
string AssetNums = AssetNum.ToString();
if (keyword != null)
{
page = 1;
}
else
{
keyword = currentFilter;
}
ViewBag.CurrentFilter = keyword;
switch (sortOrder)
{
case "asset_asce":
records = records.OrderBy(s => s.AssetKey);
break;
case "asset_desc":
records = records.OrderByDescending(s => s.AssetKey);
break;
case "serialnum_asce":
records = records.OrderBy(s => s.SerialNumber);
break;
case "serialnum_desc":
records = records.OrderByDescending(s => s.SerialNumber);
break;
case "product_asce":
records = records.OrderBy(s => s.Product.ProductName);
break;
case "product_desc":
records = records.OrderByDescending(s => s.Product.ProductName);
break;
case "owner_asce":
records = records.OrderBy(s => s.InventoryOwner);
break;
case "owner_desc":
records = records.OrderByDescending(s => s.InventoryOwner);
break;
int pageSize = 25; //Number of Records
int pageNumber = (page ?? 1);
return View(records.ToPagedList(pageNumber, pageSize));
//return View(assets.ToList());
}
View
#model PagedList.IPagedList<OrderDB.Models.Asset>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Inventory HomePage";
}
<!DOCTYPE html>
<title>Index</title>
<br />
<h2>Inventory</h2>
<table class="table" border="1">
<tr>
<th>
#Html.ActionLink("Asset Tag", "Index", new { sortOrder = ViewBag.AssetSort, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Serial Number", "Index", new { sortOrder = ViewBag.SerialSort, keyword = ViewBag.Keyword, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Product", "Index", new { sortOrder = ViewBag.ProductSort, keyword = ViewBag.Keyword, currentFilter = ViewBag.CurrentFilter })
</th>
<th>
#Html.ActionLink("Inventory Owner", "Index", new { sortOrder = ViewBag.OwnerSort, keyword = ViewBag.Keyword, currentFilter = ViewBag.CurrentFilter })
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.ActionLink(item.AssetKey.ToString(), "Details", new { id = item.AssetKey })
</td>
<td>
#Html.DisplayFor(modelItem => item.SerialNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.Product.ProductName)
</td>
<td>
#Html.DisplayFor(modelItem => item.InventoryOwner)
</td>
</tr>
}
</table>
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index",
new { page, sortOrder = ViewBag.CurrentSort, currentFilter = ViewBag.CurrentFilter }))
I have been trying to pass the quantity to my controller but cannot figure out how. I am new to this and need some help! I know that I need to make an ActionResult UpdateCart(int BookID, int quantity) but do not know what needs to go in it.
Here is my view code:
#{
ViewBag.Title = "Cart";
}
#using FinalProject_Lio_Lopez_Jafri_Wood.Controllers;
#model ShoppingCartItem
<h2>Cart</h2>
<table class="table table-hover">
<tr>
<th>Book Title</th>
<th>Book Unique Nnmber</th>
<th>Book Price</th>
<th>Quantity</th>
<th>Option</th>
<th>Sub Total</th>
</tr>
#{decimal s = 0;}
#foreach (ShoppingCartItem item in (List<ShoppingCartItem>)Session["cart"])
{
s += item.Books1.BookPrice * item.Quantity;
<tr>
<td>#item.Books1.BookTitle</td>
<td>#item.Books1.BookUniqueNumber</td>
<td>$ #item.Books1.BookPrice</td>
<td>#Html.TextBoxFor(m => m.Quantity, new { #Value = "1", #class = "form-control" , style="width:50px;" })</td>
<td>
#Html.ActionLink("Refresh Quantity", "Update", "ShoppingCart", new{id = item.Books1.BookID, quantity = item.Quantity}) | #Html.ActionLink("Remove Item", "Delete", "ShoppingCart",
new { id = item.Books1.BookID }, null)
</td>
<td>$ #(item.Books1.BookPrice * item.Quantity)</td>
</tr>
}
<tr>
<td align="right" colspan="5">TOTAL</td>
<td>$ #s</td>
</tr>
</table>
<br />
#Html.ActionLink("Continue Shopping", "Search", "Books")
<input type="button" value="Check Out" class="btn-info btn-active" style="float: right" />
Here is my controller code so far:
public class ShoppingCartController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
public ActionResult Index()
{
return View();
}
private int isExisting(int id)
{
List<ShoppingCartItem> cart = (List<ShoppingCartItem>) Session["cart"];
for (int i = 0; i < cart.Count; i++ )
if(cart[i].Books1.BookID==id)
return i;
return -1;
}
public ActionResult Delete(int id)
{
int index = isExisting(id);
List<ShoppingCartItem> cart = (List<ShoppingCartItem>)Session["cart"];
cart.RemoveAt(index);
Session["cart"] = cart;
return View("Cart");
}
public ActionResult UpdateCart(int BookID, int quantity)
{
return View("Cart");
}
public ActionResult AddToCart(int id)
{
if (Session["cart"] == null)
{
List<ShoppingCartItem> cart = new List<ShoppingCartItem>();
cart.Add(new ShoppingCartItem(db.Books.Find(id), 1));
Session["cart"] = cart;
}
else
{
List<ShoppingCartItem> cart = (List<ShoppingCartItem>) Session["cart"];
int index = isExisting(id);
if (index == -1)
cart.Add(new ShoppingCartItem(db.Books.Find(id), 1));
else
cart[index].Quantity++;
Session["cart"] = cart;
}
return View("Cart");
}
}
}
You seem to have some syntax issues. I would recommend you use resharper, it should underscodre at least such syntax errors.
You have different action names in your controller and view. MVC is not (yet) smart enough to figure out that "Update" and "UpdateCard" is the same thing.
You have another naming issue. Default MVC routing convention is to use id if you want the parameter to be part of URL and did not change routing. That's configurable, but the default is that.
Check parameters of the ActionLink. You should have specified routing parameters, but it seems you specify html attributes. Check the declaration of the Html.ActionLink. Note that to be sure you can always use named parameters.
Updates must never be doen with GET (like you do), as this provokes unwanted or random updates. Imagine for example a search engine (google) indexing your site - it will "click" your link (navigate to that) and this will add goods to the cart. Not good. I suggest you check some starter course on asp.net mvc...
Anyways, to fix the things, try:
Controller:
public ActionResult UpdateCart(int id, int quantity)
{
return View("Cart");
}
View:
#Html.ActionLink("Refresh Quantity", "UpdateCart", "ShoppingCart",
new { id = item.Books1.BookID, quantity = item.Quantity}, null)
I want in Home/Index Load Partial View I Write This Code:
NewsPagingViewModel class:
public class NewsPagingViewModel
{
public IList<DommainCalsses.Models.News> News { get; set; }
public int CurrentPage { get; set; }
public int Count { get; set; }
public int Term { get; set; }
public int Page { get; set; }
public int TotalRecords { get; set; }
}
In Controller
public virtual ActionResult ShowNews(int page=0)
{
return PartialView(Views._News, new Posc.Model.News.NewsPagingViewModel() { CurrentPage = page, Count = 3, News = _newsService.GetList(page, 3), Term = 0, Page = page, TotalRecords = _newsService.GetCount() });
}
In _News partialView
#model Posc.Model.News.NewsPagingViewModel
#{
int currentPage = Model.CurrentPage + 1;
int count = Model.Count;
int max = (Model.TotalRecords % count == 0) ? Model.TotalRecords / count : (Model.TotalRecords / count) + 1;
const int size = 8;
int firstPage = ((currentPage - size) <= 0) ? 0 : currentPage - size;
int lastPage = ((currentPage + size) >= max) ? max : currentPage + size;
}
<div id="label-table">
#foreach (var item in Model.News)
{
<div class="row">
<div class="col-sm-1" style="padding-left: 5px;margin-left: 5px;">
<img src="#item.Image" />
</div>
<div class="col-sm-5">
#Html.ActionLink(item.Abstract, MVC.Admin.News.Index())
</div>
</div>
}
#* Page Navigation *#
<div class="pagination pagination-centered">
<ul>
#if (currentPage - 1 == firstPage)
{
<li class="active"><a>First</a></li>
}
else
{
<li>
#Ajax.ActionLink("First", MVC.Admin.News.ActionNames.ShowNews, MVC.Admin.News.Name, new { page = 0, count = Model.Count }, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, OnBegin = "showLoading", UpdateTargetId = "label-table", OnSuccess = "loadAjaxComponents", OnComplete = "hideLoading" }, null)
</li>
}
#for (int i = firstPage; i < lastPage; i++)
{
#*if (i + 1 == currentPage)
{
<li class="active"><a>#i+1</a></li>
#*Html.ConvertToPersianString(i + 1)
}
else
{*#
<li>
#*Html.ConvertToPersianString(i + 1).ToString()*#
#Ajax.ActionLink((#i + 1).ToString(), MVC.Admin.News.ActionNames.ShowNews, MVC.Admin.News.Name, new { page = #i }, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, OnBegin = "showLoading", UpdateTargetId = "News", OnSuccess = "loadAjaxComponents", OnComplete = "hideLoading" }, null)
</li>
#*}*#
}
#if (currentPage == lastPage)
{
<li class="active"><a>Last</a></li>
}
else
{
<li>
#Ajax.ActionLink("Last", MVC.Admin.News.ActionNames.ShowNews, MVC.Admin.News.Name, new { page = 0, count = Model.Count }, new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, OnBegin = "showLoading", UpdateTargetId = "News", OnSuccess = "loadAjaxComponents", OnComplete = "hideLoading" }, null)
</li>
}
</ul>
</div>
</div>
And In Home/Index
<div id="News">
#Html.Action(MVC.Admin.News.ShowNews())
</div>
In the First Run Good Like This:
but when click in pagging Redirect to partial view Like this:
But I Want Refresh Partial View In Home/Index.
I would suggest you use the PagedList library. Its so awesome that Microsoft decided to use the library in their official tutorials (full tutorial here)
It provides a very clean code while doing pagination. See sample codes below.
Step 1
Add the PagedList.Mvc library using Nuget. https://www.nuget.org/packages/PagedList.Mvc/
Step 2
Integrate PagedList in your action method. Here is an example on how you could do it.
using PagedList;
public ActionResult ShowNews(int? page)
{
int currentPage = (page ?? 1);
// Fix negative page
currentPage = currentPage < 0 ? 1 : currentPage;
int pageSize = 3;
IEnumerable<Models.News> newsModels = newsService.GetList(currentPage, pageSize);
return View(newsModels.ToPagedList(currentPage, pageSize));
}
Step 3
Integrate PagedList in your View
#model PagedList.IPagedList<Models.News>
#using PagedList.Mvc;
#foreach (var item in Model.News)
{
<div class="row">
<div class="col-sm-1" style="padding-left: 5px;margin-left: 5px;">
<img src="#item.Image" />
</div>
<div class="col-sm-5">
#Html.ActionLink(item.Abstract, MVC.Admin.News.Index())
</div>
</div>
}
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action(MVC.Admin.News.ActionNames.ShowNews))
See complete tutorial here http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging-with-the-entity-framework-in-an-asp-net-mvc-application