Paging is not working in MVC4 - asp.net-mvc

I am designing one page where I am displaying some details with paging. Page works fine except paging. When i click on second page nothing happens. All data cureently displayed will also go. Also when i hit on second page control wont go to my action method. This is my pager code.
#Html.PagedListPager(Model.logDetails, page => Url.Action("Index",
new { page, currentFilter = ViewBag.CurrentFilter, filterdateTime=ViewBag.filterdateTimepageSize, }))
Page #(Model.logDetails.PageCount < Model.logDetails.PageNumber ? 0 : Model.logDetails.PageNumber) of #Model.logDetails.PageCount
This is my action method code.
[HttpPost]
public ActionResult Index(int? clientId, DateTime? dateofAction,string typeofDocument,string employeeID,string citizenId,int? currentFilter,DateTime? filterdateTime,int? page)
{
DB_KYC3Entities db = new DB_KYC3Entities();
ViewBag.docTypes = new SelectList(db.tm_doc_type, "doc_typeid", "doctype_name");
if (clientId != null)
{
page = 1;
}
else
{
clientId = currentFilter;
}
if(dateofAction!=null)
{
page = 1;
}
else
{
dateofAction = filterdateTime;
}
ViewBag.CurrentFilter = clientId;
ViewBag.filterdateTime = dateofAction;
int pageSize = 8;
int pageNumber = (page ?? 1);
VerificationLogBAL obj = new VerificationLogBAL();
int docType = obj.GetDocDetails(typeofDocument);
List<logDetails> logDetails = obj.getlogDetails(clientId?? default(int), dateofAction?? DateTime.Now, docType, employeeID, citizenId);
IPagedList<logDetails> pagedLog = logDetails.ToPagedList(pageNumber, pageSize);
logDetailsEnumeration model = new logDetailsEnumeration();
ViewBag.checkData = logDetails.Count;
model = new logDetailsEnumeration()
{
logDetails= pagedLog
};
return View("Index",model);
}
This is my view code.
<div class="forms">
#using (Html.BeginForm("Index", "VerificationLog", FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<div class="message"></div>
<div class="loginUsernamePassword">
<i class="fa fa-user"></i>
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="dataTable tableHover">
<tr>
<th width="8%" scope="col">Client ID</th>
<th width="20%" scope="col">
<div class="form-box form-box-default">
#Html.TextBox("clientId", ViewBag.CurrentFilter as string, new { #id = "clientId", #placeholder = "Client ID", #class = "form-control", #maxlength = 20 })
</div>
</th>
<th width="10%" scope="col">Date Of Action</th>
<th width="20%" scope="col">
<div class="form-box form-box-default">
#Html.TextBox("dateofAction", ViewBag.filterdateTime as string, new { #id = "dateofAction", #placeholder = "Date Of Action", #class = "txtBox form-control calender validate[required]" })
</div>
</th>
<th width="15%" scope="col">Type Of Document</th>
<th width="17%" scope="col">
<div class="form-box form-box-default">
#*#Html.TextBox("typeofDocument", ViewBag.filterdateTime as string, new { #id = "typeofDocument", #placeholder = "Type Of Document", #class = "form-control", #maxlength = 20 })*#
#Html.DropDownList("docTypes",null,new {#id = "typeofDocument", #placeholder = "Type Of Document", #class = "form-control"})
</div>
</th>
</tr>
<tr>
<th width="15%" scope="col">Employee ID</th>
<th width="17%" scope="col">
<div class="form-box form-box-default">
#Html.TextBox("employeeID", ViewBag.filterdateTime as string, new { #id = "employeeID", #placeholder = "Employee ID", #class = "form-control", #maxlength = 20 })
</div>
</th>
<th width="15%" scope="col">Citizen ID</th>
<th width="17%" scope="col">
<div class="form-box form-box-default">
#Html.TextBox("citizenId", ViewBag.filterdateTime as string, new { #id = "citizenId", #placeholder = "Citizen ID", #class = "form-control", #maxlength = 20 })
</div>
</th>
<th width="10%" scope="col" colspan="2">
<input type="submit" value="Search" class="btn btn-primary btn-cons search" />
</tr>
</table>
</div>
}
</div>
#if (Model != null && Model.logDetails.Count != 0)
{
<br />
<h2>Verification Log</h2>
<br />
<div id="GridDetails">
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="dataTable tableHover">
<tr>
<th>Label</th>
<th>Value</th>
<th>UpdatedOn</th>
<th>UpdatedBy</th>
<th>UpdatedStatus</th>
<th>RejectComment</th>
</tr>
#foreach (var group in Model.logDetails)
{
<tr>
<td>#group.contentLabel</td>
<td>#group.contentValue</td>
<td>#group.updatedOn</td>
<td>#group.updatedBy</td>
<td>#group.updatedStatus</td>
<td>#group.rejectComment</td>
</tr>
}
</table>
[HttpGet]
public ActionResult Index()
{
DB_KYC3Entities db = new DB_KYC3Entities();
ViewBag.docTypes = new SelectList(db.tm_doc_type, "doc_typeid", "doctype_name");
return View();
}
When i click on second page control wont go to my index method also. Also i have 5 textboxes so do i need to preserve the all 5 text box values in viewbag? Can someone tell me? Thanks in advance

PagedListPager makes a GET call, not a POST, so you need to remove the [HttpPost] attribute from the Index() method. Associated with that, you need to change the form to also make a GET
#using (Html.BeginForm("Index", "VerificationLog", FormMethod.Get))
And yes, you need to preserve the all 5 text box values in viewbag (or better using a view model) and add those values in the pagers Url.Action() in the same way your are adding currentFilter and filterdateTime

Related

asp.net mvc displaying contents in view on condition

I have a following view in my project where i have one dropdown and one textbox and submit button.I want to execute following scenario.
On click of submit only,I want to display the table contents.So if there is data,it will display data or else it will display "No records found".Is it possible?
My view is as follows:
model mvclearn.Models.Employee
#{
ViewBag.Title = "menu";
}
#{
Layout = null;
}
<link href="~/Content/bootstrap.css" rel="stylesheet" />
<style>
.error {
color: red;
}
</style>
<div class="container">
<div class="container"style="width:30%">
#using (Html.BeginForm("save", "Test", FormMethod.Post))
{
#Html.DropDownListFor(m => m.Service_Code, Model.ser_code, "--select--", new { #class = "form-control", #placeholder = "Enter Service code" })
#Html.ValidationMessageFor(m => m.Service_Code, "", new { #class = "error" })
#Html.TextBoxFor(m => m.Service_Name, new { #class = "form-control", #placeholder = "Service Name" })
#Html.ValidationMessageFor(m => m.Service_Name, "", new { #class = "error" })
<input type="submit" value="submit" class="btn-block" />
}
<table class="table">
#{
if (Model.data!=null && Model.data.Count() > 0)
{
<tr>
<th>
#Html.DisplayName("Service_Code")
</th>
<th>
#Html.DisplayName("Service_Name")
</th>
</tr>
foreach (mvclearn.Models.Employee item in Model.data)
{
<tr>
<td>
#item.Service_Code
</td>
<td>
#item.Service_Name
</td>
</tr>
}
}
else
{
<p>No records found</p>
}
}
</table>
</div>
In your case, you have done a nice job but the way you are dealing with the model seems to be incorrect.You cannot use Model.data!= null statement,instead,I suggest you to do something like this.Check whether the Model's attributes are null or not!
if (Model.EmployeeName!=null ){
//your code here
}
Another possible reason for your problem is the model returns null values so check whether the model's attributes has the values when it is in the view.
Hope it helped.
You Can Embed Table tag in the If condition like this ...
#if(Model.data!=null && Model.data.Count() > 0)
{
<table>
<tr>
<td></td>
</tr>
</table>
}else{
<p>There is no records</p>
}

