Incoding Framework - IML TODO MVC

Other articles in the series "Incoding Framework" :
Why ToDo ?

Were an offer to realize “Todo MVC” as a proof of IML possibilities. There is a result. First of all, in contrast to js framework, test-version doesn’t use as a container “local storage”, but use data-bases and source code (or attached file). We will consider it more. In the process of realization I built the whole of logistics (basement computation, hiding elements and etc.) on the client, although on the tasks. It’s easier (sometimes necessary) to update elements “pointwise”, that with IML-code know how to compute and reflect themselves

Code review

Today we will not compare 2 variants of decision (in this case the volume of material will be very large). We’ll make a review of code, which we’ll get in the realization “todo” app. I’ve mentioned above that in the IML realization is the server side, but in order to equalize the task for more objective comparison, we focus only on client’s side

What it consists of

The code was split into the following three View:

  • Index - main page ( actuallu it is single page )
  • Todo_List_Tmpl - a pattern for central list
  • Todo_Footer_Tmpl - – a pattern for building a basement with

Location in graphical form
 
Here's the form for TODO adding
  1. @using (Html.When(JqueryBind.Submit)  
  2.             .DoWithPreventDefault()  
  3.             .Submit(options =>  
  4.                    {  
  5.               options.Url = Url.Dispatcher()  
  6.                                .Push(new AddTodoCommand {   
  7.                          ClientId = Selector.Incoding.Cookie(CookieManager.ClientId)   
  8.                                                         });  
  9.                    })  
  10.             .OnSuccess(dsl =>  
  11.                            {  
  12.                                dsl.WithId(containerId).Core().Trigger.Incoding();  
  13.                                dsl.Self().Core().Form.Reset();  
  14.                            })  
  15.             .AsHtmlAttributes()  
  16.             .ToBeginTag(Html, HtmlTag.Form))  
  17. {  
  18.     @Html.TextBoxFor(r => r.Title, new { placeholder = "What needs to be done?", autofocus = "" })  
  19. }  

Note: Anticipating phrases like “Hey, this is not serious, codes are much bigger, you need to copy everywhere, look at other people do it!!!” I’ve an argument – there are “ C# extensions ” which permit to wrap IML constructions. Further in the article I’ll give alternative variants of tasks decision (also “repository” on GibHub with a revised code) using C# extensions

What is what
  • When(JqueryBind.Submit) - indicate objective event
  • DoWithPreventDefault - event behavior (cancel browser evaluator)
  • Submit - – send the form through Ajax.

