How to create a custom Html.ValidationMessage? - asp.net-mvc

This is my Controller:
/// <summary>
/// Activity
/// </summary>
/// <returns></returns>
public ActionResult CreateActivity()
{
AriaCRMEntities aria = new AriaCRMEntities();
var unit = from u in aria.ActivityGroupIDs select u;
List<SelectListItem> lst = new List<SelectListItem>();
foreach (var u in unit)
{
lst.Add(new SelectListItem { Text = u.ActivityGroupName.ToString(), Value = u.ActivityGroupID_FK.ToString() });
}
ViewData["activity"] = lst;
return View();
}
[HttpPost]
public ActionResult CreateActivity(FormCollection model)
{
if (ModelState.IsValid)
{
Activity activ = new Activity();
if (!string.IsNullOrEmpty(model["ActivityGroupID_FK"]))
{
AriaCRMEntities aria = new AriaCRMEntities();
activ.ActivityGroupID_FK = Int32.Parse(model["ActivityGroupID_FK"]);
activ.ActivityType = model["ActivityType"];
activ.ActivityDes = model["ActivityDes"];
aria.Activities.AddObject(activ);
aria.SaveChanges();
return RedirectToAction("Create");
}
}
return View(model);
}
This is my View :
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true,) %>
<fieldset>
<legend>Fields</legend>
<br />
<%:Html.DropDownListFor(model=>model.ActivityGroupID_FK , (IEnumerable<SelectListItem>)ViewData["activity"], "انتخاب نوع فعالیت")%><br />
<%Html.ValidationMessageFor (model=>model.ActivityGroupID_FK,"dddddddddd"); %>
<div class="editor-label">
<%: Html.LabelFor(model => model.ActivityType) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.ActivityType) %>
<%: Html.ValidationMessageFor(model => model.ActivityType,"dfsaaa") %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.ActivityDes) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.ActivityDes) %>
<%: Html.ValidationMessageFor(model => model.ActivityDes) %>
</div>
<p>
<input type="submit" value="Create" id="btn"/>
</p>
</fieldset>
<% } %>
But now I need to validate <%:Html.DropDownListFor%>. How do I create custom validation?

If you want to display a validation error message next to your drop-down list, you can do this from your controller like so:
ModelState.AddModelError("ActivityGroupID_FK", "The selected value is invalid.");
Update
I just noticed the validation message for your DropDownList looks like this:
<%Html.ValidationMessageFor (model=>model.ActivityGroupID_FK,"dddddddddd"); %>
You might want to change that like so:
<%: Html.ValidationMessageFor(model=>model.ActivityGroupID_FK,"dddddddddd") %>

Related

how to bind data to label in asp.net mvc3

I have three model Classes(code first)
ProductGroup(p)->product(c)(list of produGroups comes in drop down list while creating a new product),
Now my requirement is,
Product(p)->PreferedLocation(c),
when I select preferedLocation(Create action) link ,I have to fill the details for the particular product.Means first I need to display single product name in Label like Product:Mango
In controller
public ActionResult PreferedLocation()
{
ViewBag.ProductID = new SelectList(db.Products,"ProductID","Name");
//ViewBag.CountryID = new SelectList(db.Countries, "CountryID", "Name");
return View();
}
//
// POST: /PreferedLocation/Create
[HttpPost]
public ActionResult PreferedLocation(PreferredLocation preferredlocation)
{
if (ModelState.IsValid)
{
db.PreferredLocations.Add(preferredlocation);
db.SaveChanges();
return RedirectToAction("Index");
}
// ViewBag.ProductID = new SelectList(db.Products, "ProductID", "Name", preferredlocation.ProductID);
return View(preferredlocation);
}
In View:
<div class="editor-field">
<%: Html.EditorFor(model => model.Name) %>
<%: Html.ValidationMessageFor(model => model.Name) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.StreetAdress) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.StreetAdress) %>
<%: Html.ValidationMessageFor(model => model.StreetAdress) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Description) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.Description) %>
<%: Html.ValidationMessageFor(model => model.Description) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Latitude) %>
</div>
<div class="editor-field">
<%: Html.EditorFor(model => model.Latitude) %>
<%: Html.ValidationMessageFor(model => model.Latitude) %>
</div>
<div class="display-label">product</div>
<div class="display-field">
<%: Html.LabelFor(model=>Model.Product.Name) %>
<%: Html.ValidationMessageFor(model => model.ProductID) %>
</div>
Here I tried Code for idsplaying product name in label
but instead of product name I got output as
product
Product Name.
What modifications I have to do.
Use DisplayFor instead of LabelFor.

