ASP.NET MVC5 Client-side Validation - javascript

I have an amount field in a view that is required if a checkbox is checked.
Once Razor renders the View with Model data, and a user checks a checkbox without a corresponding amount entered. The Validation message appears. If I de-select that checkbox, the validation message does not disappear.
I've tried to use jquery to remove all the rules generated, but if the user were to checkbox again, prior to post back, those validation rules would have been removed (unless I store them... which is getting really ugly.)
Is there an acceptable way to re-validate client-side with the same requirements in the MVC Model?
Model:
[Display(Name = "Include Amount")]
public bool IncludeAmount { get; set; }
[Display(Name = "Amount")]
[RequiredIf("IncludeAmount", TargetValue = true, ErrorMessage = "Amount is required.")]
[MaxDigits(10, 2)]
[RegularExpression(RegularExpressions.Money, ErrorMessage = ErrorMessages.NumericValueInvalidFormat)]
[GreaterThanZero]
public Nullable<decimal> Amount { get; set; }
View:
<td class="dataEntryLabel" colspan="2">
#Html.LabelFor(model => model.IncludeAmount)
</td>
<td class="dataEntryField" colspan="2">
#Html.CheckBoxFor(model => model.IncludeAmount, new { id = "IncludeAmount" })
<span class="dollar-sign">#Html.TextBoxFor(model => model.Amount, "{0:F}", new { id = "Amount", disabled = "disabled" })</span>
#Html.ValidationMessageFor(model => model.Amount)
</td>
JavaScript (Client-side):
function fixUnobtrusiveValidations() {
var form = getForm();
(<any>$).validator.unobtrusive.parse(form);
}
function onClickCheckBoxIncludeAmount(){
fixUnobtrusiveValidations();
}
$('IncludeAmount').click(onClickCheckBoxIncludeAmount);

Try this to disable the client side validation on onclick events
Refer: https://jqueryvalidation.org/validate/#onclick
$("#myform").validate({
onclick: false,
});
OR
$("#yourChkboxID").validate({
onclick: false,
});

This worked:
if (!($('#IncludeAmount').checked)){
toggleValidatorVisibility($('#Amount'), false);
}
function toggleValidatorVisibility(element: any, value) {
var td: any = element.closest('td');
if (value) {
td.find('span.field-validation-error').show();
} else {
td.find('span.field-validation-error').empty();
}
}

Related

select property of selectlistitem always false

I have a view page to show a multi select check box. Here is the code to show that.
#{
foreach (SelectListItem item in Model.VendorCategoryList)
{
string name = item.Text;
bool chkResult = item.Selected;//Model.VendorCategoryList;
<tr class="VendorCategoryClassSave">
<td style="width: 4%;text-align:right;padding-right:15px;">
<label>
#Html.CheckBox("chkVendorCategoryDetailId_" + item.Value, chkResult, new { #class = "chkVendorCategoryDetailClass" })
</label>
</td>
<td style="width: 10%;">
<label>#Html.Label(name)</label>
</td>
</tr>
}
}
Controller
public ActionResult NewVendor(int custid = 0)
{
List<SelectListItem> VendorCategory = _commonRepository.VendorCategory
.AsEnumerable().Where(x => x.status == 1).Select(x => new SelectListItem
{
Text = x.catename,
Value = x.cateid.ToString(),
Selected=false
}).ToList();
foreach(SelectListItem item in VendorCategory)
{
item.Selected = setSelectedcategory(Convert.ToInt32(item.Value), custid);
}
var model = new HomeViewModel
{
VendorCategoryList = new SelectList(VendorCategory, "Value", "Text", "Selected")
};
return View("../Masters/View_Vendor", model);
}
Model
public HomeViewModel
{
public SelectList VendorCategoryList { get; set; }
}
What happens is that even though I set "true" for the Selected attribute in the selectlistitem it always shows as false. See the images below pic1. In the pic1 it says clearly that the selected property is "true". But when I select each item from the model in foreach loop, it says that the selected property is "false". See pic2. Pic2. Can you please help me what I am doing wrong.
This is only happening in the foreach loop. Out side of loop it shows the correct value(true). Thanks in advance.

Force validation on textboxfor before submit

