Last active
June 18, 2018 13:58
-
-
Save johnnyreilly/5867188 to your computer and use it in GitHub Desktop.
jQuery Validate - using the native unobtrusive support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet"> | |
<style> | |
form { padding: 10px; } | |
.error { color: red; } | |
</style> | |
</head> | |
<body> | |
<form> | |
<label for="RequiredDateDemo">A date is required (eg "15 June 2012"):</label> | |
<input | |
data-msg-date="The field RequiredDateDemo must be a date." | |
data-msg-required="The RequiredDateDemo field is required." | |
data-rule-date="true" | |
data-rule-required="true" | |
id="RequiredDateDemo" name="RequiredDateDemo" type="text" value="" /> | |
<hr /> | |
<label for="StringLengthAndRequiredDemo">A string is required between 5 and 10 characters long:</label> | |
<input | |
data-msg-maxlength="The field StringLengthAndRequiredDemo must be a string with a minimum length of 5 and a maximum length of 10." | |
data-msg-minlength="The field StringLengthAndRequiredDemo must be a string with a minimum length of 5 and a maximum length of 10." | |
data-msg-required="The StringLengthAndRequiredDemo field is required." | |
data-rule-maxlength="10" | |
data-rule-minlength="5" | |
data-rule-required="true" | |
id="StringLengthAndRequiredDemo" name="StringLengthAndRequiredDemo" type="text" value="" /> | |
<hr /> | |
<label for="RangeAndNumberDemo">Must be a number between -20 and 40:</label> | |
<input | |
data-msg-number="The field RangeAndNumberDemo must be a number." | |
data-msg-range="The field RangeAndNumberDemo must be between -20 and 40." | |
data-rule-number="true" | |
data-rule-range="[-20,40]" | |
id="RangeAndNumberDemo" name="RangeAndNumberDemo" type="text" value="-21" /> | |
<hr /> | |
<label for="RangeAndNumberDemo">An option must be selected:</label> | |
<select | |
data-msg-required="The DropDownRequiredDemo field is required." | |
data-rule-required="true" | |
id="DropDownRequiredDemo" name="DropDownRequiredDemo"> | |
<option value="">Please select</option> | |
<option value="An Option">An Option</option> | |
</select> | |
<hr /> | |
<button type="submit">Validate</button> | |
</form> | |
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.js" type="text/javascript"></script> | |
<script src="http://ajax.aspnetcdn.com/ajax/jQuery.validate/1.11.1/jquery.validate.js" type="text/javascript"></script> | |
<script type="text/javascript"> | |
var $form = $("form"); | |
$form.validate(); | |
$form.submit(function (event) { | |
if ($form.validate().valid()) { | |
event.preventDefault(); | |
alert("Valid!"); | |
} | |
}); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8" /> | |
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/css/bootstrap-combined.min.css" rel="stylesheet"> | |
<style> | |
form { padding: 10px; } | |
.error { border: 1px solid #b94a48!important; background-color: #fee!important; } | |
</style> | |
</head> | |
<body> | |
<form> | |
<div class="row"> | |
<label for="RequiredDateDemo">A date is required (eg "15 June 2012"):</label> | |
<input | |
data-msg-date="The field RequiredDateDemo must be a date." | |
data-msg-required="The RequiredDateDemo field is required." | |
data-rule-date="true" | |
data-rule-required="true" | |
id="RequiredDateDemo" name="RequiredDateDemo" type="text" value="" /> | |
</div> | |
<div class="row"> | |
<label for="StringLengthAndRequiredDemo">A string is required between 5 and 10 characters long:</label> | |
<input | |
data-msg-maxlength="The field StringLengthAndRequiredDemo must be a string with a minimum length of 5 and a maximum length of 10." | |
data-msg-minlength="The field StringLengthAndRequiredDemo must be a string with a minimum length of 5 and a maximum length of 10." | |
data-msg-required="The StringLengthAndRequiredDemo field is required." | |
data-rule-maxlength="10" | |
data-rule-minlength="5" | |
data-rule-required="true" | |
id="StringLengthAndRequiredDemo" name="StringLengthAndRequiredDemo" type="text" value="" /> | |
</div> | |
<div class="row"> | |
<label for="RangeAndNumberDemo">Must be a number between -20 and 40:</label> | |
<input | |
data-msg-number="The field RangeAndNumberDemo must be a number." | |
data-msg-range="The field RangeAndNumberDemo must be between -20 and 40." | |
data-rule-number="true" | |
data-rule-range="[-20,40]" | |
id="RangeAndNumberDemo" name="RangeAndNumberDemo" type="text" value="-21" /> | |
</div> | |
<div class="row"> | |
<label for="RangeAndNumberDemo">An option must be selected:</label> | |
<select | |
data-msg-required="The DropDownRequiredDemo field is required." | |
data-rule-required="true" | |
id="DropDownRequiredDemo" name="DropDownRequiredDemo"> | |
<option value="">Please select</option> | |
<option value="An Option">An Option</option> | |
</select> | |
</div> | |
<div class="row"> | |
<button type="submit">Validate</button> | |
</div> | |
</form> | |
<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.js" type="text/javascript"></script> | |
<script src="//ajax.aspnetcdn.com/ajax/jQuery.validate/1.11.1/jquery.validate.js" type="text/javascript"></script> | |
<script src="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script> | |
<script type="text/javascript"> | |
$("form").validate({ | |
showErrors: function(errorMap, errorList) { | |
// Clean up any tooltips for valid elements | |
$.each(this.validElements(), function (index, element) { | |
var $element = $(element); | |
$element.data("title", "") // Clear the title - there is no error associated anymore | |
.removeClass("error") | |
.tooltip("destroy"); | |
}); | |
// Create new tooltips for invalid elements | |
$.each(errorList, function (index, error) { | |
var $element = $(error.element); | |
$element.tooltip("destroy") // Destroy any pre-existing tooltip so we can repopulate with new tooltip content | |
.data("title", error.message) | |
.addClass("error") | |
.tooltip(); // Create a new tooltip based on the error messsage we just set in the title | |
}); | |
}, | |
submitHandler: function(form) { | |
alert("This is a valid form!"); | |
} | |
}); | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@model MyMvcApp.Models.MyViewModel | |
@using (Html.BeginForm()) | |
{ | |
@Html.TextBoxFor(x => x.DateTimeDemo, true) | |
<hr /> | |
@Html.TextBoxFor(x => x.StringLengthAndRequiredDemo, true) | |
<hr /> | |
@Html.TextBoxFor(x => x.RangeAndNumberDemo, true) | |
<hr /> | |
@Html.DropDownListFor(x => x.DropDownRequiredDemo, true, new SelectList(new List<SelectListItem>())) | |
<button type="submit">Validate</button> | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq.Expressions; | |
using System.Web.Mvc.Html; | |
using System.Web.Routing; | |
namespace System.Web.Mvc | |
{ | |
/// <summary> | |
/// MVC HtmlHelper extension methods - extensions that make use of jQuery Validates native unobtrusive data validation properties | |
/// </summary> | |
public static class jQueryValidateRawUnobtrusiveExtensions | |
{ | |
private const string data_val_required = "data-val-required"; | |
private const string data_val_number = "data-val-number"; | |
private const string data_val_date = "data-val-date"; | |
private const string data_val_length = "data-val-length"; | |
private const string data_val_length_min = "data-val-length-min"; | |
private const string data_val_length_max = "data-val-length-max"; | |
private const string data_val_range = "data-val-range"; | |
#region Public | |
/// <summary> | |
/// Render a TextBox for the supplied model using native jQuery Validate Unobtrusive extensions (only if true passed) | |
/// </summary> | |
/// <typeparam name="TModel"></typeparam> | |
/// <typeparam name="TProperty"></typeparam> | |
/// <param name="htmlHelper"></param> | |
/// <param name="expression"></param> | |
/// <param name="useRawUnobtrusiveAttributes">Pass true if you want to use native extensions</param> | |
/// <param name="htmlAttributes">OPTIONAL</param> | |
/// <returns></returns> | |
public static IHtmlString TextBoxFor<TModel, TProperty>( | |
this HtmlHelper<TModel> htmlHelper, | |
Expression<Func<TModel, TProperty>> expression, | |
bool useRawUnobtrusiveAttributes, | |
object htmlAttributes = null) | |
{ | |
// Return to native if true not passed | |
if (!useRawUnobtrusiveAttributes) | |
return htmlHelper.TextBoxFor(expression, htmlAttributes); | |
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); | |
var attributes = GetUnobtrusiveValidationAttributes(htmlHelper, expression, htmlAttributes, metadata); | |
return htmlHelper.TextBox(metadata.PropertyName, metadata.Model, attributes); | |
} | |
/// <summary> | |
/// Render a DropDownList for the supplied model using native jQuery Validate Unobtrusive extensions (only if true passed) | |
/// </summary> | |
/// <typeparam name="TModel"></typeparam> | |
/// <typeparam name="TProperty"></typeparam> | |
/// <param name="htmlHelper"></param> | |
/// <param name="expression"></param> | |
/// <param name="useRawUnobtrusiveAttributes"></param> | |
/// <param name="selectList"></param> | |
/// <param name="htmlAttributes"></param> | |
/// <returns></returns> | |
public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, | |
Expression<Func<TModel, TProperty>> expression, | |
bool useRawUnobtrusiveAttributes, | |
IEnumerable<SelectListItem> selectList, | |
object htmlAttributes = null) | |
{ | |
// Return to native if true not passed | |
if (!useRawUnobtrusiveAttributes) | |
return htmlHelper.DropDownListFor(expression, selectList, htmlAttributes); | |
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); | |
var attributes = GetUnobtrusiveValidationAttributes(htmlHelper, expression, htmlAttributes, metadata); | |
return htmlHelper.DropDownList(metadata.PropertyName, selectList, attributes); | |
} | |
private static RouteValueDictionary GetUnobtrusiveValidationAttributes<TModel, TProperty>(HtmlHelper<TModel> helper, | |
Expression<Func<TModel, TProperty>> expression, | |
object htmlAttributes, | |
ModelMetadata metadata) | |
{ | |
var propertyName = helper.NameFor(expression).ToString(); | |
var unobtrusiveValidationAttributes = helper.GetUnobtrusiveValidationAttributes(propertyName, metadata); | |
var attributes = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); | |
// Required | |
if (unobtrusiveValidationAttributes.ContainsKey(data_val_required)) | |
{ | |
attributes.Add("data-rule-required", "true"); | |
attributes.Add("data-msg-required", unobtrusiveValidationAttributes[data_val_required]); | |
} | |
// Number | |
if (unobtrusiveValidationAttributes.ContainsKey(data_val_number)) | |
{ | |
attributes.Add("data-rule-number", "true"); | |
attributes.Add("data-msg-number", unobtrusiveValidationAttributes[data_val_number]); | |
} | |
// Date | |
if (unobtrusiveValidationAttributes.ContainsKey(data_val_date)) | |
{ | |
attributes.Add("data-rule-date", "true"); | |
attributes.Add("data-msg-date", unobtrusiveValidationAttributes[data_val_date]); | |
} | |
// Min and Max Length | |
if (unobtrusiveValidationAttributes.ContainsKey(data_val_length)) | |
{ | |
if (unobtrusiveValidationAttributes.ContainsKey(data_val_length_min)) | |
{ | |
attributes.Add("data-rule-minlength", unobtrusiveValidationAttributes[data_val_length_min]); | |
attributes.Add("data-msg-minlength", unobtrusiveValidationAttributes[data_val_length]); | |
} | |
if (unobtrusiveValidationAttributes.ContainsKey(data_val_length_max)) | |
{ | |
attributes.Add("data-rule-maxlength", unobtrusiveValidationAttributes[data_val_length_max]); | |
attributes.Add("data-msg-maxlength", unobtrusiveValidationAttributes[data_val_length]); | |
} | |
} | |
// Range | |
if (unobtrusiveValidationAttributes.ContainsKey(data_val_range)) | |
{ | |
attributes.Add("data-rule-range", | |
string.Format("[{0},{1}]", unobtrusiveValidationAttributes["data-val-range-min"], | |
unobtrusiveValidationAttributes["data-val-range-max"]) | |
); | |
attributes.Add("data-msg-range", unobtrusiveValidationAttributes[data_val_range]); | |
} | |
return attributes; | |
} | |
#endregion | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Web.Mvc; | |
using MyMvcApp.Models; | |
namespace MyMvcApp.Controllers | |
{ | |
public class MyController : System.Web.Mvc.Controller | |
{ | |
public MyController() | |
{ | |
} | |
[HttpGet] | |
public ViewResult Index() | |
{ | |
return View(new MyViewModel()); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.ComponentModel.DataAnnotations; | |
namespace MyMvcApp.Models | |
{ | |
public class MyViewModel | |
{ | |
public System.DateTime DateTimeDemo { get; set; } | |
[StringLength(10, MinimumLength = 5), | |
Required] | |
public string StringLengthAndRequiredDemo { get; set; } | |
[Range(typeof(decimal), "-100.5", "99.5")] | |
public decimal? RangeAndNumberDemo { get; set; } | |
[Required] | |
public string DropDownRequiredDemo { get; set; } | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment