views:

89

answers:

1

For a project I'm working I've been asked to redirect an editor template to its display template based on metadata that is provided with the model.

Now I was looking at a way to do it before it hits the editor template but that seems to cause more issues than it is worth, at least with how the system has been architected.

The simplest example is the string editor, its a simple textbox but if IsReadOnly is set we want it to only show up as text, not a disabled textbox.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>
<%
    if (this.ViewData.ModelMetadata.IsReadOnly)
    {
        Response.Write(Html.DisplayForModel());
    }
    else if (this.ViewData.ModelMetadata.ShowForEdit)
    {
<%= Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = "text-box single-line" }) %>
<% } %>

So far the only real solution I can find is to copy the display template into the editor template. Does anyone have any ideas how I can do something that will work without replicating more code?

A: 

Why not do this outside of the editor template itself? Define an extension method that checks if the property is read only then either shows the edit or display template. You'll need to copy the PropertyHelper class from this answer.

public MvcHtmlString DisplayOrEditFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> selector)
{
    var property = PropertyHelper<TModel>.GetProperty(selector);
    if(property.CanWrite)
    {
        return helper.EditorFor(selector);
    }
    return helper.DisplayFor(selector);
}

Then in your view just do

<%: Html.DisplayOrEditFor(x => x.Name) %>

Only drawback is this won't work with Html.EditorForModel().

Ryan