I have a field that is required:
[Required(ErrorMessage = "Please enter a name.")]
[StringLength(80, ErrorMessage = "Name cannot be longer than 80 characters.")]
[RegularExpression("^[a-zA-Z ]+$", ErrorMessage = "Only letters can be used.")]
public string Name { get; set; }
I am using jqueryval.
My textbox:
#Html.TextBoxFor(x => x.mymodel.Name , new
{
id = "namebx",
style = "width: 100%;",
#class = "form-control loginTextBoxes"
})
#Html.ValidationMessageFor(x => x.experience.Name , "", new { #class = "text-danger" })
I have a control that when pressed scrolls the page to next section:
<div id="namebutton" class="btn btn-success"><i class="fa fa-check-circle-o"></i> Next</div>
I would like that if the validation criteria is not reached the validation warning will show and the scroll will not work until valid:
$("#namebutton").click(function() {
if ($('#namebx').valid()){
$('body').animate({ scrollTop: $('.form-group').find('.parentDiv:hidden:first').offset().top + 500 }, 1000);
$(".parentDiv:hidden:first").show("slow");
alert("true");
}
else {
alert("false");
}
});
At the moment all I get regardless of textbox content is an alert true and the page scrolls. The validation only kicks in when the submit button is clicked.

Client Side validation In MVC with Entity framework

I am working on a form in which i have to validate my user inputs (i.e, textbox and dropdownlist). in this i have used both MVC architecture as well as entity framework.
In this form i have to make a validation that the input in textboxt should not be blank and the dropdownlist should also contain a valid option
the form is generated using razor html syntax
VIEW
<form method="post">
<table>
<tr>
<td>
#Html.Label(" Cartidge Number ") <span style="color:red">*</span>
</td>
<td>
#Html.TextBoxFor(model => model.CartridgeNumber, "", new { #id = "txtNumber"})
#Html.ValidationMessageFor(model => model.Brand)
</td>
</tr>
<tr>
<td>
#Html.Label(" Brand ") <span style="color:red">*</span>
</td>
<td>
#Html.DropDownListFor(model => model.Brand, ViewBag.BrandId as SelectList,"Please Select", new { #id = "ddlBrands" })
#Html.ValidationMessageFor(model => model.Brand)
</td>
</tr>
<tr>
Model
Modelname is CartridgeModel which is generated using entity framework's database first approach
namespace MultiInfoMediaCloudSolution.Models
{
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
public partial class CartridgeModel
{
[Display(Name = "Cartridge Number: ")]
[Required(ErrorMessage = " Please Enter Cartridge Number ")]
public string CartridgeNumber { get; set; }
[Display(Name = "Brand: ")]
[Required(ErrorMessage = " Please Select Brand ")]
public string Brand { get; set; }
public string CartridgeKeywords { get; set; }
public Nullable<bool> IsActive { get; set; }
public Nullable<short> CreatedBy { get; set; }
public Nullable<System.DateTime> CreatedDate { get; set; }
public Nullable<short> ModifiedBy { get; set; }
public Nullable<System.DateTime> ModifiedDate { get; set; }
public virtual Brand BrandName { get; set; }
}
}
Controller
{
// check if the user has selected to edit the item or not.
if (userAction == "Edit")
{
var _Printer = (from c in _multiInfoMediaEntities.PrinterModels
where c.PrinterModelNo.Equals(PrinterModelNo)
select c).First();
//to store PrinterModelNo
string printerNumberTemp = _Printer.PrinterModelNo;
TempData["PrinterModelNo"] = printerNumberTemp;
TempData["IsActive"] = _Printer.IsActive;
TempData["userAction"] = "Edit";
return View(_Printer);
}
else
{
return View();
}
}
catch (Exception ex)
{
throw new Exception(ex.Message.ToString());
}
I am using a javaScript to validate my form which is unusually not giving me any result as per my expections,
the javascript is as follow
JavaScript
//................................Go Function is user for the Validation in all the List........................
function GO() {
var ddl = document.getElementById("dllFilter");
var brands = document.getElementById("ddlBrands");
if (ddl.options[ddl.selectedIndex].text == "Please Select") {
alert("Please select search field");
}
if(brands.innerText == "Please Select")
{
alert("Please select brand")
}
}
//................................
//.......................Clear function is Used for Clearing the textbox Value from all the List........................
function Clear() {
document.getElementById('txtSearch').value = 'Enter Value';
//ViewData["Selected"] = "Please Select";
}
//......................................................................................................
So, can anyone help me or guide me in solving this problem. ?
If you require simple client side validation, you can use the "required" attribute
<input type="text" required /> or in your case #Html.TextBoxFor(model => model.CartridgeNumber, "", new { #id = "txtNumber", required = "required"})
As for the dropdown you can use the same required attribute but for it to work the first 'option' child element must have a blank string for value <option value="">Please select an option</option>