Binding collections in MVC

I have a View Model that consists of an Applicant object and a TeamMember collection. When I post the model back the Team collection is always null. I've tried changing the collection from my original IEnumarable to a List but that didn't make a difference. So I changed the Controllers Edit Action to accept the FormCollection, and verified there was data in viewModel["member.FirstName"]. I'm lost as to why the binding isn't working. I tried to clean out my code samples as much as possible but I'm confused at what I'm missing. Any help is greatly appreciated!
View Model Properties
public class MyViewModel
{
public Applicant ApplicantInfo { get; set; }
public List<TeamMember> TeamMembers { get; set; }
}
Controller
[HttpPost]
public ActionResult Edit(MyViewModel viewModel)
{
// viewModel.ApplicantInfo has the form data
// viewModel.TeamMembers = null
}
View
<% using (Html.BeginForm())
{%>
<h3>
Applicant Information
</h3>
<label>
City
<%: Html.TextBoxFor(m => Model.ApplicantInfo.City)%>
</label>
<label>
State
<%: Html.TextBoxFor(m => Model.ApplicantInfo.State)%>
</label>
<h3>
Team
</h3>
<div>
<% foreach (var member in Model.TeamMembers)
{ %>
<div class="editor-field">
<%: Html.DropDownList("member.Type", Model.GetMemberTypes(member.MemberType.TypeId))%>
</div>
<div class="editor-field">
<%: Html.EditorFor(m => member.FirstName)%>
</div>
<div class="editor-field">
<%: Html.EditorFor(m => member.LastName)%>
</div>
<div class="editor-field">
<%: Html.EditorFor(m => member.Title)%>
</div>
<%} %>
</div>
<p>
<input type="submit" value="Save" />
</p>
<% } %>
I believe that input tags associated with items in a collection (when the model itself is not a collection) need to have an index in the name attribute before you can bind posted data to a view model. Here is the way I usually accomplish this...
<% for (int i=0; i<Model.TeamMembers.Count; i++) { %>
<div class="editor-field">
<%: Html.EditorFor(m => m.TeamMembers[i].FirstName)%>
</div>
<div class="editor-field">
<%: Html.EditorFor(m => m.TeamMembers[i].LastName)%>
</div>
<% } %>
I've also used the template as suggested by Shea, but I have a tad more code trying to force it to render brackets/indexes.
<% foreach (var member in Model.TeamMembers) { %>
<%: Html.EditorFor(x =>
member,
"TeamMember",
"TeamMembers["+(member.Number-1)+"]",
new { MemberTypes = Model.GetMemberTypes(member.MemberType.TypeId) })%>
<% } %>
Here is an old but still relevant article from Phil Haack on the topic.
Try using this:
<%: Html.EditorFor(m => m.TeamMembers) %>
Then, make a shared editor template with a model type of TeamMember. MVC should handle binding everything back to your viewmodel on post for you.

The wrong of two ValidationSummaries gets updated (inside of a partial view)

