I have 2 different pages, each with a form on them.
now one page if I leave a required field empty I get these validation popups:
This is the code of the image above:
<div class="form-group">
<p class="control-label col-md-5"><i class="fa fa-exclamation-triangle triangle" aria-hidden="true"></i> <b>Voorletter(s)</b></p>
<div class="col-md-4">
#Html.EditorFor(model => model.Voorletters, new { htmlAttributes = new { #class = "form-control", required = "required", placeholder="K" } })
#Html.ValidationMessageFor(model => model.Voorletters, "", new { #class = "text-danger" })
</div>
</div>
but on the other I get a popup, which if you ask me has the same code:
<div class="form-group">
<p class="control-label col-md-5"><i class="fa fa-exclamation-triangle triangle" aria-hidden="true"></i> <b>Functie</b></p>
<div class="col-md-4">
#Html.EditorFor(model => model.Functie1, new { htmlAttributes = new { #class = "form-control", required = "required" } })
#Html.ValidationMessageFor(model => model.Functie1, "", new { #class = "text-danger" })
</div>
</div>
but I would prefer the latter option, how do I always get that?
Is the latter validation message a chrome standard?
EDIT:
earlier I tried to change the first validation message "This field is required" by making a metaclass, but that only changed the text.
[MetadataType(typeof(medewerkerMetaData))]
public partial class medewerker
{
public partial class medewerkerMetaData
{
//[Required(ErrorMessage = "Verplicht invullen!")]
public string Voorletters { get; set; }
// more code
}
}
The first is showing mvc client side validation error from your [Required] attribute. The 2nd is showing the browsers HTML-5 validation message (because of the required attribute) which means you have not included the jquery.validate.js and jquery.validate.unobtrusive.js scripts in that view (or thay are loaded incorrectly ad are not working).
When you use the validation scripts, its adds the novalidate attribute to your form so that the HTML-5 validation is ignored (the 2 do not work well together).
Despite what you may think, you do not want the browsers HTML-5 validation - its is client side validation only (not server side which is the most important) and will not match your server side validation attributes.
Related
Hopefully this is an easy one...
I am having an issue with Bootstrap 5 floating labels not working when I create HTML elements using Razor syntax.
If I use plain HTML they work as expected. Using razor the labels are appearing in the state you'd expect if the text box has focus (top left of input)
<div class="form-floating mb-3">
#Html.EditorFor(model => model.Recipient, new { htmlAttributes = new { #class = "form-control", #onchange = "javascript: Changed( this, 'recipient-name' );" } })
#Html.ValidationMessageFor(model => model.Recipient, "", new { #class = "text-danger" })
#Html.LabelFor(model => model.Recipient)
</div>
Here is an image of the above on load -
Code output in UI
Has anyone had this issue, know a way to get around it or spot what I am doing wrong? (I need the input tag to be populated from the model as the form can be used to create a new request or update and existing request)
Thanks
Do you want something like below?
<div class="form-floating">
<input asp-for="Recipient" class="form-control" />
<label asp-for="Recipient"></label>
<span asp-validation-for="Recipient" class="text-danger"></span>
</div>
Thanks but I figured out what I was doing wrong. The issue was simple...
ISSUE - There was no placeholder tag which this animation relies on.
RESOLUTION - Add #placeholder = "Recipient Name"
To provide a bit more info the text input looks different when in focus/not focused. This was the issue.
It should have looked like this when not focused - Not Focused
But it was looking like this - Focused
The code that fixed the issue is
<div class="form-floating mb-3">
#Html.EditorFor(model => model.Recipient, new { htmlAttributes = new { #class = "form-control", #onchange = "javascript: Changed( this, 'recipient-name' );", #placeholder = "Recipient Name" } })
#Html.ValidationMessageFor(model => model.Recipient, "", new { #class = "text-danger" })
#Html.LabelFor(model => model.Recipient)
</div>
I am new to Entity Framework/MVC and need to know how to modify a dropdown menu autogenerated by Visual Studio. I imagine it should be pretty simple, but I have not been able to figure it out. I have used the database-first approach and have the two following tables in my database:
public partial class RestaurantRating
{
public int RestaurantRatingId { get; set; }
public int RestaurantRatingScore { get; set; }
}
public partial class RestaurantType
{
public int RestaurantTypeId { get; set; }
public string RestaurantTypeDesc { get; set; }
}
I removed the extra details, but basically one of them will store restaurant ratings (the rating being an integer) and the other one will store restaurant types (what type of food they serve). The only really difference between the two is that the rating is an integer and they type description is a string.
Visual Studio autogenerated code for the CRUD operations for these and other tables. The HTML code in Create.cshtml for these two tables is as follows:
<div class="form-group">
#Html.LabelFor(model => model.RetaurantTypeId, "RetaurantTypeId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("RetaurantTypeId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.RestaurantTypeId, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.RestaurantRatingId, "RestaurantRatingId", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("RestaurantRatingId", null, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Id, "", new { #class = "text-danger" })
</div>
</div>
And the ViewBag information for these two tables in the Create Action result in the controller is the following:
ViewBag.RestaurantRatingId = new SelectList(db.RestaurantRating, "RestaurantRatingId", "RestaurantRatingId");
ViewBag.RestaurantTypeId = new SelectList(db.RestaurantType, "RestaurantTypeId", "RestaurantTypeDesc");
The problems and expected results are the following:
The dropdown menu for RestaurantType works as expected. It simply loads the different types into a dropdown menu and allows the user to select one of them. However, the RestaurantRating will load the RatingIds instead of the descriptions, which is what I need. I have tried changing the viewbag without success.
The HTML code automatically selects the first value for the dropdown menus, but it is possible to save NULL values to the database for these fields. How can I add an empty default value for the dropdown menus above, so that if the user selects the empty value (or does not touch the dropdown menu) a NULL value will be pushed to the database?
Any help is greatly appreciated. I will be happy to provide any additional code/information. Thank you so much!
You Just need to add an option label to your dropdown like this:-
#Html.DropDownList("RetaurantTypeId", null,"optionLable goes Here", htmlAttributes: new { #class = "form-control" })
and make sure on the other side that you are binding it to a nullable model property so the model binder will be able to set the model property value to Null.
hope this answer your question.
I have a create view that allows users to enter some basic information. I need to be able to let them upload an image. This is the code that is generated when I add the controller to the project for it:
<div class="form-group">
#Html.LabelFor(model => model.Picture, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Picture, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Picture, "", new { #class = "text-danger" })
</div>
</div>
I don't know what code to put in this segment to give me the "choose a file" control. I know there has to be something out there pre-made but for the life of me I can't find it. On a related note: what should I define the type of the image to be in the model I created for it? After looking around, I saw that people were suggesting byte[] but I don't know how to display that in my index view. Any help would be greatly appreciated.
I have three dropdownlistfor in a loop that do not show the correct value from the DB. They always default to the first entry. I have checked and double checked the DB and verified that it should be the second one in the list. The list is also created correctly. What am I missing?
#foreach (CustomerMeasurementProfile oProfile in Model.Customer.CustomerMeasurementProfiles.Where(m => m.DeletedDate == null))
{
<div class="valuesforoneprofile form-group form-group-tight col-md-2">
<div class="col-md-11" >
#Html.Hidden(string.Format("Customer.CustomerMeasurementProfiles[{0}].Id", i), oProfile.Id)
#Html.Hidden(string.Format("Customer.CustomerMeasurementProfiles[{0}].CustomerId", i), oProfile.CustomerId)
#Html.TextBox(string.Format("Customer.CustomerMeasurementProfiles[{0}].Name", i), oProfile.Name, new { #class = "form-control input-sm" })
</div>
<div class="col-md-11" style="text-align:center">
#Html.CheckBox(string.Format("DeleteProfiles[{0}]", i), Model.DeleteProfiles[i])
</div>
<div class="col-md-11" style="padding-top:4px;">
#Html.DropDownListFor(m => oProfile.BodyTypeShoulderId, new SelectList(Model.BodyTypeShoulders, "Id", "Name"), new { #class = "form-control input-sm-select" })
</div>
<div class="col-md-11" style="padding-top:4px;">
#Html.DropDownListFor(m => oProfile.BodyTypePostureId, new SelectList(Model.BodyTypePosture, "Id", "Name"), new { #class = "form-control input-sm-select" })
</div>
<div class="col-md-11" style="padding-top:4px;">
#Html.DropDownListFor(m => oProfile.BodyTypeChestId, new SelectList(Model.BodyTypeChest, "Id", "Name"), new { #class = "form-control input-sm-select" })
</div>
If you want to set the selected value that is coming in Model. You need to do it like this:
#Html.DropDownListFor(m => oProfile.BodyTypeShoulderId,
new SelectList(Model.BodyTypeShoulders,
"Id",
"Name",
oProfile.BodyTypeShoulderId),
new { #class = "form-control input-sm-select" })
The above code will set the dropdown selected value to whatever is in the current Model object BodyTypeShoulderId
The first argument of DropDownListFor tells that on form post drop down selected value will be mapped with the Model property which is set there (we are passing m => oProfile.BodyTypeShoulderId) but this not sets selected Value.
For setting selected value you have to pass SelectList fourth parameter using this overload of SelectList class which is object selectedValue
Unfortunately #Html.DropDownListFor() behaves a little differently than other helpers when rendering controls in a loop. For a single object
#Html.DropDownListFor(m => oProfile.BodyTypeShoulderId, new SelectList(Model.BodyTypeShoulders, "Id", "Name"))
would work fine (if the value of BodyTypeShoulderId matches the value of one of the options, then that option would be selected). Ehsan has shown a work around when using it in a loop, however you have a few other issues in you code, not the least is that many of your properties will not post back correctly to a collection because your using a foreach loop rather than a for loop (which is generating duplicate name and id attributes). Your also generating a new SelectList in each iteration of the loop which is not very efficient.
You can solve both these and the dropdown selection issue by using an EditorTemplate. Assuming property CustomerMeasurementProfiles is typeof CustomerMeasurementProfiles, then
CustomerMeasurementProfiles.cshtml (add this to Views/Shared/EditorTemplates or Views/YourController/EditorTemplates)
#model CustomerMeasurementProfiles
#Html.HiddenFor(m => m.ID)
#Html.HiddenFor(m => m.CustomerId)
....
#Html.DropDownListFor(m => m.BodyTypeShoulderId, (SelectList)ViewData["shoulders"])
....
In the view model, add properties for the SelectList's and filtered collection of the items to display
IEnumerable<CustomerMeasurementProfiles> ActiveCustomerMeasurementProfiles { get; set; }
public SelectList BodyTypeShoulderList { get; set; }
....
and assign those values in the controller
Then in the main view
#using (Html.BeginForm())
{
...
#Html.EditorFor(m => m.ActiveCustomerMeasurementProfiles, new { shoulders = Model.BodyTypeShoulderList })
...
Using #Html.EditorFor() with a collection will correctly name the controls (and correctly select the right options) and on post back, ActiveCustomerMeasurementProfiles will now be correctly populated with all its properties.
I'm working on the simple webpage where user will be able to change some data.
I'm using #Html.EditorFor for changing that data. But I have some problems.
Here You can see my HTML Code:
<div class="form-group">
#Html.LabelFor(model => model.DeviceUser, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.DeviceUser, new { #Value = ViewBag.id})
#Html.ValidationMessageFor(model => model.DeviceUser)
</div>
</div>
As You can see I'm trying to replace DeviceUser with new Id which is passed from Controler using ViewBag.
But for unknow reason for me this textbox always holds old value.
Can anyone suggest me how to fix it?
Try changing this
#Html.EditorFor(model => model.DeviceUser, new { #Value = ViewBag.id})
to
#Html.TextBoxFor(model => model.DeviceUser, new { #Value = ViewBag.id})