MVC WebGrid Paging not working - asp.net-mvc

I have a WebGrid in a Partial Page, and the Partial Page is called from the Controller inside another page, everything is working fine, except for the paging. When I try to go to next page records, it reverts back to the main page, without the Webgrid.
My Controller Code:
[HttpPost]
public ActionResult StatisticsHistory(FormCollection fc)
{
List<StatisticsHistoryData> hisData = new List<StatisticsHistoryData>();
........
if (hisData != null)
{
hisData = StatisticsHistoryMethods.HistoryDetailsBetweenDates(fromDate, toDate, environmentId);
return PartialView("_StatusHistoryGrid", hisData);
}
else
{
}
return StatisticsHistory();
}
My Webgrid in the Partial Page:
#model IEnumerable<AppFabricAdmin.Models.StatisticsHistoryData>
#{var Grid = new WebGrid(source: Model, canPage:true, rowsPerPage:2, canSort: true);
}
#{
if (Model.Count() > 0)
{
#Grid.GetHtml(tableStyle: "webGrid", headerStyle: "header", alternatingRowStyle: "alt", mode: WebGridPagerModes.All,
columns: Grid.Columns(Grid.Column("Environment", format: #<b>#item.Environment</b>, style: "AIDColumn"),
Grid.Column("Initial Status", format: #<b>#item.InitialStatus</b>, style: "FirstNameColumn"),
Grid.Column("Final Status", format: #<b>#item.FinalStatus</b>, style: "LastNameColumn"),
Grid.Column("Action Taken", format: #<b>#item.ActionTaken</b>, style: "EmailIDColumn"),
Grid.Column("Comments", format: #<b>#item.Comments</b>, style: "EmailIDColumn"),
Grid.Column("Time Stamp", format: #<b>#item.TimeStamp</b>, style: "EmailIDColumn")
))
}
else
{
<p>
No records found.</p>
}
I have also tried using #using (Ajax.BeginForm()) in the main page and hv also tried using ajaxUpdateContainerId:"grid" in the Grid, but nothing works. Pls help.

Related

How to refresh mvc webgrid

I am using a WebGrid in my mvc application.
<div class="grid-div" id="webgridid">
#grid.GetHtml(
tableStyle: "gridTable",
headerStyle: "gridHead",
footerStyle: "gridFooter",
columns: new[]
{
grid.Column("name","Name", canSort: true, style: "name"),
grid.Column("description","Description", canSort: true, style: "description"),
grid.Column("duration","Duration", canSort: true, style: "duration"),
})
</div>
I can edit the selected row values using a form. After editing this values, it is not reflecting in my webGrid. But it is reflecting in DataBase. To reflect this in to the webGrid, I need to refresh the webGrid by loading datas from DB. How can I reload contents to webGrid from DB? Also after reloading it, this pageNumber should the old one. How to do this?
Finally I find the solution for my problem. I have to define a <div> with ID and refer the div’s id in the ajaxUpdateContainerId attribute of WebGrid control that will allow WebGrid to update data asynchronously using Ajax.
<div id="ajaxgrid">
#{
var grid = new WebGrid(Model, rowsPerPage: 10, selectionFieldName: "SelectedRow", ajaxUpdateContainerId: "ajaxgrid");
}
</div>
Then, call the GetHtml method of WebGrid, so that Razor Engine can generate corresponding HTML for it. After the end of <div> tag.
#grid.GetHtml(
tableStyle: "gridTable",
headerStyle: "gridHead",
footerStyle: "gridFooter",
columns: new[]
{
grid.Column("name","Name", canSort: true, style: "name"),
grid.Column("description","Description", canSort: true, style: "description"),
grid.Column("duration","Duration", canSort: true, style: "duration"),
})
Then in my ajax call for updation I have added location.reload() to refresh my WebGrid.
$.ajax({
url: '#Url.Action("User", "UserDetails")',
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
data: formData,
contentType: false,
processData: false,
success: function (result) {
if (result == "OK") {
location.reload();
}
else
alert(result);
},
error: function (result) {
alert('Error!');
}
});
Now its working fine for me.

How to bind a WebGrid in a PartialView, which is in JQueryUI ModalPopup

I have this PartialView, which is loaded from the Layout of an MVC4 application.
On a button click in the main navigation menu the method SearchCustomers is called in an ajax post (shown below). Everything seems to work. Fiddler shows Data is coming back as supposed however the grid is not visible in the Popup. I wonder what am I doing wrong?
The Partial View
#model Invoice.Web.ViewModels.SearchCustomerWindowVM
<h2>Search Results</h2>
<div id="resultsGrid">
#{
if (Model.CustomersList != null)
{
var grid = new WebGrid(Model.CustomersList, rowsPerPage: 6, ajaxUpdateContainerId:"searchResults ");
#grid.GetHtml(
fillEmptyRows: true,
alternatingRowStyle: "alternate-row",
headerStyle: "grid-header",
footerStyle: "grid-footer",
mode: WebGridPagerModes.All,
firstText: "<< First",
previousText: "< Prev",
nextText: "Next >",
lastText: "Last >>",
columns: new [] {
grid.Column("Forename", canSort: false),
grid.Column("Surname"),
grid.Column("PostCode"),
grid.Column("",
header: "Actions",
format: #<text>
#Html.ActionLink("Edit", "Edit", new { id=item.CustomerID} )
|
#Html.ActionLink("Delete", "Delete", new { id=item.CustomerID} )
</text>
)
}
)
}
}
The Ajax Post - I guess the problem is here!!
<script>
$( "#searchCustomers" ).dialog({
autoOpen: false,
height: 350,
width: 700,
modal: true
});
$("#searchButton")
.button()
.click(function() {
$("#searchCustomers").dialog("open");
});
function searchCustomers() {
var forename = $("#Forename").val();
var surname = $("#Surname").val();
var postCode = $("#PostCode").val();
debugger;
var request = {
foreName: forename,
surName: surname,
postCode: postCode
};
$.ajax({
type: "POST",
url: "/Customer/SearchCustomers",
data: JSON.stringify(request),
datatype: "JSONP",
contentType: "application/json; charset=utf-8",
success: function (returndata) {
// if (returndata.ok) {
//$.post(data.Url, function(partial) {
// $('#IdOfDivToUpdate').html(partial);
$("#searchCustomers").dialog("open");
//alert("The File Has Been Downloaded.");
$('#resultsGrid').html(returndata);
//} else {
// window.alert('Error Saving Authorisation.');
//}
}
}
);
}
</script>
The Controller method:
public ActionResult SearchCustomers(string postCode, string surName, string foreName)
{
var model = new SearchCustomerWindowVM();
var modelList = new List<SearchCustomerWindowVM>();
var customersList = _customerRepository.GetAllCustomers().ToList();
foreach (var cust in customersList)
{
model.Forename = cust.FirstName;
model.Surname = cust.Surname;
model.PostCode = cust.ContactDetails.PostCode;
modelList.Add(model);
}
return Json(modelList);
// return Json(new {error = true, message = "all good."});
}
As you see I have tried other approaches in the Ajax post, which I have commented out.
Thanks in advance.
on your controller change the return to partial view
return PartialView("_PartialName", model);
then in the success of your ajax call
$('#searchCustomers').html(result);
$("#searchCustomers").dialog("open");
this way you load the div with the partial view and then open the dialog