In my little app I've a strongly typed partial view (the Login Form) this is rendered within the Masterpage, this looks as follows:
<!-- Login Box -->
<div class="login">
<div class="login-bg clearingfix">
<% Html.RenderPartial("LoginViewControl", Model); %>
</div>
</div>
<!-- / Login Box -->
The Model of this partial view is:
using System;
using System.Web;
using System.ComponentModel.DataAnnotations;
using mpws.Util.Validation;
namespace mpws.Models
{
public class LoginViewModel
{
[Required]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
}
}
And the View itself contains a Validationsummary: <%= Html.ValidationSummary() %>
I created another View called SignUp, also this is strongly typed with the type as follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using mpws.Util.Validation;
namespace mpws.Models
{
public class SignUpViewModel
{
[Required]
public string UserName { get; set; }
[Required]
public string Password { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
[Required]
public string EmailAddress { get; set; }
[Required]
public string EmailAddressRepeat { get; set; }
public string Occupation { get; set; }
public string SuggestedBy { get; set; }
public IValidationState validationState { get; set; }
}
}
here my SignUp View:
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<mpws.Models.SignUpViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
SignUp
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2>SignUp</h2>
<div id="SignUpForm">
<% using (Html.BeginForm("SignUp","Account", new mpws.Models.SignUpViewModel())) {%>
<%: Html.ValidationSummary() %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.Resource("Strings, Username") %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.UserName) %>
<%: Html.ValidationMessageFor(model => model.UserName) %>
</div>
<div class="editor-label">
<%: Html.Resource("Strings, Password") %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Password) %>
<%: Html.ValidationMessageFor(model => model.Password) %>
</div>
<div class="editor-label">
<%: Html.Resource("Strings, FirstName") %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FirstName) %>
<%: Html.ValidationMessageFor(model => model.FirstName) %>
</div>
<div class="editor-label">
<%: Html.Resource("Strings, LastName") %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.LastName) %>
<%: Html.ValidationMessageFor(model => model.LastName) %>
</div>
<div class="editor-label">
<%: Html.Resource("Strings, EmailAddress") %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.EmailAddress) %>
<%: Html.ValidationMessageFor(model => model.EmailAddress) %>
</div>
<div class="editor-label">
<%: Html.Resource("RepeatEmailAddress") %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.EmailAddressRepeat) %>
<%: Html.ValidationMessageFor(model => model.EmailAddressRepeat) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Occupation) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Occupation) %>
<%: Html.ValidationMessageFor(model => model.Occupation) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.SuggestedBy) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.SuggestedBy) %>
<%: Html.ValidationMessageFor(model => model.SuggestedBy) %>
</div>
<p>
<button class="button positive" type="submit">
<img alt="" src="<%= ResolveUrl("~/Content/public/ui/button/tick.png") %>" />
<%: Html.Resource("Strings, SignUp") %>
</button>
<button class="button negative" type="reset">
<img alt="" src="<%= ResolveUrl("~/Content/public/ui/button/cross.png") %>" />
<%: Html.Resource("Strings, Cancel") %>
</button>
</p>
</fieldset>
<% } %>
</div>
</asp:Content>
and the login partial View:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<mpws.Models.LoginViewModel>" %>
<!-- This should be outsourced into it own .js fila -->
<script type="text/javascript">
/// <reference path="jquery-1.4.1-vsdoc.js" />
$(document).ready(function () {
$('#LoginForm form').live('submit', function () {
$.post($(this).attr('action'), $(this).serialize(), function (result) {
if ($.isString(result)) {
$("#LoginForm").replaceWith($(result));
}
else if (result["Successfull"]) {
window.location.href = result["RedirectUrl"];
}
else {
alert('Unknown Error...');
}
});
return false;
});
});
jQuery.isString = function (o) {
return (typeof o === "string");
}
</script>
<div id="LoginForm">
<% using (Html.BeginForm("SignIn", "Account"))
{%>
<fieldset>
<legend>Login</legend>
<%if(!ViewContext.ViewData.ModelState.IsValid) {%>
<%= Html.ValidationSummary_jQueyUIfriendly() %>
<%= Html.ValidationSummary() %>
<br />
<%} %>
<div class="editor-label">
<%: Html.Resource("Strings, Username") %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.UserName)%> <br />
<%: Html.ValidationMessageFor(model => model.UserName)%>
</div>
<div class="editor-label">
<%: Html.Resource("Strings, Password") %>
</div>
<div class="editor-field">
<%: Html.PasswordFor(model => model.Password)%><br />
<%: Html.ValidationMessageFor(model => model.Password)%>
</div>
<p>
<button class="button positive" type="submit">
<img alt="" src="<%= ResolveUrl("~/Content/public/ui/button/tick.png") %>" />
<%: Html.Resource("Strings, SignIn") %>
</button>
</p>
</fieldset>
<% } %>
</div>
Well if now someone clicks the "SignUp"-Submitbutton, the validation errors are shown in the validationsummary of the signUp view but also in the validationsummary of the partial view "LoginViewControl"... Any idea why? I thought maybe the Modelstate is globally handeld but if I click the "login"-Submitbutton the validation Messages are only shown in the partial view...
Any idea?
Thanks in advance
Johannes

