Skip to content Skip to sidebar Skip to footer

Extending Html Helper

The code I am looking to produce is similar to:
Copy

You can use default display attribute to specify display name.There is no need for custom attributes.And you can use this extension like this:

@Html.LabelledTextBoxFor(model => model.EmailAddress)

Note: I have tried myself and it is working correctly.

Update: More simple version

publicstaticMvcHtmlStringLabelledTextBoxFor2<TModel, TResult>(this HtmlHelper<TModel> html, Expression<Func<TModel, TResult>> expression)
    {
        ExpressionType type = expression.Body.NodeType;
        if (type ==ExpressionType.MemberAccess)
        {
            var metadata =ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            var displayName = metadata.DisplayName;
            var propName = metadata.PropertyName;

            StringBuilder sb = new StringBuilder();

            sb.Append("<div class=\"form-group\">");
            sb.AppendFormat("<label for=\"{0}\">{1}</label>", propName, displayName);
            sb.AppendFormat(
                        "<input type=\"email\" class=\"form-control\" id=\"{0}\" placeholder=\"Enter email\">",
                        propName);
             sb.Append("</div>");
             returnMvcHtmlString.Create(sb.ToString());
        }

        returnMvcHtmlString.Create("");
    }

Solution 2:

I would use @Html.EditorFor template. So create EditorTemplates folder in Views/Shared in your MVC project with a name EmailAddress.cshtml - it will display this template for every [DataType(DataType.EmailAddress)] defined in your model.

So: EmailAddress.cshtml should look sth like this:

<div class="form-group">
<labelfor="email">@Html.LabelFor(x => x)</label>@Html.TextBoxFor(x => x, new { @class = "form-control", placeholder = ViewData.ModelMetadata.Watermark })
</div>

Model should look like this:

publicclassSomeModel {

    [DataType(DataType.EmailAddress)]
    [Display(Name="Some string for LabelFor", Prompt = "Placeholder in input"]
    publicstring SomeEmail { get; set; }
}

Note here, that I've used Prompt property of Display metadata, which I linked to placeholder via ViewData.ModelMetadata.Watermark in EmailAddress.cshtml. Html.LabelFor will always take property Name from Display and DataType is needed for linking between EditorTemplates and model property.

And invoke all this "magic" by using

@Html.EditorFor(m=>m.SomeEmail)

on a page, where you use SomeMode model.

I hope this does make sense.

Solution 3:

No need to reinvent the wheel. Check out TwitterBootstrapMVC.

The code you'd be writing would look similar to the below:

@Html.Bootstrap().FormGroup().TextBoxFor(model => model.EmailAddress).Placeholder("Enter email")

Disclaimer: I'm the authot of TwitterBootstrapMVC.

TwitterBootstrapMVC for use on Bootstrap 3 is not free. See details on the website.

Solution 4:

The Data Annotations go in the viewmodel above the property:

[DisplayName("Email Address")]
publicstring EmailAddress { get; set; }

Then, in your view, you'd have something like this:

@Html.LabelFor(m => m.EmailAddress)
@Html.TextBoxFor(m => m.EmailAddress, new { @placeholder="Enter email", @class="form-control", @id="email" })

Post a Comment for "Extending Html Helper"