Adding a link button in the footer of WebGrid Mvc3

I have inserted the link buttons "Add New Record" and "Save All" at the bottom of my Webgrid. But I want them to be in the footer of the WebGrid. I have searched for this a lot, but found nothing. Can someone tell me how to add a link or button in the "footer" of a WebGrid.
Here is some code of my WebGrid
#model IEnumerable<MvcGrid2.Models.Employee>
#{
WebGrid grid = new WebGrid(
source: Model,
rowsPerPage: 4);
}
#grid.GetHtml(htmlAttributes: new { id = "WebGrid1" },
tableStyle:"gridTable",
headerStyle: "gridHead",
footerStyle: "gridFooter",
rowStyle: "gridRow",
alternatingRowStyle: "gridAltRow",
mode: WebGridPagerModes.All,
firstText: "<<",
previousText: "<",
nextText: ">",
lastText: ">>",
columns: grid.Columns(
#* grid.Column( columnName : "EmployeeId",
format: #<text>#item.EmpId</text>),*#
grid.Column(columnName: "Employee Id",
format: #<span>
<span id="spanEmpId_#(item.EmpId)">#item.EmpId</span>
#Html.TextBox("EmpId_" + (int)item.EmpId, (int)item.EmpId, new { #style = "display:none" })
</span>),
grid.Column(columnName: "Employee Name",
format: #<span>
<span id="spanEmpName_#(item.EmpId)">#item.EmpName</span>
#Html.TextBox("EmpName_" + (int)item.EmpId, (string)item.EmpName, new { #style = "display:none" })
</span>),
grid.Column(columnName: "Designation",
format: #<span>
<span id="spanEmpDesg_#(item.EmpId)" >#item.Designation</span>
#Html.TextBox("EmpDesg_" + (int)item.EmpId, (string)item.Designation, new { #style = "display:none" })
</span>),
grid.Column(columnName: "Action",
format: #<text>
Edit
Update
Cancel
Update
Cancel
Delete
</text>)
))
WebGrid doesn't have a modifiable footer per se. However if you view the tutorial on ASP.NET you'll see a way to make that happen in css.
What you can do is make your last row the same css class as your footer, or you can insert your buttons/links with javascript. Neither approach is clean, but as far as I can tell there is not a better way to accomplish your goal without rewriting the control. Many people have suggested looking into Telerik's controls, if you have/can get a license for their stuff.

