Code Monkey home page Code Monkey logo

silverware-validator's Introduction

SilverWare Validator

Latest Stable Version Latest Unstable Version License

A form validation module for SilverStripe v4 which supports alternative client-side backends and customisable validation rules. Ships with Parsley.js as the default validation backend. Configured out-of-the-box for use with Bootstrap v4 forms.

Contents

Requirements

Installation

Installation is via Composer:

$ composer require silverware/validator

Configuration

As with all SilverStripe modules, configuration is via YAML. The SilverStripe dependency injector is used to configure the validator backend. The module ships with a backend that uses Parsley.js:

SilverStripe\Core\Injector\Injector:
  ValidatorBackend:
    class: SilverWare\Validator\Backends\ParsleyBackend

The module has been designed to be as "backend agnostic" as possible. While Parsley.js is very powerful and should cater for most validation needs, you could certainly roll your own backend implementation and integrate it into the validator frontend using configuration.

Usage

To make use of the validator in your app, simply use the validator class in the header of your code:

use SilverWare\Validator\Validator;

You will also need to use the validator rule classes you wish to apply to your form, for example:

use SilverWare\Validator\Rules\LengthRule;
use SilverWare\Validator\Rules\PatternRule;
use SilverWare\Validator\Rules\RequiredRule;

Create a validator instance in your controller method that returns the Form, for example:

public function Form()
{
    $fields  = FieldList::create([
        ...
    ]);
    
    $actions = FieldList::create([
        ...
    ]);
    
    $validator = Validator::create();
    
    // define validator rules here!
    
    $form = Form::create($this, 'Form', $fields, $actions, $validator);
    
    return $form;
}

Now you can define your validator rules using the methods shown below.

Validator Rules

SilverWare Validator ships with many pre-built rules which you can use straight away to validate your forms. These rules support both client-side and server-side validation. Included with SilverWare Validator are the following rule classes:

Each of these rules will be covered in greater detail below.

Setting Rules

To set a rule for a particular form field, use the setRule method, and pass the field name and the rule instance. For example:

$validator->setRule(
    'MyFieldName',
    LengthRule::create(10, 20) // this field's value must be 10-20 characters in length
);

To set more than one rule for a field, you can use the setRules method and pass an array of rule instances:

$validator->setRules(
    'MyDomainName',
    [
        RequiredRule::create(),  // this field is required
        DomainRule::create()     // this field must be a valid domain name
    ]
);

Required Fields

Since fields are often required for almost any form, shortcut methods have been provided to define required fields. Use addRequiredField with the field name and optional custom message parameter:

$validator->addRequiredField('MyRequiredField');
$validator->addRequiredField('MyOtherRequiredField', 'Dis field be mandatory, yo!');

To add required fields in bulk, use addRequiredFields with an array of field names:

$validator->addRequiredFields([
    'ThisFieldIsRequired',
    'SoIsThisField',
    'AndThisField'
]);

Custom Messages

All rule classes come with a default message which is shown to the user when the rule validation fails. You can define your own custom messages by using the setMessage method on a rule, for example:

$validator->setRule(
    'MyAge',
    MaxRule::create(130)->setMessage(
        'I find it hard to believe you are over 130 years old!'
    )
)

Disabling Validation

By default, SilverWare Validator performs both client-side and server-side validation. While it's recommended to leave both methods of validation enabled, if you need to disable either, you can use the following methods:

$validator->setClientSide(false);  // disables client-side validation
$validator->setServerSide(false);  // disables server-side validation

Trigger Events

The out-of-the-box validator Parsley.js is set to trigger form validation upon field change by default. You can customise when you'd like validation to be triggered by using the setTriggerOn method on the backend, for example:

$validator->getBackend()->setTriggerOn([
    'focusin',
    'focusout'
]);

You can also simply pass the trigger events as a string:

$validator->getBackend()->setTriggerOn('focusin focusout');

Parsley.js supports triggering by any of the standard jQuery events.

Rules

AlphaNumRule

use SilverWare\Validator\Rules\AlphaNumRule;

Tests that the value is an alphanumeric string, containing only basic letters, numbers, and the underscore character.

$validator->setRule(
    'MyFieldName',
    AlphaNumRule::create()
);

CheckRule

use SilverWare\Validator\Rules\CheckRule;

Used for a OptionsetField such as CheckboxSetField. Ensures that the user chooses a certain number of options, between the given $min and $max parameters.

$validator->setRule(
    'MyCheckboxSet',
    CheckRule::create(2, 4)  // user must select between 2 and 4 options
);

ComparisonRule

use SilverWare\Validator\Rules\ComparisonRule;

Compares the value of one field to another, using the specified comparison type:

  • ComparisonRule::LESS_THAN
  • ComparisonRule::LESS_THAN_OR_EQUAL
  • ComparisonRule::GREATER_THAN
  • ComparisonRule::GREATER_THAN_OR_EQUAL
$validator->setRule(
    'MyLesserValue',
    ComparisonRule::create(
        ComparisonRule::GREATER_THAN,
        'MyGreaterValue'
    )
);

