This control needs reference to MVCControlToolkit.Controls.Core-x.x.x.js. Moreover, if the date part of the DateTime must be shown with a Datepicker one of the following must be installed: jQuery Datepicker, Bootstrap Datepicker, or jQuery mobile Datebox. The control autodetects which Datepicker is installed and behaves accordingly. The Datepicker scripts must be placed before  MVCControlToolkit.Controls.Core-x.x.x.js since autodetection takes place there.

The TypedEditDisplay renders some text that when clicked or double clicked (depending on the settings) transforms into a Text, thus allowing the editing of the text. The text content is posted also if the text is not edited at all. Like the TypedTextBox it has two states: edit mode, and display mode. It has the following behavior:

  1. When in display mode it is empty,  it shows The NullDisplayText defined either in a  DisplayFormat, or in a Format attribute.
  2. When in display mode and not empty, it shows the data it contains in a "formatted" form. The formatted form is built as follows:
    • Only if the data it contains is a number it is formatted according to the numeric formats defined here: the Globalize library. Please note that this is a subset of the standard formatting options available in .Net. 
    • A string prefix and a string postfix are applied to the the result of the previous step
    • The above steps are applied each time the user modify the text box value
    • The client formatting string, the prefix and the postfix are defined in the Mvc Controls Toolkit FormatAttribute that inkerits from the .Net standardDisplayFormatAttribute.
    • The FormatAttribute specifications can be overriden by optional parameters of the helper.
  3. When in edit mode all formatting disappears and it becomes a TextBox to allow editing. In case of numbers only characters adequate for the TextBox type are allowed while typing. Thus, for instance in case of an unsigned integer no sign and no decimal separator will be allowed.


 It accepts two sets of htmlAttributes, the first one for the DisplayMode and the second one for the Edit mode. They are optional, but if you provide one of them you must provide also the other possibly null. Below the most complete override of the helper:


public static MvcHtmlString TypedEditDisplayFor<M, T>(this HtmlHelper<M> htmlHelper,
            Expression<Func<M, T>> expression,
            IDictionary<string, object> displayAttributes,
            IDictionary<string, object> editAttributes,
            ContentAlign contentAlign = ContentAlign.None,
            bool simpleClick = false,
            string overrideClientFormat = null,
            string overrideClientPrefix = null,
            string overrideClientPostfix = null,
            bool editEnabled = true,
            CalendarOptions calendarOptions = null)


 public static MvcHtmlString TypedEditDisplay<M, T>(this HtmlHelper<M> htmlHelper,
            string name,
            T value,
            IDictionary<string, object> displayAttributes,
            IDictionary<string, object> editAttributes,
            ContentAlign contentAlign = ContentAlign.None,
            bool simpleClick = false,
            string overrideClientFormat = null,
            string overrideClientPrefix = null,
            string overrideClientPostfix = null,
            bool editEnabled=true,
            CalendarOptions calendarOptions=null)

The simpleClick parameter specifies if it goes into edit mode with a simple click or with a double click. In both cases the control returns in display mode on the onblur event (when the textbox looses focus). 

Moving between the display state and the edit state can be done also programmatically. Specifically, if you set to false the  editEnabled  parameter of theTypedEditDisplay extension methods, then transitions between the display and edit states can be done with the help of an EditDisplayToggle button. A single EditDisplayToggle may toggle simultaneously the state of all TypedEditDisplay contained in a common container (such as a div or a tr). More specifically, the EditDisplayToggle is inserted in the same container of all TypedEditDisplay we would like to toggle, and it is passed a jQuery selector that univocally defines the ancestor container it must act on; it toogles all TypedEditDisplay that are in the first ancestor that matchs the jQuery selector.

The EditDisplayToggle is useful to move a whole grid item between the edit and display states. When all TypedEditDisplay are in edit mode and we click the EditDisplayToggle  all TypedEditDisplay are validated, and the global move to the display mode is performed only if all validations are succesful. 

Below an overload of the EditDisplayToggle:


