Screenshots:
code
ui result
I want disable email field but [Editable(false)] attribute does not work.
How can I solve this problem?
[NopResourceDisplayName("Admin.Address.Fields.Email")]
[AllowHtml]
//[Editable(false)]
public string Email { get; set; }
ReadOnly(true) attribute also does not work.
You can change your HTML Helper method from EditorFor to TetBoxFor. Something line this.
#Html.TextBoxFor(model => model.Email, new { #class = "form-control", #readonly = "readonly" })
Related
In my cshtml file I have the lines
#Html.ValidationMessageFor(m => m, "{{dict.err_comb_cluster}}", new { #class = "text-danger" })
#Html.ValidationMessageFor(m => m.WarnMailAddress, "{{dict.val_req_err_alarm_email}}", new { #class = "text-danger" })
#Html.ValidationMessageFor(m => m.EmailToSendTo, "{{dict.val_req_err_email}}", new { #class = "text-danger" })
This has the effect that if there is an error concerning the WarnMailAddress or the field EmailToSendTo, the validation message for it will be displayed, but if at the same time there is an error concerning the whole model (that triggers "m => m"), the validation message for this error will not be displayed. It will be only displayed as soon as the other errors have been corrected. In other words, there is a hierarchy of the validation messages.
What we want to achieve is to display all the validation messages at once, ignoring this hierarchy. I've extensively used Google to find possible answers to my question but found none.
Additional information: The validation for the entire model is made using a custom attribute. We defined:
[MetadataType(typeof(CLUSTER_Validation))]
[CustomValidation(typeof(ClusterUniqueAttribute), "IsValid")]
public partial class CLUSTER: VMIEntityObject<CLUSTER>
{
and
public class ClusterUniqueAttribute : ValidationAttribute
{
public static ValidationResult IsValid(CLUSTER cluster)
{
The attributes for the properties are defined inside the class CLUSTER_Validation, and this looks like:
[Display(Description = "Email-Adresse", Name = "Email-Adresse", Order = 15)]
[RequiredIf("isSendMaiImmidiately", true, ErrorMessage = "If alarm email has been activated, an email address must be provided")]
public string WarnMailAddress { get; set; }
I have an extended User class like this:
public class User : IdentityUser
{
public string Nombre { get; set; }
public string Apellidos { get; set; }
public int DepartamentoID { get; set; }
public Departamento Departamento { get; set; }
}
In my Edit view I have this field definition:
<div class="form-group">
#Html.LabelFor(model => model.Roles.FirstOrDefault().RoleId, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(m => m.Roles.ElementAtOrDefault(0).RoleId, (SelectList)ViewBag.RoleList, "Seleccionar un rol", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Roles.FirstOrDefault().RoleId)
</div>
</div>
When I send the form, the Roles collection is empty.
Why the Binder does not add the role to the Roles collection?
Greetings and thanks.
I try to add more information to respond to Rajesh's comments.
In the Get action the model contains the information of the role, and the view shows it correctly. A drop-down list shows the available roles, and the user's role appears selected. When in the view I select another different role and send the form, in the Post action, the Roles collection of the model no longer contains information.
GET action
POST action
I do not know how to debug the work of the Binder
Why the Binder does not add the role to the Roles collection?
It happens because #Html.DropDownListFor and default model binder are not smart enough. Your #Html.DropDownListFor produces something like this:
<select class="form-control" id="RoleId" name="RoleId">
<option value="1">Role_1</option>
<option value="2">Role_2</option>
</select>
Since name=RoleId the model binder will try to bind it to RoleId property of your model and it knows nothing about Roles property and moreover that Roles prop is enumerable.
To make it work your model must have RoleId property or you can use Html.ListBoxFor extension if you want to select multiple roles:
#Html.ListBoxFor(m => m.SelectedRoles, (SelectList)ViewBag.RoleList, new { #class = "form-control" })
Then your model must have public List<string> SelectedRoles { get; set; } property.
Another option is to create a custom model binder using IModelBinder interface. This option gives you unlimited capabilities to map the request data to the model.
I have a form with shipping and billing information using a view model containing some required attributes.
Here's an exctract of the code enough to explain the issue.
Extract of the view model:
public class CheckoutViewModel
{
[Required]
public string ShippingPostalCode { get; set; }
[Required(ErrorMessage = "*")]
public string BillingPostalCode { get; set; }
}
Extract of the razor form:
#Html.TextBoxFor(m => m.ShippingPostalCode, new { #class = "form-control", placeholder = "Postal code" })
#Html.TextBoxFor(m => m.BillingPostalCode, new { #class = "form-control", placeholder = "Postal code", data_bind = "attr: { 'readonly': billingSameAsShipping }" }) #Html.ValidationMessageFor(model => model.BillingPostalCode)
I use Knockout to make the billing fields (including BillingPostalCode) readonly if a checkbox is checked using the observable billingSameAsShipping variable.
<input type="checkbox" data-bind="checked: billingSameAsShipping" id="billingSameAsShippingCheckbox" />
If the checkbox is not checked, and the BillingPostalCode is left empty, the validation fires correctly.
However, if BillingPostalCode is empty but the checkbox is checked, making the field readonly, the validation is not fired and the ModelState's IsValid is having the value true.
Any clues if this expected behaviour, or ideas how to work around it?
Any help is appreciated. Thanks.
Edit: I added the JavaScript code if it helps.
var shipping = {
billingSameAsShipping: ko.observable(false)
};
ko.applyBindings(shipping);
$("#billingSameAsShippingCheckbox").on("change", function () {
if (this.checked) {
$("#BillingPostalCode").val($("#ShippingPostalCode").val());
}
});
It seems that the jQuery validator that it uses ignores readonly inputs.
I managed to fix it with this.
$.validator.setDefaults({ ignore: null });
I've got a model field like so:
[Required(ErrorMessage = "Required!")]
[Display(Name = "Some ID")]
[DataType(DataType.Text)]
[RegularExpression(#"SomeRegexHere"]
public string someId { get; set; }
On my view, I have a form for updating the model. Something like this:
<div class="form-group">
#Html.LabelFor(model => model.someId, htmlAttributes: new { #class = "control-label" })
#Html.EditorFor(model => model.someId, new { htmlAttributes = new { type = "number", #class = "form-control" } })
#Html.ValidationMessageFor(model => model.someId, "", new { #class = "text-danger" })
</div>
Say on this same view I can fill in this field in order to submit it to the database, but I may also fill in some other field to retrieve an entry in the database by this value. However, I'd like to apply the same validations to both fields. Without creating a dummy model attribute, can I display validation errors for both fields?
As I understand form you question, you need
conditional validation. It is better to use third party validation provider for this porpose. I recommend MVC Foolproof Validation. Have a look on this and this as samples for conditional validation in foolproof.
I'm having the following code:
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
And I'm looking for a way to add the html attribute required to it, so a user can't submit without having the field filld. But now sure how to do? I know the easies way is to add required But don't know how, i tryed with #html "reguired" Without any luck.
EDIT:
Answere = required = ""
You can add RequiredAttribute to your model property:
[Required(ErrorMessage = "Title is required")]
public string Title { get;set; }
And add ValidationMessageFor to your cshtml:
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(m => m.Model)
Then add model validation to controller method via. It's the standard pipeline for asp.net mvc.
You also can implement your own HtmlHepler to add required attribute to your html code.
You will need this for client validation
"~/Scripts/jquery.js"
, "~/Scripts/jquery.validate.js"
,"~/Scripts/jquery.validate.unobtrusive.js"
whereas for only server side on Controller or necessary even if some disables javascript
if (ModelState.IsValid)
As above using annotation
[Required(ErrorMessage = "Title is required")]
public string Title { get;set; }
Using Fluent API
public class ClassNameConfiguration : EntityTypeConfiguration<ClassName>
{
public ClassNameConfiguration()
{
Property(x => x.Title).IsRequired();
}
}