locked
Razor Pages change disabled Attribute if bool condition is true RRS feed

  • Question

  • User-1886250979 posted
    I want to make a <select> field disabled based on a <input> field above the <select> field.

    My html code:

    <fieldset>
                <select id="patchday" asp-for="Patchday" asp-items="Html.GetEnumSelectList<Patchday>()" required>
                <option value="" disabled selected>Patchday</option>
                    </select><br/>
                <span asp-validation-for="Patchday"  class="text-danger"></span>
    </fieldset>

    My C# Code: public bool Disabled { get; set; } = true;

    My C# Code on PageRemote validation function:

            public IActionResult OnPostCheckName() {
                var stage = GetStage();
    
                // Check Stage for Patchday Dropdown
                if (stage.Equals("Produktion")){
                    Disabled = false;
                    return Page();
                }
                
            
                return new JsonResult(true);
            }

    I have tried things like disabled="@Model.Disabled" or disabled="@Model.Disabled ? "disable" : null)" but none of that works. The condition can change multiple times. Is there a way to achieve this?

    Tuesday, August 4, 2020 9:25 AM

Answers

  • User-821857111 posted

    Ludtwigk

    I get this error message when i try it:  

    The tag helper 'select' must not have C# in the element's attribute declaration area.

    Opt out of tag helper processing for that tag: https://www.learnrazorpages.com/razor-pages/tag-helpers/#selective-tag-processing

    Or just use a standard HTML tag without the asp-for attributes:

    <select id="PatchDay" name="PatchDay" @(Model.Disabled ? "disabled" :null)>
        <option>Default option</option>
        @foreach(var x in Html.GetEnumSelectList<PatchDay>())
        {
            <option value="@(x.Value)" selected="@(Model.PatchDay == x.Value)">@x.Text</option>
        }
    </select>

    Actually, Razor conditional attributes work with disabled too:

    <select id="PatchDay" name="PatchDay" disabled="@Model.Disabled">
        <option>Default option</option>
        @foreach(var x in Html.GetEnumSelectList<PatchDay>())
        {
            <option value="@(x.Value)" selected="@(Model.PatchDay == x.Value)">@x.Text</option>
        }
    </select>

    If Model.Disabled evaluates to false or null, the disabled attribute is not rendered at all. If it evaluates to true, it is rendered as disabled="disabled"

    https://www.mikesdotnetting.com/article/201/cleaner-conditional-html-attributes-in-razor-web-pages

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, August 5, 2020 2:05 PM

