Scrum Masters

A form-entry Tag Helper | Passion for Coding


& #13;. .

Composing line of work applications generally suggests developing a great deal of types for information entry. Composing the HTML for them over and over once again bores and likewise suggests copy-pasting the design structure into each and every single type. Copy-pasting works great as long as we one mores than happy with the style, however when it requires to be changed (beyond what’s possible by CSS), all types in the application requirement to alter. To treat this, I developed a form-entry tag assistant. Now developing an entry for a field in a type is as easy as << form-entry asp-for=" LocationName"/>>

Utilizing the default scaffolding in Visual Studio, I would get a type that duplicates the very same pattern over and over once again, for each residential or commercial property of the view design.

<< << << <
    << << << < << <<<<
    <<< type asp-action=" Produce">
<> 
 < div asp-validation-summary=" ModelOnly">  
<< div class=" form-group" > 
 < label asp-for=" Call" class
<=" control-label" >  
 < input asp-for=" Call" class=" form-control><"/ > 
<.
<< period asp-validation-for>
<=" Call" class=" text-danger"><>  
< 
. < div class=" form-group" > 
 < label asp-for=" Address" class=" control-label" >  
<< input asp-for="
 
. < period asp-validation-for="  
  
. < div class=" form-group" > 
 < label asp-for=" City" class=" control-label" >  
<< input asp-for="
 
. < period asp-validation-for=" City" class
=
<" text-danger" >  
  
. < div class=" form-group" > 
 < input type= "send" worth =" Produce" class= "btn btn-default"/ > 
.  
.   Utilizing my>form-entry tag assistant, the code needed is significantly less. 
          << form-entry asp- for =" Call"/  > < form-entry asp- for<=" Address" >
        >< form-entry asp- for =">
/ >       < type asp-action=" Produce" > 
 < div>
asp-validation-summary=
<" ModelOnly" class=" text-danger" >  
 < form-entry asp-for=" Call"/ > 
. < form-entry asp-for =" Address"/ > 
. < form-entry asp-for =" City"/ > 
. < div class=" form-group" > 
 < input type =" send" worth =" Produce "class=" btn btn-default"/ > 
.  
. 
         The style goals for the form-entry  tag assistant can be summed up as  DRY(* ). DRY is brief for Do Not Repeat Yourself One factor for that is to lower typing. However that is not the most vital part. No, the fundamental parts are readability and maintainability. With the   form-entry tag assistant the code gets much cleaner and it is much easier to see what fields the type are really comprised of. The other vital part is maintainability. Duplicating the very same html pattern over and over once again in all types in application suggests spreading out the understanding of how types look throughout the application. That understanding must remain in one single location. Utilizing Razor I although believed it would be great to be able to utilize Razor for the design template itself, to quickly have the ability to call the tag assistants for creating labels and so on properly. Regrettably I didn't prosper in this goal. The factor is that the tag assistants are developed on the presumption that the razor file includes the kind of the design. And here we wish to have the ability to utilize a generic Razor declare all various designs in the task. Recycling Tag Helpers When the Razor course ended up difficult, I rather took a look at calling the tag assistants from code. This too ended up being difficult as it would need creating the ideal context for a tag assistant. However thanks to the layered architecture of the tag assistants recycle was still possible. The integrated in tag assistants do refrain from doing the Html generation themselves. Rather they depend on an 
     IHtmlGenerator to do that. And the  IHtmlGenerator ended up te be relatively easy to call from my customized tag assistant.
     public class  FormEntryTagHelper:  TagHelper.
 {
         personal readonly IHtmlGenerator htmlGenerator; personal readonly  HtmlEncoder htmlEncoder;
.
 public FormEntryTagHelper( IHtmlGenerator htmlGenerator, HtmlEncoder htmlEncoder
        ) { this htmlGenerator =  htmlGenerator; this  htmlEncoder
         = htmlEncoder;} 
.
 personal  const string ForAttributeName  =" asp-for";
.

     public ModelExpression  For {
     get;  set;} 
.

         public ViewContext ViewContext  { get; set ;} 
.
 public override space Process
        ( TagHelperContext context, TagHelperOutput output) {.
output  TagName =" div" ;
output
         TagMode = TagMode StartTagAndEndTag ;
output Qualities Include(
    " class", " form-group")
    ;
.
  utilizing( var author 
       = brand-new  StringWriter() ) {.
WriteLabel ( author) ;
WriteInput
    ( author);

WriteValidation( author)

output Material

 AppendHtml( author ToString(
    ));} } 
.
  personal space WriteLabel( TextWriter author) {
     var tagBuilder  = htmlGenerator  GenerateLabel
    (
ViewContext,.
 For  ModelExplorer,.

     For Call,.
labelText :  null
    ,.
htmlAttributes:   brand-new { @ class
         =" control-label" } ); 
.
tagBuilder WriteTo ( author, htmlEncoder);} 
    
.
 personal space WriteInput
( TextWriter author) {

tagBuilder = htmlGenerator GenerateTextBox( ViewContext,. For
ModelExplorer

,.

For

Call,. worth: null

,.
format :  null,.
htmlAttributes:  brand-new
   {  @ class =
  " form-control" } );
.
tagBuilder WriteTo( author, htmlEncoder)
  ;
    } 
.
 personal  space WriteValidation(
     TextWriter author) {  var tagBuilder  =
   htmlGenerator GenerateValidationMessage ( 
ViewContext,.
 For  ModelExplorer,.
 For[HtmlAttributeName(ForAttributeName)]
   Call,.
message :   null,.
tag :  null ,.
htmlAttributes: [HtmlAttributeNotBound]
  [ViewContext]
   brand-new { @  class = " text-danger"}  );
.
tagBuilder   WriteTo( author, htmlEncoder);
  } }  public class FormEntryTagHelper: TagHelper

