user1765862 user1765862 - 7 months ago 67
HTML Question

mvc helper for rendering custom textbox

Inside razor view I'm using html helper

@Html.TextBoxFor(model => model.YearsInService, new { @class = "col-lg-1" })


which renders following html

<input id="YearsInService" class="col-lg-1" type="text" value="" name="YearsInService"
data-val-required="The YearsInService field is required."
data-val-number="The field YearsInService must be a number."
data-val="true" disabled="disabled">


since I want to implement validation with tooltip messages like this
I need solution input element to be rendered like this

<input
data-msg-number="The field YearsInService must be a number."
data-rule-number="true"
data-rule-required="true"
id="YearsInService" name="YearsInService" type="text" value="" />



question is: how can build custom mvc helper for rendering second html
code in razor view?

Answer

You can create a HtmlHelper extension method to output your html.

public static MvcHtmlString ToolTipTextBoxFor<TModel, TValue>(this HtmlHelper<TModel> helper, 
    Expression<Func<TModel, TValue>> expression, object htmlAttributes)
{
    IDictionary<string, object> attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
    attributes.Add("data-msg-number", "The field YearsInService must be a number.");
    attributes.Add("data-rule-number", true);
    ... other 'fixed' attributes as required
    return InputExtensions.TextBoxFor(helper, expression, attributes);
}

and then in the view

@ToolTipTextBoxFor(m => m.YearsInService, new { @class = "col-lg-1" })

and of course you could create other overloads to match the TextBoxFor() method overloads.

Edit

From your comments, you also want to generate data-rule- attributes based on the properties validation attributes. To do this, you can get the ModelMetatdata

ModelMetadata metaData = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);

and then check its properties

for example

if (metaData.IsRequired)
{
    attributes.Add("data-rule-required", true);
}