MVC3 WebGrid - #Url.Action using image button - asp.net-mvc-3

I got a problem that actually I do not yet solved. For some reasons I had a request to replace the text used in Html.ActionLink with a more visual design using images as button inside a WebGrid for the usuale operations like modify, duplicate, publish and delete.
Reading I have tried many ways but none led me to the final stage:
#{
var grid = new WebGrid(Model, new List<string>(), canPage: true, rowsPerPage: 5);
grid.Pager(WebGridPagerModes.NextPrevious);
#grid.GetHtml(tableStyle: "webGrid",
htmlAttributes: new { id = "DataTable" },
headerStyle: "header",
alternatingRowStyle: "alt",
columns:
grid.Columns(
grid.Column("Description", header: "Description"),
grid.Column("DateCreation", header: "Creation Date"),
grid.Column("CompanyOwner", header: "Company"),
grid.Column("Owner", header: "User"),
grid.Column("Status", header: "Status"),
grid.Column("Action", header: "Action",
format: (item) => #Url.Action("publish",
"PublishItem",
new { id = item.ID })))
);
}
To do that I start with a model created with a linq to entities where I added the column Action, the one that I want to use to place my buttons. How do I place the images to work as buttons as I done in a normal table:
<a href="#Url.Action("PublishPill", new { id = item.ID })">
<img src="../../Images/world_32px.png", alt="Edit" title="Publish" border="0" /></a>

You can use
grid.Column(header: "Contraseña", format: #<text><a href="#Url.Action("ChangePassword", "Home", new { id = item.Identification })" ><img src="../../Content/images/password.png" alt="" style="border:none;" /></a></text>, style: "colOperation")

Related

Mvc3 webgrid paging and sorting not working?

I have a webgrid which is populated with data from database, and im providing edit and delete functionality with edit functionality in popup...Im facing few issues in this
The first issue is I enabled paging and sorting and both are not working, the second issue is when the user clicks the Edit button a popup fires and user Edits the data and submits it and the changes are made to database but the grid is still holding the original data..
posting my sample code
<div id="grid">
#grid.GetHtml(
tableStyle: "gridTable",
headerStyle: "gridHead",
footerStyle: "gridFooter",
rowStyle: "gridRow",
alternatingRowStyle: "gridAltRow",
columns:grid.Columns(
grid.Column("FirstName", "First Name", style: "colFirstName"),
grid.Column("LastName", "LastName", style: "colLastName"),
grid.Column("Country", "Country", style: "colEmail"),
grid.Column(header:"Edit",format:#<text>#Html.ActionLink("Edit", "EditDetails", new { id = item.Id }, new { #class = "editLink" })</text>,style: "colOperation"),
grid.Column(header: "Delete", format: #<text><img src="../../Content/images/delete.png" alt="" style="border:none;" /></text>, style: "colOperation")),
mode: WebGridPagerModes.Numeric)
</div>

MVC 3 Razor pass webgrid row data to controller using actionlink

I have a webgrid with an actionlink which I want to use to edit the selected row in a new view. I know that I can use an actionlink to supply an arguement to my actionresult method but I don't know how to pass the webgrid's row data to my controller apart from using actionlink.
#{
ViewBag.Title = "Index";
}
<h2>
Index</h2>
<p>
#Html.ActionLink("Create New User", "CreateUser")
</p>
<div class="webgrid-wrapper">
#model IEnumerable<UserManager.Models.vw_UserManager_Model_Add_Users>
#{
ViewBag.Title = "Jobs";
WebGrid grid = new WebGrid(Model, canPage: true, canSort: true, rowsPerPage: 15, selectionFieldName: "selectedRow", fieldNamePrefix: "gridItem");
}
#grid.GetHtml(
fillEmptyRows: true,
tableStyle: "webgrid",
alternatingRowStyle: "webgrid-alternating-row",
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
selectedRowStyle: "webgrid-selected-row",
rowStyle: "webgrid-row-style",
mode: WebGridPagerModes.All,
columns: new[] {
//grid.Column("ApplicationId"),
//grid.Column("salutation"),
//grid.Column("PasswordSalt"),
grid.Column("FirstName"),
//grid.Column("LoweredEmail"),
//grid.Column("PasswordQuestion"),
//grid.Column("PasswordAnswer"),
// grid.Column("PasswordFormat"),
grid.Column("LastName"),
grid.Column("Password"),
grid.Column("isactive"),
//grid.Column("IsLockedOut"),
grid.Column("email"),
grid.Column("module_name"),
//grid.Column("LastLoginDate"),
//grid.Column("LastPasswordChangedDate"),
//grid.Column("LastLockoutDate"),
//grid.Column("FailedPasswordAttemptCount"),
//grid.Column("FailedPasswordAttemptWindowStart"),
//grid.Column("FailedPasswordAnswerAttemptCount"),
//grid.Column("FailedPasswordAnswerAttemptWindowStart"),
// Rest of grid columns, seen previously
#*grid.Column(
"",
header: "Actions",
format: #<text>
#Html.ActionLink("Edit", "Edit", new { id = item.email })
</text>
) ,
grid.Column(
"",
header: "Actions",
format: #<text>
#Html.ActionLink("Delete", "Delete", new { id = item.email })
</text>
) *#
#* grid.Column(
header:"",
format:#<text><div id="btnSelectedRow">
"#item.GetSelectLink("Edit")</div></text>
),*#
grid.Column(
header:"",
format:#<text><div id="btnSelectedRow">
"#Html.ActionLink("Edit record",
"EditUser",
"UserManager",
new {selectedRow = grid.SelectedRow },
null
)</div></text>
)
})
#if (grid.HasSelection)
{
var record = grid.SelectedRow;
#*#RenderPage("~/Views/UserManager/EditUser.cshtml", new { record = grid.SelectedRow })*#
}
</div>
<script type="text/javascript">
$(document).ready(function () {
function jQueryUIStyling() {
$('input:button, input:submit').button();
// Style tables.
$('.webgrid-wrapper').addClass('ui-grid ui-widget ui-widget-content ui-corner-all');
$('.webgrid-title').addClass('ui-grid-header ui-widget-header ui-corner-top');
jQueryTableStyling();
}
//
// Style tables using jQuery UI theme. This function is
// split out separately so that it can be part of the AJAX
// callback of the WebGrid WebHelper in ASP.NET MVC.
//
function jQueryTableStyling() {
$('.webgrid').addClass('ui-grid-content ui-widget-content');
$('.webgrid-header').addClass('ui-state-default');
$('.webgrid-footer').addClass('ui-grid-footer ui-widget-header ui-corner-bottom ui-helper-clearfix');
}
});
</script>
My controller
public ActionResult EditUser(System.Web.Helpers.WebGrid record)
{
record.ToString();
return View();
}
Summary
How to pass row data using ActionLink from one view to another via ActionResult method.
You have two options, really: have your action take the user Id and look the user up, or have each row of your grid contain a form which sends all the user details to the action when you click 'edit'. Which of those you choose depends on what your action is supposed to do:
If it redirects to a form where the user can edit the user they selected, use the first approach
If it takes all the user details and saves an updated user, use the second approach
Edit
To pass the id you can use this for the action link:
#Html.ActionLink(
"Edit record",
"EditUser",
"UserManager",
new { id = item.email })
...and this for the action signature:
public ActionResult EditUser(string id)

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, __ = __ });
}

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.

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