If condition or for loop in a webgrid - asp.net-mvc-3

I am using this webgrid in my view.
<div class="grid">
#{
var grid = new WebGrid(Model.SearchResults, canPage: true, rowsPerPage: 15);
grid.Pager(WebGridPagerModes.NextPrevious);
#grid.GetHtml(
htmlAttributes: new { #style = "width:100%", cellspacing = "0" },
columns: grid.Columns(
grid.Column(header: "Customer Name", format: (item) => Html.ActionLink((string)item.FullName, "ShowContracts", new { id = item.UserId }, new { #style = "color: 'black'", #onmouseover = "this.style.color='green'", #onmouseout = "this.style.color='black'" })),
grid.Column(header: "SSN", format: item => item.SSN)
))
}
</div>
I search with SSN and display the results in a webgrid. The displayed data is dummy data.
I have a bool AccountVerified in my viewmodel, now I should not give action link to the accounts which are not verified and display text next to them saying account verification pending. Can someone help me on this?

Try the following:
grid.Column(
header: "Customer Name",
format: (item) =>
(bool)item.AccountVerified
? Html.ActionLink(
(string)item.FullName,
"ShowContracts",
new {
id = item.UserId
},
new {
style = "color: 'black'",
onmouseover = "this.style.color='green'",
onmouseout = "this.style.color='black'"
}
)
: Html.Raw("pending")
)
or write a custom HTML helper to avoid this monstrosity and simply:
grid.Column(
header: "Customer Name",
format: item => Html.PendingLink(item)
)

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

Either or Validation in Razor MVC3

I have a razor view with a couple of textboxes.
I want want to make it so that you either choose one of the textboxes or 3 of the others and you can't submit unless you enter in text in at least one of those choices...
IE you could enter in a social security number, or you could enter in a persons first, last names and Date Of Birth. For the last option, you must enter in the first, last name and the DOB. Is this possible using unobtrusive validation?
The following is my parial
<div id="searchByDemographicsDiv"style="float: left;width: 50%; display:inline; ">
#*#using(Html.BeginForm("SearchByDemographic", "SearchPatients",FormMethod.Post, new{ id = "searchByDemographics"})){*#
#using (Ajax.BeginForm("SearchByDemographic", "SearchPatients", null, new AjaxOptions { HttpMethod = "POST", LoadingElementId = Url.Content("~/Images/ajax-loader.gif"), OnSuccess = "binddata", OnFailure = "FailAlert" }, new { id = "searchByDemographics" })){
<ul>
<li>#Html.Label("SSN", new { #for = "SSN" }) <br />#Html.TextBox("SSN", null, new { id = "SSN", name = "SSN", #class = "SSN" })</li>
</ul>
<ul>
<p>Or</p>
</ul>
<ul>
<li>#Html.Label("FirstName", new { #for = "FirstName" }) <br />#Html.TextBox("FirstName", null, new { id = "FirstName", #class = "demoGrphcs", name = "FirstName" })</li>
<li>#Html.Label("LastName", new { #for = "LastName" }) <br />#Html.TextBox("LastName", null, new { id = "LastName", #class = "demoGrphcs", name = "LastName" })</li>
<li>#Html.Label("dateOfBirth", new { #for = "dateOfBirth" }) <br />#Html.TextBox("dateOfBirth", null, new { id = "dateOfBirth", #class = "demoGrphcs", name = "dateOfBirth" })</li>
<li>#Html.Label("Address1", new { #for = "Address1" }) <br />#Html.TextBox("Address1", null, new { id = "Address1" })</li>
<li>#Html.Label("Address2", new { #for = "Address2" }) <br />#Html.TextBox("Address2", null, new { id = "Address2" })</li>
<li>#Html.Label("City", new { #for = "City" }) <br />#Html.TextBox("City", null, new { id = "City" })</li>
<li>#Html.Label("State", new { #for = "State" }) <br />#Html.TextBox("State", null, new { id = "State" })</li>
<li>#Html.Label("Country", new { #for = "Country" }) <br />#Html.TextBox("Country", null, new { id = "Country" })</li>
<li>#Html.Label("PostCode", new { #for = "PostCode" }) <br />#Html.TextBox("PostCode", null, new { id = "PostCode" })</li>
</ul>
<input type="submit" value="Search By Demographics" class="button" id="submitDemo"/>
}
</div>
I essentially want the user to be able to search by either SSN or the other Demographic info with firstName lastName and DateOfBirth being required fields. If searching by SSN, I want that to be a required field. very complicated I know.
UPDATED**origninal validation on my form elements **UPDATE
$("#searchByDemographics").validate({
rules: {
SSN: {
require_from_group: [1, ".SSN"]
},
FirstName: {
require_from_group: [1, ".demoGrphcs"]
},
LastName: {
require_from_group: [1, ".demoGrphcs"]
},
DateOfBirth: {
require_from_group: [1, ".demoGrphcs"]
}
},
messages : {
SSN: 'Please Enter either a valid SSN or Demographic Info below',
FirstName: 'First name is required',
LastName: 'Last name is required',
DateOfBirth: 'Date of Birth is required'
}
});
I think simple way is pass all these value from model and check it on POST , do validation according to your requirement.
I'm not sure why you want to go for unobtrusive validation in this case because the validation is very specific. Unobtrusive validation makes much sense when the validation you are trying to accomplish is kind of reusable but that's not in your case.
I would suggest you to implement IValidatableObject in the model for server-side validation and do the client-side validation using plain jquery.

Razor webgrid sorting not working if grid is loaded using ajax

This is my code
WebGrid passiveAdGrid = new WebGrid(Model.InactiveAds, rowsPerPage: 10, ajaxUpdateContainerId: "passiveAdGrid");
<div >
#passiveAdGrid.Pager(WebGridPagerModes.NextPrevious);
#passiveAdGrid.GetHtml(tableStyle: "webGrid",
headerStyle: "header",
alternatingRowStyle: "alt",
htmlAttributes: new { id = "passiveAdGrid" },
columns: passiveAdGrid.Columns(
passiveAdGrid.Column(format: #<text><img src="#Url.Content("~/Content/images/preview-photo.gif")" alt="Image"/></text>),
passiveAdGrid.Column("Title", "Title", canSort: true),
passiveAdGrid.Column("ExpirationDate", "Date of Expiry", canSort: true),
passiveAdGrid.Column("NumViews", "Number of views", canSort: true),
passiveAdGrid.Column(format: (item) => Html.ActionLink("Activate", "PostAd", "Ads", new { relist = item.Id }, null)),
passiveAdGrid.Column(format: (item) => #Ajax.ActionLink("Remove", "RemoveAd", "Ads", new { adID = item.Id, status = "ActivationPending" }, new AjaxOptions { UpdateTargetId = "AdView", HttpMethod = "POST", OnBegin = "return confirm('Are you sure you wish to delete this Ad?');" }))
));
</div>
its works fine if the above code is executed while page first time loading ...
In my case I am loading this grid using ajax (ie,calling a action in cotroller which return a partial view via ajax and replace that resulting html with existing html)... But sorting is not working anymore after relaoding the grid using ajax

How to Navigate to a view spacifying the view name and controller when i click a row in mvc3 webgrid?

<div style="text-align:center" class="grid">
#{
var grid = new WebGrid(Model.SearchResults, canPage: true, rowsPerPage: 15);
grid.Pager(WebGridPagerModes.NextPrevious);
#grid.GetHtml(headerStyle: "webgrid-header", footerStyle: "webgrid-footer", selectedRowStyle: "webgrid-selected-row", alternatingRowStyle: "webgrid-alternating-row", rowStyle: "webgrid-row-style",
columns: grid.Columns(
grid.Column(header: "Customer Name", style: "text-align-center", format: (item) => Html.ActionLink((string)item.FullName, "ShowContracts", new { id = item.UserId }, new { #style = "color: 'black'", #onmouseover = "this.style.color='green'", #onmouseout = "this.style.color='black'" })),
grid.Column(header: "SSN", style: "text-align-center", format: item => item.SSN)
))
}
</div>
For now I am clicking an item in a row and navigatin to a different page, but i want to click on a row to navigate.
Thanks for any help.

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