I have an app with about 50 of these:
#Html.LabelFor(m => m.CurrentLineItem.Address.Address1, new { #class = "textBox-label" })
It seems to me hardcoding a class is not a good idea. Is there a way to abstract this out further? Like maybe:
#Html.LabelWithTextBoxLabelClass(m=> m.CurrentLineItem.Address.Address1);
just like others said, make your own Html Helper, code like below:
public static class LabelExtensions
{
public static MvcHtmlString LabelWithTextBoxLabelClass(this HtmlHelper helper, string expression)
{
return helper.Label(expression, new { #class = "textBox-label" });
}
public static MvcHtmlString LabelForWithTextBoxLabelClass<TModel,TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel,TValue>> expression)
{
return helper.LabelFor(expression, new {#class = "textBox-label"});
}
}
now you can use it like what you want:
#Html.LabelWithTextBoxLabelClass(m=> m.CurrentLineItem.Address.Address1);
You can make your own Html helpers, or you can use Bootstrap Html Helpers for MVC. Take a look at here: http://www.codeproject.com/Articles/570762/TwitterBootstrapMvc
With bootstrap you can simply set your label class like this:
#Html.Bootstrap().LabelFor(m => m.Property).Class("textBox-label")
Related
I have an #html.textBox and I am woundering if I can define Label inside rather then using separate #html.label tag ...
many thanks
Textbox
#Html.TextBox("Input_AvailableMark_Element", null, new { id = #item.ElementID + "_AM", #class = "ElementAvailableMarks k-grid-input k-textbox_3" })
Label
#Html.Label("AvailableMark", null, new {#class ="inputTextLabel_Custom_1" })
The only way I can think of to do that is with usage of placeholder attribute:
#Html.TextBoxFor(model => model.SomeProperty, new { placeholder = Model.SomeProperty })
I'm assuming you are using DataAnnotations for your models. So for example if you want the Display attribute value to be in your placeholder then you need to write this extension method to fetch data annotation DISPLAY attribute:
public static class GetAttributeExtension
{
public static string GetDisplayName<TModel, TValue>(this TModel model, Expression<Func<TModel, TValue>> expression)
{
return GetDisplayName(expression);
}
public static string GetDisplayName<TModel, TValue>(Expression<Func<TModel, TValue>> expression)
{
var propertyName = ((MemberExpression)expression.Body).Member.Name;
return typeof(TModel).GetAttribute<DisplayAttribute>(propertyName).Name;
}
}
And then you can do something like this:
#Html.TextBoxFor(model => model.SomeProperty, new { placeholder = Model.GetDisplayName(m => m.SomeProperty) })
Depending on what browsers you need to support, the easiest option is as #Marko suggests, add the placeholder attribute.
http://www.w3schools.com/tags/att_input_placeholder.asp
However, if you need to support non-HTML5 compliant browsers, this will not work. There are some javascript libraries that will do this behavior for you
http://www.wduffy.co.uk/jLabel/
I have used jLabel before and it works pretty well, but is not without its problems.
I want to write my own custom HTML helper that extends an existing helper. E.g. I want to create to extend #Html.EditorFor like so:
#Html.EditorFor(model => model.percent, new { data_a_sign="%", data_p_sign="s" })
Becomes:
#Html.PercentEditorFor(model => model.percent)
How would one go about writing that?
Something like this?
namespace AdminPortal.Helpers
{
public static class HtmlHelpers
{
public static MvcHtmlString PercentEditorFor<TModel>(this HtmlHelper html,
Expression<Func<TModel>> expression)
{
// Some Magic?
}
}
}
Any pointers would be greatly appreciated.
It's just a matter of returning the existing EditorFor method from your own helper:
public static MvcHtmlString PercentEditorFor<TModel>(this HtmlHelper html,
Expression<Func<TModel>> expression)
{
return html.EditorFor(...);
}
Put your own modified parameters into the EditorFor method. No magic required :)
I have a label as
<%= Html.Label("");%>
i want to add content to label at runtime, unfortunately it doesn't take any other parameter to create id property for it. can't i create id property for it just similar to asp:label
thanks,
michaeld
No need to use the HtmlHelper functions always and everywhere if they don't fit your need. They're just supposed to make your life easier, not harder. Use good ole HTML here:
<label id="id_for_label"></label>
If you want to keep using HtmlHelper functions you can always create your own extension methods.
For example:
public static class LabelHelper
{
private static string HtmlAttributes(object htmlAttributes)
{
var builder = new StringBuilder();
foreach (PropertyDescriptor descriptor in
TypeDescriptor.GetProperties(htmlAttributes))
{
builder.AppendFormat(" {0}=\"{1}\" ", descriptor.Name,
descriptor.GetValue(htmlAttributes));
}
return builder.ToString();
}
public static MvcHtmlString MyLabel(this HtmlHelper htmlHelper,
string labelText, object htmlAttributes)
{
var attributes = HtmlAttributes(htmlAttributes);
return MvcHtmlString.Create(
String.Format("<label for=\"{0}\" {1}>{0}</label",
labelText, attributes.Trim()));
}
}
Then you can add a label to a view in the following manner:
<%: Html.MyLabel("Hello, World!", new { #id = "myLabel" })%>
The generated HTML is:
<label for="Hello, World!" id="myLabel">Hello, World!</label>
For MVC 3 such a helper function is already available:
http://msdn.microsoft.com/en-us/library/gg538318(v=VS.99).aspx
I use the HTML Helpers to render my fields:
<%=Html.EditorFor(m => m.User.Surname)%>
and the output would be something like this:
<input class="text-box single-line" id="User_Surname"
name="User.Surname" type="text" value="" />
The helper uses the className + '.' รจ fieldName to build the id.
I need to pass the id to a jQuery function. Is there a way to have it without hardcoding it?
Maybe an helper which can use the ASP.NET MVC2 conventions?
ASP.NET MVC 4 has Html.IdFor() built in that can return this:
#Html.IdFor(m => m.User.Surname)
See this question: get the generated clientid for a form field, this is my answer:
I use this helper:
public static partial class HtmlExtensions
{
public static MvcHtmlString ClientIdFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression)
{
return MvcHtmlString.Create(
htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(
ExpressionHelper.GetExpressionText(expression)));
}
}
Use it just as you would any other helper: #Html.ClientIdFor(model=>model.client.email)
I've followed the instructions of Mac's answer here and I've built my own custom extension:
public static class HtmlHelperExtensions
{
public static string HtmlIdNameFor<TModel, TValue>(
this HtmlHelper<TModel> htmlHelper,
System.Linq.Expressions.Expression<Func<TModel, TValue>> expression)
{
return (GetHtmlIdNameFor(expression));
}
private static string GetHtmlIdNameFor<TModel, TValue>(Expression<Func<TModel, TValue>> expression)
{
if (expression.Body.NodeType == ExpressionType.Call)
{
var methodCallExpression = (MethodCallExpression)expression.Body;
string name = GetHtmlIdNameFor(methodCallExpression);
return name.Substring(expression.Parameters[0].Name.Length + 1).Replace('.', '_');
}
return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1).Replace('.', '_');
}
private static string GetHtmlIdNameFor(MethodCallExpression expression)
{
var methodCallExpression = expression.Object as MethodCallExpression;
if (methodCallExpression != null)
{
return GetHtmlIdNameFor(methodCallExpression);
}
return expression.Object.ToString();
}
}
I've imported my application's namespace
<%# Import Namespace="MvcApplication2" %>
and finally I can use my code like this:
<%=Html.HtmlIdNameFor(m=>m.Customer.Name)%>
unless you create your own User.Surname EditorTemplate which you pass in some HTML attributes you won't be able to do this with EditorFor
However you can use TextBoxFor and set the id
<%= Html.TextBoxFor(m => m.User.Surname, new { id = "myNewId" })%>
On the topic of retrieving this element with a jQuery selector you can achieve this without having to hardcode by using some of the ends-with selector. Using that you could probably still use EditorFor and just select it with $("[id^='Surname]")`. If you're trying to select this specific element there's really no way to NOT hardcode SOMETHING in your jQuery code.
i would like to change the way LabelFor render. Can i do that with a DisplayTemplate?
LabelFor generate a label tag and i would like to add a ":" at the end of the label.
thank you!
alex
Here is an HTML Helper that will do that:
public static class LabelExtensions {
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString SmartLabelFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression) {
return LabelHelper(html,
ModelMetadata.FromLambdaExpression(expression, html.ViewData),
ExpressionHelper.GetExpressionText(expression));
}
internal static MvcHtmlString LabelHelper(HtmlHelper html, ModelMetadata metadata, string htmlFieldName) {
string labelText = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();
if (String.IsNullOrEmpty(labelText)) {
return MvcHtmlString.Empty;
}
// uncomment if want * for required field
//if (metadata.IsRequired) labelText = labelText + " *";
labelText = labelText + ":";
TagBuilder tag = new TagBuilder("label");
tag.Attributes.Add("for", html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(htmlFieldName));
tag.SetInnerText(labelText);
return MvcHtmlString.Create(tag.ToString(TagRenderMode.Normal));
}
}
To use it:
<%:Html.SmartLabelFor(m => m.FirstName)%>
It will render:
<label for="FirstName">First Name:</label>
Or if you uncomment the required field related *
<label for="FirstName">First Name *:</label>
Just write a regular <label> element in plain HTML:
<label>My Label:</label>
If you want to output the for="" attribute and accurately render the control's name then use this extension method:
using System;
using System.Linq.Expressions;
using System.Web.Mvc;
namespace MvcLibrary.Extensions
{
public static class HtmlExtensions
{
public static MvcHtmlString FieldIdFor<TModel, TValue>(
this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{
string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
string inputFieldId = html.ViewContext.ViewData.
TemplateInfo.GetFullHtmlFieldId(htmlFieldName);
return MvcHtmlString.Create(inputFieldId);
}
}
}
Then you can use in your view like so:
<label for="<%= Html.FieldIdFor(m => m.EmailAddress) %>">E-mail address:</label>
<%= Html.TextBoxFor(m => m.EmailAddress) %>
The other posts cover different approaches, they are all equally valid, which one you go for is matter of personal preference. I personally prefer writing the <label> as plain HTML as it gives designers more flexibility with changing markup, adding extra attributes such as CSS classes etc. Also I feel the label text is a view concern and shouldn't be decorated on the ViewModel class, but that's just my personal opinion/preference, I know some people here will disagree with me and that's fine :-)
You can create a String.ascx in DisplayTemplates folder and provide your own implementation. Refer to the Overriding Templates section of the following article.
http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html
You could do this using MVC 2 (if possible) if you pass a custom ViewModel to the view.
using System.ComponentModel;
public class PersonViewModel
{
public PersonViewModel(string name)
{
this.Name = name;
}
[DisplayName(".Display Anything You Like Here.")]
public string Name { get; set; }
I think the best approach would be writing your own helper method that renders what you like. You can overload the existing method or simply create a new method.