How to require a field with a value of "yes" using javascript?

I need to be able to require certain fields if someone selects a value of "Yes" from a dropdown. I've used the following code but it doesn't seem to work.
$(function () {
$('#anyAdditionalInc').keyup(function () {
if ($(this).val() == "No") {
$('#additionalIncomeSource').removeAttr('required');
$('#additionalIncomeAmt').removeAttr('required');
} else {
$('#additionalIncomeSource').attr('required', 'required');
$('#additionalIncomeAmt').attr('required', 'required');
}
});
});
My dropdown looks like this
<div class="form-group">#Html.LabelFor(m => m.anyAdditionalInc, new { #class = "col-sm-2 control-label" })
<div class="col-sm-10">
<div class="col-sm-4">#Html.DropDownListFor(m => m.anyAdditionalInc, new SelectList(new List
<Object>{ new { value = "", text = "----"}, new { value = "Yes", text = "Yes"}, new { value = "No", text = "No"}, }, "value", "text"), new { #class = "form-control", id = "anyAdditionalInc" }) #Html.ValidationMessageFor(m => m.anyAdditionalInc)</div>
</div>
</div>
Any help is appreciated. It doesnt seem to want to require the validation on the source and amt fields when selecting yes.
A dropdown (I guess you mean a <select> element by that) doesn't have much keyup events. Try change instead:
$(function () {
$('#anyAdditionalInc').change(function () {
var active = $(this).val() != "No"),
fields = $('#additionalIncomeSource, #additionalIncomeAmt');
fields.prop('required', active);
if (!active) fields.val("");
});
});
Even though #Bergi answered the question from a client-side perspective, since you tagged the question asp.net-mvc-4 I presume you may wish to know how it's done on the server side (where it really matters!):
You can simply check it in your controller:
public ActionResult Foo(SomeModel someModel) {
if (someModel.anyAdditionalInc != "Yes") {
ModelState.AddModelError("", "You must select yes");
}
}
Or if you want to push the logic into your model itself:
public class SomeModel: IValidatableObject {
public string anyAdditionalInc {get; set;}
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext) {
if (this.anyAdditionalInc != "Yes") {
yield return new ValidationResult("You must select yes");
}
}
}
Notice how the model:
Implements IValidateableObject
Has a method named Validate which returns the type IEnumerable<ValidationResult>
During the model binding process this method will automatically be called and if a validation result is returned your ModelState will no longer be valid. So using this familiar code in your controller will make sure you don't take any action unless your custom conditions check out:
public class SomeController {
public ActionResult SomeAction() {
if (ModelState.IsValid) {
//Do your stuff!
}
}
}

KendoUI, Knockout, conditional validation of a field

