Building the page Html on the client side with the client side control flow statements.

It is possible to build or to modify dynamically the Html of the page on the client side by inserting control statements in the Html of the page, analogously to what happens on the sever side within Razor or aspx Views. To keep the Html well formed such control statements are inserted within existing tags as Html5 attributes or within comments.

Such control statements are automatically rendered by the _if, _ifnot _foreach and _with Html extension methods whose use is similar to the analogous server side if, for and  foreach control statements.

An _if block is started by an Html._if(...) statement and it is closed by the Html._end() statement as in the example below:

 

 @Html._if(m => m.Quantity.Total, format: "{0}<4")
    @Html.DateTimeFor(m => m.DeliveryDate, DateTime.Today,
                                            false).Date()
 @Html._end()

 

Where the m => m.Quantity.Total expression is transformed into the adequate javascript Client Side ViewModel property name, and then it is inserted into the format string to yeld the javascript if condition.

The complete signature of the _if extensione method is:

 

public static MvcHtmlString _if<T, F>(
            this HtmlHelper<T> htmlHelper,
            Expression<Func<T, F>> expression,
            ExternalContainerType itemsContainer = ExternalContainerType.koComment,
            object htmlAttributes = null,
            string afterRender=null,
            string format = null,
            params LambdaExpression[] otherExpressions
            )

 

Where:

  • expression and otherExpression are Lambda Expressions that are automatically transformed into the adequate javascript property names and inserted into the format string to yeld the if condition. 
  • itemsContainer defines the httml tag that will enclose the if content. The default is koComment that specifies that no container will be used to enclose the if content. In this case the content of the if will be inserted between two adequate Html comments.
  • htmlAttributes are the Html attributes of itemsContainer.
  • afterRender is either a javascript function name or an anonymous javascript function, that is something like function(x){....}. This function is executed each time the if condition becomes true and consequently the if content is rendered. The function is passed the array of all root DOM nodes contained in the if statement. It is a good opportunity to initialize them, by calling for instance some jQuery plugin(such as .draggable or .sortable).

It is worth to point out that the if content is destroyed each time the if condition becomes false and it is created again each time the if condition becomes true.

The _ifnot extension method is completely analogous, the only difference being that the condition is negated.

 

The _for extension method is a little more elaborate:

  1. The Html._foreach(...) method is called on an IEnumerable and returns an html helper, say h, that can be used to render the generic item of that IEnumerable.
  2. The content of the _foreach is enclosed between the h._begin() and h._end() statements.

Below an example of nested _foreach:

 

@{var h1 = Html._foreach(m => m.Matrix, MVCControlsToolkit.Controls.ExternalContainerType.table);}
    @h1._begin()
        @{var h2 = h1._foreach(m => m, MVCControlsToolkit.Controls.ExternalContainerType.tr); }
        @h2._begin()
            <td>
                @h2._D(m => m.Name)
                
                @h2.TypedTextBoxFor(m => m.Value)
                @h2.ValidationMessageFor(m => m.Value, "*")
            </td>
        @h2._end()
    @h1._end()

 

The signature of the _foreach extension method is: 

 

        public static HtmlHelper<F> _foreach<T, F>(
            this HtmlHelper<T> htmlHelper,
            Expression<Func<T, IEnumerable<F>>> expression,
            ExternalContainerType itemsContainer = ExternalContainerType.koComment,
            object htmlAttributes = null,
            string afterAdd=null,
            string beforeRemove=null,
            string afterRender=null,
            string afterAllRender = null, 
            string existingTemplate = null 
            )
            where F: class

 

Where the meaning of the parameters is the same as the ones of the ClientBlockRepeater.

The _foreach is analogous to the ClientBlockRepeater. The differences are listed below:

  • existingTemplate, if provided must be the name of a template that has been rendered in the page. If it is provided the body of the foreach may be empty, since all items are rendered with existingTemplate template. 
  • The ClientBlockRepeater, has some options more and can be used with all template engines, while the _foreach uses just the native knockout template engine.
  • The ClientBlockRepeater can use previously defined templates.
  • The syntax of the _foreach is easier to use, expecially in the case of nested loops. 

The _with extension method renders an item in a template only if that item is not null. It is similar to a _foreach executed on a collection that is either empty or contains a single item.

Below an example of use of the _with extension method:

 

                                @{var h = item._with(m => m.Quantity);}
                                @h._begin()
                                @h.TypedEditDisplayFor(m => m.Total)
                                @h.ValidationMessageFor(m => m.Total, "*")
                                @h._end()

 

The signature of the _with extension method is:

 

        public static HtmlHelper<F> _with<T, F>(
            this HtmlHelper<T> htmlHelper,
            Expression<Func<T, F>> expression,
            ExternalContainerType itemsContainer = ExternalContainerType.koComment,
            object htmlAttributes = null,
            string afterRender = null,
            bool forceHtmlRefresh=false,
            string existingTemplate = null,
            bool isDetail = false)

 

Where the meaning of the parameters is the same as the ones of the _if extension method. The isDetail parameter declares that the html rendered by the _with is the detail view of a data item. The isDetail and the forceHtmlRefresh are used just if the Data Moving Pluging is installed.


Last edited Jun 22, 2014 at 10:42 AM by frankabbruzzese, version 6

Comments

No comments yet.