All replies

  • User-474980206 posted

    In html the disabled attribute does not require a value, so no matter what you set the value to its disabled (by convention it’s common to use disabled=“disabled”). It’s the same for selected. try

    <option @(Model.Disabled ? “disabled” : “”) >

    Tuesday, August 4, 2020 2:47 PM
  • User-1886250979 posted

    But i want to make the select field disabled not the option

    Tuesday, August 4, 2020 3:00 PM
  • User-821857111 posted

    But i want to make the select field disabled not the option
    Move the conditional check to the select element.

    <select id="patchday" asp-for="Patchday" asp-items="Html.GetEnumSelectList<Patchday>()" required @(Model.Disabled ? "disabled" : null )>
    Tuesday, August 4, 2020 4:10 PM
  • User711641945 posted

    Hi Ludtwigk,

    >I have tried things like disabled="@Model.Disabled" or disabled="@Model.Disabled ? "disable" : null)" but none of that works. The condition can change multiple times. Is there a way to achieve this?

    For you set the Disabled=true in your C# code,so when you firstly render the razor pages,the select field should be disabled.Because this code `(@Model.Disabled ? "disable" : null)` means the data should be `disable` when Disabled= true and the data should be null when Disable = false.

    From the docs(https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.remoteattribute?view=aspnetcore-3.1),you need to know that remote validation configures Unobtrusive validation to send an Ajax request to the web site. The invoked handler should return JSON indicating whether the value is valid.So it could not change the value when you return page because it is a validation with ajax.

    Custom validation js like below:

    Index.cshtml:

    @page
    @model IndexModel
    <form method="post" id="Test">
        <input asp-for="Name" />
        <fieldset>
            <select id="patchday" required @(Model.Disabled ? "disabled" : "" )>
                <option value="" selected>Patchday</option>
                <option value="">aaaa</option>
            </select><br />
        </fieldset>
        <input type="submit" value="submit" />
    </form>
    @section Scripts {
    @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    <script>
        $(document).ready(function(){
            $('#Name').change(function () {
                $("#Test").validate().element("#Name");
            });
            $('#Test').validate({
                rules: {
                    Name: {
                        remote: {
                            url: "/Index?handler=CheckName",
                            headers: { 'RequestVerificationToken': $('input:hidden[name="__RequestVerificationToken"]').val() },
                            type: "post",
                            success: function (data) {
                                if (data == false) {
                                    $('#patchday').removeAttr("disabled");
                                }
                            }
                        },
                    },
                }
    
            });
        });
    </script>
    }

    Index.cshtml.cs:

    public class IndexModel : PageModel
    {
    
        //[PageRemote(AdditionalFields = "__RequestVerificationToken",HttpMethod = "post",PageHandler = "CheckName")]
        [BindProperty]
        public string Name { get; set; }
        public bool Disabled { get; set; } = true;
        public void OnGet()
        {
        }
        public IActionResult OnPostCheckName()
        {
            var stage = GetStage();
            // Check Stage for Patchday Dropdown
            if (stage.Equals("Produktion")){
                Disabled = false;
                return new JsonResult(false);
            }
            return new JsonResult(true);
        }
    }

    Best Regards,

    Rena

    Wednesday, August 5, 2020 8:40 AM
  • User-1886250979 posted

    I get this error message when i try it:  

    The tag helper 'select' must not have C# in the element's attribute declaration area.

    Wednesday, August 5, 2020 12:06 PM
  • User-1886250979 posted

    I can't do this: 

    @(Model.Disabled ? "disabled" : "" )

    Because of this error message: 

    The tag helper 'select' must not have C# in the element's attribute declaration area.

    Wednesday, August 5, 2020 12:08 PM
  • User-821857111 posted

    Ludtwigk

    I get this error message when i try it:  

    The tag helper 'select' must not have C# in the element's attribute declaration area.

    Opt out of tag helper processing for that tag: https://www.learnrazorpages.com/razor-pages/tag-helpers/#selective-tag-processing

    Or just use a standard HTML tag without the asp-for attributes:

    <select id="PatchDay" name="PatchDay" @(Model.Disabled ? "disabled" :null)>
        <option>Default option</option>
        @foreach(var x in Html.GetEnumSelectList<PatchDay>())
        {
            <option value="@(x.Value)" selected="@(Model.PatchDay == x.Value)">@x.Text</option>
        }
    </select>

    Actually, Razor conditional attributes work with disabled too:

    <select id="PatchDay" name="PatchDay" disabled="@Model.Disabled">
        <option>Default option</option>
        @foreach(var x in Html.GetEnumSelectList<PatchDay>())
        {
            <option value="@(x.Value)" selected="@(Model.PatchDay == x.Value)">@x.Text</option>
        }
    </select>

    If Model.Disabled evaluates to false or null, the disabled attribute is not rendered at all. If it evaluates to true, it is rendered as disabled="disabled"

    https://www.mikesdotnetting.com/article/201/cleaner-conditional-html-attributes-in-razor-web-pages

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, August 5, 2020 2:05 PM
  • User-1886250979 posted

    Is there a way to archieve this without js?

    Wednesday, August 5, 2020 2:27 PM
  • User-821857111 posted

    Is there a way to archieve this without js?

    Yes - in the solution I just posted.

    Wednesday, August 5, 2020 3:36 PM
  • User711641945 posted

    Hi Ludtwigk,

    Ludtwigk

    Is there a way to archieve this without js?

    Actually,as my previous post said,the principle of PageRemote validation is to send an Ajax request to the web site,which woks in the jquery-validate.js and jquery.validate.unobtrusive.js. PageRemote itself is a client side validation.

    You could try to use FluentValidation which is server side validation,refer to:

    https://github.com/FluentValidation/FluentValidation/blob/master/docs/custom-validators.md

    Best Regards,

    Rena

    Thursday, August 6, 2020 6:53 AM