Since the [last post](http://blog.techdominator.com/article/supporting-complex-type-properties-in-the-dynamic-form-tag-helper.html), the dynamic form tag helper supports generating form groups for complex properties.

Now the html generated by the dynamic form tag helper is not customizable and it would be nice if it was.

There might be numerous reasons for customizing the default behavior, but we are going to focus on the following: styling and using custom html form controls.

In this post we are going to introduce capabilities for tweaking some default behavior and adding custom css classes by using a nested tag helper. 

The full code is in [the usual Github repository](https://github.com/MissaouiChedy/DynamicFormTagHelper).

## Objective

We are going to add capability for tweaking the following form elements:

- The text content of the submit button
- The css classes of the submit button
- For a specific property(form group):
    - Choosing a custom `input` element razor template
    - Adding css classes to the generated `<label>`, `<input>` or validation message `<span>`

Consider the following form:
<div class="img-container">
![Customized generated form](https://blog.techdominator.com/imgs/CustomizedForm.optimized.webp)
</div>

Arbitrary css classes have been applied to the BirthDate `label` as well as to the "Person's full name" `input` element. This is what makes the BirthDate `label` <span style="color:purple">purple</span> and the "Person's full name"'s text <span style="color:yellowgreen">yellowish green</span>(not the real color's name ;-)).

In addition, a custom date time picker widget has been used for the BirthDay field. Here I used the [bootstrap datetimepicker](https://eonasdan.github.io/bootstrap-datetimepicker/) which allows to select dates more conveniently.

Let's now take a look on how to achieve this.

## Customizing behavior with the TweakTagHelper

Let's consider the usage of the dynamic tag helper in the following `cshtml` view:
<script src="https://gist.github.com/MissaouiChedy/27dbb3b2bed56f897d205f2ce5b84d1d.js"></script>

Here you will notice the usage of the new `tweak` nested tag helper.
The `TweakTagHelper` is intended to be used inside the `DynamicFormTagHelper` in order to modify the generation behavior of a form group related to a specific property. 

In this regard, it can accepts one of the view model's properties as an argument along with the aspects to customize, which can be one of the following:
 - `asp-input-path` the path to a custom html form control
 - `asp-label-classes`, `asp-input-classes` and `asp-validation-classes` the additional css classes that are going to be added to the relevant form group element(`label`, `input` or validation `span`)
 
It is possible to target properties nested under complex types as we can see in the last used `tweak` instance(targeting `OwnedDog.BirthDate`).

The `DynamicFormTagHelper` has been modified to read customization configuration and to take it in account. We are going to see later how this capability is implemented.

## Customizing the Submit Button

Two attributes have been added to the `DynamicFormTagHelper`:
 - `asp-submit-button-text` for specifying the text content
 - `asp-submit-button-classes` for specifying additional css classes for the submit button

Here is an example usage:
<script src="https://gist.github.com/MissaouiChedy/7f7362f05e3fb548ace8240781fffb6b.js"></script>

This sets the submit button text to "Create Person!" and adds the `btn-success` class to it.

## Reading Tweaking Configuration in the DynamicFormTagHelper

Consider the following snippet from the `DynamicFormTagHelper`:
<script src="https://gist.github.com/MissaouiChedy/d6cabcb76e3cc6f95a55e505560d3006.js"></script>

Under the `DynamicFormTagHelper.ProcessAsync` method we create an object belonging to the `TweakingConfiguration` class, we pass this object to the `context` object and we launch the execution of the children tag helpers content.

The `TweakingConfiguration` object acts as a data transfer object that is going to be populated by the children `TweakTagHelper`.

As we can see in the following example the `TweakingConfiguration` object named `tweakConfig` is subsequently passed to the `FormGroupBuilder.GetFormGroup` method and is also used directly to properly generate the submit button:

<script src="https://gist.github.com/MissaouiChedy/cf446a7f5b9515363583e1942f26a5cd.js"></script>

### Transferring Data from the TweakingTagHelper to the DynamicFormTagHelper

As we saw in [The Very Basics of Nesting for Tag Helpers](http://blog.techdominator.com/article/the-very-basics-of-nesting-for-tag-helpers.html), child to parent communication is performed via the `TagHelperContext` object that is passed to each of the parent and children `ProcessAsync` method.

Let's consider the following code it's the actual `TweakingTagHelper` class implementation:

<script src="https://gist.github.com/MissaouiChedy/001c1fe359763d4e92c68b50f66705bb.js"></script>

First, the `HtmlTargetElement` attribute is slapped on the tag helper class to allow its usage only under the `dynamic-form` tag helper.

Then, you can see that `TweakTagHelper` defines the properties mapped to the relevant html attributes.

Finally, the `TweakTagHelper.ProcessAsync` creates a `PropertyTweakingConfiguration` object that represents *the customization of a specific property*. The created instance is then added to the `TweakingConfiguration` object fetched from the `TagHelperContext`. Keep in mind here that the fetched `TweakingConfiguration` instance is the same one referenced by the `dynamic-form` tag helper.

Here we can see that the `TweakTagHelper` fulfills a very simple responsibility: *reading data from the cshtml view and passing its parent tag helper (`dynamic-form`) in a convenient format.*

The implementations of the [`TweakingConfiguration`](https://github.com/MissaouiChedy/DynamicFormTagHelper/blob/master/TagHelpers/DynamicFormTagHelper.cs#L22) and the [`PropertyTweakingConfiguration`](https://github.com/MissaouiChedy/DynamicFormTagHelper/blob/master/TagHelpers/DynamicFormTagHelper.cs#L13) classes are very basic, you can take a look at them in the Github repository. 

Now let's get to the `FormGroupBuilder` modifications. 

## Using the Tweaking Configuration inside the FormGroupBuilder

First off, the `FormGroupBuilder` has been modified and became a regular class (as opposed to a [static class](https://msdn.microsoft.com/en-us/library/79b3xss3.aspx)).

As you might know the form generation process depends on the following services: `ViewContext`, `HtmlEncoder`, `IHtmlGenerator` and recently `IHtmlHelper`.

Passing the instances of these services to each method involved in the form group rendering process became painful so I refactored it to a regular class with the previous dependencies defined as private fields.

Then, a new argument `tweakingConfig` argument has been added to the  `FormGroupBuilder.GetFormGroup` method. This argument is expected to contain the `TweakingConfiguration` object built by the various `tweak` tag helpers used.

The `tweakingConfig` object is then passed to the private methods responsible for rendering the elements of the form group in order to allow them to take the tweaking configuration into account.

### Custom Template Rendering
Let's take a look at the private `FormGroupBuilder.buildInputHtml` method:

<script src="https://gist.github.com/MissaouiChedy/ee350f590d82c146271361e37a5bee6b.js"></script>

When a tweaking configuration is available for the currently processed `property` and the configuration defines a form control template via the `InputTemplatePath` property, the specified template is rendered instead of the default `InputTagHelper`.

The `renderInputTemplate` method uses the `IHtmlHelper.Editor` method to render the form control:

<script src="https://gist.github.com/MissaouiChedy/9667156245dd0ffe416e100ff4f4fa76.js"></script>

The previous method uses a classic `IHtmlHelper` take a look at [Using the old HtmlHelper inside tag helpers](http://blog.techdominator.com/article/using-html-helper-inside-tag-helpers.html) for more details.

### Adding Custom CSS Classes

Adding custom css classes is straightforward, we just pass a `TagHelperAttributeList` populated with the developer defined classes to the existing [`GetGeneratedContentFromTagHelper`](https://github.com/MissaouiChedy/DynamicFormTagHelper/blob/master/TagHelpers/FormGroupBuilder.cs#L135) method as in the following `buildLabelHtml` method:

<script src="https://gist.github.com/MissaouiChedy/3391f45980c7dea23f31c12edfc526c1.js"></script>

Notice here the usage of the [C# 6 null conditional operator](https://davefancher.com/2014/08/14/c-6-0-null-propagation-operator/) when passing the eventually configured classes.

## Closing Thoughts

In this attempt, we showed that it was possible to introduce configurability via nested tag helpers to the `dynamic-form` tag helper.

Usually developers would want to influence the form rendering via the model class and the attributes slapped on it and its properties. But it could be cleaner to specify some stuff in the cshtml view such as css classes.

A lot of work still needs to be done to make the `dynamic-form` tag helper more reliable and usable, at this point it is just a prototype.

Finally, using the `HtmlHelper.Editor` reminded me of the old `EditorTemplates` and `DisplayTemplates` facility which allowed to place display and editor templates named after a specific type in a specific location for later use via the `EditorFor` and `DisplayFor` methods.

`EditorFor` is able to generate a form control for a specific property and is able fetch a custom editor templates by type name automatically if it is placed under `Shared/EditorTemplates`.

That allowed the developer to specify a default editing widget for a specific type. 

I wonder if we could bring this capability to tag helpers... 