error while posting pagedlist from view to the controller

I've an indexed page in MVC with data that displays in a table format from the database and using paging. I want to edit only one column of the table. Can I post the paging list to the controller for editing. If so how?
I'm able to edit with normal list getting error while passing PagedList
--- this is my index page----
#model PagedList.IPagedList<emp_prac.Models.Employee>
#using PagedList.Mvc;
#*#model List<emp_prac.Models.Employee>*#
#using (Html.BeginForm("UpdateOrder", "Employee", FormMethod.Post))
{
Html.AntiForgeryToken();
Html.EditorForModel();
ViewBag.Title = "Employee Details";
<h2>Employee Details</h2>
<p>
#Html.ActionLink("Create New", "InsertEmployee")
</p>
<table class="table">
<thead>
<tr>
<th>Edit</th>
<th>Delete</th>
<th>Name</th>
<th>Email</th>
<th>Phone No</th>
<th>Salary</th>
<th>Joining Date</th>
<th>PDF</th>
<th>Status</th>
<th>Order</th>
</tr>
</thead>
<tbody>
#for (int i = 0; i < Model.Count; i++)
{
<tr>
<td>#Html.ActionLink("Edit", "EditEmployee", new { id = Model[i].emp_id }) </td>
<td>#Html.ActionLink("Delete", "DeleteEmployee", new { id = Model[i].emp_id }, new { onclick = "return confirm('Are you sure you want to delete?');", #class = "btn-btn-default" }) </td>
<td>#Html.DisplayFor(model => model[i].emp_name)</td>
<td>#Html.DisplayFor(model => model[i].emp_email)</td>
<td>#Html.DisplayFor(model => model[i].emp_phone_no)</td>
<td>#Html.DisplayFor(model => model[i].emp_salary)</td>
<td>#Html.DisplayFor(model => model[i].emp_joining_date)</td>
<td>#Html.ActionLink("PDF", "UploadPdf", new { id = Model[i].emp_id }) </td>
<td>#(Html.DisplayFor(model => model[i].emp_status).ToString() == "1" ? "Active" : "Inactive")</td>
<td>#Html.TextBoxFor(model => model[i].emp_order, new { style = "width: 35px" })</td>
<td>#Html.HiddenFor(model => model[i].emp_id)</td>
</tr>
}
</tbody>
</table>
<button type="submit" value="Order" onclick="location.href='#Url.Action("UpdateOrder","Employee")'">Order</button>
}
<br />
Page #(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of #Model.PageCount
#Html.PagedListPager(Model, page => Url.Action("Index", new { page }))`
---This is my controller action method---
[HttpPost]
public ActionResult UpdateOrder(PagedList<Employee> obj_view)
{
foreach (var abc in obj_view)
{
Employee obj = new Employee();
obj.emp_order = abc.emp_order;
obj.emp_id = abc.emp_id;
obj.Mode = "O";
Employee.InsertUpdateEmployee(obj);
}
return RedirectToAction("Index");
}
I looked deeply into your code , as per my point of view, below line may cause the error.
**<button type="submit" value="Order" onclick="location.href='#Url.Action("UpdateOrder","Employee")'">Order</button>
}**
Reason:
When you post the data through the form post, you no need to specify the onclick in the submit button
Solution:
Just replace the above line with simple submit button like this
**<input type="submit" value="Order" class="btn btn-default" />**
And see in the button click event whether you get the data or not using breakpoint.
Hope you will surely get the data now , kindly let me know your thoughts or feedbacks
Thanks
Karthik

