ASP.NET Core Razor: Conditional attribute without value - asp.net-core

I want to conditionally render a readonly attribute in an <input>. In the ASP.NET Core dialect of Razor the interpretation of attributes is a little different opposed to System.Web.Mvc.
In System.Web.Mvc I used to do:
<input name="Name" class="form-control" #(Model.MyCondition ? "readonly" : "") />
In ASP.NET Core, the same does not work: no error, but the attribute isn't rendered either.
<input asp-for="Name" class="form-control" #(Model.MyCondition ? "readonly" : "" ) />
Once the attribute is present in the HTML it is enforced, so I cannot do something with the value of the attribute. This snippet would cause the input to always be read-only:
<input asp-for="Name" class="form-control" readonly="#(Model.MyCondition ? "readonly" : "" )" />
Now, I can work around by creating a tag helper that would respond to the is-readonly tag, but that seems very convoluted for something so simple.
How do I conditionally render a no-value attribute without resorting to a custom tag helper?

If you set the value to null when your condition isn't matched (instead of an empty string) then the attribute will not be rendered, as follows:
<input asp-for="Name" class="form-control" readonly="#(Model.MyCondition ? "readonly" : null )" />

#{
var htmlAttributes = (MyModel.MyCondition == true) ? (object)new
{
##readonly = "readonly"
} : null;
}
#Html.TextBoxFor(m => m.Nom, htmlAttributes)

What I do is create an #if statement. I find it more transparent.
#if (Model.MyCondition)
{
<input asp-for="Name" class="form-control" readonly="readonly" />
}
else
{
<input asp-for="Name" class="form-control" />
}

Related

How to bind the value to input field to a control by using ternary operator check

I have some input controls where I am trying to bind the value by checking for null which doesn't worked
<input id="LastKnownLatitudeDegree" name="VesselMissing.LastKnownLatitudeDegree" value="#Model.VesselMissing != null ? #Model.VesselMissing.LastKnownLatitudeDegree : ''" class="form-control" max="89" min="0" step="1" type="number" data-dec="0"><span>°</span>
If I am using a null check on top of the control it is not getting visible to the user to enter the data
#if (#Model.VesselMissing != null)
{
<input id="LastKnownLatitudeDegree" name="VesselMissing.LastKnownLatitudeDegree" value="#Model.VesselMissing.LastKnownLatitudeDegree" class="form-control" max="89" min="0" step="1" type="number" data-dec="0"><span>°</span>
}
I have some bunch of controls like this where I need to bind the value field. There is an other method which I tried out is working but I would like to know if there is a possibility to do as per the first statement
This works but I have some 20 controls so I am considering to make it work as per the first statemet
#{
string LastKnownLatitudeDegree = string.Empty;
if(Model.VesselMissing !=null)
{
LastKnownLatitudeDegree = Model.VesselMissing.LastKnownLatitudeDegree;
}
}
<input id="LastKnownLatitudeDegree" name="VesselMissing.LastKnownLatitudeDegree" value="#LastKnownLatitudeDegree class="form-control" max="89" min="0" step="1" type="number" data-dec="0"><span>°</span>
In both cases you have syntax error.
<input id="LastKnownLatitudeDegree" name="VesselMissing.LastKnownLatitudeDegree"
value="#(Model.VesselMissing != null ? Model.VesselMissing.LastKnownLatitudeDegree : "")" />
or
#if (Model.VesselMissing != null)
{
<input id="LastKnownLatitudeDegree" name="VesselMissing.LastKnownLatitudeDegree" value="#Model.VesselMissing.LastKnownLatitudeDegree" class="form-control" max="89" min="0" step="1" type="number" data-dec="0"><span>°</span>
}

Razor tag helper bool Radio buttons clientside 'Required' validation

I am using Razor Pages Tag helpers for a Yes/No in a form on a page. All other fields in the form have client side unobtrusive validation, but the bool? Yes/No does not. I have a few radio Yes/No's like this, how do I get the client side to work for them?
[Required]
public bool? Have7DaysWorth { get; set; }
I tried moving away from tag helpers too, butit doesn't hook up with this:
<label asp-for="Have7DaysWorth" class="control-label"></label>
<div>
<input type="radio" id="daysRadio1" name="Have7DaysWorth "
checked="#(Have7DaysWorth == true ? "checked": null)"
class="custom-control-input" value="true">
<label class="custom-control-label" for="daysRadio1">Yes</label>
</div>
<div>
<input type="radio" id="pharmacyRadio2" name="Have7DaysWorth "
checked="#(Have7DaysWorth == false ? "checked": null)"
class="custom-control-input" value="false">
<label class="custom-control-label" for="daysRadio1">No</label>
</div>
<span asp-validation-for="Have7DaysWorth " class="text-danger"></span>
I know from searching there are some suggestions about pre-selecting one, but that isn't then a conscious value that a user has entered into a form, so not an option here.
I have tried some other ways, but they seemed to lose the value when the modelstate wasn't valid and was returned.
How do I get the client side to work for bool radios in the expected way that I want?
You're not using asp-for on the radios, so it has no idea it should be required, as there's no involvement with the model, and thus the Required attribute on that property.
An old thread but if you're having to upgrade a razor page website to Bootstrap 5 you'll run into this issue.
This will not work as you cannot use asp-for with C# statement not inside an attribute
<input asp-for="MarketingPrefs" type="radio" class="btn-check" value="true" #(Model.MarketingPrefs.HasValue && Model.MarketingPrefs.Value ? "checked" : null)>
If you omit the asp-for like this then local validation won't work
<input id="MarketingPrefsYes" name="MarketingPrefs" type="radio" class="btn-check" value="true" #(Model.MarketingPrefs.HasValue && Model.MarketingPrefs.Value ? "checked" : null)>
This is how to do it
<div class="btn-group" role="group">
#Html.RadioButtonFor(model => model.MarketingPrefs, "true", new { #class = "btn-check", #id="MarketingPrefsYes" })
<label class="btn btn-outline-secondary" for="MarketingPrefsYes">Yes</label>
#Html.RadioButtonFor(model => model.MarketingPrefs, "false", new { #class = "btn-check", #id="MarketingPrefsNo" })
<label class="btn btn-outline-secondary" for="MarketingPrefsNo">No</label>
</div>

