In addition to @Vincent's solutions, here are other ways to accomplish enabling/disabling a control based on a condition.
The quickest solution is the first option below, using the ExpandoObject
to add on the disabled
attribute when the condition is met. The last option below, the custom Select Tag Helper, provides a cleaner implementation of a <select>
tag that requires some processing.
All that matters is the presence of the disabled attribute
Note the following from MDN, stated in this SO post:
All that matters is that if the [disabled] attribute is present at all, regardless of its actual value, its value is considered to be true. The absence of the attribute means its value is false.
Use ExpandoObject to add disabled
attribute
@{
dynamic htmlAttributes = new System.Dynamic.ExpandoObject();
htmlAttributes.id = "ddlOption" + this.ViewData["TabId"];
htmlAttributes.tabindex = 5001;
htmlAttributes.title = "Options";
if (this.Model.Options.Count() > 1) { htmlAttributes.disabled = "disabled"; }
}
@Html.DropDownListFor(m => m.SelectedOptions,
new SelectList(this.Model.Options, "Key", "Value"),
"Select...",
(object)htmlAttributes)
Custom HTML Helper chained to DropDownListFor
See this SO post. The custom HTML Helper allows for a cleaner implementation of C#/Razor syntax in your Razor page. The code below uses a custom HTML Helper named .DisableIfFilled(this.Model.Options.Count())
that takes one parameter.
@Html.DropDownListFor(m => m.SelectedOptions,
new SelectList(this.Model.Options, "Text", "Value"),
"Select...",
new { @id = "ddlOption" + this.ViewData["TabId"], tabindex = 5001, title="Options" }).DisableIfFilled(this.Model.Options.Count())
DisableHtmlControlExtension.cs
using Microsoft.AspNetCore.Html;
namespace WebApplication1.Helpers
{
public static class DisableHtmlControlExtension
{
public static IHtmlContent DisableIfFilled(
this IHtmlContent htmlContent, int numOfOptions)
{
if (numOfOptions > 1)
{
StringWriter writer = new System.IO.StringWriter();
htmlContent.WriteTo(writer, System.Text.Encodings.Web.HtmlEncoder.Default);
string html = writer.ToString();
const string disabled = "\"disabled\"";
html = html.Insert(html.IndexOf(">",
StringComparison.Ordinal), " disabled= " + disabled);
return new HtmlString(html);
}
return htmlContent;
}
}
}
Add the following to the Razor page:
@using WebApplication1.Helpers
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
Custom Select Tag Helper
Instead of the DropDownListFor
HTML Helper, the Select Tag Helper provides clearer readability for <select>
tag output.
<select asp-for="SelectedOptions" asp-items="@this.Model.Options"
class="ctrl" tabindex=5001 title="Options" disableif>
<option value="">Select...</option>
</select>
DisableIfSelectTagHelper.cs
using Microsoft.AspNetCore.Razor.TagHelpers;
namespace WebApplication1.Helpers
{
[HtmlTargetElement("select", Attributes = "disableif")]
public class DisableIfSelectTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
// https://rion.io/2017/04/27/extending-tag-helpers-in-asp-net-core-applications/
base.Process(context, output);
string content = output.PostContent.GetContent();
// Process only if more than on one instance of the
// '<option>' tag exists.
// https://stackoverflow.com/questions/17502488/how-to-identify-if-a-string-contains-more-than-one-instance-of-a-specific-charac
if (content.IndexOf("<option") != content.LastIndexOf("<option"))
{
output.Attributes.Add("disabled", null);
}
// Remove custom 'disableif' attribute that's used
// to trigger the tag helper.
TagHelperAttribute attr = output.Attributes.First(t => t.Name == "disableif");
output.Attributes.Remove(attr);
}
}
}
Add the following to the Razor page:
@using WebApplication1.Helpers
@addTagHelper WebApplication1.Helpers.DisableIfSelectTagHelper, WebApplication1