Paging issue in ASP.Net Mvc Application

I am developing an MVC application in which I use a DropdownList to select "vendor". When I select a vendor from the dropdown then the view shows products related to the selected vendor.
I use paging to display multiple pages of particular vendor's products.
My issue is when I select a vendor from dropdown, at change event it displays products on all pages properly. If I select 2nd page it shows products from 2nd page. But next time if I select another vendor from dropdown, it shows 2nd page of selected vendor. But what I want is to display first page of selected vendor initially.
Controller code as below
public ActionResult Index(int? page ,int VendorId = 0)
{
var pageNumber = (page ?? 1);
var pagesize = 2;
if (VendorId == 0)
{
VendorId = Convert.ToInt32(Session["InventoryVendorId"]);
}
VendorService vendorService = new VendorService();
SelectList SelectList = new SelectList(vendorService.GetAll().OrderBy(t => t.Name), "Id", "Name", VendorId);
ViewData["list"] = SelectList;
int id = Convert.ToInt32(Session["loggedEmpId"]);
CommonService.SetEmployeeId(id);
if (VendorId != 0)
{
Session["InventoryVendorId"] = VendorId;
ProductService ProductService = new ProductService();
var productList = ProductService.GetProductInventory().Where(x=>x.VendorId == VendorId);
return View(productList.ToPagedList(pageNumber, pagesize));
}
else
{
return View();
}
}
code for view as below
#model PagedList.IPagedList<StockWatch.DTO.ProductDTO>
#using PagedList.Mvc;
#using System.Web.UI.WebControls
#{
ViewBag.Title = "Index";
int VendorId = Convert.ToInt32(Session["InventoryVendorId"]);
}
<link href="~/Content/PagedList.css" rel="stylesheet" />
<div class="row-fluid">
<div id="vendorDropdownDiv4" class="span12 " style="margin-left:0px;margin-top:10px;">
<div class="span6" >
<div class="span4" style="margin-left:1px;" >
<label >Vendor</label>
</div>
<div class="span6" >
#Html.DropDownList("VendorId", ViewData["list"] as SelectList, "-- Select vendor --", new { #id = "vendorIdforInventory", #name = "VendorId" })
</div>
</div>
<div class="span3" style="text-align:right">
#* <input class="btn btn-primary" type="submit" value="Load" id="create"/>*#
#*<input class="btn btn-default" value="Cancel" style="width:45px;" onclick="window.location.href='#Url.Action("index") '"/>*#
</div>
</div>
</div>
<div id="Newindexview"></div>
#if(Model != null)
{
</div>
<div class="span12" style="margin-left:0px;">
<table>
<thead>
<tr >
<th style="width:250px;" >Product Name
</th>
<th style="width:180px; text-align:left;" >Product Code
</th>
<th style="border-right: solid #e8eef4 thick; width: 0px; text-align:right;">Avg. Weight
</th>
#{
foreach (var location in ViewBag.loc)
{
<th style="width:10px;text-align:right;">#location.Name</th>
}
}
</tr>
</thead>
<tbody>
#foreach (var p in Model)
{
<tr>
<td style="width:250px;">
#p.Name
</td>
<td style="width:180px;text-align:left;">
#p.ProductCode
</td>
<td style="border-right: solid #e8eef4 thick; width: 15px; text-align:right">
#p.AvgWeight
</td>
#foreach (var location in ViewBag.loc)
{
flag = false;
if(p.Inventory != null)
{
foreach (var loc in p.Inventory)
{
if (location.Name == loc.LocationName)
{
<td style="width:10px; text-align:right;">#loc.Quantity</td>
flag = true;
}
}
}
if (flag == false)
{
<td style="width:10px; text-align:right;">0</td>
}
}
</tr>
}
</tbody>
</table>
</div>
<div class="span12" style="margin-left:0px;">
<div class="span6" style="margin-left:0px;">
#Html.PagedListPager(Model, page => Url.Action("Index", new {page ,searchContent=searchcontent}))
</div>
</div>
</div>
}
and jquery code as below
$("#vendorIdforInventory").change(function () {
var vendorid = $('#vendorIdforInventory').val();
$.ajax({
url: '#Url.Action("Index", "Inventory")',
data: {
VendorId: vendorid
},
type: "POST",
success: function (data) {
location.reload();
$('#modeldiv1').empty();
$('#vendorDropdownDiv4').hide();
$('#Newindexview').html("");
$('#Newindexview').html(data);
}
});
});
How to solve this paging issue?
You need to pass the currentFilter from your view back into your controller (which you have with VendorID), and set the page accordingly. Details are in the ASP.NET tutorial on paging at 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.
Look at how they've implemented filtering using the searchString and currentFilter variable, that's what will make sure that when a new string is entered (or selected from a drop down list in your case) that the paging responds accordingly.
Specifically, this is what I think you're missing in your code
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
...
int pageNumber = (page ?? 1);

