Many of the properties on my model need to be represented a simple group of Yes/No radio buttons. I need to check the corresponding radio button for pre-entered values. I went with a partial. Here's what I did:
RadioButtonsYesNo.ascx
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<KeyValuePair<string,string>>" %>
<div id="<%:Model.Key %>">
<%: Html.ValidationMessage(Model.Key)%>
<ul class='RadioButtonsYesNo'><li>
<%: Html.RadioButton(Model.Key, "Yes", Model.Value == "Yes", new { id = Model.Key + "_Yes" })%>
<label for='<%: Model.Key %>_Yes'>Yes</label>
</li><li>
<%: Html.RadioButton(Model.Key, "No", Model.Value == "No", new { id = Model.Key + "_No" })%>
<label for='<%: Model.Key %>_No'>No</label>
</li></ul>
</div>
Usage
<% Html.RenderPartial("RadioButtonsYesNo", new KeyValuePair<string, string> ("MyProp",Model.MyProp)); %>
Is there a best practice for passing in the property of interest and having RadioButtonFor render correctly?
Thanks.
Or in Razor:
#{
var yesRadioName = Model.Key + "_Yes";
var noRadioName = Model.Key + "_No";
#Html.RadioButtonFor(m => m.Key, true, new { #id = yesRadioName })
#Html.Label(yesRadioName , "Yes")
#Html.RadioButtonFor(m => m.Key, false, new { #id = noRadioName })
#Html.Label(noRadioName, "No")
}
Why not using RadioButtonFor in an editor template:
<%# Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<% string name = ViewData.TemplateInfo.GetFullHtmlFieldId(""); %>
<div id="<%: name %>">
<%: Html.ValidationMessageFor(x => x) %>
<ul class="RadioButtonsYesNo">
<li>
<%: Html.RadioButtonFor(x => x, "Yes", new { id = name + "_Yes" }) %>
<label for="<%: name %>_Yes">Yes</label>
</li>
<li>
<%: Html.RadioButtonFor(x => x, "No", new { id = name + "_No" }) %>
<label for="<%: name %>_No">No</label>
</li>
</ul>
</div>
And then:
<%: Html.EditorFor(x => x.MyProp) %>
Related
I have a page which has 'n' number of panels and each panel need to be rendered based on certain condition and then the panel content as well rendered based on condition.
The page design can be shown below.
http://www.imageupload.co.uk/images/2014/08/08/PanelArrangment.png
I have to add too much of if statement which makes my code ugly.
<div class="panel-body clearfix">
<% if (/* some condtion */)
{ %>
<divclass="PanelGroup clearfix">
<label>
Name
</label>
<div class="field_area">
<%=Html.ComplexComponent()%>
</div>
</div>
<% }%>
<label>
Duration
</label>
<% if (/* some condtion */)
<div class="PanelGroup clearfix">
<label>
Time
</label>
<div class="field_area">
<%=Html.TextBox("Time", "", new { autocomplete = "off", maxlength =10, #class = "small" })%>
</div>
</adiv>
<% if (/* some condtion */)
<div class="PanelGroup clearfix">
<label>
DurationId
</label>
<div class="field_area">
<%=Html.TextBox("DurationId", "", new { autocomplete = "off", maxlength =10, #class = "small" })%>
</div>
</div>
<% }%>
After some changes I managed to reduce the condition by moving some of them to html helpers and below is my current code.
<%
using (Html.Panel())
{
using (var row = Html.PanelRow("Name"))
{
if(row.canShow) {
<%=Html.ComplexComponent()%>
}
}
%>
<label>
Panel
</label>
<%
using (var row = Html.PanelRow("Time"))
{
if(row.canShow) {
%>
<%=Html.TextBox("Time", "", new { autocomplete = "off", maxlength =10, #class = "small" })%>
<%
}}
using (var row = Html.PanelRow("Duration"))
{
if(row.canShow) {
%>
<%=Html.TextBox("Duration", "", new { autocomplete = "off", maxlength =10, #class = "small" })%>
<%
}}
}
%>
I am just wondering is there any better way than this to make my code better?
I am using ASP.Net MVC 3.0 with web forms and not possible to use Razor view.
I want to retrieve data from database and show in dropdown. I used Model so i can take from model also. But it is not correctly retrieve. If In database 4 entries means it shows 4 dropdowns buttons but inside the dropdown there is no values. Can anyone help me out this problem?
My code in view
<div class="editor-label">
<%: Html.Label("Basic Qualification")%>
</div>
<div class="editor-field">
<div id="basic-qualification-container1" style="margin-bottom:4px;" class="basic-qualification-container left">
<% if (ViewData["BasicQualificationDegrees"]!=null){ %>
<% for (int i=0; i < Model.CandidateQualifications.Count();i++) {%>
<%: Html.DropDownList("BasicQualificationDegree1", new SelectList((IEnumerable<Dial4Jobz.Models.Degree>)ViewData["CandidateBasicQualifications"], "Id", "Name", (IEnumerable<int>)ViewData["BasicQualificationDegrees"]), new { #class = "qualification" })%>
<%: Html.TextBox("BasicQualificationSpecialization1", "", new { #title = "Enter basic qualification degree", #class="specialization" })%>
<%} %>
<%} else { %>
<select id="BasicQualificationDegree1" name="BasicQualificationDegrees"></select>
<%} %>
</div>
<div class="left">
<input type="button" id="btnAddBasicQualification" value="Add" />
<input type="button" id="btnDelBasicQualification" value="Remove" />
</div>
</div>
As per your question,
<% for (int i=0; i < Model.CandidateQualifications.Count();i++) {%>
what is this? why did you count the viewdata?
Code
<% if (ViewData["BasicQualificationDegrees"]!=null){ %>
<% var containerId = "basic-qualification-container" + i.ToString(); %>
<div id="<%: containerId %>" style="margin-bottom:4px;" class="basic-qualification-container left">
<%: Html.DropDownList("BasicQualificationDegree" + i.ToString(), new SelectList((IEnumerable<Dial4Jobz.Models.Degree>)ViewData["CandidateBasicQualifications"], "Id", "Name", basicQualifications.ElementAt(i-1).DegreeId), new { #class = "qualification" })%>
<%: Html.TextBox("BasicQualificationSpecialization" + i.ToString(), basicQualifications.ElementAt(i-1).Specialization, new { #title = "Enter basic qualification degree", #class = "specialization" })%>
</div>
<% } %>
<% } else { %>
<div id="basic-qualification-container1" style="margin-bottom:4px;" class="basic-qualification-container left">
<%: Html.DropDownList("BasicQualificationDegree1", new SelectList((IEnumerable<Dial4Jobz.Models.Degree>)ViewData["CandidateBasicQualifications"], "Id", "Name"), new { #class = "qualification" })%>
<%: Html.TextBox("BasicQualificationSpecialization1", "", new { #title = "Enter basic qualification degree", #class = "specialization" })%>
</div>
Hope It helps!.
I have 2 or more forms with different one hidden value like:
<div class="comment-body">
<% using (Html.BeginForm(Model.ActionName, "Home", Model.RouteValues, FormMethod.Post, new { id = "FormAddComment", name = "FormAddComment" }))
{ %>
<% = Html.ValidationSummary(false) %>
<fieldset>
<% if (Model.CommentParentID != null)
{
htmlAttributes = new { placeholder = "Add a reply...", id = "Comment" };
postButtonTitle = "Post Reply";
%>
<input type="hidden" name="CommentParentID" id="CommentParentID" value="<% = Model.CommentParentID.ToString() %>" />
<%} %>
<% = Html.TextAreaFor(model => model.Comment, htmlAttributes)%>
<% = Html.ValidationMessageFor(model=>model.Comment) %>
<input type="submit" value="<% = postButtonTitle %>" class="small blue awesome noborder"
border="0" />
<% if (Model.CommentParentID != null)
{%>
<a class="hide-sub-comment" href="javascript:void(0);">Cancel</a>
<%} %>
</fieldset>
<%} %>
</div>
Problem is when I try to validate entered value I got the validator message twice. When I add text and click "post" again - one validator is hidden, but page is not valid yet. Why and how to solve it?
Thanks
Modifying answer since you changed the question.
You could do something like this
<script type="text/javascript">
$(document).ready(function () {
$("#NotHiddenComment").change(function () {
var temp = $("#NotHiddenComment").val();
$("#HiddenCommentID").text(temp);
});
});
</script>
This will make sure both fields have the same value so you do not get validation errors.
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") %>
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>