Inserting links into a WebGrid - asp.net-mvc-3

I'm looking to create some hyperlinks in a Webgrid. I'd like to have the "User Name" column display it's values as hyperlinks instead of text. Is it possible to incorporate the #Html.ActionLink function into the WebGrid below?
The columnName expects a string which corresponds to a property of the model that is being passed to the view. So the problem is how to get that into a link.
View:
#model IEnumerable<CIMsWebApp.Client.Group.Entities.IUser>
#{ var grid = new WebGrid(Model, canSort: true, canPage: true, defaultSort: "UserName", ajaxUpdateContainerId: "myUserGrid"); }
#grid.GetHtml(
tableStyle: "dataGrid",
headerStyle: "header",
alternatingRowStyle: "evenRow",
columns: grid.Columns
(
grid.Column(header: "User Name", columnName: "UserName", canSort: false),
grid.Column(header: "Role(s)", columnName: "Rolebuilder", canSort: false),
grid.Column(header: "Active", columnName: "ActiveInd", canSort: false),
grid.Column(header: "Action", format:
#<span><input type="button" class="edit-user" id="#item.PersonId" value="EDIT" />
</span>, canSort: false)
)
)

So the problem is how to get that into a link.
You could use the format parameter to provide any custom format you like for this cell (btw you already did this for the last column):
grid.Column(
header: "Subject",
columnName: "UserName",
format: item => Html.ActionLink((string)item.UserName, "SomeAction", new { id = (int)item.PersonId })
)

Related

Pagination on WebGrid deactivates after adding entries

I'm using a WebGrid with pagination in conjunction with an AJAX popup window to add new entries. I've noticed that after I've added an entry the pagination links at the bottom of the WebGrid become inactive.
The popup calls the controller's Save action which finishes with the following:
return PartialView("_PersonGrid", pModel.Persons);
There are three views that are used here. An index, a grid and a popup. The grid is embedded in the index and the popup can be called by clicking on buttons on the grid and index.
The index view has the following code:
#using (Ajax.BeginForm(new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "myUserGrid" }))
{
<div id="myUserGrid">
#Html.Partial("_PersonGrid", Model.Persons)
</div>
<br />
//other code
}
The grid view (_PersonGrid.cshtml) is:
#model IEnumerable<CIMsWebApp.Client.Group.Entities.IPerson>
#{ var grid = new WebGrid(Model, canSort: true, canPage: true, defaultSort: "UserName", ajaxUpdateContainerId: "myUserGrid"); }
#grid.GetHtml(
tableStyle: "dataGrid",
headerStyle: "header",
alternatingRowStyle: "evenRow",
columns: grid.Columns
(
grid.Column(header: "User Name", columnName: "UserName", format: item => Html.Raw("<a href='#' class='userNames' data-personid='"+item.PersonId+"'>" + item.UserName + "</a>"), canSort: false),
grid.Column(header: "Role(s)", columnName: "Rolebuilder", canSort: false),
grid.Column(header: "Active", columnName: "ActiveIndBuilder", canSort: false),
grid.Column(header: "Action", format:
#<span><input type="button" class="edit-user" id="#item.PersonId" value="EDIT" />
</span>, canSort: false)
)
)
finally the popup view is:
#model CIMsWebApp.Models.PersonModel
#using (Html.BeginForm("Save", "Person", FormMethod.Post, new { id = "formUser" }))
{
//code
}
When I first arrive at the page or If I refresh it they become active again.
I'm guessing your "ajaxUpdateContainerId: "myUserGrid"" is a div with an id="myUserGrid" and the partial is loaded in there.. So correct me if I'm wrong but I believe that div should be in your partial. It's a bit confusing sometimes but you should try this out..
View:
#*Everything else except the div*#
#{Html.RenderPartial("_PersonGrid", Model)
PartialView:
#model IEnumerable<CIMsWebApp.Client.Group.Entities.IPerson>
<div id="myUserGrid">
#{ var grid = new WebGrid(Model, canSort: true, canPage: true, defaultSort: "UserName", ajaxUpdateContainerId: "myUserGrid"); }
#grid.GetHtml(
tableStyle: "dataGrid",
headerStyle: "header",
alternatingRowStyle: "evenRow",
columns: grid.Columns
(
grid.Column(header: "User Name", columnName: "UserName", format: item => Html.Raw("<a href='#' class='userNames' data-personid='"+item.PersonId+"'>" + item.UserName + "</a>"), canSort: false),
grid.Column(header: "Role(s)", columnName: "Rolebuilder", canSort: false),
grid.Column(header: "Active", columnName: "ActiveIndBuilder", canSort: false),
grid.Column(header: "Action", format:
#<span><input type="button" class="edit-user" id="#item.PersonId" value="EDIT" />
</span>, canSort: false)
)
)
</div>
If this doesn't work, give some additional data (the view in which you call the partial, where and how you call the save action, etc...)
After looking into how the WebGrid pagination actually works it seems that after carrying out a save it then tries to call a GET method on the Save method. So I created a method for this very purpose and then redirected it back to the Index method. The final two parameters get passed directly to the query string which are then used in the pagination.
[ActionName("Save")]
public ActionResult Pagination(string page, string __, long id = 0)
{
return RedirectToAction("Index", new {id = id, page=page, __ = __ });
}

