diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs index 25fb1aff3e..a3adc4eae7 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpInputTagHelperService.cs @@ -259,15 +259,14 @@ public class AbpInputTagHelperService : AbpTagHelperService } var idAttr = inputTagHelperOutput.Attributes.FirstOrDefault(a => a.Name == "id"); + var idValue = idAttr?.Value?.ToString(); - if (idAttr == null) + if (string.IsNullOrEmpty(idValue)) { return; } - var infoText = _tagHelperLocalizer.GetLocalizedText(idAttr.Value + "InfoText", TagHelper.AspFor.ModelExplorer); - - inputTagHelperOutput.Attributes.SetAttribute("aria-describedby", infoText); + inputTagHelperOutput.Attributes.SetAttribute("aria-describedby", idValue + "InfoText"); } protected virtual bool IsInputCheckbox(TagHelperContext context, TagHelperOutput output, TagHelperAttributeList attributes) @@ -356,14 +355,18 @@ public class AbpInputTagHelperService : AbpTagHelperService } var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); + var idValue = idAttr?.Value?.ToString(); var localizedText = _tagHelperLocalizer.GetLocalizedText(text, TagHelper.AspFor.ModelExplorer); var div = new TagBuilder("div"); - div.Attributes.Add("id", idAttr?.Value + "InfoText"); div.AddCssClass("form-text"); div.InnerHtml.Append(localizedText); - inputTag.Attributes.SetAttribute("aria-describedby", idAttr?.Value + "InfoText"); + if (!string.IsNullOrEmpty(idValue)) + { + div.Attributes.Add("id", idValue + "InfoText"); + inputTag.Attributes.SetAttribute("aria-describedby", idValue + "InfoText"); + } return div.ToHtmlString(); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs index 854415f8c1..928082d6e8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/AbpSelectTagHelperService.cs @@ -216,15 +216,14 @@ public class AbpSelectTagHelperService : AbpTagHelperService } var idAttr = inputTagHelperOutput.Attributes.FirstOrDefault(a => a.Name == "id"); + var idValue = idAttr?.Value?.ToString(); - if (idAttr == null) + if (string.IsNullOrEmpty(idValue)) { return; } - var infoText = _tagHelperLocalizer.GetLocalizedText(idAttr.Value + "InfoText", TagHelper.AspFor.ModelExplorer); - - inputTagHelperOutput.Attributes.SetAttribute("aria-describedby", infoText); + inputTagHelperOutput.Attributes.SetAttribute("aria-describedby", idValue + "InfoText"); } protected virtual string GetInfoAsHtml(TagHelperContext context, TagHelperOutput output, TagHelperOutput inputTag) @@ -249,14 +248,18 @@ public class AbpSelectTagHelperService : AbpTagHelperService } var idAttr = inputTag.Attributes.FirstOrDefault(a => a.Name == "id"); + var idValue = idAttr?.Value?.ToString(); var localizedText = _tagHelperLocalizer.GetLocalizedText(text, TagHelper.AspFor.ModelExplorer); var div = new TagBuilder("div"); - div.Attributes.Add("id", idAttr?.Value + "InfoText"); div.AddCssClass("form-text"); div.InnerHtml.Append(localizedText); - inputTag.Attributes.SetAttribute("aria-describedby", idAttr?.Value + "InfoText"); + if (!string.IsNullOrEmpty(idValue)) + { + div.Attributes.Add("id", idValue + "InfoText"); + inputTag.Attributes.SetAttribute("aria-describedby", idValue + "InfoText"); + } return div.ToHtmlString(); } diff --git a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo/Abp/AspNetCore/Mvc/UI/Bootstrap/TagHelpers/Form/AbpSelectTagHelperService_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo/Abp/AspNetCore/Mvc/UI/Bootstrap/TagHelpers/Form/AbpSelectTagHelperService_Tests.cs index 79d61ff74d..4ec7948846 100644 --- a/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo/Abp/AspNetCore/Mvc/UI/Bootstrap/TagHelpers/Form/AbpSelectTagHelperService_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Mvc.UI.Tests/Volo/Abp/AspNetCore/Mvc/UI/Bootstrap/TagHelpers/Form/AbpSelectTagHelperService_Tests.cs @@ -55,6 +55,29 @@ public class AbpSelectTagHelperService_Tests service.LastGroupHtml.ShouldContain("aria-describedby=\"TestSelectInfoText\""); } + [Fact] + public async Task Info_text_should_skip_id_and_aria_describedby_when_select_has_no_id() + { + var service = new TestAbpSelectTagHelperService(selectId: null); + var tagHelper = new AbpSelectTagHelper(service) + { + AspFor = CreateModelExpression(), + InfoText = "Description" + }; + + var output = CreateOutput(); + + await tagHelper.ProcessAsync(CreateContext(), output); + + service.LastGroupHtml.ShouldContain("
GetSelectTagAsync(TagHelperContext context, TagHelperOutput output, TagHelperContent childContent) { + var attributes = new TagHelperAttributeList(); + if (!string.IsNullOrEmpty(_selectId)) + { + attributes.Add("id", _selectId); + } + LastSelectTag = new TagHelperOutput( "select", - new TagHelperAttributeList { { "id", "TestSelect" } }, + attributes, (_, _) => Task.FromResult(new DefaultTagHelperContent())) { TagMode = TagMode.StartTagAndEndTag