DateRule

use SilverWare\Validator\Rules\DateRule;

Ensures that the entered value is a date of the specified format. The rule constructor supports two arguments. The first is the required date format using the client-side Moment.js specification.

The optional second argument specifies the server-side PHP date format, however the rule will convert the client-side format appropriately if you omit the second argument.

$validator->setRule(
    'MyDateField',
    DateRule::create('YYYY-MM-DD')  // ensures an ISO standard date, e.g. 2017-05-12
);

DigitsRule

use SilverWare\Validator\Rules\DigitsRule;

Ensures only digits are entered, i.e. the numbers 0-9 only.

$validator->setRule(
    'MyDigitsField',
    DigitsRule::create()
);

DomainRule

use SilverWare\Validator\Rules\DomainRule;

Tests that the entered value is a valid domain name. Supports the new TLD domains and also localhost.

$validator->setRule(
    'MyDomainName',
    DomainRule::create()
);

EmailRule

use SilverWare\Validator\Rules\EmailRule;

Ensures that the value is a valid email address.

$validator->setRule(
    'MyEmailField',
    EmailRule::create()
);

EqualToRule

use SilverWare\Validator\Rules\EqualToRule;

Ensures that the value of one field is equal to the value of another.

$validator->setRule(
    'MyFirstValue',
    EqualToRule::create('MySecondValue')
);

IntegerRule

use SilverWare\Validator\Rules\IntegerRule;

Tests that the entered value is a valid positive or negative integer.

$validator->setRule(
    'MyIntField',
    IntegerRule::create()
);

LengthRule

use SilverWare\Validator\Rules\LengthRule;

Ensures that the length of the entered value is between the specified $min and $max range.

$validator->setRule(
    'MyFieldName',
    LengthRule::create(20, 40)  // value must be between 20-40 characters in length
);

MaxCheckRule

use SilverWare\Validator\Rules\MaxCheckRule;

Used for a OptionsetField such as CheckboxSetField. Specifies that the user may only select a maximum number of options.

$validator->setRule(
    'MyCheckboxSet',
    MaxCheckRule::create(4)  // user can select a maximum of 4 options
);

MaxLengthRule

use SilverWare\Validator\Rules\MaxLengthRule;

Ensures that the entered value is of a maximum length.

$validator->setRule(
    'MyFieldName',
    MaxLengthRule::create(40)  // value must be 40 characters in length or less
);

MaxRule

use SilverWare\Validator\Rules\MaxRule;

Tests that a numeric value is less than or equal to the specified amount.

$validator->setRule(
    'MyNumberField',
    MaxRule::create(255)  // number value must be 255 or less
);

MaxWordsRule

use SilverWare\Validator\Rules\MaxWordsRule;

Ensures that the value is of the specified number of words or less.

$validator->setRule(
    'MyTextArea',
    MaxWordsRule::create(50) // value must be 50 words or less
);

MinCheckRule

use SilverWare\Validator\Rules\MinCheckRule;

Used for a OptionsetField such as CheckboxSetField. Ensures that the user selects a minimum number of options.

$validator->setRule(
    'MyCheckboxSet',
    MinCheckRule::create(2)  // user must select at least 2 options
);

MinLengthRule

use SilverWare\Validator\Rules\MinLengthRule;

Ensures that the entered value is of a minimum length.

$validator->setRule(
    'MyFieldName',
    MinLengthRule::create(20)  // value must be at least 20 characters in length
);

MinRule

use SilverWare\Validator\Rules\MinRule;

Tests that the numeric value is greater than or equal to the specified amount.

$validator->setRule(
    'MyNumberField',
    MinRule::create(42)  // the entered value must be 42 or greater
);

MinWordsRule

use SilverWare\Validator\Rules\MinWordsRule;

Ensures that the entered value is of the specified number of words or greater.

$validator->setRule(
    'MyTextArea',
    MinWordsRule::create(20)  // value must contain at least 20 words
);

NotEqualToRule

use SilverWare\Validator\Rules\NotEqualToRule;

Ensures that the value of one field is NOT equal to the value of another.

$validator->setRule(
    'MyFirstValue',
    NotEqualToRule::create('MySecondValue')
);

NumberRule

use SilverWare\Validator\Rules\NumberRule;

Tests that the entered value is numeric, i.e. an integer or a floating-point number.

$validator->setRule(
    'MyNumericValue',
    NumberRule::create()  // value must be numeric
);

PatternRule

use SilverWare\Validator\Rules\PatternRule;

Uses a regular expression to test the entered value. Ensure that the format of your regular expression works in both JavaScript, and also PHP preg_match so that both client and server validation functions correctly.

$validator->setRule(
    'MyFieldName',
    PatternRule::create('/ware$/')  // ensures the entered string ends with 'ware'
);

RangeRule

use SilverWare\Validator\Rules\RangeRule;

Specifies a number range that the entered value must be between.