In MVC, one Edit HttpPost is working, the other one isn't. What am I missing?

Googling generally and on SO hasn't helped me yet, so:
I am building my first MVC application from scratch, going by the MVC Music Store example but instead building a little application where arena Fighters can be created and made to Fight each other. (Fighters and Fight have been made linked to underlying tables through EF).
I have controllers for both the Fighters and the Fights. The Edit Actionresult for Fights is working, but for Fighters it is not. When I hit the button to save my alterations I return to the associated Index page, but no changes have been committed. This is my question: why is this failing?
From BarracksController, with the faulty non-updating HttpPost Edit (should have been named FighterController, but neverthemind):
//
// GET: /Barracks/Edit
public ActionResult Edit(int id)
{
ViewData.Model = _FightDb.Fighters.Single(f => f.Id == id);
return View();
}
//
// POST: /Barracks/Edit
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var fighter = _FightDb.Fighters.Single(f => f.Id == id);
try
{
UpdateModel(fighter, "Fighter");
var x = ViewData.GetModelStateErrors();
_FightDb.SaveChanges();
return RedirectToAction("Index");
}
catch
{
var viewModel = fighter;
return View(viewModel);
}
}
(As you can see, I've included the GetModelStateErrors trick from this SO question, but the result for x is null)
This is the controller that does work, FightController:
//
// GET: /Fights/Edit
public ActionResult Edit(int id)
{
var viewModel = new FightDetailsViewModel
{
Fight = _FightDb.Fights.Single(f => f.ID == id),
Fighters = _FightDb.Fighters.ToList()
};
return View(viewModel);
}
//
// POST: /Fights/Edit
[HttpPost]
public ActionResult Edit(int id, FormCollection collection)
{
var fight = _FightDb.Fights.Single(f => f.ID == id);
try
{
UpdateModel(fight, "Fight");
_FightDb.SaveChanges();
return RedirectToAction("Index");
}
catch
{
var viewModel = new FightDetailsViewModel
{
Fight = _FightDb.Fights.Single(f => f.ID == id),
Fighters = _FightDb.Fighters.ToList()
};
return View(viewModel);
}
}
This is edit.aspx for the Fighters: (Edited after comment)
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Mvc3_EF_BW_Fight.Models.Fighter>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphMain" runat="server">
<h2>Edit</h2>
<%: Html.EditorForModel() %>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
Which uses the following Fighter.ascx in Shared:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Mvc3_EF_BW_Fight.Models.Fighter>" %>
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fighter</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.Id) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Id) %>
<%: Html.ValidationMessageFor(model => model.Id) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FighterName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FighterName) %>
<%: Html.ValidationMessageFor(model => model.FighterName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FighterStyleDescription) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FighterStyleDescription) %>
<%: Html.ValidationMessageFor(model => model.FighterStyleDescription) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FighterLongDescription) %>
</div>
<div class="editor-field">
<%: Html.TextAreaFor(model => model.FighterLongDescription) %>
<%: Html.ValidationMessageFor(model => model.FighterLongDescription) %>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
This is the edit.aspx for Fights
<%# Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<Mvc3_EF_BW_Fight.ViewModels.FightDetailsViewModel>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="cphMain" runat="server">
<h2>Edit</h2>
<%: Html.EditorFor(model => model.Fight, new { Fighters = Model.Fighters })%>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="head" runat="server">
</asp:Content>
And this is the Fight.ascx:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Mvc3_EF_BW_Fight.Models.Fight>" %>
<% using (Html.BeginForm())
{%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend>Fields</legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.ID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.ID) %>
<%: Html.ValidationMessageFor(model => model.ID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FightName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FightName) %>
<%: Html.ValidationMessageFor(model => model.FightName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter1ID) %><br />
<%: Html.LabelFor(model => model.Fighter1Reference.Value.FighterName)%>
</div>
<div class="editor-field">
<%: Html.DropDownList("Fighter1ID", new SelectList(ViewData["Fighters"] as IEnumerable, "ID", "FighterName", Model.Fighter1ID))%>
<%: Html.ValidationMessageFor(model => model.Fighter1ID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter2ID) %>
</div>
<div class="editor-field">
<%: Html.DropDownList("Fighter1ID", new SelectList(ViewData["Fighters"] as IEnumerable, "ID", "FighterName", Model.Fighter1ID))%>
<%: Html.ValidationMessageFor(model => model.Fighter2ID) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter1Login) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Fighter1Login) %>
<%: Html.ValidationMessageFor(model => model.Fighter1Login) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Fighter2Login) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Fighter2Login) %>
<%: Html.ValidationMessageFor(model => model.Fighter2Login) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FightStatusID) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FightStatusID) %>
<%: Html.ValidationMessageFor(model => model.FightStatusID) %>
</div>
<p>
<input type="submit" value="Save" />
</p>
</fieldset>
<% } %>
And this is my viewmodel for Fights:
public class FightDetailsViewModel
{
public Fight Fight { get; set; }
public List<Fighter> Fighters { get; set; }
}
There is no ViewModel for Fighters (none that is involved in this scenario, anyway).
I can post any code you may wish to see.
Edit: I've looked at Using ViewModel Pattern with MVC 2 Strongly Typed HTML Helpers and ASP.NET MVC 2 UpdateModel() is not updating values in memory or database , but i haven't seen a solution there yet.
Instead of this UpdateModel(fighter, "Fighter"); try calling the updte model just like this UpdateModel(fighter);. The difference is between the two edits that in case of Fighter your model is directly the Fighter so you do not need the name, while in case of the Fight you call the Editor for model.Fight so you need the name. See this question as well: asp.net mvc2 - how to get model and model.something in the same way in controller?

