Git Product home page Git Product logo

johnnyreilly / jquery.validation.unobtrusive.native Goto Github PK

View Code? Open in Web Editor NEW
78.0 10.0 26.0 16.74 MB

Provides MVC HTML helper extensions that marry jQuery Validation's native unobtrusive support for validation driven by HTML 5 data attributes with MVC's ability to generate data attributes from Model metadata. With this in place you can use jQuery Validation as it is. Please look at the project site for demos and documentation.

Home Page: https://johnnyreilly.github.io/jQuery.Validation.Unobtrusive.Native/

License: MIT License

C# 13.87% CSS 20.68% JavaScript 12.48% PowerShell 0.40% HTML 20.80% Less 31.76% ASP.NET 0.02%

jquery.validation.unobtrusive.native's Introduction

jQuery Validation Unobtrusive Native Build Status

Find it on NuGet: jQuery.Validation.Unobtrusive.Native.MVC5

jQuery.Validation.Unobtrusive.Native is a collection of ASP.Net MVC HTML helper extensions that make use of jQuery Validation's native unobtrusive support for validation driven by HTML 5 data attributes. Microsoft shipped jquery.validate.unobtrusive.js back with MVC 3. It provided a way to apply data model validations to the client side using a combination of jQuery Validation and HTML 5 data attributes (that's the "unobtrusive" part).

