Reputation: 55
I have form model and I want to use property name as value for some form field attributes. What would be the best way for that? (In this case, I would like to have id="PropertyName").
// FormViewModel
[Display(Name = "First name*")]
[Required(ErrorMessage = "This field is required")]
public string FirstName { get; set; }
// Index.cshtml
<form id="form1" asp-controller="controller" asp-action="Index" method="post">
<div class="form-group">
@Html.TextBoxFor(m => m.FirstName, new
{
@id = "firstName",
@placeholder = Html.DisplayNameFor(m => m.FirstName)
})
@Html.ValidationMessageFor(m => m.FirstName)
</div>
</form>
tnx!
Upvotes: 2
Views: 1472
Reputation: 9024
As @teo van kot said, MVC does that by default. But, if path to your property is something like model.Submodel.PropertyName, ID attribute will be "Submodel_PropertyName". If you want just "PropertyName", then this extension method/wrapper can be used:
public static class Extension method
{
public static IHtmlContent CustomTextBoxFor<TModel, TResult>(this IHtmlHelper<TModel> helper, Expression<Func<TModel, TResult>> expression)
{
// very simple implementation, can fail if expression is not as expected!
var body = expression.Body as MemberExpression;
if(body == null) throw new Exception("Expression refers to a method, not a property");
return helper.TextBoxFor(expression, null, new { id = body.Member.Name, placeholder = helper.DisplayNameFor(expression) });
}
}
in the razor view output will be like this:
@Html.CustomTextBoxFor(x => x.Foo)
<input id="Foo" name="Foo" type="text" placeholder="Foo" value="">
@Html.TextBoxFor(x => x.Foo)
<input id="Foo" name="Foo" type="text" value="">
@Html.CustomTextBoxFor(x => x.AnotherModel.Foo)
<input id="Foo" name="AnotherModel.Foo" type="text" placeholder="Foo" value="">
@Html.TextBoxFor(x => x.AnotherModel.Foo)
<input id="AnotherModel_Foo" name="AnotherModel.Foo" type="text" value="">
Problem with first and third approach, so using this technique, if you have same property name on several places in the model:
@Html.CustomTextBoxFor(x => x.DeliveryAddress.StreetName)
@Html.CustomTextBoxFor(x => x.BillingAddress.StreetName)
both input tags will have the same ID attribute!
Examples are written for MVC6, MVC5 uses different HtmlHelper types.
Upvotes: 1
Reputation: 885
Based on the coment above, it looks like the solution you are seeking is this
@Html.TextBoxFor(m => m.FirstName,
new { @id = Model.FirstName,
@placeholder = Html.DisplayNameFor(m => m.FirstName)
})
But I'd say there's definitely a code smell there ... that is a very odd thing to do.
Upvotes: 0
Reputation: 12491
You just shouldn't escape your placeholder
property like this:
@Html.TextBoxFor(m => m.FirstName, new
{
@id = "firstName",
placeholder = Html.DisplayNameFor(m => m.FirstName)
})
Also there is no need in @id = "firstName"
strongly typed helpers add id
attribute with Property name by default, so it will be like this in your case:
@Html.TextBoxFor(m => m.FirstName, new
{
placeholder = Html.DisplayNameFor(m => m.FirstName)
})
Upvotes: 0