I am trying to implement server side validation, by changing the class of an HTML child element within a TagHelper. The TagHelper is the "kendo-datepicker", however the current code modifies the class of the "span" tag and I would like to modify the class of the child "input" tag.
After some research it appears GetChildContentAsync may be useful, but all my attempts to use it are failing.
Taghelper:
[HtmlTargetElement("kendo-datepicker")]
[HtmlTargetElement("select")]
[HtmlTargetElement("input")]
public class ValidationErrorClassTagHelper : TagHelper
{
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
//output.Attributes.ContainsName("class")
if (context.TagName == "kendo-datepicker")
{
TagHelperAttribute taghelperAttribute = context.AllAttributes["for"];
if (taghelperAttribute != null)
{
ModelExpression modelExpression = (ModelExpression)taghelperAttribute.Value;
ViewContext.ViewData.ModelState.TryGetValue(modelExpression.Name, out ModelStateEntry entry);
if (entry != null && entry.Errors.Any())
{
output.Attributes.SetAttribute("class", "form-control " + "is-invalid");
}
}
}
}
}
Current (incorrect) HTML Output:
<span class="k-datepicker k-input form-control is-invalid k-input-solid k-input-md k-rounded-md" style=""><input class="form-control k-input-inner valid" required="" data-val="true" data-val-required="Enter the date observed." id="ADR_Date" name="ADR.Date" type="text" value="6/07/2023" data-role="datepicker" role="combobox" aria-expanded="false" aria-haspopup="grid" aria-controls="ADR_Date_dateview" autocomplete="off" aria-disabled="false" aria-readonly="false" aria-describedby="ADR_Date-error" aria-invalid="false"><button aria-label="select" tabindex="-1" class="k-input-button k-button k-icon-button k-button-md k-button-solid k-button-solid-base" type="button" role="button"><span class="k-icon k-i-calendar k-button-icon"></span></button></span>
Unfortunately the taghelperoutput is rendering jquery instead of html:
PostElement = <script>kendo.syncReady(function(){jQuery("#ADR_Date").kendoDatePicker({"format":"d","value":new Date(2023,6,6,0,0,0,0)});});</script>
A very raw idea would be to do
and then get the content via
GetContentas astringand then parse thisstringand thenSetContentafter you added theclass. This is an admittedly dirty solution we should only resort to if there is nothing else that we can do.Alternatively, you could look into
context.Itemsand see whether the input is there under some key. If so, then you could work with that one.