The principal of this was and is fantastic. But since that time the jQuery Validation project has implemented its own support for driving validation unobtrusively (this shipped with jQuery Validation 1.11.0). The advantages of the native support over jquery.validate.unobtrusive.js are:

  • Dynamically created form elements are parsed automatically. jquery.validate.unobtrusive.js does not support this.
  • jquery.validate.unobtrusive.js restricts how you use jQuery Validation. Want to use showErrors etc? Well you'll need to go native...
  • Send less code to your browser, make your browser to do less work, get a performance benefit (though you'd probably have to be the Flash to actually notice the difference)

This project intends to be a bridge between MVC's inbuilt support for driving validation from data attributes and jQuery Validation's native support for the same. This is achieved by hooking into the MVC data attribute creation mechanism and using it to generate the data attributes used by jQuery Validation.

You can see more detail on the demo site.

Getting started

If you haven't already, ensure that the following entries can be found in your web.config:

<appSettings>
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
</appSettings>

Include jQuery.Validation.Unobtrusive.Native into your project (available on nuget or on GitHub). With this in place you should be able to switch from using the existing TextBoxFor / DropDownListFor / CheckBoxFor / TextAreaFor / RadioButtonFor / ListBoxFor / PasswordFor HtmlHelper statements in your views and to jQuery.Validation.Unobtrusive.Native's equivalent by passing true to the useNativeUnobtrusiveAttributes parameter. (By convention this is the first parameter after the Expression<Func<TModel, TProperty>> expression parameter.

Ensure that you have the latest version of jquery.validate.js, you can find it here. Oh, and remember that you no longer need to serve up the jquery.validate.unobtrusive.js on a screen where you are using jQuery.Validation.Unobtrusive.Native. All you need is jquery.validate.js (and of course jQuery).

P.S. If you're using the source code from GitHub in Visual Studio, make sure you have the Package Manager option "Allow NuGet to download missing packages during build" set to true. This will ensure that the required packages are downloaded from NuGet.

Examples

Where you would previously have written:

@Html.TextBoxFor(x => x.RangeAndNumberDemo)

To use jQuery.Validation.Unobtrusive.Native you would put:

@Html.TextBoxFor(x => x.RangeAndNumberDemo, true)

Or, where you would have written:

@Html.DropDownListFor(x => x.DropDownRequiredDemo, new List<SelectListItem> {
    new SelectListItem{ Text = "Please select", Value = "" },
    new SelectListItem{ Text = "An option", Value = "An option"}
})

Now you would put:

@Html.DropDownListFor(x => x.DropDownRequiredDemo, true, new List<SelectListItem> {
    new SelectListItem{ Text = "Please select", Value = "" },
    new SelectListItem{ Text = "An option", Value = "An option"}
})

The only differences above are the extra true parameters being passed. If you had passed false instead jQuery.Validation.Unobtrusive.Native internally calls the inbuilt MVC implementation. I have considered keeping jQuery.Validation.Unobtrusive.Native's HtmlHelpers entirely separate from the inbuilt MVC ones and instead implementing TextBoxNativeFor / DropDownListNativeFor etc... methods which share the same signatures as the inbuilt MVC ones. For now this is the way it is but it could change if people feel strongly enough - if you've an opinion then drop me a line with your rationale.

By the way, the above examples (and others) can be found in the MVC demo project jVUNDemo on GitHub - this demo site be viewed at johnnyreilly.github.io/jQuery.Validation.Unobtrusive.Native/. 2 of the demos (Remote and Globalize) do not work completely as static sites (which GitHub pages are). If you would like to see these demo's in action it's best you run the jVUNDemo project locally.

State of the Union

This is basically a "done" project. Work is complete and I'm not aware of any missing pieces. I could port this to ASP.Net Core / MVC 6 when it ships but I don't have any immediate plans to. Never say never though.

Author

John Reilly

Credits

Inspired by jquery.validate.unobtrusive.js and entirely dependent on http://github.com/jzaefferer/jquery-validation and http://aspnet.codeplex.com/wikipage?title=MVC.

Copyright

Copyright © 2013 John Reilly.

License

MIT license - http://www.opensource.org/licenses/mit-license.php

Changelog

1.3.0 / 2015-11-27

1.2.0 / 2015-06-08

1.1.2 / 2015-01-07

1.1.1 / 2014-05-27

1.1.0.0 / 2013-10-04

  • Added support for PasswordFor, previously missing.

1.0.0.0 / 2013-09-04

  • Fix to allow usage of EditorTemplates (thanks to @DavidCarroll for this)
  • Fix to make range culture invariant to enable use by cultures where the decimal place is represented by something other than a decimal place (eg in Germany 20.5 is expressed as 20,5 - JavaScript can't handle this yet).
  • Given major version number now that the rough edges have been dealt with.

0.4.1.0 / 2013-08-25

  • Now possible to override generated data attributes with those passed in htmlAttributes parameter.

0.4.0.0 / 2013-08-14

  • All missing helpers now covered (TextArea / ListBox etc)
  • Switch to new mechanism to support users implementing their own custom validations
  • Included demo of custom validations implementation

0.2.0 / 2013-08-07

  • Initial release
  • Included demo of dynamic content using Knockout.

0.1.0 / 2013-07-29

  • Beta release - not fully featured

jquery.validation.unobtrusive.native's People

Contributors

davidcarroll avatar johnnyreilly avatar lok0919 avatar zhaph avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jquery.validation.unobtrusive.native's Issues

No Html.EditroFor/DisplayFor overloads

Hi

I've noticed that there are no overloaded functions for Html.EditroFor/DisplayFor, this means that the validation attributes that are generated are using the old data-val attributes instead of the new data-rule attributes. Is there anyway we could add support for this in another release?

Remote validation ignores additionalFields

Additional fields are mentioned in additional data attributes (data-rule-remote), but jQuery validation ignores them. I suspect this feature is not implemented in native jQuery validation.

Would be nice to have a list of known differences between this and Microsoft's implementation somewhere.

Support for EditorFor helper

It appears there is no support for the EditorFor helper in the current version. Any plans to do so? I notice that the HTML generated by EditorFor produces the old MS data-val* attributes (due to UnobtrusiveJavaScriptEnabled being set to true). I've started going down the path of merging the attributes from an EditorFor(expression) and a TextBoxFor(expression, true). From what I can see, the latest version of jQuery Validation doesn't use the data-val* attributes any longer, so I'm guessing I don't need to output those at all. I'm just wondering if you've considered supporting EditorFor or if you've already found issues that wouldn't make it practical before I continue much further.

I really like the potential usefulness of jQVUN! Thanks. —Jeff

name and id attributes are doubling on TextBoxFor helper

For instance, I have a model with a property named "TitleCode" and when the HTML gets rendered, I see the following:

<input name="TitleCode.TitleCode" id="TitleCode_TitleCode" type="text" 
value="Mr" data-rule-maxlength="10" 
data-msg-maxlength="The field Title must be a string with a maximum length of 10.">

The name should just be "TitleCode". My workaround is at the end.

The model property looks like

[UIHint("Text"), DisplayName("Title"), StringLength(10)]
public string TitleCode { get; set; }

I am using a EditorTemplate as follows:

@model string
@{
    var help = Html.HelpMessageFor(m => m, "help-block");
}
<div class="control-group @help.errorClass">
    @Html.LabelFor(m => m, new { @class = "control-label"})
    <div class="controls">
        @Html.TextBoxFor(m => m, true)@Html.Raw(help.message)
    </div>
</div>

I didn't fork and issue a pull request because I'd rather you look into this since I am not sure I know why this happened. I suspect it is the use of an EditorTemplate which your demos are not using and my code is.

This is my workaround in your code if this helps. This was done inside the TextBoxExtensions.cs file. It is likely that I will run into the same issue on other extensions like CheckboxFor etc.

// The foillowing code will prevent the name from being doubled up like name="TitleCode.TitleCode"
var name = metadata.PropertyName;
if (htmlHelper.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix.EndsWith(name))
    name = "";
var textBox = Mapper.GenerateHtmlWithoutMvcUnobtrusiveAttributes(() =>
    htmlHelper.TextBox(name, metadata.Model, format, attributes));
//var textBox = Mapper.GenerateHtmlWithoutMvcUnobtrusiveAttributes(() =>
//    htmlHelper.TextBox(metadata.PropertyName, metadata.Model, format, attributes));

I like your project, nicely done.

Bug: popover error message shows and disappears if you submit the form by hitting Enter

Not sure if it's a bug with Unobtrusive Native, but I'd like to solicit thoughts.

Repro steps are fairly simple:

  1. open the Advanced Demos/Tooltip demo (https://johnnyreilly.github.io/jQuery.Validation.Unobtrusive.Native/AdvancedDemo/Tooltip.html)
  2. set focus on the first input field ("A number must be entered:")
  3. hit Enter

The input fields turn red (which is good as they're invalid), the "The TextBox field is required." popover error message appears for a moment then immediately disappears.

From what I can tell, the 'show' event gets fired by the tooltip, but 'shown', 'hide' or 'hidden' do not.

I keep in investigating, if I get to any results, will post a follow-up comment. Thoughts are welcome.

System.Web.Mvc.Html.SelectExtensions

Hey guys, i had to recompile the DLL to change the namespace of the DropDownListFor

For some reason it is in the wrong class.

in the original DLL it is in DropDownListExtensions

My framework is trying to find it in the SelectExtensions instead.

And place it into the System.Web.Mvc.Html namespace.

It works for me now that i recompiled it.

Validation not working on IE8

I recently gave a try to this plugin, unfortunately it doesn't seem to perform client side validation on IE8.

To be fair, that was the reason why I took a look a this plugin because it was not working on my implementation.

Reproducing this problem is fairly easy.

On IE8 ( no compatibility mode or emulation mode)
Go to: http://jqueryvalidationunobtrusivenative.azurewebsites.net/Demo/Required
Press Submit.

A post is done and no feedback is provided.

I do realise this is a fairly tricky question, but I was looking for someone who could either shed some light or at least share known possible workarounds.

On top of that IE8 flag the following errors:

Webpage error details

User Agent: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)
Timestamp: Wed, 5 Mar 2014 16:51:07 UTC

Message: Object doesn't support this property or method
Line: 1
Char: 14863
Code: 0
URI: http://jqueryvalidationunobtrusivenative.azurewebsites.net/bundles/jquery?v=OCFAn1NcaUrZ5VLi0Kt8lefDjHOF7mvtdw-2FUpZjJ01

Message: Bootstrap requires jQuery
Line: 1
Char: 31
Code: 0
URI: http://jqueryvalidationunobtrusivenative.azurewebsites.net/bundles/bootstrap?v=TrsnDoe6JguD6Lw3KbE7sMj0JMocLZEq5ursbRw7N3s1

Message: 'jQuery' is undefined
Line: 1
Char: 1
Code: 0
URI: http://jqueryvalidationunobtrusivenative.azurewebsites.net/bundles/jquery-validation?v=v2z4Z8qXYF6JsuzzQtx0LtcGD7Um7k1RcQLNLYyA-NE1

Message: Object expected
Line: 305
Char: 9
Code: 0
URI: http://jqueryvalidationunobtrusivenative.azurewebsites.net/Demo/Required

Jquery unobtrusive validations not working on type="number" with nullable int

I am using Jquery unobtrusive validations with mvc and i have a model with field
int? MinSalary{get;set;}

the validations work fine in mozilla and ie but fail in chrome when i add the Non interger input in the text box

    @Html.LabelFor(m => m.MinSalary)
                            @Html.TextBoxFor(m => m.MinSalary, new {  @class = "form-control", type = "number", min = "0",  })
                            @Html.ValidationMessageFor(m => m.MinSalary)

the validation also works fine with type="text" but shouldnt it also work otherwise.

Validation won't work with multi level models

Hi
I don't know if it's a normal behavior but validation doesn't work when you use a multi level models like this

public class MainModel
{
      public Model1 model1 { get; set; }
      public Model2 model2 { get; set; }
}

All validations fail even if the model is valid.

Luckily I have only validation in 1 model so I changed the code for

public class Model1
{
      public Model2 model2 { get; set; } // no validation in this one

      // All the properties with validation directly here
      ...
 }

I don't know if there's a reason for this. If not I think it could be a nice improvement.

Thank you
Marc

Adding HTML5 constraint attributes?

I've noticed that both the regular MVC implementation and your "Native" implementation do not automatically write out the constraint attributes that are native to HTML5.

Things like:

  • required
  • maxlength
  • max
  • min
  • etc.

Doesn't jQuery Validation support these HTML5 attributes natively now? In case something goes wrong with the script, this would still allow you to provide a validation through the regular browser-native validation constraints.

It feels wrong to rely only on data-attributes for things that are actually supported and built into HTML5.

Add support for Regex

Your library doesn't support regex validation (RegularExpressionAttribute). Please add it.
Microsoft jQuery Unobtrusive Validation supports it.

All checkboxes are being required regardless of [Required] attribute

I don't know what would have caused this, but we just noticed this during our development today. I noticed that the HTML output is adding the [data-rule-required] attribute, despite having no [Required] attribute on our model.

We only want our booleans to be required if the [Required] attribute is added to the view model. Amy I missing something?

We're using jQuery.Validation.Unobtrusive.Native.MVC5 (1.3.0) and jquery.validate.js (v1.15.0).
Here's our code.

public class SomeViewModel
{
    public bool Terms { get; set; }
}
@model SomeViewModel

@using (Html.BeginForm())
{
    @Html.CheckBoxFor(m => m.Terms, true)
    <button type="submit" class="btn btn-primary">Submit</button>
}

Am I missing something?

Wrong version of .NET Framework

The primary reference "X" could not be resolved because it was built against the "Y" framework. This is a higher version than the currently targeted framework "Z".

I use .NET Framework 4.0 and MVC 3, but dll-file compiled for "4.5".

Are you might to compile nuget-package for other versions of .NET Framework?

Client side validation attributes generated for integer fields is incorrect.

Hi, firstly thanks for sharing the great project.

Having a small issue. When generating client side attributes for an integer field. The data-rule generated is for "number" when instead is should be a "digit". This means client side validation does not occur when an invalid decimal value is entered.

Thanks again.
Matt

Checkbox expected behaviour

Hi. FIrst up thanks for this lib.

I was curious about the expected behaviour of bools/checkboxes. Note that using the example below, built-in unobtrusive validation produces no validation message (default(bool) is valid) for the checkbox.

This library produces a (required) validation message.

ModelState errors collection for 'Obsolete' is empty in both cases.

I think the default behaviour should be preserved, thoughts?

View:

@model WebApplication1.Controllers.TestViewModel
@using (Html.BeginForm())
{
    <div class="form-group">
        @Html.CheckBoxFor(p => p.Obsolete, true)
        @Html.ValidationMessageFor(p => p.Obsolete)

        @Html.TextBoxFor(p => p.Test, true)
        @Html.ValidationMessageFor(p => p.Test)
    </div>

    <input type="submit" value="Submit" />
}

@using (Html.BeginForm())
{
    <div class="form-group">
        @Html.CheckBoxFor(p => p.Obsolete)
        @Html.ValidationMessageFor(p => p.Obsolete)

        @Html.TextBoxFor(p => p.Test)
        @Html.ValidationMessageFor(p => p.Test)
    </div>

    <input type="submit" value="Submit" />
}
@section scripts {
    @Scripts.Render("~/bundles/jqueryval")
<script>
    $('form:eq(0)').validate();
    </script>
}

Controller:

public ActionResult Index()
        {
            var viewModel = new TestViewModel(); 
            return View(viewModel);
        }

        [HttpPost]
        public ActionResult Index(TestViewModel viewModel)
        {
            if (ModelState.IsValid)
            {
                return View();
            }
            return View(viewModel);
        }

ViewModel

public class TestViewModel
    {
        public bool Obsolete { get; set; }

        [Required]
        public string Test { get; set; }
    }

CheckBoxFor MVC5 - hidden?

Hi Guys,

Awesome project. (MVC5 version)

Not sure if this is a bug for feature. I'm getting lots of ""System.Collections.Generic.Dictionary`2+ValueCollection[System.String,System.Object" and a hidden input as well

Using:
@Html.CheckBoxFor(x => x.Accounttype1,true)

Where:
[Display(Name = "TFSA")]
[Required(ErrorMessage = "What type of account or accounts would you like to open?")]
public bool Accounttype1 { get; set; }

I get this html:

 <input type="checkbox" value="true" name="Accounttype1" id="Accounttype1" values="System.Collections.Generic.Dictionary`2+ValueCollection[System.String,System.Object]" keys="System.Collections.Generic.Dictionary`2+KeyCollection[System.String,System.Object]" count="2">
 <input type="hidden" value="false" name="Accounttype1">

ValidationMessage and ValidationSummary

Your project does not support ValidationMessage and ValidationSummary, I think you should document that. While nothing stops you from using ValidationMessage and ValidationSummary, you cannot share the same element to display server and client messages, hide the server message when validating, show messages in the summary instead by each individual control, etc. These features are exclusive to the unobtrusive library.

ASP.NEt Core

Is this going to be updated to use ASP.NET Core.

I could have a go if you can't.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.