I am using kendoui widgets with knockoutjs for datasource. I have a checkbox that is data bound to StartClientFromWebEnabled observable variable. An input text box is visible only when the checkbox ic checked (StartClientFromWebEnabled is true). The input has a required attribute. I want the required validation to be triggered only when the checkbox is checked.
Here is my html:
<table>
<tr>
<td><label for="startClientFromWebEnabled">Client Launch From Web:</label></td>
<td><input type="checkbox" id="startClientFromWebEnabled" name="startClientFromWebEnabled" data-bind="checked: StartClientFromWebEnabled, enable: IsEditable" onchange="startClientFromWebToggleRequiredAttribute()" /></td>
</tr>
<tr data-bind="visible: StartClientFromWebEnabled">
<td><label for="mimeType">Protocol:</label></td>
<td>
<input id="mimeType" name="mimeType" data-bind= "value: MimeType, enable: IsEditable" />
<span class="k-invalid-msg" data-for="mimeType"></span>
</td>
</tr>
</table>
I tried some scenarios including setting onChange event on the checkbox with the following javascript function adding and removing the required attribute:
startClientFromWebToggleRequiredAttribute = function () {
var checkbox = document.getElementById("startClientFromWebEnabled");
var mimeType = document.getElementById("mimeType");
if (checkbox.checked) {
mimeType.setAttribute("required", "required");
}
else {
mimeType.removeAttribute("required");
}
}
The problem is I will need this functionality for many dependent properties in my application and my option is to make this function generic with some parameters and call it from the html with the corresponding paramater values like this:
toggleRequiredAttribute = function (checkboxElement, inputElement1, inputElement2 ... ) {
var checkbox = document.getElementById(checkboxElement);
var inputElement1 = document.getElementById(inputElement1);
if (checkbox.checked) {
inputElement1.setAttribute("required", "required");
}
else {
inputElement1.removeAttribute("required");
}
}
<input type="checkbox" id="startClientFromWebEnabled" name="startClientFromWebEnabled" data-bind="checked: StartClientFromWebEnabled, enable: IsEditable" onchange="toggleRequiredAttribute('startClientFromWebEnable', 'mimeType')" />
I really do not like this scenario. I wonder is there something like a conditional validation in kendoui that trigger only when some condition is satisfied. Any other suggestions are also welcome.
I had the same issue, I created a custom validator which also handles the server side validation, this example is not 100% complete but all the validation is working, this validates the string length dependant on a checkbox state, it also uses resources for error message etc so will need a little modification, it uses the kendo ui validation client side, let me know if this is useful:
Model Properties:
public bool ValidateTextField { get; set; }
[CustomValidator("ValidateTextField", 6, ErrorMessageResourceType=typeof(Errors),ErrorMessageResourceName="STRINGLENGTH_ERROR")]
public string TextField{ get; set; }
Custom Validator:
[AttributeUsage(AttributeTargets.Field|AttributeTargets.Property, AllowMultiple=false, Inherited=true)]
public class CustomValidatorAttribute : ValidationAttribute, IClientValidatable {
private const string defaultErrorMessage="Error here.";
private string otherProperty;
private int min;
public CustomValidatorAttribute(string otherProperty, int min) : base(defaultErrorMessage) {
if(string.IsNullOrEmpty(otherProperty)) {
throw new ArgumentNullException("otherProperty");
}
this.otherProperty=otherProperty;
this.min=min;
this.ErrorMessage = MyResources.Errors.STRINGLENGTH_ERROR;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext) {
bool valid = true;
var curProperty = validationContext.ObjectInstance.GetType().
GetProperty(otherProperty);
var curPropertyValue = curProperty.GetValue
(validationContext.ObjectInstance, null);
if(Convert.ToBoolean(curPropertyValue)) {
string str=value.ToString();
valid = str.Length >= min;
if(!valid) { return new ValidationResult(MyResources.Errors.STRINGLENGTH_ERROR); }
}
return ValidationResult.Success;
}
#region IClientValidatable Members
public System.Collections.Generic.IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) {
var rule=new ModelClientValidationRule {
ErrorMessage = this.ErrorMessage,
ValidationType="checkboxdependantvalidator"
};
rule.ValidationParameters["checkboxid"]=otherProperty;
rule.ValidationParameters["min"]=min;
yield return rule;
}
public override string FormatErrorMessage(string name) {
return String.Format(CultureInfo.CurrentUICulture, ErrorMessageString,
name);
}
}
Javascript:
(function ($, kendo) {
$.extend(true, kendo.ui.validator, {
rules: { // custom rules
customtextvalidator: function (input, params) {
//check for the rule attribute
if (input.filter("[data-val-checkboxdependantvalidator]").length) {
//get serialized params
var checkBox = "#" + input.data("val-checkboxdependantvalidator-checkboxid");
var min = input.data("val-checkboxdependantvalidator-min");
var val = input.val();
if ($(checkBox).is(':checked')) {
if (val.length < min) {
return false;
}
}
}
return true;
}
},
messages: { //custom rules messages
customtextvalidator: function (input) {
// return the message text
return input.attr("data-val-checkboxdependantvalidator");
}
}
});
})(jQuery, kendo);
Helpful posts:
http://www.codeproject.com/Articles/301022/Creating-Custom-Validation-Attribute-in-MVC-3
http://blogs.msdn.com/b/simonince/archive/2011/02/04/conditional-validation-in-asp-net-mvc-3.aspx

Categories