.
{
. personal readonly IHtmlGenerator
htmlGenerator; 
. personal readonly HtmlEncoder htmlEncoder

;

. 
. public FormEntryTagHelper( IHtmlGenerator htmlGenerator, HtmlEncoder htmlEncoder)

.
{
. this.htmlGenerator = htmlGenerator;

. this.htmlEncoder = htmlEncoder;

.

} 
. 
. personal const string ForAttributeName="asp-for";

.

.
 
. public ModelExpression For {get; set;} 

.

.
 

.(* )
. public ViewContext ViewContext {
get;
set;} 
. 
. public override space Process( TagHelperContext context, TagHelperOutput output)

.
{
.
output.TagName="div"; 
. output.TagMode= TagMode.StartTagAndEndTag;

. output.Attributes.Add(" class", "form-group");

.

. utilizing( var author = brand-new StringWriter())

.
{

. WriteLabel( author);

. WriteInput( author)
;

. WriteValidation( author);

.
output.Content.AppendHtml( writer.ToString());


.} 
.} 
.

.
personal space WriteLabel( TextWriter author) 
. {

.
var tagBuilder= htmlGenerator.GenerateLabel( 
.
ViewContext, 
. For.ModelExplorer, 
. For.Name, 
. labelText: null, 
. htmlAttributes: brand-new {

@class=" control-label"}); 
. 
.
tagBuilder.WriteTo
(
author, htmlEncoder); 
.}

.

. personal space WriteInput (TextWriter author) 
.
{

. var tagBuilder= htmlGenerator.GenerateTextBox( 
.
ViewContext,

.
For.ModelExplorer, 
. For.Name, 
. worth: null, 
.

format:
null, 
. htmlAttributes: brand-new {
@class=" form-control"}
.
); 
. 
. tagBuilder.WriteTo( author,
htmlEncoder) 
;

.} 
. 
. personal space WriteValidation(
TextWriter author) 
.
{

.
var tagBuilder= htmlGenerator.GenerateValidationMessage( 
.
ViewContext,

. For.ModelExplorer, 
. For.Name, 
. message: null, 
. tag: null, 
. htmlAttributes: brand-new {

@class="text-danger"}); 
. 
. tagBuilder.WriteTo( author, htmlEncoder);

.
} 
.
}
  
. Published in 
. C#, Web on 2018-04-23|Tagged Asp.Net Core 

.


.

.

. .