In my form I have:
#Html.LabelFor(m => m.Name)
#Html.ValidationMessageFor(m => m.Name)
#Html.TextBoxFor(m => m.Name, new { #class = "", placeholder = "Full Name" })
Q: How to check if field is valid and add a class to the LabelFor if it's specific field is not valid?
#Html.LabelFor(m => m.Name, if !valid: new { #class="error"} )
You're along the right lines but try this:
#Html.LabelFor(m => m.Name, new { #class= !ViewData.ModelState.IsValid ? "error" : ""} )
Using a ternary statement should work in this scenario as I use them myself on a frequent basis in normal DIV and INPUT HTML.
Edit: After chatting with Alex for a while in the StackOverflow chat system, this is the final working solution I came up with. Unfortunately, Alex is using Unobstrusive JQuery so the below code will only work if client side validation is not added.
#{
var errorCollection = new ModelErrorCollection();
if (ViewData.ModelState.Any(a => a.Value.Errors.Count > 0)) {
errorCollection = ViewData.ModelState["PropertyName"].Errors;
}
}
#Html.LabelFor(m => m.PropertyName, null, new { #class =
errorCollection.Any() ? "cssClassName" : "" })
Related
How can I change the password box to disabled.
#Html.Editor("password")
something like
Html.TextBoxFor(model => model.User, new {disabled = "disabled"})
You're close. You have to prefix your attributes with #:
Html.TextBoxFor(model => model.User, new { #disabled = "disabled" })
You can read only text box using Html Attributes
#Html.TextBoxFor(model => model.User, new { #readonly="readonly",
style = "width:80%;" })
Strange thing.
My Grid seems and work correct, only untypical thing is that input during editing has:
class="text-box single-line"
instead of
class="k-textbox k-input"
Also in case when grid is completly same like in demo.
I dont know how it can happens. Copy of whole view - without some js :
#model IEnumerable<TranslationModel>
#{
ViewBag.Title = "Translations";
Layout = "~/Views/Shared/_PrivateLayout.cshtml";
Html.EnableClientValidation();
}
<h2>Translations</h2>
#(Html.Kendo().Grid<TranslationModel>(Model)
.Name("grid")
.Columns(columns =>
{
columns.Bound(e => e.Shortcut).Width(150);
columns.Bound(e => e.LanguageName).Width(100);
columns.Bound(e => e.Content);
columns.Command(command => { command.Custom("ExtraPopUpEdit").Click("ExtraPopUpEdit").Text("..."); }).Width(100);
})
.ToolBar(toolbar => {
toolbar.Save();
})
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable((p => p.PageSizes(new[] { 5 , 10, 20, 50, 100 })))
.Sortable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.Batch(true)
.ServerOperation(true)
.PageSize(10)
.Events(events => events.Error("error_handler"))
.Aggregates(a =>
{
a.Add(e => e.Content.Equals(string.Empty)).Count();
}
)
.Model(model =>
{
model.Id(e => e.Id);
model.Field(e => e.Shortcut).Editable(false);
model.Field(e => e.LanguageName).Editable(false);
})
.Group(g => g.Add(e => e.Shortcut))
.Read(read => read.Action("Translations_Read", "Admin"))
.Update(update => update.Action("Translations_Update", "Admin"))
)
)
Those classes are rendered by ASP.NET MVC when Html.EditorFor is used. If you want to remove them you have to use editor templates.
I assume you have already figured this out on your own, but for future reference for anyone else, like me, who has this problem. The solution I found is - along the lines of what Atanas said - to just copy the EditorTemplates folder from Kendo's distribution into your project. They have templates for 12 different types (in both ascx and cshtml).
The directory I copied is within the Kendo download, in \wrappers\aspnetmvc\Examples\VS2013\Kendo.Mvc.Examples\Views\Shared\EditorTemplates. Copy that into your ~/Views/Shared, delete either the *.ascx or *.cshtml files depending on your needs, and you're good to go!
I've overridden the default editor template (Object.ascx) to produce form (body) HTML that follows to Twitter Bootstrap's guidelines (http://twitter.github.io/bootstrap/base-css.html#forms) which is executed via Html.EditorForModel().
#if (ViewData.TemplateInfo.TemplateDepth > 1)
{
#(Model == null ? ViewData.ModelMetadata.NullDisplayText : ViewData.ModelMetadata.SimpleDisplayText)
}
else
{
foreach (var property in ViewData.ModelMetadata.Properties.Where(m => m.ShowForEdit #*&& m.ModelType != typeof (System.Data.EntityState)*# && !m.IsComplexType && !ViewData.TemplateInfo.Visited(m)))
{
if (property.HideSurroundingHtml)
{
#Html.Editor(property.PropertyName)
}
else
{
<div class="control-group #(!ViewData.ModelState.IsValidField(property.PropertyName) ? "error" : ViewData.ModelState.ContainsKey(property.PropertyName) ? "success" : "" )">
#if (!string.IsNullOrEmpty(Html.Label(property.PropertyName).ToHtmlString()))
{
#Html.Label(property.GetDisplayName() + (property.IsRequired ? " *" : ""), new { #class = "control-label" })
}
<div class="controls">
#Html.Editor(property.PropertyName)
#Html.ValidationMessage(property.PropertyName, "*", new { #class = "help-inline" })
</div>
</div>
}
}
}
This works well unless I want to tweak the form (e.g. change the ordering or add fieldsets). I basically want to separate part of the above code into another editor template, which resulted in Property.ascx. This will render a label, input and validation message for a given property, executed via Html.Editor("{PropertyName"}) or Html.EditorFor(m => m.{PropertyName}).
<div class="control-group #(!ViewData.ModelState.IsValidField(ViewData.ModelMetadata.PropertyName) ? "error" : ViewData.ModelState.ContainsKey(ViewData.ModelMetadata.PropertyName) ? "success" : "" )">
#if (!string.IsNullOrEmpty(Html.Label(ViewData.ModelMetadata.PropertyName).ToHtmlString()))
{
#Html.Label(ViewData.ModelMetadata.GetDisplayName() + (ViewData.ModelMetadata.IsRequired ? " *" : ""), new { #class = "control-label" })
}
<div class="controls">
#Html.Editor(ViewData.ModelMetadata.PropertyName)
#Html.ValidationMessage(ViewData.ModelMetadata.PropertyName, "*", new { #class = "help-inline" })
</div>
</div>
The problem with the above editor template is that it doesn't render the correct input for the given type. So a date/time property will just render a normal text box without the type attribute.
Am I going about this the right way? Should I be using a standard HTML helper or a partial view? If so, how do we handle the generic nature?
MVC 5.1 includes a fix for exactly this case, Bootstrap support for editor templates.
You can include additional properties for the markup by supplying an anonmyous object as the second parameter to EditorFor
#Html.EditorFor(model => model, new { htmlAttributes = new { #class = "form-control" }, })
my code is :
#(Html.Telerik().Grid<Model>()
.Name("TestGrid")
.ClientEvents(events =>
{
events.OnDataBound("validate");
events.OnDataBinding("onDataBinding");
})
.DataBinding(db => db.Ajax()
.Select("Action1", "Controller1", new { ldata, filter }).Enabled(true)
)
.Columns(c =>
{
c.Bound(ctl => ctl.Uname)
.ClientTemplate("<input type='radio' id='rdbutton'name='IsSelected'/>")
//.ClientTemplate("<input name='<#= UserName #>' type='radio' />")
.Title("").Filterable(false).Sortable(false).Width(5);
c.Bound(itm => itm.Fname).Title("FName").Width(200).HtmlAttributes(new { #style = "vertical-align: top !important;" });
c.Bound(itm => itm.LNAme).Title("Lname").Width(200).HtmlAttributes(new { #style = "vertical-align: top !important;" });
c.Bound(itm => itm.Location).Title("Location").Width(200).HtmlAttributes(new { #style = "vertical-align: top !important;" });
})
.Selectable()
.Sortable()
.Filterable()
.Pageable(pg =>
{
pg.PageSize(3);
})
)
Columns are binded since they need to retrieve the values when search.
Yo mate,
First suggestion - use the Kendo MVC Grid - there you have an option called AutoBind which you can set to false.
If you definitely want to use the old Grid - use the OnDataBinding event and prevent it the first time.
e.g.
var isFirst = true;
function onGridDataBinding(e){
if(isFrist)
{
isFirst=false;
e.preventDefault();
}
}
I have this RadioButton:
#Html.LabelFor(model => model.Person.Type)
#Html.Label("Type1")
#Html.RadioButtonFor(model => model.Person.Type, "F", new { disabled = "disabled" })
#Html.Label("Type2")
#Html.RadioButtonFor(model => model.Person.Type, "J", new { disabled = "disabled" })
And, I have this Display:
#Html.LabelFor(model => model.Person.Field)
#Html.DisplayFor(model => model.Person.Field)
I need a javascript function that replace this Dispay (Person.Field) if RadioButton is checked at "Type1" ("F").
How can I do this?