$validator->setRule(
    'MyNumericValue',
    RangeRule::create(1, 5)  // value must be between 1 and 5
);

RemoteRule

use SilverWare\Validator\Rules\RemoteRule;

Tests the value on the client-side using an Ajax request, and uses Guzzle to test the value when submitted to the server.

The following arguments are permitted for the rule constructor:

$rule = RemoteRule::create(
    $url,  // url to call
    $params,  // request parameters, e.g. ['myVar' => 123]
    $options, // options for request, e.g. ['type' => 'POST']
    $remoteValidator  // remote validator to use, 'default' or 'reverse'
);

For example, you might use the RemoteRule to check if a username is available:

$validator->setRule(
    'MyUserName',
    RemoteRule::create(
        $this->Link('checkusername')  // controller method
    )->setMessage('That username is unavailable')
);

The server will receive the name of the field and it's value as parameters, i.e. ?MyUserName=sallybloggs. By default, if the RemoteRule receives an HTTP status code of between 200-299, it is considered to be valid. Anything else will return an invalid result.

If you'd like to reverse this behavior, i.e. 200-299 is considered to be invalid, you can use "reverse" mode:

$validator->setRule(
    'MyUserName',
    RemoteRule::create(
        $this->Link('checkusername')
    )->setRemoteValidator('reverse')
);

For more information on using remote validation, see the Parsley.js documentation.

RequiredRule

use SilverWare\Validator\Rules\RequiredRule;

Defines the specified field as a required (mandatory) field that must be completed by the user.

$validator->setRule(
    'MyRequiredField',
    RequiredRule::create()
);

URLRule

use SilverWare\Validator\Rules\URLRule;

Ensures that the entered value is a valid URL.

$validator->setRule(
    'MyURL',
    URLRule::create()
);

WordsRule

use SilverWare\Validator\Rules\WordsRule;

Ensures that the entered value is between $min and $max words.

$validator->setRule(
    'MyTextArea',
    WordsRule::create(10, 25)  // user must enter between 10 and 25 words
);

Issues

Please use the GitHub issue tracker for bug reports and feature requests.

To-Do

  • Tests

Contribution

Your contributions are gladly welcomed to help make this project better. Please see contributing for more information.

Attribution

Maintainers

Colin Tucker Praxis Interactive
Colin Tucker Praxis Interactive

License

BSD-3-Clause © Praxis Interactive

silverware-validator's People

Contributors

colintucker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

silverware-validator's Issues

validate depending on choice of other field

Hi,
Is there an option to validate or not validate a field depending on choice of a optionset field? For example: I have an optionset field with different payment options. Depending of the choice of payment I show or hide fields below by jQuery. If fields are hidden they must not validated.

Use of Validator on getCMSValidator breaks the Silverstripe Admin

Hi,
first of all thank you for the module. It is very well done so thank you for that.
There is an issue when trying to use the module in the getCMSValidator() function of an object like so

    /**
     * CMS Fields
     * @return Validator
     */
    public function getCMSValidator()
    {
      $validator = Validator::create();
      $validator->setRules(
          'Title',
          [
            RequiredRule::create()
          ]
      );
      return $validator;
    }

And it is that on the first load of a page when the validator is used it breaks the layout of the page because the parsley file does not load correctly, hence stopping a bunch of SS js files from loading.
When trying that approach the admin looks like this:
image
then on reload it's fine.
I do not know if you intended your module to be used in this scenario as you don't officially list it in your documentation, however it can definitely be used in this scenario since it implements the Silverstripe Validator abstract. It works very well after the page reload (all the custom rules work too).
Matter of fact I was using it in the getCMSValidator because I found your module coming from the Shea Dawson ZenValidator one (he lists the use as a CMSValidator).
So long story short, the parsley file is the issue, which would not matter in the way I am using the Validator except that it cannot be de-activated in a straightforward way, I know that you have listed

$validator->setClientSide(false);

as an option, however that does not stop parsley from failing to load on ajax request.
Also trying to override the js_required in the Parsley Backend like so

SilverWare\Validator\Backends\ParsleyBackend:
  js_required:
    - []

does not work because it only adds to the js list.
Luckily you have done well to provide extension hooks so the way I solved this was like such:

class ValidatorFix extends DataExtension
{
  public function updateRequiredJS(&$js){
    $js = array();
  }

}

Which works alright when applied to ParsleyBackend class
.
Sorry for the long description I wanted to make you understand the situation.

Anyway, this is not an issue per se as you already provided devs options to override such behaviour, however I cannot determine why the parsley file conflicts with SS backend so my best suggestion would be the following: if you intend the module to be used as a CMS Validator too I'd suggest that you allow the config file to override the js options completely.
Obviously if you can determine why parsley conflicts it would be even better but I suspect parsley file has a problem in itself (on the ZenValidator page from Shea he has an option to disable the parsley file when the Validator is used in the getCMSValidator function).

Guzzle update?

Hi,

Is it possible to update Guzzle to version 7.* in the composer file? I get conflicts with other repositories now.

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.