npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

aspnet-client-validation

v0.11.0

Published

Enables ASP.NET MVC client-side validation, without jQuery!

Downloads

5,761

Readme

ASP.NET Client Validation

Enables ASP.NET MVC client-side validation without jQuery! Originally forked from https://github.com/ryanelian/aspnet-validation. This library replaces the need for jquery.validate.min.js, jquery.validate.unobtrusive.min.js. It's a nearly drop-in replacement. The only difference is you need to initialize the library as shown in the Quickstart Guide.

npm Build Status

Install

npm install aspnet-client-validation

or

yarn add aspnet-client-validation

Alternatively, extract these files from the dist.zip folder of the latest release:

  • aspnet-validation.min.js
  • aspnet-validation.min.js.map

aspnet-client-validation uses Promise API, which is not supported in Internet Explorer. It is recommended to use promise-polyfill or ts-polyfill or core-js to resolve this issue...

If you are also using Bootstrap, you may un-jQuery the application by using https://github.com/thednp/bootstrap.native

Quick Start Guide

Via <script src="...">

<script src="promise-polyfill.min.js"></script>
<script src="aspnet-validation.min.js"></script>
// Exposes window['aspnetValidation']
var v = new aspnetValidation.ValidationService();
v.bootstrap();

Via CommonJS / Browserify

require('core-js');
const aspnetValidation = require('aspnet-client-validation');

let v = new aspnetValidation.ValidationService();
v.bootstrap();

Via TypeScript / ES Modules

import 'ts-polyfill';
import { ValidationService } from 'aspnet-client-validation';

let v = new ValidationService();
v.bootstrap();

Use instapack for easy, rapid, and painless web application front-end development using TypeScript!

Why?

jquery-3.3.2.min.js + jquery.validate.min.js + jquery.validate.unobtrusive.min.js = 112 KB

aspnet-validation.min.js: 10.6 KB (9.46%, ~4 KB GZIP)

  • promise-polyfill: +3.06 KB (< 1 KB GZIP)

Also, jquery.validate.unobtrusive.min.js has not been meaningfully updated in over a decade, and is hard to configure.

Building the Source Code

git clone https://github.com/haacked/aspnet-client-validation.git
npm install
script/build   # If using PowerShell: script/build.ps1

Adding Custom Validation

Example stolen from https://docs.microsoft.com/en-us/aspnet/core/mvc/models/validation

Server Code (C#)

public class ClassicMovieAttribute : ValidationAttribute, IClientModelValidator
{
    private int _year;

    public ClassicMovieAttribute(int Year)
    {
        _year = Year;
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        Movie movie = (Movie)validationContext.ObjectInstance;

        if (movie.Genre == Genre.Classic && movie.ReleaseDate.Year > _year)
        {
            return new ValidationResult(GetErrorMessage());
        }

        return ValidationResult.Success;
    }

    public void AddValidation(ClientModelValidationContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        MergeAttribute(context.Attributes, "data-val", "true");
        MergeAttribute(context.Attributes, "data-val-classicmovie", GetErrorMessage());

        var year = _year.ToString(CultureInfo.InvariantCulture);
        MergeAttribute(context.Attributes, "data-val-classicmovie-year", year);
    }
}

Client Code

import { ValidationService } from 'aspnet-client-validation';
let v = new ValidationService();

v.addProvider('classicmovie', (value, element, params) => {
    if (!value) {
        // Let [Required] handle validation error for empty input...
        return true;
    }

    // Unlike the original, data-val-classicmovie-year is bound automatically to params['year'] as string!
    let year = parseInt(params.year);
    let date = new Date(value);
    let genre = (document.getElementById('Genre') as HTMLSelectElement).value;

    if (genre && genre === '0') {
        return date.getFullYear() <= year;
    }

    return true;
});

v.bootstrap();

Adding Custom Asynchronous Validation

Other than boolean and string, addProvider callback accepts Promise<string | boolean> as return value:

v.addProvider('io', (value, element, params) => {
    if (!value) {
        return true;
    }

    return async () => {
        let result: number = await Some_IO_Operation(value);
        return result > 0;
    };
});

Controlling when validation occurs

Events

By default, validation occurs immediately upon changes to form fields: on input for inputs and textareas, and on change for selects.

One can change to a different event by setting a field's data-val-event attribute. For example, one can use data-val-event="blur" to validate that field on the blur event.

Timing

To prevent unnecessary validation, a debounce of 300ms is used. This ensures validation does not occur for every keystroke, which is especially important during remote validation.

In some cases it may be unnecessary, for example when performing local validation on blur (rather than on change). To change the default:

v.debounce = 0;

Subscribing to Client Form Validation Event

const form = document.getElementById('form');
form.addEventListener('validation', function (e) {
    /* Check if form is valid here. */
});

Programatically validate a form

v.validateForm(document.getElementById('form'));

Checking form validity

v.isValid(document.getElementById('form'))

By default it will try to validate the form, before returning whether the form is valid. This can be disabled by setting the prevalidate parameter like so:

v.isValid(document.getElementById('form'), false)

You can also supply a callback function to be run after the check.

v.isValid(document.getElementById('form'), true, myCallbackFn)

Checking field validity

Similar to checking a forms validity, you can check individual fields too.

v.isFieldValid(document.getElementById('field'))

By default it will try to validate the form surrounding the field, before returning whether the field is valid. This can be disabled by setting the prevalidate parameter like so:

v.isFieldValid(document.getElementById('field'), false)

You can also supply a callback function to be run after the check.

v.isFieldValid(document.getElementById('field'), true, myCallbackFn)

Hidden fields validation

By default validation is skipped for hidden fields. To enable validation for hidden fields validation use:

v.allowHiddenFields = true;

Monitoring the DOM for changes

If configured, aspnet-client-validation can monitor the DOM for changes using MutationObserver, if the browser supports it. As new elements are added/modified, the library will automatically wire up validation directives found. This can be very useful when using frameworks that modify the DOM, such as Turbo. To configure this, set the watch option to true when calling bootstrap:

let v = new aspnetValidation.ValidationService();
v.bootstrap({ watch: true });

Alternatively, to update the validation service for a specific form (which was created or modified dynamically) without using a MutationObserver:

let form = document.getElementById('my-form');
v.scan(form);

Customizing CSS for use with other libraries

One can customize the CSS classes so the generated markup is compatible with various frameworks. For example, to integrate with Bootstrap (v5+):

var v = new aspnetValidation.ValidationService();
v.ValidationInputCssClassName          = 'is-invalid';                 // change from default of 'input-validation-error'
v.ValidationInputValidCssClassName     = 'is-valid';                   // change from default of 'input-validation-valid'
v.ValidationMessageCssClassName        = 'invalid-feedback';           // change from default of 'field-validation-error'
v.ValidationMessageValidCssClassName   = 'valid-feedback';             // change from default of 'field-validation-valid'
//v.ValidationSummaryCssClassName      = 'validation-summary-errors';  // unnecessary: bootstrap lacks validation summary component
//v.ValidationSummaryValidCssClassName = 'validation-summary-valid';   // "
v.bootstrap();

Logging

There is a rudimentary logging infrastructure in place if you want to get more insight into what the library is doing. To enable logging, pass an object that implements the Logger interface (see below) in to the ValidationService constructor. The window.console object satisfies this interface automatically:

// The Logger interface, for reference
export interface Logger {
    log(message: string, ...args: any[]): void;
    warn(message: string, ...args: any[]): void;
}

let v = new aspnetValidation.ValidationService(console);
v.bootstrap();