webgrid is empty after sorting

I have a webgrid defined within a partial view. (This is an MVC 4 project.) The webgrid isn't the only thing in the partial view, so the webgrid is bound to a List within the model of the partial view.
The grid populates and sorts as it should when a column header is clicked, but when I repopulate the grid by a call to an action method (via a form post set up using Ajax.BeginForm) and then click on a column header, the grid contents disappear. (The action method queries a database using search criteria provided on the form by the user.)
What could be causing this? How can it be resolved?
The partial view starts with:
#model DonationImport.Models.GiftWithSplits
The contents of the partial view are within a form designated by:
#using (Ajax.BeginForm("SearchConstit", "Batch", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "constitSearchArea" }))
The WebGrid is defined as follows:
#{
var constitGrid = new WebGrid(source: Model.SearchResults, rowsPerPage: 100, ajaxUpdateContainerId: "constitGrid");
<div style="overflow-x: scroll; width: 100%;">
<div style="width: 1910px;">
#constitGrid.GetHtml(htmlAttributes: new { id = "constitGrid" },
columns: constitGrid.Columns(
constitGrid.Column(format: #<text><button onclick="selectConstituent('#item.Constituent_ID')" >select</button></text>, style: "searchResultsColumnWidth"),
constitGrid.Column("Constituent_ID", header: "ConstitID", style: "searchResultsColumnWidth", format: #<text>#Html.ActionLink((string)item.Constituent_ID, "PriorGifts", new { constitID = item.Constituent_ID }, new { target = "Prior Payments" })</text>),
constitGrid.Column("IsActive", header: "Active", style: "searchResultsColumnWidth"),
constitGrid.Column("LastName", header: "Last", style: "searchResultsColumnWidth"),
constitGrid.Column("FirstName", header: "First", style: "searchResultsColumnWidth"),
constitGrid.Column("MiddleInitial", header: "M.I.", style: "searchResultsNarrowColumnWidth"),
constitGrid.Column("Spouse", header: "Spouse", style: "searchResultsColumnWidth"),
constitGrid.Column("EmailAddress", header: "E-mail", style: "searchResultsWideColumnWidth"),
constitGrid.Column("AddressLine1", header: "Address Line 1", style: "searchResultsWideColumnWidth"),
constitGrid.Column("City", header: "City", style: "searchResultsWideColumnWidth"),
constitGrid.Column("State", header: "State", style: "searchResultsColumnWidth"),
constitGrid.Column("Zip", header: "Zip", style: "searchResultsWideColumnWidth"),
constitGrid.Column("SearchResultsText", header: "Search Results", style: "searchResultsWideColumnWidth"),
constitGrid.Column("IsActivePledge", header: "Pledge", style: "searchResultsNarrowColumnWidth"),
constitGrid.Column("ReceiptWarning", header: "Receipt Warning", style: "searchResultsWideColumnWidth"),
constitGrid.Column("IsMember", header: "Mbr", style: "searchResultsNarrowColumnWidth")),
alternatingRowStyle: "altrow")
</div>
</div>
}
When one clicks on:
<input type="submit" value="Search" />
within the form, the action method called is as follows:
[HttpPost]
public PartialViewResult SearchConstit(DonationImport.Models.GiftWithSplits g)
{
GiftWithSplits giftWithSplits = new GiftWithSplits(); // model (object) to be returned to the partial view
// send back gift data which we are currently using
giftWithSplits.GiftToVerify = g.GiftToVerify;
// search using provided data
string middleInitial = empty2null(g.GiftToVerify.SourceMiddleName);
if (!string.IsNullOrWhiteSpace(middleInitial))
middleInitial = middleInitial.Substring(0, 1); // just supply the initial, not the entire name
string zip = empty2null(g.GiftToVerify.SourceZip);
if (!String.IsNullOrWhiteSpace(zip))
zip = zip.Substring(0, 5); // we want only the first 5 digits of the zip
giftWithSplits.SearchResults = db.SearchDonor(null, g.GiftToVerify.DonationSourceCode, empty2null(g.SourceAcctMemo), null, empty2null(g.GiftToVerify.SourceLastName),
empty2null(g.GiftToVerify.SourceFirstName), middleInitial, empty2null(g.GiftToVerify.SourceAddress1),
empty2null(g.GiftToVerify.SourceCity), empty2null(g.GiftToVerify.SourceState), zip, empty2null(g.GiftToVerify.SourceCountry),
empty2null(g.GiftToVerify.SourceEmailAddress), empty2null(g.GiftToVerify.SourcePhone)).ToList();
if (giftWithSplits.SearchResults.Count == 0)
{
SearchDonor_Result emptyResult = new SearchDonor_Result();
emptyResult.Constituent_ID = "[None Found]";
giftWithSplits.SearchResults.Add(emptyResult);
}
return PartialView("_ConstitSearch", giftWithSplits);
}
As you can probably tell, I am a beginner in this MVC approach.
Additional thoughts (added later)...
It seems the source of the problem is that the links generated by the WebGrid HTML help for the column headers are based on the URL related to the action method which produced the grid. When the grid is first displayed, the link is: /Batch/Verify/34?sort=FirstName&sortdir=ASC since the grid was build as a part of the entire Verify view (coming out of the Verify action method). But, when one searches for manually-entered search criteria, the grid is build from the SearchConstit action method which populates only a partial view, so the URL in the column header link is now: /Batch/SearchConstit?sort=FirstName&sortdir=ASC.
Also, the "Search" button is associated with a POST because it needs to pass data from the form fields to use as search criteria; whereas, the WebGrid column headers are using a GET, and apparently there is no way to force them to POST. So, the problem seems to boil down to how to pass the search criteria from the form fields without posting the form.
I can think of a possible solution using Session variables, but I'm hesitant to do it that way.
Another option might be to abandon the use of the WebGrid.
Any ideas?
I found your question, when i was searching solution for same problem. I also faced same problem. I have used web grid to display data.
I have used filter/pagination. I used text box for search in grid also.
I am making post call for search. Webgrid was disappearing when i clicked filter and paging button. I google a lot and didn't find any solution. Finally i found solution so thought of posting.
You need to use get ajax call instead of post call that will solve you problem. Do not use beginform post for search.
Index.cshtml is my main view. Here i m rendering partial view (_GridPartialView.cshtml). Index view has one webgrid and search text box.
I am using ajax call to search in webgrid. Ajax code is mention below.
**Index.cshtml:**
#model List<Login>
#{
ViewBag.Title = "User";
}
<h2 style="background-color: grey">User</h2>
<table>
<tr>
<td>
<input type="text" id="txtSearch" placeholder=" Search..." onkeyup="Search()" />
#Html.ActionLink("Create New User", "CreateUser")</td>
</tr>
<tr>
<td>
<div id="divPartialView">
#Html.Partial("~/Views/Shared/_GridPartialView.cshtml", Model)
</div>
</td>
</tr>
</table>
<script type="text/javascript">
function Search() {
var searchVal = $("#txtSearch").val();
$.ajax({
type: "GET",
url: '/User/Search',
data: { searchString: searchVal },
dataType: 'html',
success: function (data) {
$('#divPartialView').html(data);
}
});
}
</script>
_GridUserPArtialView.cshtml: This is partial view used in index view.
#model List<Login>
<script src="../../Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
<style type="text/css">
.webGrid { margin: 4px; border-collapse: collapse; width: 500px; background-color:#FCFCFC;}
.header { background-color: #C1D4E6; font-weight: bold; color: #FFF; }
.webGrid th, .webGrid td { border: 1px solid #C0C0C0; padding: 5px; }
.alt { background-color: #E4E9F5; color: #000; }
.gridHead a:hover {text-decoration:underline;}
.description { width:auto}
.select{background-color: #389DF5}
</style>
#{
var grid = new WebGrid(null, canPage: true, rowsPerPage: 5, selectionFieldName: "selectedRow", ajaxUpdateContainerId: "grid");
grid.Pager(WebGridPagerModes.NextPrevious);
grid.Bind(Model, autoSortAndPage: true, rowCount: Model.Count);}
<div id="grid">
#grid.GetHtml(
tableStyle: "webGrid", mode: WebGridPagerModes.All,
firstText: "<< First",
previousText: "< Prev",
nextText: "Next >",
lastText: "Last >>",
headerStyle: "header",
alternatingRowStyle: "alt",
selectedRowStyle: "select",
columns: grid.Columns(
grid.Column("UserName", "User Name", style: "description"),
grid.Column("FirstName", "First Name"),
grid.Column("LastName", "Last Name"),
grid.Column("Action", format: #<text>
#if (#item.LoginUserName != "administrator"){
#Html.ActionLink("Edit", "Edit", new { id=item.LoginUserName})
#Html.ActionLink("Delete","Delete", new { id = item.LoginUserId},new { onclick = "return confirm('Are you sure you wish to delete this user?');" })
}
</text>, style: "color:Gray;" , canSort: false)
))
</div>
**UserController.cs**: This is Search action method inside. usercontroller. It is HTTPGET.
[HttpGet]
public PartialViewResult Search(string searchString)
{
List<Login> userListCollection = new List<Login_User>();
userListCollection = Login_User_Data.GetAllUsers();
if (Request.IsAjaxRequest())
{
if (!string.IsNullOrEmpty(searchString))
{
Log.Info("UserController: Index() Started");
var searchedlist = (from list in userListCollection
where list.FirstName.IndexOf(searchString,StringComparison.OrdinalIgnoreCase) >=0
|| list.LoginUserName.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0
|| list.LastName.IndexOf(searchString, StringComparison.OrdinalIgnoreCase) >= 0
select list
).ToList();
return PartialView("~/Views/Shared/_GridPartialView.cshtml", searchedlist);
}
else
{
Log.Info("UserController: Search(Login_User user) Ended");
return PartialView("_GridPartialView", userListCollection);
}
}
else
{
return PartialView("_GridPartialView", userListCollection);
}
Log.Info("UserController: Search() Ended");
}
Hope this will help you. Let me know if you have any concern.
From: www.Dotnetmagics.com
The Solution is pretty simple, you need to do a GET, whenever you sort or page the web gird, it will try to get data and hit the a HttpGet Action, this will work as follows:
[HttpGet]
public ActionResult YourActionMethod()
{
return PartialView("YourView",YourModel);
}
The best part is, upon sorting, the request will send a parameter named as "sortBy" too, you can use this here and decide what you want to do with the binded Model with the grid. You can inspect what URL the Sort header will hit by using the "Developer Tools" in your browser.
Note : By default the action method it would be hitting would be same as the controller name.

how to hide/show button on view condition inside mvc view?

i want to hide/show a button on condition but not able to do it inside view.
#{
ViewBag.Title = "Mapping";
WebGrid grid = null;
if (ViewBag.Mappings != null)
{
grid = new WebGrid(source: ViewBag.Mappings,
defaultSort: "Id",
canPage: true,
canSort: true,
rowsPerPage: 10);
}
}
<h3>#ViewData["Message"]</h3>
#if (grid != null)
{
#grid.GetHtml(
tableStyle: "grid",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: grid.Columns(
grid.Column("", header: null, format: #<text>#Html.ActionLink("Edit", "Index", new { uid = (Guid)item.id, userAction = "Edit" }, new { #class = "edit" })
#Html.ActionLink("Delete", "Index", new { uid = (Guid)item.id, userAction = "Delete" }, new { #class = "Delete" })</text>),
grid.Column("PricingSecurityID"),
grid.Column("CUSIP"),
grid.Column("Calculation")
)
)
}
if(#ViewBag.Mappings != null)
{
#Html.ActionLink("Update", "Index", new { userAction = "Update" }, new { #class = "Update" })
}
In the above view if ViewBag.Mappings != null then i'm populating webgrid.
And if webgrid is populated I need to show a Update button under a webgrid, but where i go wrong to achieve this in condition ?
Move the "#" on the 4th line from the bottom:
Before:
if(#ViewBag.Mappings != null)
After:
#if(ViewBag.Mappings != null)

Resources