I am building a MVC5 form and need to put validation for required fields. I am having several text controls that require to be validated. I tried putting the [Required] attribute on the model as well as added the required keyword in the htmlattributes on the client side but the validation never fires. Could somebody tell me how to handle this validation
<div class="form-group">
#Html.LabelFor(model => model.CustomerNumber, htmlAttributes: new { #class = "control-label col-md-4" })
<div class="col-md-8">
<div class="editor-field">
#Html.EditorFor(model => model.CustomerNumber, new { htmlAttributes = new { Value = Model.CustomerNumber == 0 ? "" : Model.CustomerNumber.ToString(), #class = "form-control", style = "width:100%", #readonly = "readonly", required = "required" } })
</div>
#Html.ValidationMessageFor(model => model.CustomerNumber, "", new { #class = "text-danger" })
</div>
</div>
add [Required] or other validator Attribute to your Model fields.
add jQuery Validate libs to your _Layout.cshtml file.
Example :
...
<body>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/bootstrap")
</body>
</html>
Related
I have a mvc5 project with ability to create;edit and delete records.
There are 3 textboxes.
Based on value in textBox1, I want to disable TextBox3 and 4;
if frequency.Value='Weekly'
{
Disable TextBox_BiWeekly
Enable TextBox3_Weekly
}
if frequency.Value='BiWeekly'
{
Disable TextBox3_Weekly
Enable TextBox4_BiWeekly
}
This is part of code in Edit.cshtml
<div class="form-group">
#Html.LabelFor(model => model.frequency, htmlAttributes: new { #class = ".col-form-label col-md-2" })
<div class="col-md-10">
<div class="form-check">
#Html.EditorFor(model =>model.frequency)
#Html.ValidationMessageFor(model =>model.frequency, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Weekly, htmlAttributes: new { #class = ".col-form-label col-md-2" })
<div class="col-md-10">
<div class="form-check">
#Html.EditorFor(model =>model.Weekly)
#Html.ValidationMessageFor(model =>model.Weekly, "", new { #class = "text-danger" })
</div>
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BiWeekly, htmlAttributes: new { #class = ".col-form-label col-md-2" })
<div class="col-md-10">
<div class="form-check">
#Html.EditorFor(model =>model.BiWeekly)
#Html.ValidationMessageFor(model =>model.BiWeekly, "", new { #class = "text-danger" })
</div>
</div>
</div>
I am not sure how to disable or enable Textboxes
Thanks MR
Probably the best way to do this would be in JavaScript so that the textboxes can enable/disable on the fly based on the value of your frequency input.
Something like:
$(function() {
EnableDisableFrequency();
$('#Frequency').change(function() {
EnableDisableFrequency();
});
});
function EnableDisableFrequency() {
if ($('#Frequency').val() === "Weekly") {
$('#BiWeekly').prop('disabled', true);
$('#Weekly').prop('disabled', false);
} else if ($('#Frequency').val() === "BiWeekly") {
$('#BiWeekly').prop('disabled', false);
$('#Weekly').prop('disabled', true);
}
}
My JavaScript is a bit rusty but I'm pretty sure that should work.
I would however agree with Stephen Muecke that your Frequency input should be a dropdownlist.
#Html.DropDownListFor(m => m.Frequency, Model.FrequencyList)
Just define FrequencyList in your ViewModel as a List that contains all potential values which I assume is just Weekly and BiWeekly
FrequencyList = new List<SelectListItem>
{
new SelectListItem
{
Text = "Weekly",
Value = "Weekly"
},
new SelectListItem
{
Text = "BiWeekly",
Value = "BiWeekly"
}
};
The JavaScript can remain the same.
I have an asp.net core 2.0 site using VS 2017 (ver. 15.4) & C#. I have a 'Comments' model that has been scaffoled. A user has to be logged in to create a new comment. In 'Create.cshtml' I want the 'Date' and the 'UserName' to be filled in a label- not an input. Just trying to keep a user from using a false name to create a comment. I need to use code in 'Create.html' to accomplish this. Here is what I have in 'Create.html':
Date (this works):
<div class="form-group">
#Html.LabelFor(model => model.Date, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.LabelFor(model => model.Date, DateTime.Now.ToShortDateString())
#Html.ValidationMessageFor(model => model.Date, "", new { #class = "text-danger" })
</div>
</div>
UserName (this does NOT work) :
<div class="form-group">
#Html.LabelFor(model => model.UserName, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.LabelFor(model => model.UserName, new { htmlAttributes = new { #class = "control-label", #Value = User.Identity.Name } })
#Html.ValidationMessageFor(model => model.UserName, "", new { #class = "text-danger" })
</div>
</div>
I'm trying to get the UserName filled in using a label. Thanks for any suggestions. Jeff
Well couple problems on your approach:
There is no value attribute on a label element
Since you have the ViewModel for the Create.cshtml view, and you have a UserName property, there is no point to do LabelFor or TextBoxFor with no value and initialize the element value on the Razor view. You could have done so when initializing the ViewModel on the server side.
Fix
You can initialize the model property UserName with the value of User.Identity.Name on the server side, and remove the #value = User.Identity.Name on the view.
My 2 cents
If you just want to display the UserName and not expect it comes back as input, you don't have to put #Html.ValidationMessageFor() there. You are not getting a value when doing post back anyway.
And for the same reason, you can just use a regular <label> element with Razor 1 way binding to display the value, i.e.,
<div class="col-md-10">
<label class="control-label col-md-2">#Model.UserName</label>
</div>
I see you're using Bootstrap. There is a class from Bootstrap 4 called form-control-plaintext that will style an input element and make it look like a label, so that you can actually bind the value to an input as well.
<!-- Throwing in Tag Helper just for fun -->
<div class="form-group row">
<label asp-for="UserName" class="col-form-label col-md-2"></label>
<div class="col-md-10">
<input type="text" class="form-control-plaintext" asp-for="UserName"
readonly />
</div>
</div>
I am implementing the kendo datepicker in my MVC 5 application. I am not sure for what reason the viewmodel property is not being set with what is selected in the datetimepicker
<div class="form-group">
#Html.LabelFor(model => model.ContractStartDate, htmlAttributes: new { #class = "control-label col-md-5" })
<div class="col-md-6">
#*#Html.EditorFor(model => model.ContractStartDate, new { htmlAttributes = new { #class = "form-control" } })*#
#(Html.Kendo().DatePickerFor(model => model.ContractStartDate)
.Name("contractdatepicker")
.Value("10/10/2011")
.HtmlAttributes(new { style = "width: 100%" })
)
#Html.ValidationMessageFor(model => model.ContractStartDate, "", new { #class = "text-danger" })
</div>
</div>
The problem is your .Name("contractdatepicker"). When this is rendered it will become the name and id tag on the <input> and therefore won't bind to your viewmodel. If you omit that attribute it will automatically add the name and id ContractStartDate. So, just remove that tag and if you refer to it in javascript change the reference to #ContractStartDate.
The dateTime picker is not showing in the view for me to select a date for my ReturnDate.It wont give me the little arrow to select from a calendar (datetime picker) and it already fills in values. It just shows a textbox that contains : '0001/01/01 12:00:00 AM'
in my model this is my Returndate field:
[DataType(DataType.Date)]
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
public DateTime? ReturnedDate { get; set; }
my View is:
<div class="form-group">
#Html.LabelFor(model => model.ReturnedDate, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ReturnedDate)
#Html.ValidationMessageFor(model => model.ReturnedDate)
</div>
</div>
using jquery ui this is my new view:
#model FCproject.Models.Purchase
#{
ViewBag.Title = "Create";
}
<script src="~/Scripts/jquery-ui-1.11.4.min.js"></script>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<h4>Purchase</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.ReturnedDate, new { #class = "control-label col-md-2", #id = "datepicker" })
<div class="col-md-10">
#Html.EditorFor(model => model.ReturnedDate)
#Html.ValidationMessageFor(model => model.ReturnedDate)
</div>
</div>
<script>
$(function () {
$("#datepicker").datepicker();
});
</script>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
But it still shows a textbox with no datetime picker.
if you are running on IE that feature doesn't work, chrome works the best on ui's.
But if still gives you problem i'll suggest you use jquery datepicker:
your View (Modified):
<div class="form-group">
#Html.LabelFor(model => model.ReturnedDate, new { #class ="control-label col-md-2", #id = "datepicker" })
<div class="col-md-10">
#Html.EditorFor(model => model.ReturnedDate)
#Html.ValidationMessageFor(model => model.ReturnedDate)
</div>
</div>
<script>
$(function() {
$( "#datepicker" ).datepicker();
});
</script>
OR visit
http://api.jqueryui.com/datepicker/
Dont forget to reference your ui scripts e.g: (Depending on your script version)
<script src="~/Scripts/jquery-ui-1.11.4.min.js"></script>
I Can't get the Display -> Order attribute to work.
I'm using VS2013 update 4 and the System.ComponentModel.DataAnnotations appears to be up to date with runtime version 4.0.30319.
I built a tiny MVC app with a small model:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;
namespace TestDataAnnotation.Models
{
[MetadataType(typeof(TestDB))]
public class TestDB
{
public int TestDBID { get; set; }
[Display(Order=2)]
public int MyProperty1 { get; set; }
[Display(Order=1)]
public int MyProperty2 { get; set; }
}
}
I created a controller and view using scaffolding. The GET for the Create is standard MVC
// GET: TestDBs/Create
public ActionResult Create()
{
return View();
}
The View is also standard MVC:
<div class="form-horizontal">
<h4>TestDB</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.MyProperty1, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MyProperty1, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MyProperty1, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.MyProperty2, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.MyProperty2, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.MyProperty2, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
MyProperty2 should display first, but it does not. I've tried numerous variations of this but can't get "Order" to work. I've had the MetadataType statement in the code and not in the code. I've tried order= -9. I've tried various different values for the order attribute. Display->Name works fine. Apparently, I'm missing some key idea here. Thanks for any and all help!
The Order parameter applies when there's something dynamic operating on the model and generating HTML, like a grid view. Here, you've literally rendered the properties in a given order. Setting Order isn't going to override explicit HTML.