MVC4 Filtering with checkboxes

I have created create function in my controller which display all genres in checkoxes like this:
Controller:
public ActionResult Create()
{
var db = new MainDatabaseEntities();
var viewModel = new ANIME
{
GENRES = db.GENRES.Select(c => new { ID_GE = c.ID_GE, GENRE = c.GENRE, isSelected = false }).ToList().Select(g => new GENRES
{
ID_GE = g.ID_GE,
GENRE = g.GENRE,
isSelected = false
}).ToList()
};
return View(viewModel);
}
View:
#model AnimeWeb.Models.ANIME
#using (Html.BeginForm(null, null, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<table>
<tr>
<td class="lefttablecontent" id="top">
<div class="editor-label">
#Html.HiddenFor(model => model.ID_AN)
</div>
<div class="editor-label">
Original title
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TITLE_OR)
#Html.ValidationMessageFor(model => model.TITLE_OR)
</div>
<div class="editor-label">
English title
</div>
<div class="editor-field">
#Html.EditorFor(model => model.TITLE_EN)
#Html.ValidationMessageFor(model => model.TITLE_EN)
</div>
<div class="editor-label">
Genres
</div>
<div class="editor-list">
#Html.EditorFor(model => model.GENRES)
#Html.ValidationMessageFor(model => model.GENRES)
</div>
</td>
<td class="righttablecontent" id="top">
<p>
<input type="submit" value="Create" />
</p>
</td>
</tr>
</table>
}
}
EditorTemplate for Genres:
#model AnimeWeb.Models.GENRES
#Html.HiddenFor(model => model.ID_GE)
#Html.HiddenFor(model => model.GENRE)
<table>
<tr>
<td class=" right">
#Html.EditorFor(model => model.isSelected)
</td>
<td>
#Html.LabelFor(model => model.isSelected, Model.GENRE)
</td>
</tr>
</table>
Now I would like to display the same template with all genres and use it for filtering in index, but I'm not sure how to do this.
Controller:
public ActionResult Index(string sortOrder, string currentFilter, int? page)
{
using (var db = new MainDatabaseEntities())
{
ViewBag.CurrentSort = sortOrder;
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = searchString;
var anime = from s in db.ANIME.Include("GENRES")
select s;
int pageSize = 10;
int pageNumber = (page ?? 1);
return View(anime.ToPagedList(pageNumber, pageSize));
}
}
View:
#model PagedList.IPagedList<AnimeWeb.Models.ANIME>
#using PagedList.Mvc;
<link href="~/Content/PagedList.css" rel="stylesheet" type="text/css" />
#{
ViewBag.Title = "Index";
}
<p>
#if (Roles.IsUserInRole("Administrator"))
{
#Html.ActionLink("Create New", "Create")
}
</p>
#foreach (var item in Model) //
{ //
#Html.EditorFor(modelItem => item.GENRES); // I'm not sure about this line
} //
<table>
<tr>
<th>
Anime
</th>
<th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.ActionLink(item.TITLE_OR, "Details", new { id = item.ID_AN })
</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 }))
When I try to display it with #Html.EditorFor(modelItem => item.GENRES) it displays only genres that are selected within each anime but I need all genres to filter with them. I'm not even sure is this a good way to make it. Any suggestions?

