ASP.Net MVC-5 Editor Templates, ViewData & placeholder (watermark) results in extraneous markup

1.4k views Asked by At

I have implemented an Editor Template for each of my input types which populate the css "placeholder" with the "Prompt" Display annotation from my models.

In the first instance I just added "placeholder"=ViewData.ModelMetaData.Watermark to ViewData and passed ViewData in to the TextBox() HtmlAttributes parameter as suggested in several posts on here and around. (Thanks to Darin Dimitrov in particular.)

However, this had the effect of adding "returnurl", "title" and several other ViewData properties to each and every input control. Not very satisfactory.

I took a look at this post and was about to give it a try when I figured I would take that idea and create an array of strings that represent the Keys of the ViewData properties I don't want included in the input-markup and loop through the ViewData and only add those properties that aren't in that list.

This is my code for the String Editor Template (Shared\EditorTemplates\String.cshtml):

@{
IDictionary<string, object> htmlAtts = new Dictionary<string, object>();
string[] varData = {"ReturnUrl", "Title"}; //there are more values in my actual code
foreach (KeyValuePair<string, object> entry in ViewData)
{
    if (!varData.Contains(entry.Key)) {
        htmlAtts.Add(entry.Key, entry.Value);
    }
}
htmlAtts["placeholder"] = ViewData.ModelMetadata.Watermark;
}
@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, htmlAtts)

(BTW this code will be re-factored to keep it DRY)

It would have been nice if "placeholder" was implemented by the framework, or if there was a simple way of grabbing the HTML attributes at this point and adding the "placeholder" to those attributes only, without having to do this loop to exclude non-HTML-Attribute-ViewData.

Am I missing something? Is there a better way of achieving what this solution has done?

2

There are 2 answers

0
lukkea On BEST ANSWER

As I mention in my question, this is the code for the String Editor Template that solved the problem (Shared\EditorTemplates\String.cshtml):

@{
IDictionary<string, object> htmlAtts = new Dictionary<string, object>();
string[] varData = {"ReturnUrl", "Title"}; //there are more values in my actual code
foreach (KeyValuePair<string, object> entry in ViewData)
{
    if (!varData.Contains(entry.Key)) {
        htmlAtts.Add(entry.Key, entry.Value);
    }
}
htmlAtts["placeholder"] = ViewData.ModelMetadata.Watermark;
}
@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, htmlAtts)
1
Taylor Hall On

If all you are trying to accomplish is to add the placeholder from the ViewData.ModelMetadata.Watermark, then your String Template can be as simple as follows:

@Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { placeholder = ViewData.ModelMetadata.Watermark })

And your placeholder text can be set in the DataAnnotations of your View Model.