0

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?

user1765862
  • 13,635
  • 28
  • 115
  • 220

3 Answers3

1

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);
}
  • great, is there any way to improve this to use model data annotation attributes, for exapmle if it's decorated with Required to include data-rule-required in this helper, ... – user1765862 Apr 14 '16 at 12:11
  • I guess you haven't tried it yet. The `data-val` attributes will be added :) - its calling the `InputExtensions.TextBoxFor()` method which adds everything. –  Apr 14 '16 at 12:13
  • Also refer last part of [this answer](http://stackoverflow.com/questions/26955073/converting-asp-net-mvc-razor-helper-function-into-a-method-of-a-helper-class/26955246#26955246) for adding the namespace to your `web.config.cs` file to avoid `@using` statements in your view –  Apr 14 '16 at 12:16
  • Just read your comment again - did you mean `data-val-required` or `data-rule-required`? –  Apr 14 '16 at 12:19
  • I mean data-rule-required – user1765862 Apr 14 '16 at 12:25
  • I also guessing that you want to include `data-rule-number="true"` if the property is a numeric type? If so, you could first look at the answers [here](http://stackoverflow.com/questions/1749966/c-sharp-how-to-determine-whether-a-type-is-a-number) and you can pass `metadata.ModelType` to Jürgen Steinblock's solution –  Apr 14 '16 at 12:39
0

If I correctly understood what you want, I am sure you need Editor Template

user2216
  • 809
  • 1
  • 8
  • 24
0

You can add custom html attributes using one of the TextBoxFor overloads:

@Html.TextBoxFor(x => x.YearsInService, new { data_msg_number = "The field YearsInService must be a number.", data_rule_number="true" })

If you are OK with using EditorFor instead of TextBoxFor then I would suggest creating editor templates. There is nice article describing the basics.

If you would like to create a new Html.MySuperTextBoxFor extension method, then check out this.

Community
  • 1
  • 1
Dmitri Trofimov
  • 753
  • 3
  • 14