How to include links at the end of a row in a WebGrid?

I am trying to display data in an MVC3 application that shows data from a database. Originally I hacked together a solution using tables which can be seen here: .
I later updated my view so as to use a Webgrid instead:
I would like to include the Edit and Delete links from my first effort into the Webgrid solution. Does anyone know how I can do this (I could make some of the entries in the webgrid into links-this would be suitable for the edit option but not for the delete)
Current View code:
#model IEnumerable
#{
ViewBag.Title = "DisplayMembers";
}
DisplayMembers
#{ var grid = new WebGrid(Model, canSort: false, canPage: true, defaultSort: "UserRoleId"); }
#grid.GetHtml(
tableStyle: "dataGrid",
headerStyle: "header",
alternatingRowStyle: "evenRow",
columns: grid.Columns
(
grid.Column(header: "User Role ID", columnName: "UserRoleId"),
grid.Column(header: "UserName", columnName: "UserName"),
grid.Column(header: "Role ", columnName: "Role"),
grid.Column(header: "Active", columnName: "ActiveInd")
))
this should help
grid.Column(header: "Edit", format: #<text>#Html.ActionLink("Edit", "EditAction", "ControllerName", new{#userRoleId=#item.UserRoleId})</text>),
grid.Column(header: "Delete", format: #<text>#Html.ActionLink("Delete", "DeleteAction", "ControllerName", new { #userRoleId= #item.UserRoleId})</text>)
I solved it be using an HTML.Actionlink as follows:
grid.Column(columnName: "Select", header: "",
format:#<text>#Html.ActionLink("Select", "Create", new {item.Name},null) </text>)

I want to call loader image when I click sorting and paging for MVC webgrid?

I create a div and tried calling Jquery like loader.show(). But not sure how to trigger it when I page or sort the mvc webgrid?
My web grid:
<div id="grid">
#{
var grid = new WebGrid<MemberSearch>(ajaxUpdateContainerId: "grid",
rowsPerPage: Model.PageSize, defaultSort: "LastName");
grid.Bind(Model.Member, rowCount: Model.TotalRows, autoSortAndPage: false);
// NOTE: I've created another html helper to allow a server-paged grid to be rendered in one call (complete with compiler type inference) as shown below
//var grid = Html.ServerPagedGrid(Model.Products, Model.TotalRows, rowsPerPage: Model.PageSize);
}
#grid.GetHtml(tableStyle: "webgrid",
headerStyle: "webgrid-header",
footerStyle: "w-footer",
alternatingRowStyle: "webgrid-alternating-rows",
columns: grid.Columns(
grid.Column(format: #<text>#Html.ActionLink("Edit", "Edit", new { Id = item.Id }) </text>),
grid.Column("fullname", header: "Name", format: #<text>#item.fullname</text>),
grid.Column("Email", header: "Email", format: #<text>#item.Email</text>),
grid.Column("companyname", header: "Company", format: #<text>#item.companyname</text>),
grid.Column("regDate", header: "Registration Date", format: #<text>#item.regDate</text>),
grid.Column("country", header: "Country", format: #<text>#item.country</text>),
grid.Column("modifiedDate", header: "Profile Modified", format: #<text>#item.modifiedDate</text>),
grid.Column("ciscontactid", header: "CIS ID", format: #<text>#item.ciscontactid</text>)
)
)
</div>
In your document.ready add the following:
$('thead > tr > th > a[href$="sort"]').click(function () {
loader.show()
});
This will select the th tags and the a tags that the WebGrid getHtml generates for you. This will handle when the grid is sorted.

How to display dynamic Html.ActionLink label?

This code works, but displays "Details" for every row of my table:
#appsGrid.GetHtml(
tableStyle: "table",
headerStyle: "head",
alternatingRowStyle: "alt",
columns: appsGrid.Columns(
appsGrid.Column(columnName: "Code",
header: "",
format: (item) => Html.ActionLink("Details",
"Index",
"ApplicationTechStack",
new {Code = item.Code},
null
),
However, when I try to change the line to format: (item) => Html.ActionLink(item.Code, it gives me error. How come? item is of class that has Code property, as visible in other parts - returns routing values just fine...
What needs to be done to display the hyperlink text dynamically? Oh, I'm on MVC 3.
Try this. Displaytext is your dynamic value.
`columns: appsGrid.Columns(
appsGrid.Column(columnName: "Code",
header: "",
format: (item) => Html.ActionLink((string)item.DisplayText,
"Index",
"ApplicationTechStack",
new {Code = item.Code},
null),

Razor WebGrid doesn't keep scrollbar position

Whenever I page or sort my ajax enabled webgrid, my scrollbar position is reset to the top of the page. Is there a way to maintain the scrollbar position?
#model Registrar.WebUI.Models.InstructorPageViewModel
#{
var grid = new WebGrid(canPage: true,
canSort: true,
rowsPerPage: Model.PagingInfo.ItemsPerPage,
ajaxUpdateContainerId: "grid");
grid.Bind(Model.Instructors, rowCount:Model.PagingInfo.TotalItems, autoSortAndPage:false);
grid.Pager(WebGridPagerModes.All);
}
<div id="grid">
#grid.GetHtml(columns: grid.Columns(
grid.Column(format: x => Html.ActionLink("Edit", "Edit", new {id=x.Id})),
grid.Column("FirstName", "First Name"),
grid.Column("LastName", "Last Name"),
grid.Column("Email"),
grid.Column("UserName", "User Name"),
grid.Column("Phone") )
)
</div>
This is because generated sort link in your header has href="#". I've got the same problem and this is my solution.
This is my _grid.cshtml partial view
#{
var grid = new WebGrid(Model.LeaseOffers, canPage: false, ajaxUpdateContainerId: "offerGrid", ajaxUpdateCallback: "afterLoad()");
}
<div id="offerGrid" class="offer-table-wrapper">
#grid.GetHtml(
rowStyle: "offer-table-tr-odd",
alternatingRowStyle: "offer-table-tr-even",
columns: grid.Columns(
grid.Column("ProviderLogo", "", format: #<img src="#Url.Content(string.Format(Constants.LeaseOfferProviderLogoContentUrlFormat, item.ProviderId))" />, style: "col-first", canSort: false),
grid.Column("ProviderName", "Leasingodawca", format: #<div>#item.ProviderName</div>, style: "col-name"),
grid.Column("DownPayment", "Udział Własny", format: #<div>#item.DownPayment.ToString(Constants.PercentDataToStringFormat)</div>, style: "col-third"),
grid.Column("LeasePeriod", "Okres leasingu", format: #<div>#string.Format(Constants.LeasePeriodDataFormat, item.LeasePeriod)</div>),
grid.Column("LeasePayment", "Rata leasingu", format: #<div>#string.Format(Constants.MoneyDataFormat, item.LeasePayment)</div>),
grid.Column("ResidualValue", "Wartość wykupu", format: #<div>#item.ResidualValue.ToString(Constants.PercentDataToStringFormat)</div>),
grid.Column("TotalLeasePayments", "Suma opłat", format: #<div>#item.TotalLeasePayments.ToString(Constants.PercentDataToStringFormat)</div>),
grid.Column("Actions", "", format: #<div><img src="#Href("~/Modules/LeaseBroker.Orchard.Module/Content/Images/Mockups/wezleasing.png")"/></div>, style: "col-last", canSort: false)
),
htmlAttributes: new { cellpadding = "0", cellspacing = "0" }
)
<script language="javascript">
function afterLoad() {
$("#offerGrid > table > thead > tr > th > a").attr('href', 'javascript:void(0)');
}
jQuery(document).ready(function ($) {
afterLoad();
});
</script>
Just after grid is loading i'm replacing all href attributes in header links into "javascript:void(0)"
You need to make sure that autopostback is disabled, It sounds like your page is redirecting, you just may not be noticing as it is happening so fast.

Resources