public static MvcHtmlString EditDisplayToggle<VM>(
            this HtmlHelper<VM> htmlHelper,
            string containerSelector,
            string gotoDisplayTextOrUrl,
            string gotoEditTextOrUrl,
            string id,
            object htmlAttributes,
            ManipulationButtonStyle manipulationButtonStyle = ManipulationButtonStyle.Button,
            string changeStateCallback = null




  • containerSelector is the jQuery selector that defines the container the button acts on.
  • gotoDisplayTextOrUrl is the text to show on the button when a click will cause a move from the edit to the display mode. If the button is an image button it is the url of an image.
  • gotoEditTextOrUrl is the text to show on the button when a click will cause a move from the display to the edit mode. If the button is an image button it is the url of an image.
  • id is the html id of the control. It is prefixed with the current name prefix, so you can safely use the same id for the buttons in all items of an items control.
  • htmlAttributes are the usual Htnl attributes of all Html helpers. There is also another overload that accepts a dictionary.
  • manipulationButtonStyle specifies the style of the button (normal button, link, or image).
  • changeStateCallback is a callback that is called on each TyepedEditDisplay whenever it changes state. It can be either the name of a javascript function, or an anonymous function like: function(x,y){....}. The callback is called with two parameters. The first parameter is the pointer to the input element that composes the TypedEditDisplay; its html id is the id to be used in all client calls to the TypedEditDisplay (see here). The second parameter is one of the following three strings:
    • "goneDisplay": when the control moved to the display mode.
    • "goneEdit": when the control moved to the edit mode.
    • "failedGoneEdit": when the control failed moving in Display mode, because of some validation errors, and returns in edit mode.

Below an example of use of the EditDisplayToggle: 


<div class='editDisplayContainer'>
                @Html.TypedEditDisplayFor(m => m.SingleRole,
                                m => m.Code,
                                m => m.Name,
                                m => m.GroupCode,
                                m => m.GroupName,
                                m => new {style="color:White; background-color:Black"},
                                m =>  {
                                    if (m == null)
                                        return new 
                                            @class = "watermark"
                                    return new
                                        style = m.Code % 2 == 0 ?
                                            "color:Blue; background-color:White" :
                                            "color:Red; background-color:White"
                                }), editEnabled: false)
               @Html.ValidationMessageFor(m => m.SingleRole, "*")
               @Html.EditDisplayToggle(".editDisplayContainer", "finish editing", "edit value", "EditDisplayButton", changeStateCallback:"function(el, op){alert(el.id+' '+op);}")       


The calendarOptions optional parameter can be used when the TypedEditDisplay is used to render a DateTime. If it is not null a  Datepicker appears when the control is in edit mode. For details on the CalendarOptions class, please see the DateTimeInput documentation.

Important: when using either Bootstrap or jQuery Mobile Datepickers the only option used is the Dateformat, all other options must be passed as Html 5 attributes as detailed in the Datepickers documentation, however a CalendarOptions instance must be passed in any case, otherwise the control assumes that no Datepicker must be shown. Usually, no DateFormat is passed and the right format is extracted either by a FormatAttribute or by a DisplayFormatAttribute. If no format is specified the short date format for the current culture is used.

displayAttributes and editAttributes are used to set Html attributes. There are also overloads that accepts an anonymous object in place of the IDictionary<string, object>.

Finally there are overloads that accepts a parameter ChoiceList<TItem, T, TDisplay> items. When this parameter is not null the TypedEditDisplay becomes a DropDown when in edit mode. For more details on the ChoiceList<TItem, T, TDisplay> class please see the documentation about the DropDown helper.

The TypedEditDisplay is particularly useful as a field of complex item controls like the TreeView or SortableList

Below, an example of use in the definition of a node template of a TreeView:


_S.L<EmailElement>(h => string.Format(
                            "<div class='folder' >{0} {1} {2} {3} {4}</div>", 
                            h.TypedEditDisplayFor(m => m.Name).ToString(),
                            h.TreeViewAddButton(1, Url.Content("~/Content/document_add_16.png"), 
                            h.TreeViewAddButton(0, Url.Content("~/Content/folder_add_16.png"), 
                            h.Hidden("IsFolder", true).ToString()))


Below the definition of the EmailElement class:


public class EmailElement
        public bool IsFolder { get; set; }
        [Required, Format(NullDisplayText="empty name")]
        public string Name {get; set;}
        public List<EmailElement> Children { get; set; }


Finally everything working:

Last edited Jun 22, 2014 at 11:55 AM by frankabbruzzese, version 19


No comments yet.