passing whole datatable from view to the controller action method

I have the view below:
<table cellpadding="0" cellspacing="0" border="0" class="display mobile_dt1" id="SearchResults">
<thead>
<tr>
#* <input type="checkbox" name="Test" onclick="SetAllCheckBoxes('PartialViewName')" *#
<th id="CHCKID" class="checkBoxClass">Check All #Html.CheckBox("checkboxall", new { #id = "checkall", #name = "StatusList" })</th>
<th>Export</th>
<th>Request ID</th>
<th id="RQSTNMSRCHID" style="display: none">#BVPConstants.RQSTNMSRCH</th>
<th id="RQSTSTTSSRCHID">#BVPConstants.RQSTSTTSSRCH</th>
<th>Strategic Initiative</th>
<th id="BSNGRPL1ID">#BVPConstants.BSNGRPL1</th>
<th id="EXCTVSPNSRID">#BVPConstants.EXCTVSPNSR</th>
<th id="RQSTCLSFNID">#BVPConstants.RQSTCLSFN</th>
<th id="BUSNDBYDTID">#BVPConstants.BUSNDBYDT</th>
<th id="CRTDBYSRCHID">#BVPConstants.CRTDBYSRCH</th>
<th id="CRTDONID">#BVPConstants.CRTDON</th>
</tr>
</thead>
<tbody>
#if (Model != null)
{
foreach (var SearchResult in Model)
{
<tr>
<td class="chck">#Html.CheckBox("checkboxall", new { #id = "check" })</td>
<td>#Html.ActionImage("", "", new { #Id = "export" }, null, null, null, "~/Content/img/ico/filePDFUpload.png", "Download")</td>
<td>#Html.ActionLink(SearchResult.RequestId.ToString(), "Edit", "BusinessRequest", new { requestId = SearchResult.RequestId }, new { #onerror = "closeLoading()", #onload = "closeLoading()", #onclick = "showLoading()" })</td>
<td>#Html.ActionLink(SearchResult.RequestName.ToString(), "Edit", "BusinessRequest", new { requestId = SearchResult.RequestId }, new { #onerror = "closeLoading()", #onload = "closeLoading()", #onclick = "showLoading()" }) </td>
<td>#SearchResult.Status</td>
<td>#SearchResult.StrategicInitiativeNumber</td>
<td>#SearchResult.BusinessGroup</td>
<td>#SearchResult.ExecutiveSponsorNumber</td>
<td>#SearchResult.RequestClassification</td>
<td>#SearchResult.BusinessNeedByDate</td>
<td>#SearchResult.CreatedBy</td>
<td>#SearchResult.CRTTs</td>
</tr>
}
}
</tbody>
</table>
I want to send the SearchResults datatable to the below controller method:
public PartialViewResult ExportToExcel(DataTable table) {
List<SearchRequestModel> srchlist = new List<SearchRequestModel>();
StringWriter stringWriter = new StringWriter();
var grid = new GridView();
grid.DataSource = table;
grid.DataBind();
Response.ClearContent();
Response.AddHeader("Content-Disposition", "attachment; filename=Prioritization.xls");
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
HtmlTextWriter htmlTextWriter = new HtmlTextWriter(stringWriter);
grid.RenderControl(htmlTextWriter);
Response.Write(stringWriter.ToString());
Response.End();
return PartialView("_SearchHistory", srchlist);
}
The Action Method parameter maps automatically the Request.Form. That said, you will only be able to make your DataTable parameter work (has values) if you have form fields in your table.
Since you don't want to allow the user to edit the data I would recommend you to use hidden fields. You can do them either "manually" (<input type="hidden" />) or use the MVC Html helper (#Html.HiddenFor()).

Resources