Passing parameters to telerik asp.net mvc grid

I have a telerik asp.net mvc grid which needs to be populated based on the search criteria the user enters in separate text boxes. The grid is using ajax method to load itself initially as well as do paging.
How can one pass the search parameters to the grid so that it sends those parameters "every time" it calls the ajax method in response to the user clicking on another page to go to the data on that page?
I read the telerik's user guide but it does not mention this scenario. The only way I have been able to do above is by passing the parameters to the rebind() method on client side using jquery. The issue is that I am not sure if it is the "official" way of passing parameters which will always work even after updates.
I found this method on this post on telerik's site: link text
I have to pass in multiple parameters. The action method in the controller when called by the telerik grid runs the query again based on the search parameters.
Here is a snippet of my code:
$("#searchButton").click(function() {
var grid = $("#Invoices").data('tGrid');
var startSearchDate = $("#StartDatePicker-input").val();
var endSearchDate = $("#EndDatePicker-input").val();
grid.rebind({ startSearchDate: startSearchDate ,
endSearchDate: endSearchDate
});
});
So according to Telerik "recommended approach is to set the arguments in the onDataBinding event".
function onGridBinding(e) {
if (cancelGridBinding) {
// ...
}
else {
var searchValue = 'something';
e.data = { search: searchValue };
}
}
For myself I use ViewModel object that I pass using jQuery and javascript object, my View is stongly typed SearchMemberModel, witch contains my search fields and I have a Textbox for every fields in my view. My databinding is on passing the Model to the controller. Then I build my object in javascript and pass it to my controller in the rebind call.
Here's my code :
View and javascrip
<%# Page Language="C#" MasterPageFile="~/Views/Shared/Admin.Master" Inherits="System.Web.Mvc.ViewPage<Enquete.Models.SearchMemberModel>" %>
<% using (Html.BeginForm()) {%>
<%: Html.ValidationSummary(true) %>
<fieldset>
<legend><%: Resources.Search %></legend>
<div class="editor-label">
<%: Html.LabelFor(model => model.MemberNumber) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.MemberNumber) %>
<%: Html.ValidationMessageFor(model => model.MemberNumber) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Email) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Email) %>
<%: Html.ValidationMessageFor(model => model.Email) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.FirstName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.FirstName) %>
<%: Html.ValidationMessageFor(model => model.FirstName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.LastName) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.LastName) %>
<%: Html.ValidationMessageFor(model => model.LastName) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Phone) %>
</div>
<div class="editor-field">
<%: Html.TextBoxFor(model => model.Phone) %>
<%: Html.ValidationMessageFor(model => model.Phone) %>
</div>
<div class="editor-label">
<%: Html.LabelFor(model => model.Active) %>
</div>
<div class="editor-field">
<%: Html.CheckBoxFor(model => model.Active) %>
<%: Html.ValidationMessageFor(model => model.Active) %>
</div>
<p>
<input type="submit" value="<%: Resources.ToSearch %>" id="btnSearch" />
</p>
</fieldset>
<% } %>
<%= Html.Telerik().Grid<SerializableMember>()
.Name("Grid")
.Columns(colums =>
{
colums.Bound(c => c.Email).Title(Resources.Email);//.ClientTemplate("<a href=\"" + Url.Action(MVC.Admin.Edit()) + "/<#=Id#>\" ><#=Email#></a>");
colums.Bound(c => c.FirstName).Title(Resources.FirstName);
colums.Bound(c => c.LastName).Title(Resources.LastName);
colums.Bound(c => c.MemberNumber).Title(Resources.MemberNumber);
colums.Bound(c => c.Active).Title(Resources.Active).HeaderHtmlAttributes(new { #class = "center-text" }).HtmlAttributes(new { #class = "center-text" }).ClientTemplate("<img src=\"Content/images/icons/<#=Active#>.png\" alt=\"<#=Active#>\" />");
colums.Bound(c => c.Id).Title(" ").HtmlAttributes(new { #class = "center-text" }).ClientTemplate("<a href=\"" + Url.Action(MVC.Member.ResetPassword()) + "/<#=Id#>\" title=\"" + Resources.ResetPassword + "\" >" + Resources.ResetPassword + "</a>");
colums.Bound(c => c.Id).Title(" ").HtmlAttributes(new { #class = "center-text" }).ClientTemplate("<a href=\"" + Url.Action(MVC.Member.Activate()) + "/<#=Id#>\" title=\"" + Resources.Activate + "\" >" + Resources.Activate + "</a>");
colums.Bound(c => c.Id).Title(" ").HtmlAttributes(new { #class = "center-text" }).ClientTemplate("<a href=\"" + Url.Action(MVC.Member.Deactivate()) + "/<#=Id#>\" title=\"" + Resources.Deactivate + "\" >" + Resources.Deactivate + "</a>");
})
//.DataBinding(d => d.Ajax().Select("ListAjax", "Member", Model))
.DataBinding(d => d.Ajax().Select(MVC.Member.ListAjax(Model).GetRouteValueDictionary()))
.Sortable()
.NoRecordsTemplate(Resources.NoData)
%>
<%= Html.AntiForgeryToken() %>
<script type="text/javascript">
$(document).ready(function () {
$('#btnSearch').click(function () {
var grid = $('#Grid').data('tGrid');
var searchModel = {
MemberNumber: $('#MemberNumber').val(),
Email: $('#Email').val(),
FirstName: $('#FirstName').val(),
LastName: $('#LastName').val(),
Phone: $('#Phone').val(),
Active: $('#Active').is(':checked')
};
grid.rebind(searchModel);
return false;
});
});
</script>
<%= Html.Telerik().ScriptRegistrar().jQuery(false).DefaultGroup(g => g.DefaultPath("~/Content/Javascript/2010.3.1110"))%>
And that's my controller
[GridAction]
public virtual ActionResult ListAjax(SearchMemberModel search)
{
var gridModel = new GridModel<SerializableMember>();
var data = _session.All<Member>();
if (search != null)
{
if (search.Active) data = data.Where(x => x.Active);
if (!string.IsNullOrEmpty(search.Email)) data = data.Where(x => x.Email.Contains(search.Email));
if (!string.IsNullOrEmpty(search.FirstName)) data = data.Where(x => x.FirstName.Contains(search.FirstName));
if (!string.IsNullOrEmpty(search.LastName)) data = data.Where(x => x.LastName.Contains(search.LastName));
if (!string.IsNullOrEmpty(search.MemberNumber)) data = data.Where(x => x.MemberNumber.Contains(search.MemberNumber));
if (!string.IsNullOrEmpty(search.Phone)) data = data.Where(x => x.Phone.Contains(search.Phone));
}
var list = new List<SerializableMember>(data.Count());
list.AddRange(data.ToList().Select(obj => new SerializableMember(obj)));
gridModel.Data = list;
return View(gridModel);
}
I can give you my search model class too :
public class SearchMemberModel
{
[LocalizedDisplayName("MemberNumber")]
public string MemberNumber { get; set; }
[LocalizedDisplayName("Email")]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
[LocalizedDisplayName("FirstName")]
public string FirstName { get; set; }
[LocalizedDisplayName("LastName")]
public string LastName { get; set; }
[LocalizedDisplayName("Phone")]
public string Phone { get; set; }
[LocalizedDisplayName("ActiveOnly")]
public bool Active { get; set; }
}
Hope it can helps anyone out there!
This is actually documented here.
<script type="text/javascript">
$(document).ready(function () {
$('#apply').click(function () {
var params = {
showDisabled : $('input[name=ShowDisabled]').attr('checked'),
showExpired : $('input[name=ShowDisabled]').attr('checked')
};
var grid = $('#Grid').data('tGrid');
grid.rebind(params);
});
});
</script>
Here's the controller action bound to your select command:
[GridAction(EnableCustomBinding=true)]
public ActionResult _BindGrid(GridCommand command, string mode, int? id, bool showExpired, bool showDisabled)
{
return View(new GridModel(GetMessageGridItems(command, mode, id, showExpired, showDisabled)));
}
The param 'command' has the sorting and paging information. Note: this solution is for an ajax-ified grid. If you are doing straight-up posts, you can still use the GridCommand command parameter to maintain the state of paging/filtering/sorting.
Give this one a try: Telerik MVC Grid External Filter
It's a jquery plugin which enables you to set the filter by custom input controls.
Here is a much easier way to pass parameters back from your form during the telerix ajax post back.
Simply hook into the global $.ajaxPrefilter event and use jquery to serialize the contents of your from to the URL that is being submitted. This will work with ASP.MVC model binding
<script type="text/javascript">
$.ajaxPrefilter(function (options) {
options.url = options.url + "&" + $("form").serialize();
});
</script>

Resources