Note: few comments on presented realization:

  • Url where to send the form is set in options ( not through attribute variable “action” at "form"
  • ClientId can be derived as Hidden that on InitIncoding entered meaning from cookies to call Submit with no parameters.
  • OnSuccess - realize after successful submit finish.
  • Trigger Incoding to containerId - start the whole IML code for Container element (description below).

Note

Anticipating phrases like “Hey, this is not serious, codes are much bigger, you need to copy everywhere, look at other people do it!!!” I’ve an argument – there are “ C# extensions ” which permit to wrap IML constructions. Further in the article I’ll give alternative variants of tasks decision (also “repository” on GibHub with a revised code) using C# extensions

  • Form reset - make a reset of form elements
  • AsHtmlAttributes - collect IML code in convenient for asp.net mvc (RouteValueDictionary
  • ToBeginTag - – pack up getting attribute in the tag “form” ( work principle as Html.BeginForm)

Note

Html.BeginForm may be used (“action”,”controller”,Post,iml.AsHtmlAttributes())

The form for TODO adding ( alternative variant )
  1. @using (Html.Todo().BeginForm(setting =>  
  2.                              {  
  3.                 setting.TargetId = containerId;  
  4.                 setting.Routes = new { ClientId = Selector.Incoding.Cookie(CookieManager.ClientId) };  
  5.                              }))  
  6. {  
  7.     @Html.TextBoxFor(r => r.Title, new { placeholder = "What needs to be done?", autofocus = "" })  
  8. }  
Note

Code became smaller and the most important thing now you can expand method for concrete project needs (validation, redirect after submit and etc.)
  1. public class BeginFormSetting  
  2. {  
  3.     public string TargetId { getset; }  
  4.   
  5.     public object Routes { getset; }  
  6. }  
  7.   
  8. public BeginTag BeginForm(Action configure)  
  9. {  
  10.     var setting = new BeginFormSetting();  
  11.     configure(setting);  
  12.   
  13.     var url = new UrlHelper(HttpContext.Current.Request.RequestContext);  
  14.     return this.helper.When(JqueryBind.Submit)  
  15.                .DoWithPreventDefault()  
  16.                .Submit(options =>  
  17.                            {  
  18.                                options.Url = url.Dispatcher()  
  19.                                                 .Push(setting.Routes);  
  20.                            })  
  21.                .OnSuccess(dsl =>  
  22.                               {  
  23.                                dsl.WithId(setting.TargetId).Core().Trigger.Incoding();  
  24.                                dsl.Self().Core().Form.Reset();  
  25.                               })  
  26.                .AsHtmlAttributes()  
  27.                .ToBeginTag(this.helper, HtmlTag.Form);  
  28. }  

Note

Most of you are acquainted with ASP.NET MVC, but it is necessary to point out that in place of “usual” parameters, we propose anonymous method, that gets setting class.

Container
  1. @(Html.When(JqueryBind.InitIncoding | JqueryBind.IncChangeUrl)  
  2.       .Do()  
  3.       .AjaxGet(Url.Dispatcher()  
  4.                   .Query(new  
  5.                          {  
  6.                           ClientId = Selector.Incoding.Cookie(CookieManager.ClientId),  
  7.                           Type = Selector.Incoding.HashQueryString(r => r.Type)  
  8.                          })  
  9.                   .AsJson())  
  10.       .OnSuccess(dsl =>  
  11.                      {  
  12.                        string urlTmpl = Url.Dispatcher()  
  13.                                   .Model(new GetTodoByClientQuery.Tmpl { FooterId = footerId })  
  14.                                   .AsView("~/Views/Home/Todo_List_Tmpl.cshtml");  
  15.                        dsl.Self().Core().Insert.WithTemplateByUrl(urlTmpl).Html();  
  16.                        dsl.WithId(footerId).Core().Trigger.Incoding();  
  17.                      })  
  18.       .AsHtmlAttributes(new { id = containerId })  
  19.       .ToDiv())  
WHAT’S WHAT?
  • When(JqueryBind.InitIncoding | IncChangeUrl) - – specifies target events

    InitIncoding - – works at first appearance of element on a page (doesn’t matter ajax or usually)

    IncChangeUrl - – works at “hash” changing

    Do - behavior of event

  • AjaxGet - indicate the url, which will be sent to ajax request

    ClientId - get the value from “cookies”

    Type - get the value from “Hash Query String”

  • OnSuccess - realize after successful AjaxGet finish

    Insert data to self by template - put in findings from request ( json ) through template ( Todo_List_Tmpl below) in current element.

Note

Template can be through any available Selector, ex. earlier Jquery.Id was basic, but uploading on ajax is preferable

  • Trigger incoding to footerId - start entire IML code for footer element (description below )
  • AsHtmlAttributes -collect IML code and set value containerId ( guid ) to Id attribute

Note

The use of guid as Id vouch for unique element of page, especially relevant for single page application

  • ToDiv - pack up getting attributes in the tag div

Note

ToDiv is C# extensions over RouteValueDictionary, that’s why it is easy to write necessary variant.

Container (alternative way)
  1. @Html.Todo().Container(setting =>  
  2.              {  
  3.                 setting.Id = containerId;  
  4.                 setting.Url = Url.Dispatcher()  
  5.                                  .Query(new  
  6.                                               {  
  7.                           ClientId = Selector.Incoding.Cookie(CookieManager.ClientId),  
  8.                           Type = Selector.Incoding.HashQueryString(r => r.Type)  
  9.                                               })  
  10.                                  .AsJson();  
  11.                 setting.Tmpl = Url.Dispatcher()  
  12.                                   .Model(new GetTodoByClientQuery.Tmpl { FooterId = footerId })  
  13.                                   .AsView("~/Views/Home/Todo_List_Tmpl.cshtml");  
  14.                 setting.DependencyId = footerId;  
  15.              })  
Note

In the future it’s necessary to add block ui or other actions, now you can centralize 
  1. public class ContainerSetting  
  2. {  
  3.     public string Id { getset; }  
  4.   
  5.     public string Url { getset; }  
  6.   
  7.     public string Tmpl { getset; }  
  8.   
  9.     public string DependencyId { getset; }  
  10. }  
  11.   
  12. public MvcHtmlString Container(Action configure)  
  13. {  
  14.     var setting = new ContainerSetting();  
  15.     configure(setting);  
  16.   
  17.     return helper.When(JqueryBind.InitIncoding | JqueryBind.IncChangeUrl)  
  18.                  .Do()  
  19.                  .AjaxGet(setting.Url)  
  20.                  .OnSuccess(dsl =>  
  21.                                 {  
  22.                           dsl.Self().Core().Insert.WithTemplateByUrl(setting.Tmpl).Html();  
  23.                           dsl.WithId(setting.DependencyId).Core().Trigger.Incoding();  
  24.                                 })  
  25.                  .AsHtmlAttributes(new { id = setting.Id })  
  26.                  .ToDiv();  
  27. }  
Footer
  1. @(Html.When(JqueryBind.None)  
  2.       .Do()  
  3.       .Direct(new FooterVm  
  4.                         {  
  5.         AllCount = Selector.Jquery.Class("toggle").Length(),  
  6.         IsCompleted = Selector.Jquery.Class("toggle").Is(JqueryExpression.Checked),  
  7.         CompletedCount = Selector.Jquery.Class("toggle")  
  8.                                         .Expression(JqueryExpression.Checked)  
  9.                                         .Length(),  
  10.                         }))  
  11.       .OnSuccess(dsl =>  
  12.                      {  
  13.                       string urlTmpl = Url.Dispatcher()  
  14.                                           .Model(new TodoFooterTmplVm  
  15.                                                      {  
  16.                                                            ContainerId = containerId  
  17.                                                      })  
  18.                                           .AsView("~/Views/Home/Todo_Footer_Tmpl.cshtml");  
  19.                        dsl.Self().Core().Insert.Prepare().WithTemplateByUrl(urlTmpl).Html();  
  20.                      })  
  21.       .AsHtmlAttributes(new { id = footerId })  
  22.       .ToDiv())  
What’s what
  • When(JqueryBind.None) - indicate target events

    None - When allows to indicate any user’s event as a line “MySpecialEvent”, but experience has shown that for menu scripts one is enough.

  • Do - behavior of event

  • Direct - can be examined as bib of action that perform no actions, but can work with data.

    AllCount
    - get the number of objects with “toggle” class.

Note

Enhancing Method (in place of Length) could be used to call any jQuery method and to write C# extensions over JquerySelectorExtend

  • IsCompleted - check up for tagged objects with “toggle” class

Note

If opportunities of ready-made jQuery selector are not enough, so you can use Selector.Jquery.Custom(“your jquery selector”

  • CompletedCount - get the numBer of tagged objects with “toggle” class

Note

To get the JS function value:

  1. Selector.JS.Call("MyFunc",new []  
  2.                               {  
  3.                                   Selector.Jquery.Self(),  
  4.                                   "Arg2"                   
  5.                               })  
  • OnSuccess - realize after successful finish of AjaxGet.

  • Insert prepare data to self by template - put in prepared data ( prepare ) from direct through template (Todo_Footer_Tmpl below ) in the current element.

Note

Before to put data in “prepare” fulfil selectors, that are in the fields.

  • AsHtmlAttributes - collect IML code.

  • ToDiv - pack up getting attributes in the tag div.
Todo List Tmpl

Template markup for todo list building

  1. @using (var template = Html.Incoding().Template())  
  2. {  
  3.  <ul>  
  4.   @using (var each = template.ForEach())   
  5.    {  
  6.     @using (each.Is(r => r.Active))   
  7.     { @createCheckBox(true) }  
  8.     @using (each.Not(r => r.Active))  
  9.     { @createCheckBox(false) }  
  10.   
  11.     <li class="@each.IsInline(r=>r.Active,"completed")">  
  12.       <label>@each.For(r=>r.Title)</label>  

Note

Back code is more than shown in the example (logic of elements is deleted). It’s made for comfortable explanation of template

What is what?
  • Html.Incoding().Template() - open the context ( in the context of using) template building
  • template.ForEach() - start to iterate through elements ( in the context of using)
  • using(each.Is(r=>r.Active)) - start to iterate through elements ( in the context of using)
  • createCheckBox - anonymous function C# функция for making checkbox (description below)
  • each.IsInline(r=>r.Active,"completed") - if after Active true so get back “completed”

Note

There are also IsNotLine and IsLine.

  • each.For(r => r.Title) - depict the value of Title field

Note

Accessing to fields happens on the base indicated model (Yep, I’m again about typification)

Other elements Button del
  1. @(Html.When(JqueryBind.Click)  
  2.       .Do()  
  3.       .AjaxPost(Url.Dispatcher().Push(new DeleteEntityByIdCommand  
  4.                                  {  
  5.                                          Id = each.For(r => r.Id),  
  6.                                          AssemblyQualifiedName = typeof(Todo).AssemblyQualifiedName  
  7.                                  }))  
  8.       .OnBegin(r =>  
  9.                    {  
  10.                        r.WithSelf(s => s.Closest(HtmlTag.Li)).Core().JQuery.Manipulation.Remove();  
  11.                        r.WithId(Model.FooterId).Core().Trigger.Incoding();  
  12.                        r.WithId(toggleAllId).Core().Trigger.None();  
  13.                    })  
  14.       .AsHtmlAttributes(new { @class = "destroy" })  
  15.       .ToButton(""))  
What is what
  • When(JqueryBind.Click) - – indicate target event

  • Do - behavior of event

  • AjaxPost- indicate Url, which will be sent to ajax request 

    Id- value from Todo

    AssemblyQualifiedName - get the name of element type ( or another C# code ).

  • OnBegin- take before the beginning of action (AjaxPost)

Note

Of course, it’s better to use OnSuccess, because a mistake may happen on the server (timeout or something else) and transaction will not complete because OnBegin works before a call of AjaxPost, but the TodoMVC examples on js framework use local storage (which is faster than ajax) and that’s why I’ve dodged in order not to lose operation speed.

  • Remove closest LI - delete the closest LI
  • Trigger incoding to footer id - start the whole IML code for element footer (description above)
  • Trigger none to toggle all - start IML code (only None chain) for element Toggle All (description below)

Note

If for both to call the same trigger, it would be possible to use the following variant:

dsl.WithId(Model.FooterId, toggleAllId).Core().Trigger.Incoding();
  • AsHtmlAttributes - collect IML code
  • ToButton- pack up getting attribute in tag button

Note

ToButton allows to indicate contents, but in this case it’s not necessary because the picture installs through CSS

Button Del ( alternative variant )
  1. @Html.Todo().Verb(setting =>  
  2.        {  
  3.            setting.Url = Url.Dispatcher().Push(new DeleteEntityByIdCommand  
  4.                                                    {  
  5.                                  Id = each.For(r => r.Id),  
  6.                                  AssemblyQualifiedName = typeof(Todo).AssemblyQualifiedName  
  7.                                                    });  
  8.            setting.OnBegin = dsl =>  
  9.                                  {  
  10.                    dsl.WithSelf(s => s.Closest(HtmlTag.Li)).Core().JQuery.Manipulation.Remove();  
  11.                    dsl.WithId(Model.FooterId).Core().Trigger.Incoding();  
  12.                    dsl.WithId(toggleAllId).Core().Trigger.None();  
  13.                                  };  
  14.            setting.Attr = new { @class = "destroy" };  
  15.        })  
Note

OnBegin take Action, that allows to scale easily your “extensions” instill in it IML. (more examples further)
  1. public class VerbSetting  
  2. {  
  3.     public string Url { getset; }  
  4.   
  5.     public Action<IIncodingMetaLanguageCallbackBodyDsl> OnBegin { getset; }  
  6.   
  7.     public Action<IIncodingMetaLanguageCallbackBodyDsl> OnSuccess { getset; }  
  8.   
  9.     public object Attr { getset; }  
  10.   
  11.     public string Content { getset; }  
  12. }  
  13.   
  14. public MvcHtmlString Verb(Action<VerbSetting> configure)  
  15. {  
  16.     var setting = new VerbSetting();  
  17.     configure(setting);  
  18.   
  19.     return this.helper.When(JqueryBind.Click)  
  20.                .Do()  
  21.                .AjaxPost(setting.Url)  
  22.                .OnBegin(dsl =>  
  23.                             {  
  24.                                 if (setting.OnBegin != null)  
  25.                                     setting.OnBegin(dsl);  
  26.                             })  
  27.                .OnSuccess(dsl =>  
  28.                               {  
  29.                                   if (setting.OnSuccess != null)  
  30.                                       setting.OnSuccess(dsl);  
  31.                               })  
  32.                .AsHtmlAttributes(setting.Attr)  
  33.                .ToButton(setting.Content);  
  34. }  

Note

As long Verb uses in some scripts, it's easy to make optional parameters. I check them on “null” and assign a value on default

Checkbox Completed
  1. var createCheckBox = isValue => Html.When(JqueryBind.Change)  
  2.                                     .Do()  
  3.                                     .AjaxPost(Url.Dispatcher().Push(new ToggleTodoCommand  
  4.                                                        {  
  5.                                                      Id = each.For(r => r.Id)  
  6.                                                        }))  
  7.                                     .OnBegin(dsl =>  
  8.                                                   {  
  9.                              dsl.WithSelf(r => r.Closest(HtmlTag.Li))  
  10.                                 .Behaviors(inDsl =>  
  11.                                                         {  
  12.                    inDsl.Core().JQuery.Attributes.RemoveClass("completed");  
  13.                    inDsl.Core().JQuery.Attributes.AddClass("completed")  
  14.                                       .If(builder => builder.Is(() => Selector.Jquery.Self()));  
  15.                                                          });  
  16.   
  17.                              dsl.WithId(Model.FooterId).Core().Trigger.Incoding();  
  18.                              dsl.WithId(toggleAllId).Core().Trigger.None();  
  19.                                                   })  
  20.                                      .AsHtmlAttributes(new {@class="toggle" })  
  21.                                      .ToCheckBox(isValue);  

Note

As long Verb uses in some scripts, it's easy to make optional parameters. I check them on “null” and assign a value on default

What is what
  • When(JqueryBind.Change) - indicate target event
  • Do - – behavior of event
  • AjaxPost - indicate Url, which will be send to ajax request

Note

AjaxPost and AjaxGet is “denominate“ version of Ajax, which has many additional tuning OnBegin – take before the start actions (AjaxPost)

  • OnBegin - take before the start actions (AjaxPost)
  • Remove class on closest LI - delete class “completed” at the nearest LI
  • Add class on closest LI if self is true- add class “completed”

Note

Now in IML doesn’t realized a possibility “else”, but in 2.0 version is planted

  • AsHtmlAttributes - collect IML code and install the value “toggle” to attribute “class”
  • ToCheckBox - pack up
Filter by type todo
  1. @{  
  2.     const string classSelected = "selected";  
  3.     var createLi = (typeOfTodo,isFirst) => Html.When(JqueryBind.InitIncoding)  
  4.                                                .Do()  
  5.                                                .Direct()  
  6.                                                .OnSuccess(dsl =>  
  7.                                                            {  
  8.            var type = Selector.Incoding.HashQueryString(r => r.Type);  
  9.                if (isFirst)  
  10.            dsl.Self().Core().JQuery.Attributes.AddClass(classSelected)  
  11.                                    .If(s => s.Is(() => type == ""));  
  12.   
  13.            dsl.Self().Core().JQuery.Attributes.AddClass(classSelected)  
  14.                                    .If(s => s.Is(() => type == typeOfTodo.ToString()));  
  15.                                                               })  
  16.                                                .When(JqueryBind.Click)  
  17.                                                .Do()  
  18.                                                .Direct()  
  19.                                                .OnSuccess(dsl =>  
  20.                                                            {  
  21.            dsl.WithSelf(r => r.Closest(HtmlTag.Ul).Find(HtmlTag.A))  
  22.               .Core().JQuery.Attributes.RemoveClass(classSelected);  
  23.            dsl.Self().Core().JQuery.Attributes.AddClass(classSelected);                                            
  24.                                                            })  
  25.                                                .AsHtmlAttributes(new {   
  26.                           href = "#!".AppendToHashQueryString(new { Type = typeOfTodo })  
  27.                                                                      })  
  28.                                                .ToLink(typeOfTodo.ToString());  
  29. }  
  30.   
  31.  <li>  @createLi(GetTodoByClientQuery.TypeOfTodo.All,true)        </li>  

Note

One more example how to realize anonymous functions in the context of “razot view”

What is what
  • When(JqueryBind.InitIncoding) - indicate target event
  • Do - – behavior event
  • Direct - realize noting
  • OnSuccess - realize after successful finish

Note

There is no differences between “OnBegin” and “OnSuccess” for”Direct”, but OnError and OnBreak works in the same way as for others.

  • var type - declare a variable that we will use in expressions.

  • add class to self if IsFirst is true And type is Empty - add class if current element is the first and in “type” is empty.

  • add class to self if type is current type - add class to current element if “type” is equal to argument typeOfTodo

  • When(JqueryBind.Click) - indicate target event

  • Do - behavior of event

Note

We don’t cancel behavior of hyperlink because we need the browser to update location

  • Direct - take noting
  • remove class - delete class selected at all A, that are in the nearest UL
  • add class to self - add class selected to the current element
  • AsHtmlAttributes - collect IML code and install attribute “href”

Filter by type todo ( alternative method )
  1. <li>  
  2.     @Html.Todo().LiHash(setting =>  
  3.                             {  
  4.                          setting.IsFirst = true;  
  5.                          setting.SelectedClass = classSelected;  
  6.                          setting.Type = GetTodoByClientQuery.TypeOfTodo.All;  
  7.                             })                      
  8. </li>  
  1. public class LiHashSetting  
  2. {              
  3.     public bool IsFirst { getset; }  
  4.   
  5.     public string SelectedClass { getset; }  
  6.   
  7.     public GetTodoByClientQuery.TypeOfTodo Type { getset; }  
  8. }  
  9.   
  10. public MvcHtmlString LiHash(Action configure)  
  11. {  
  12.     var setting = new LiHashSetting();  
  13.     configure(setting);  
  14.   
  15.     return helper.When(JqueryBind.InitIncoding)  
  16.                  .Do()  
  17.                  .Direct()  
  18.                  .OnSuccess(dsl =>  
  19.                                 {  
  20.      var type = Selector.Incoding.HashQueryString(r => r.Type);  
  21.           if (setting.IsFirst)  
  22.      dsl.Self().Core().JQuery.Attributes.AddClass(setting.SelectedClass)  
  23.                              .If(s => s.Is(() => type == ""));  
  24.   
  25.      dsl.Self().Core().JQuery.Attributes.AddClass(setting.SelectedClass)  
  26.                              .If(s => s.Is(() => type == setting.Type.ToString()));  
  27.                                 })  
  28.                  .When(JqueryBind.Click)  
  29.                  .Do()  
  30.                  .Direct()  
  31.                  .OnSuccess(dsl =>  
  32.                                 {  
  33.      dsl.WithSelf(r => r.Closest(HtmlTag.Ul).Find(HtmlTag.A))  
  34.         .Core().JQuery.Attributes.RemoveClass(setting.SelectedClass);  
  35.      dsl.Self().Core().JQuery.Attributes.AddClass(setting.SelectedClass);  
  36.                                 })  
  37.                  .AsHtmlAttributes(new {   
  38.                        href = "#!".AppendToHashQueryString(new { Type = setting.Type })  
  39.                                        })  
  40.                  .ToLink(setting.Type.ToString());  
  41. }  
Absolute advantages!

The advantages of IML I’ve tried to show in the last article, but it wasn’t convincing, that’s why I will try again:

  • Typification - Of course, each looks at typification from its own point of view. Somebody think that here you have to write more codes (that’s right), others doesn’t have enough flexibility that is inherent to non-typification languages, but IML is first of all C#, so those developers who chose it, I think, will appreciate this advantage.

  • Powerful extensions - In the article I gave some of them, but there are much more in practice. I will give some more examples to put the words into action:

  • Drop down
  1. @Html.For(r=>r.HcsId).DropDown(control =>  
  2.                                {  
  3.                 control.Url = Url.Action("HealthCareSystems""Shared");  
  4.                 control.OnInit = dsl => dsl.Self().Core().Rap().DropDown();  
  5.                 control.Attr(new { @class = "selectInput", >"width:375px" });  
  6.                                })  
  • Dialog
  1. @Html.ProjectName().OpenDialog(setting =>  
  2.                          {  
  3.                             setting.Url = Url.Dispatcher()  
  4.                                              .Model<GroupEditProviderOrderCommand>()  
  5.                                              .AsView("~/Views/ProviderOrder/Edit.cshtml");  
  6.                             setting.Content = "Edit";  
  7.                             setting.Options = options => { options.Title = "Edit Order"; };  
  8.                          })  

Note: OnInit takes Action<JqueryUIDialogOptions>, that allows to scale easily your extensions instill in it IML. The list could be endless, but the main idea is that IML allows to perform any task, while html extensions solves a problem with design reuse.

  1. @(Html.ProjectName()  
  2.       .Grid<CTRPrintLogModel>()  
  3.       .Columns(dsl =>  
  4.                {  
  5.             dsl.Template(@<text>  
  6.                           <span>@item.For(r=>r.Comment)</span>  
  7.                                     </text>)  
  8.                   .Title("Comment")  
  9. and more ...
  • Tabs
  1. @(Html.Rap()  
  2.       .Tabs<Enums.CarePlanTabs>()  
  3.       .Items(dsl =>  
  4.              {  
  5.    dsl.AddTab(Url.Action("GapsAndBarriersInc""GapsAndBarriers"), Enums.CarePlanTabs.GapsAndBarriers);    dsl.AddTab(Url.Action("RedFlags""PatientRedFlag"), Enums.CarePlanTabs.RedFlags);                      dsl.AddTab(Url.Action("Goals""IncGoal"), Enums.CarePlanTabs.SelfCareGoals);  
  6.    dsl.AddTab(Url.Action("Index""IncAppointment"), Enums.CarePlanTabs.Appointments);          
  7.              }))  

Note

Every developer who knows html extensions can build such element for his project needs
  • The Work with hash - in this article we examined only on IncChangeUrl level, but we have:

    Hash.Fetch - put values from hash into (sandbox) elements
    Hash.Insert/Update - – put values into hash from elements
    Hash.Manipulate - allows delicately (set/ remove by key) tune current hash

  • AjaxHash - is an analog of Submit, not for form, but for Hash

  • The Work with Insert - – for TODO realization I didn’t have to use, but in real projects it’s used everywhere

    Insert Generic

    All the examples above were built on one model, but it often happens that scripts where findings are “containers”. In this case in Insert there is a possibility to indicate with what part of model we work through For and also “template” for each of its own
  1. Html.When(JqueryBind.InitIncoding)  
  2.     .Do()  
  3.     .AjaxGet(Url.Action("FetchComplex""Data"))  
  4.     .OnSuccess(dsl =>  
  5.                    {  
  6.          dsl.WithId(newsContainerId).Core()  
  7.             .Insert.For<ComplexVm>(r => r.News).WithTemplateByUrl(urlTemplateNews).Html();  
  8.          dsl.WithId(contactContainerId).Core()  
  9.             .Insert.For<ComplexVm>(r => r.Contacts).WithTemplateByUrl(urlTemplateContacts).Html();  
  10.                    })  
  11.     .AsHtmlAttributes()  
  12.     .ToDiv()  
The Work with validation (server as a client) -

There are instrument for validation in may js framework, but IML has integration with server and backing any validation engine ( FluentValidation, standart MVC) with no necessity to write additional code.
  • Code command
  1. if (device != null)  
  2.    throw IncWebException.For<AddDeviceCommand>(r => r.Pin, "Device with same pin is already exist");  
  • Code view
.OnError(dsl => dsl.Self().Core().Form.Validation.Refresh())

Note

Handler OnError must be attached to the element that causes action ( submit , ajaxpost or etc ).

  •  Less scripts - with increase of project js framework demands lots of js files, but IML has fixed set of libraries (plug-ins not counted).
  • Typificated template - about typification by kind, but for template constructing it’s very important.
  • template replace by engine - choose any of them, syntax is the same.
  • .Complex solution - IML is a part of Incoding Framework and in contrast to js framework we have full infrastructure (server/client/ unit testing ) for projects developing that is tightly integrated with each other.
Conclusion

At realization of IML I’ve followed the rule: less updates to the page, I mean I recounted this all on the client, but in practice (of ours projects) often the weak part is server, because lot of actions are impossible or preferable on client. For example, Impossible (because of productivity):

  • Paginated - of the base consists of hundreds of thousands of recordings, it’s wrong to deliver capacity on client
  • Order - the same reason
  • Where - the same reason
  • And other actions that connects with the data base

Difficult calculation on the base values of fields (total amount of order including tax) could be not preferable. It’s better send on server request (with values of fields) and put in results

In the context of IML calculation could be solved by following ways:

  • Single value
  1. var val = Selector.Incoding.AjaxGet(url);  
  2. dsl.WithId(yourId).Core().JQuery.Attributes.Val(val);  
  • Data set
  1. dsl.With(r => r.Name(s => s.Last)).Core().Insert.For<ContactVm>(r => r.Last).Val();  
  2. dsl.With(r => r.Name(s => s.First)).Core().Insert.For<ContactVm>(r => r.First).Val();   
  3. dsl.With(r => r.Name(s => s.City)).Core().Insert.For<ContactVm>(r => r.City).Val();  
I can continue to tell you about IML possibilities (and Incoding Framework) but the article as already long. That’s why those who want to learn more about our tool can find the materials on the Net. I understand to prove that IML is able to solve tasks not worse than popular js framework is rather difficult, but in the next articles I will make a review of autocomplete, Tree View, grid and other popular scripts realization, that will show more possibilities of our toll.


Similar Articles