MVC4: HTML5 boolean attributes rendered with True/False value

I'm trying to render a radiobutton with some boolean attributes (required and disabled) using:
#Html.RadioButton("radio-name","false", new { id="test", required=Model.BooleanValue})
and
<input type="radio" name="radio-name" id="radio-name-no" value="false" class="radio" #if (!Model.BooleanValue) { <text>required</text> } disabled="#Model.BooleanValue" />
But the output is this:
<input id="test" name="radio-name" required="False" value="false" type="radio">
and
<input name="radio-name" id="radio-name-no" value="false" class="radio" disabled="True" type="radio">
MVC4 should render the boolean attributes as per HTML5 specs, so why it's outputting disabled="True" (or False) instead of disabled="disabled" or disabled (or nothing at all if the BooleanValue property is false)?
You can include conditionally rendered attributes like this:
<input
type="radio"
required="#(!Model.BooleanValue)"
disabled="#Model.BooleanValue" />
The solution was pretty strange. While doing some tests, I put an #if in the HTML input tag. This if was used to show the required attribute. After this #if, I put the disabled="#Model.BooleanValue" attribute.
It seems that this order disrupted the expected behaviour. Placing the disabled attribute before the #if solved the problem (later I have deleted the #if and converted it to required="#(!Model.BooleanValue)").

Based on If condition I want make the field as required in angular2

<div *ngFor="let proc of procInputList" >
<label >{{proc.key_ | Capitalize}}</label>
<input id="{{proc.key_}}" name="inputparams" type ="text" class="form-control" required = "proc.r_q == Y ? required :none" />
</div>
But unfortunately its not working for me..and I don't want to use forms there.
To condition an attibute you can:
<input class="form-control" [required] = "proc.r_q == 'Y'" />

asp-for tag adds required field validation on checkbox in asp.net core

I have asp.net core application and im trying to add simple checkbox without any validation. Checkbox is bound to boolean property on model. Below is the code
Model
public class MyModel
{
public bool IsEmployee { get; set; }
}
cshtml
<form>
<div>
<label asp-for="IsEmployee">Is Employee</label>
<input type="checkbox" asp-for="IsEmployee"/>
</div>
<button id="btnSave" class="btn btn-primary" type="button">Save</button>
</form>
<script src="~/js/test.js"></script>
javascript
$(function () {
var kendoValidator = $('form').kendoValidator().data("kendoValidator");
$('#btnSave').click(function () {
if (kendoValidator.validate()) {
alert('true');
}
else {
alert('false');
}
})
})
I am using asp-for tag helper on input element. Note that IsEmployee property DOES NOT have [Required] attribute. But because of asp-for tag helper the rendered html has data-val-required and data-val attributes on input element. It also adds one more hiddden input element with same name.
Below is rendered html.
(also note that i think it only happens when input type is checkbox. for textboxes its working fine)
<form novalidate="novalidate" data-role="validator">
<div>
<label for="IsEmployee">Is Employee</label>
<input name="IsEmployee" id="IsEmployee" type="checkbox" value="true" data-val-required="The IsEmployee field is required." data-val="true">
</div>
<button class="btn btn-primary" id="btnSave" type="button">Save</button>
<input name="IsEmployee" type="hidden" value="false">
</form>
I am using kendovalidator as well which adds data-role="validator" on form element.
Issues
There are 2 issues here
1> As soon as i click on check the box error message appears as The IsEmployee field is required.
2>kendoValidator.validate() method always returns false regardless of checkbox is selected or not.
Demo here JSFiddle
Update 2
We cannot bind nullable bool to checkbox. I am using asp.net core. I am not sure what the equivalent syntax in asp.net core for the suggestion here which is valid for classic asp.net
Add data-validate="false" to the checkbox input. The kendoValidator will ignore all inputs with that attribute set to false.
<input type="checkbox" asp-for="IsEmployee" data-validate="false" />
If you don't wan't the default generated html you have 2 choices.
Don't use it ! You are not forced to use the tag helpers, they are there for when you do need other html attributes generated. In this case just use < input name="IsEmployee" ...>
Change the way asp-for behaves for your checkbox. You can do this be either creating your own IHtmlGenerater or by extending the DefaultHtmlGenerator and overriding GenerateCheckBox and possibly GenerateInput and then registering it with something like services.TryAddSingleton();
Hope this helpes you.