Git Product home page Git Product logo

horprogs / just-validate Goto Github PK

View Code? Open in Web Editor NEW
486.0 14.0 91.0 3.69 MB

Modern, simple, lightweight (~5kb gzip) form validation library written in Typescript, with no dependencies (no JQuery!). Support a wide range of predefined rules, async, files, dates validation, custom error messages and styles, localization. Support writing custom rules and plugins.

Home Page: https://just-validate.dev/

License: Other

JavaScript 1.97% HTML 8.49% CSS 2.60% Shell 0.02% TypeScript 67.07% MDX 19.86%
validation vanilla-javascript form-validation form forms input javascript file-validation async-validation

just-validate's Introduction

Screenshot 2023-01-16 at 23 35 59

codecov npm Codacy Badge Known Vulnerabilities Release workflow

Modern, simple, lightweight (~5kb gzip) form validation library written in Typescript, with no dependencies (no JQuery!). Support a wide range of predefined rules, async, files, dates validation, custom error messages and styles, localization. Supporting writing custom rules and plugins.

Why JustValidate?

It's a right choice for you, if you have a site, a landing page without React, JQuery etc. and you want to quick, simple and powerful solution for validating your form.

Features

  • small size and zero dependencies
  • no need to change your HTML
  • a wide range of pre-defined rules
  • custom rules
  • support plugins
  • custom styles and css classes for invalid fields and error messages
  • custom messages
  • showing tooltips as error messages
  • custom places for the error labels
  • localization (defining error messages for different languages)
  • user-friendly setup: console warning messages if something incorrect
  • written in Typescript and good test coverage

Installation

npm

npm install just-validate --save

yarn

yarn add just-validate

And then use it as an imported module:

import JustValidate from 'just-validate';

const validate = new JustValidate('#form');

Or if you don't use module bundlers, just include JustValidate script on your page from CDN and call it as window.JustValidate:

<script src="https://unpkg.com/just-validate@latest/dist/just-validate.production.min.js"></script>
<body>
  <script>
    const validate = new window.JustValidate('#form');
  </script>
</body>

Predefined rules

There are plenty of rules which you could use out of the box:

  • required, non-empty fields
  • valid email address
  • min/max text length
  • valid number
  • min/max number
  • valid password
  • valid strong password
  • check for the custom regexp
  • min/max count of uploaded files
  • min/max size, types, extensions, names of uploaded files
  • format date, check for isAfter/isBefore dates

Quick start

Let's say we have a basic HTML layout:

<form action="#" id="form" autocomplete="off">
  <label for="name">Enter your name</label>
  <input
    type="text"
    class="form__input form-control"
    placeholder="Enter your name"
    autocomplete="off"
    name="name"
    id="name"
  />
  <label for="email">Enter your email</label>
  <input
    type="email"
    class="form__input form-control"
    placeholder="Enter your email"
    autocomplete="off"
    name="email"
    id="email"
  />
  <button class="btn btn-primary" id="submit-btn">Submit</button>
</form>

Next, let's add JustValidate to our layout and define some simple rules.

First, we should create the instance new JustValidate('#form') by passing a form selector, or the element as an argument.

Second, we call .addField() with a field selector as the first argument and an array of rules as the second argument.

const validation = new JustValidate('#form');

validation
  .addField('#name', [
    {
      rule: 'minLength',
      value: 3,
    },
    {
      rule: 'maxLength',
      value: 30,
    },
  ])
  .addField('#email', [
    {
      rule: 'required',
      errorMessage: 'Email is required',
    },
    {
      rule: 'email',
      errorMessage: 'Email is invalid!',
    },
  ]);

And that's it! Now our form is validated!

More

Please, check out the examples and documentation. Or try the playground.

just-validate's People

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  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  avatar  avatar  avatar  avatar

just-validate's Issues

translate error messages

How can i translate the error messages?
Only email is correctly translate.

<script src="<?php echo base_url('assets/just-validate/dist/js/just-validate.min.js');?>"></script>
		<script>
		new window.JustValidate('#form', {
			rules: {
				fullname: {
					required: true,
					minLength: 2,
					maxLength: 60
				},
				email: {
					required: true,
					email: true
				},
				message: {
					maxLength: 1000,
				},
				privacy: {
					required: true
				},
			},

			colorWrong: "#f0506e",
			focusWrongField: true,
			messages: {
				required: 'Il campo è richiesto',
				email: 'Inserisci una e-mail valida',
				maxLength: 'Il campo deve contenere massimo :value characters',
				minLength: 'Il campo deve contenere minimo :value characters',
			},
		});
		</script>

Re validate on change a select element

I just added this after line 590. Just to revalidate a input after change a option on select.

if (item.type === 'select-one') { item.addEventListener('change', function (ev) { delete _this2.result[item.name]; _this2.validateItem({ name: item.name, value: item.value, group: [] }); _this2.renderErrors(); }); }

Default form submit not working

Hello,

Till now, there was no such situation in the application but now I came across a situation not I want to trigger default form submit in my web application.

At present, I must use AJAX to submit the form. but I am expecting that this library can also be used for just validate the form and after successfull validation pass, default HTML submit should trigger.

Is there a way to achive this ?

Conditional validation not working on `change` event

Describe the bug
I noticed that condition validation as you mentioned in your example don't work on change event.
I have a select list and depending on the select list input, I want to validate checkbox's checked attribute.

It gives error as

Field not found. Check the field selector

To Reproduce
Steps to reproduce the behavior:

  1. Add one checkbox and select list with some elements.
  2. Add validation like below to
document.querySelector("[name='user[notification_settings_attributes][is_delay_enabled]']").addEventListener("change", (event) => {
      if (event.target.value === "") {
        this.notificationPreferencesFormValidator.removeField("[name='user[notification_settings_attributes][is_delay_enabled]']");
      } else {
        this.notificationPreferencesFormValidator.addField("[name='user[notification_settings_attributes][is_delay_enabled]']", [
          {
            rule: "required",
            errorMessage: "Must be checked"
          },
        ]);
      }
    });

Expected behavior
It should also listen properly to change event.

Thank you.

reverse function property for showErrors

Greetings from Turkey.

Can you add reverse operation for showError function? The showSuccess field wouldn't be bad at all. This feature is required when using with Promise.

Same set of validations on Multiple Form Selectors

Hi,

I think, plugin instance can be bound only to single form selector at a time. But suppose we have same set of fields but there form selectors are different (e.g., create-project, edit-project) then in that case, we need to iterate loop on those selector or form tag itself and place validations inside the loop to take validations in to effect.

Do you have any such plans to add this support or any other perfect solution the plugin has ?

e.g. validation object

formValidation = new JustValidate(".create-project, .edit-project", {
  errorFieldCssClass: "is-invalid",
  errorLabelCssClass: "invalid-feedback",
  focusInvalidField: true,
  lockForm: false,
  tooltip: {
    position: "top"
  },
}).onSuccess((event) => {
  event.preventDefault();
  axios({
    ...
  });
}).onFail((fields) => {
});

and then selector can be form class or name or id of users choice.

Thanks in advance.

Adding class in ajax response

Greetings from Turkey,

I have a question for version 3.5. After Ajax response, what to do to add Bootstrap 'invalid-feedback' to input?

I am designing login page and I need to add warning text to input for wrong password. Jquery is not being added with 'class.add' attribute.

<div class="col-12">
    <label>E-Mail</label>
    <input type="email" class="form-control" id="email">
    <div class="invalid-feedback" id="emailerror">
    </div>
</div>
const validation = new JustValidate('#GirisForm', {
validation.addField('#email', [
{
	rule: 'required',
]) ).onSuccess((event) => {
   $.ajax({
	type:"POST",
	url: "login/", 
	data:{email: email},
	    success: function(data) { }
       });
});

how to apply custom function

I'm trying to understand how to use a custom function,

i.e. tied with callback, but validation pass..

like:

function myCallbackFunction(name, value){
  ...
  return false;
}

..
rules: {
 myField: myCallbackFunction, 
 anotherField: { required: true}
}
..

how can I use custom function for validation?

Deleted FormData

Hi! I tried to send my form with just-validate (new syntax, 3.0.0 and more), but formData just cleared.

On older versions where the attributes are still present "data-validate-field" this does not happen.

.onSuccess((event) => {
      const form = document.querySelector('.form');
      let formData = new FormData(form); // this formData is empty on new versions JustValidate

Setting the rules doesn't seem to override the default rules.

For instance, the following seems to have no effect on the password rule.

Even setting password: false seems to have no effect.

  new window.JustValidate('.js-form', {
            Rules: {
                password: {
                    required: true,
                    password: true,
                    minLength: 0,
                    maxLength: 18,
                    strength: {
                        custom: '/.*/'
                    }
                }
            },
            Messages: {
                required: 'The field is required',
                email: 'Please enter a valid email address',
                maxLength: 'The field must contain a maximum of :value characters',
                minLength: 'The field must contain a minimum of :value characters',
                password: 'Password is not valid',
                remote: 'Email already exists'
            }
        });

revalidate() on an inputHandler ignores focusInvalidField config on Chrome

Describe the bug
I have to revalidate form after input change on my form to enable or disable submit button. My global config has "focusInvalidField" set to false. Works perfectrly fine on Mozilla. On the last version of Chrome, whenever I type in my input, focus is lost.

To Reproduce
On Chrome

  1. Having set Just Validate config properly
    Capture d’écran du 2022-04-14 12-08-08
  2. Having input handler on my fields
    Capture d’écran du 2022-04-14 12-08-45
  3. Using revalidate() to enable or disable submit button
    Capture d’écran du 2022-04-14 12-09-15

Expected behavior
Should not lose focus on the input i'm typing in whenever "focusInvalidField" is set to false

Not able to switch error messages in languages

Describe the bug
I referred your example and wrote my own validations in my project which should support verious languages for error messages as well

import { Controller } from "@hotwired/stimulus";
import i18n from "protaskz/i18next/setup";
import JustValidate from "just-validate";

export default class extends Controller {

  static targets = ["form", "blockeeId", "reason"];

  initialize() {
  }

  connect() {
    this.validateBlockedUserForm();
  }

  disconnect() {
  }

  validateBlockedUserForm() {
    if (typeof(this.formTarget) != "undefined" && this.formTarget != null) {
      let blockedUserForm = new JustValidate("[name='blocked-user-form']", {
        errorFieldCssClass: "is-invalid",
        errorLabelCssClass: "invalid-feedback",
        successFieldCssClass: "is-valid",
        successLabelCssClass: "valid-feedback",
        focusInvalidField: true,
        lockForm: false,
        tooltip: {
          position: "top"
        },
      }).onSuccess((event) => {
        event.preventDefault();
        Turbo.navigator.submitForm(event.target);
      }).onFail((fields) => {
      });

      [
        {
          key: "User is required",
          dict: {
            es: "Se requiere el usuario para bloquear",
            pt: "O usuário para bloquear é necessário",
          }
        },
        {
          key: "Reason for blocking is required",
          dict: {
            es: "Se requiere el motivo del bloqueo",
            pt: "O motivo do bloqueio é obrigatório",
          }
        }
      ]

      console.log(App.locale)
      blockedUserForm.setCurrentLocale(App.locale)

      if (typeof(this.blockeeIdTarget) != "undefined" && this.blockeeIdTarget != null) {
        blockedUserForm.addField("[name='blocked_user[blockee_id]']", [
          {
            rule: "required",
            errorMessage: "User is required"
          },
        ]);
      }
      if (typeof(this.reasonTarget) != "undefined" && this.reasonTarget != null) {
        blockedUserForm.addField("[name='blocked_user[reason]']", [
          {
            rule: "required",
            errorMessage: "Reason for blocking is required"
          },
        ]);
      }
    }
  }
}

Expected behavior
It should set locale and depending on that error message must be shown

Screenshots
Screenshot from 2022-05-06 19-42-34

and console.showing locale is changed.

Screenshot from 2022-05-06 19-44-36

Additional context

I followed example but unable to make sure that the library is not setting the locale or the problem is at my side.

TS type error for 'rule' property

It might be my Typescript config (see below), but the rule property in the Rule object is not accepting any of the accepted strings, such as 'required', 'email', 'minLength' etc.

Looks to me like an issue with the enum declaration.

This is the typescript error:
Type '"required"' is not assignable to type 'Rules | undefined'.ts(2322)
interfaces.d.ts(32, 5): The expected type comes from property 'rule' which is declared here on type 'FieldRuleInterface'

Screen Shot 2021-12-14 at 4 34 56 PM

Thanks for the help.

My Ts Config

{
  "compilerOptions": {
    "target": "es5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
    "lib": [
      "dom",
      "es6",
      "dom.iterable",
      "scripthost"
    ], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
    "module": "commonjs", /* Specify what module code is generated. */
    "moduleResolution": "node", /* Specify how TypeScript looks up a file from a given module specifier. */
    "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the `checkJS` option to get errors from these files. */
    "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */
    "sourceMap": true, /* Create source map files for emitted JavaScript files. */
    "outDir": "./dist/",
    "removeComments": true, /* Disable emitting comments. */
    "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */
    "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables `allowSyntheticDefaultImports` for type compatibility. */
    // "preserveSymlinks": true,                         /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */
    "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */
    /* Type Checking */
    "strict": true, /* Enable all strict type-checking options. */
  },
  "exclude": [
    "node_modules",
    "public/mockServiceWorker.js" // would be the default
  ]
}

package.json
{ "name": "crm", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "start": "webpack serve", "start:msw": "USE_MSW_MOCK_API=yes DEBUG=* npm start", "build": "webpack --config webpack.config.prod.js", "test": "echo \"Error: no test specified\" && exit 1", "lint": "eslint .", "lint:fix": "eslint . --fix" }, "author": "", "license": "ISC", "dependencies": { "just-validate": "^2.0.0", "msw": "^0.36.3" }, "devDependencies": { "@babel/core": "^7.16.0", "@babel/eslint-parser": "^7.16.3", "@babel/preset-react": "^7.16.0", "@types/dotenv-webpack": "^7.0.3", "@types/mini-css-extract-plugin": "^2.4.0", "@types/node": "^16.11.12", "@typescript-eslint/eslint-plugin": "^5.6.0", "@typescript-eslint/parser": "^5.6.0", "dotenv-webpack": "^7.0.3", "eslint": "^8.4.1", "eslint-config-airbnb": "^19.0.2", "eslint-config-airbnb-typescript": "^16.1.0", "eslint-config-prettier": "^8.3.0", "eslint-config-wesbos": "^3.0.2", "eslint-plugin-html": "^6.2.0", "eslint-plugin-import": "^2.25.3", "eslint-plugin-jsx-a11y": "^6.5.1", "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-react": "^7.27.1", "eslint-plugin-react-hooks": "^4.3.0", "html-webpack-plugin": "^5.5.0", "mini-css-extract-plugin": "^2.4.5", "prettier": "^2.5.1", "ts-loader": "^9.2.6", "typescript": "^4.5.3", "webpack": "^5.64.4", "webpack-cli": "^4.9.1", "webpack-dev-server": "^4.6.0" }, "msw": { "workerDirectory": "public" } }

Index.ts

import JustValidate from 'just-validate';

const validation = new JustValidate('#form');
validation
    .addField('#name', [
        {
            rule: 'minLength',
            value: 3,
        },
        {
            rule: 'maxLength',
            value: 30,
        },
    ])
    .addField('#email', [
        {
            rule: 'required',
            errorMessage: 'Email is required',
        },
        {
            rule: 'email',
            errorMessage: 'Email is invalid!',
        },
    ]);

0 is not acceptable in `minNumber` Rule

Hello Owner,

I came across one issue that rule minNumber is not accepting 0 saying:

Value for minNumber rule for [[name='model[field_name]']] field is not defined. The field will be always invalid.

My code was :

validator.addField("[name='model[field_name]']", [
  {
    rule: "maxNumber",
    value: 100,
    errorMessage: "Number should be less than 100"
  },
  {
    rule: "minNumber",
    value: 0,
    errorMessage: "Number should be greater than 0"
  },
]);

Was there anything wrong from my side or how we can fix this ?

Any plan for Implementing Date Validation Rule

Hi.

I went through the documentation of this plugin. I found almost all frequently used validation rules except date.

Do you have any plan to implement it ? If date validation rule is added, I think, I would be a plus point this library will have.

If you have a plan to implement it, I would be very happy to use this plugin for validations.

It will be very great if you can plan for some frequent options, viz., min date, max date, depending on value of other field (eg. validation of end date depending on start date), required date validations, date format and separator validations, etc

Please let me know your comment on this.

Not working on select tag

If you submit the form with all the required inputs empty and the select an option the select stays as invalid.
And if you change the value of any other input the selects of the form will constantly get marked as invalid.

Apply Min and Max Length Validations Only if there is Value

I came across a situation that I want to apply min and max length validations to fields only if there is a value entered for that field.

Example:

minLength - 2
maxLength - 50

I added these validation rules for the field but I want to apply these validations only if there is a value within that textbox.

Empty string is just fine and if string isn't empty then apply min and max length validations.

Is there a way to achive this ?

Disabled button in the form getting enabled on validation

Describe the bug
I have a disabled button called "Delete" which is disabled.
On Validation Fail/Success the "Delete" button disabled attribute is removed and it becomes enabled.

To Reproduce
Steps to reproduce the behavior:

  1. Have a Form with 2 or more buttons. One is submit and the other one is of type button and is disabled.
  2. Click on Submit and the other disabled button becomes enabled.
  3. The disabled attribute is removed and is replace by style with no value.

Expected behavior
The disabled button should not become enabled.

minLength rule validates successfully on empty fields

Why does your minLength rule validate successfully on empty fields? You made it on purpose? It's not obvious and ambiguous, don't you think so? It means, we need extra specify "required" rule for empty fields, because "minLength" rule works like empty value >= minLength value. This is strange, and I hope you fix it.

Remove fields/group(s) at once

Thx for the great validation library 😄.
It might be an edge case, idk.

I have a conditional validation like that #30. But I want to remove multiple validation fields/group(s) at once. Cuz, it causes an error when the relevant input fields/group(s) are removed from the DOM depending on the condition.

If I remove fields one by one with removeField its throws an error in my case.
And I cannot remove the required group(s).

Reproduction

https://codepen.io/AsimTahir/pen/XWexbpM

  1. Toggle radio Everything to No push notifications.
  2. Open the Browser Console tab.
  3. See error.
    just-validate.production.min.js:1 Uncaught Error: Field with #last-name selector not found! Please check the field selector.
    

Error trackback

  1. The error came from the refresh method.

    Object.keys(this.fields).forEach((key) => {

  2. It is triggered by the addField method.

    this.refresh();

As you can see the first field was successfully removed. But in other(s) its throws an error.

Temporary solution

import JustValidate from 'just-validate';

class JustValidateExtended extends JustValidate {
    /**
     * Remove multiple fields at once
     * @param  {Array<string>} fields
     * @returns {this}
     */
    removeFields(...fields) {
        if (!Array.isArray(fields) && fields?.length <= 0) {
            throw Error(
                `Field selectors are not valid. Please specify an array of strings. And make sure the array is not empty.`
            );
        }

        fields.forEach((field) => {
            if (typeof field !== "string") {
                throw Error(
                    `Field selector is not valid. Please specify a string selector.`
                );
            }

            if (!this.fields[field]) {
                console.error(`Field not found. Check the field selector.`);
                return this;
            }

            delete this.fields[field];
        });
        this.refresh();
        return this;
    }

    /**
     * Remove required group
     * @param {string} groupField
     * @returns {this}
     */
    removeRequiredGroup(groupField) {
        if (typeof groupField !== "string") {
            throw Error(
                `Group selector is not valid. Please specify a string selector.`
            );
        }

        if (!this.groupFields[groupField]) {
            console.error(`Group not found. Check the group selector.`);
            return this;
        }

        delete this.groupFields[groupField];
        this.refresh();
        return this;
    }

    /**
     * Remove multiple required groups at once
     * @param  {Array<string>} groupFields
     * @returns {this}
     */
    removeRequiredGroups(...groupFields) {
        if (!Array.isArray(groupFields) && groupFields?.length <= 0) {
            throw Error(
                `Group selectors are not valid. Please specify an array of strings. And make sure the array is not empty.`
            );
        }

        groupFields.forEach((groupField) => {
            if (typeof groupField !== "string") {
                throw Error(
                    `Group selector is not valid. Please specify a string selector.`
                );
            }

            if (!this.groupFields[groupField]) {
                console.error(`Group not found. Check the group selector.`);
                return this;
            }

            delete this.groupFields[groupField];
        });
        this.refresh();
        return this;
    }
}

Temporary solution Usage

const validation = new JustValidateExtended("#conditional-fields-form", {
	errorFieldCssClass: "is-invalid",
	errorLabelStyle: {
		fontSize: "14px",
		color: "#dc3545"
	},
	focusInvalidField: true,
	lockForm: true
});

validation
    .addField("#first-name", {
	        rule: "required",
	        errorMessage: "First name is required!"
        },
    )
    .addField("#last-name", {
	        rule: "required",
	        errorMessage: "Last name is required!"
        },
    )
    .addField("#email-address", {
	        rule: "required",
	        errorMessage: "Email address is required!"
        },
    )
    .addRequiredGroup(
        "#by-email",
        "You should select at least one communication channel"
    );

validation
    .removeFields("#first-name", "#last-name", "#email-address")
    .removeRequiredGroup("#by-email");

Not all field corrections clear out errors.

Describe the bug

I have a really simple form and validation scenario:

<div class="form-group">
	<label for="select">Selection</label>

	<div class="input-group">
	  <select id="select" name="select">
		<option value="0" disabled selected hidden>- please select -</option>
		<option value="1">One</option>
		<option value="2">Two</option>
		<option value="3">Three</option>
	  </select>        
	  <input id="cost" name="cost" type="number" min="0" placeholder="Cost" /> 
	  <span>dollar(s)</span>
	</div>

	<span id="errors"></span>

</div>
let validation = new JustValidate('#form')
  .addField('#select', [
    { rule: 'minNumber', value: 1, errorMessage: 'Selection required.' }
  ],
  { errorsContainer: "#errors" })
  .addField('#cost', [
    { rule: 'required', errorMessage: 'Cost is required.' },
    { rule: 'minNumber', value: 1, errorMessage: 'Cost must be greater than zero.' }
  ], { errorsContainer: "#errors" })

Expected behavior
When I hit submit, both errors end up in the container. (they do).
When I correct the select, the error disappears - (it does)
When I correct the number field, the error disappears - (it does not)

At first I thought - "Oh, it must be wiping out the first child in the element - so I switched the order of the fields to make the number error appear first - but it still behaves the same as listed above.

I think the number type isn't working - so to confirm that, I changed it to a "text" type, and it worked like I expected it to.

What I think is happening is that the input[type="number"] isn't triggering a reset of the errorsContainer?

Hopefully this is an easy fix.

Other than that - THIS IS THE BEST VALIDATION LIB EVER!

`addRequiredGroup` not working with nested usage

Describe the bug
addRequiredGroup method throws an error when nesting with checkbox required group, even if the required group contains checkbox(es) or radio(s).

To Reproduce

  1. Go to https://codepen.io/AsimTahir/pen/vYWVOLB
  2. Open the Browser's Console tab
  3. See error
    just-validate.production.min.js:1 Uncaught Error: Group should contain either or checkboxes or radio buttons
        at O.addRequiredGroup (just-validate.production.min.js:1:17980)
        at pen.js:9:12
    

Expected behavior
Both nested required groups should be initialized properly.

Additional context

Error trackback
  1. The error came cause by isRadio and isCheckbox variables.

    Just-validate/src/main.ts

    Lines 1080 to 1086 in de6039b

    const inputs: NodeListOf<HTMLInputElement> = elem.querySelectorAll('input');
    const isRadio = Array.from(inputs).every((input) => input.type === 'radio');
    const isCheckbox = Array.from(inputs).every(
    (input) => input.type === 'checkbox'
    );

    The inputs variable contains checkbox or radio input but both isRadio and isCheckbox variables return false.

Temporary solution

import JustValidate from "just-validate";

class JustValidateExtended extends JustValidate {
  addRequiredGroup(
    groupField: string,
    errorMessage?: string,
    config?: FieldConfigInterface,
    successMessage?: string
  ): JustValidate {
        if (typeof groupField !== "string") {
            throw Error(
                `Group selector is not valid. Please specify a string selector.`
            );
        }

        const elem = this.form!.querySelector(groupField) as HTMLElement;

        if (!elem) {
            throw Error(
                `Group with ${groupField} selector not found! Please check the group selector.`
            );
        }

        const inputs = elem.querySelectorAll("input[type=radio],input[type=checkbox]");

        const isRadio = Array.from(inputs).some((input) => input.type === 'radio');
        const isCheckbox = Array.from(inputs).some((input) => input.type === 'checkbox');
        // or
        // const isRadio = elem.querySelectorAll("input[type=radio]").length > 0;
        // const isCheckbox = elem.querySelectorAll("input[type=checkbox]").length > 0;

        if (!isRadio && !isCheckbox) {
            throw Error(
                `Group should contain either or checkboxes or radio buttons`
            );
        }

        this.groupFields[groupField] = {
            rules: [
                {
                    rule: "required",
                    errorMessage,
                    successMessage,
                },
            ],
            groupElem: elem,
            elems: Array.from(inputs),
            type: isRadio ? "radio" : "checkbox",
            isDirty: false,
            isValid: undefined,
            config,
        };

        inputs.forEach((input) => {
            this.setListeners(input);
        });

        return this;
    }
}

window.JustValidate = JustValidateExtended;

Method for manual validation

Hi,

I come across a situation to manually call form validations from some logical section written in JavaScript function.

The required feature for me is to show preview of the image only if image file is valid. Image field validations are set in JustValidate and there is method missing to validate the form from the method I have wrote for displaying image preview. I hope, there should be a method to call validations manually from that method. (function validate()). In this case, form was having only one field and it's for image upload.

In another screnario, I am having a form with multiple fields with one file field. In this case as well, I should show image preview, but I don't want validate entire form from the method I used for showing image preview. In this case, I just want to revalidate that perticular file field.

If this two methods could be implemented then they may have signature like:

To manually validate entire form.

  document.querySelector("form").validate()

and to validate / revalidate single form field:

  const fv = new JustValidate("form", {
    ...
  });
  
  fv.revalidateField("#field_name");
  or
  fv.validateField("#field_name");

If these two scenarios can be supported with some methods like above then that will be great.

Thank you.

Feature Request: CSS class configuration options accept multiple class names

Is your feature request related to a problem? Please describe.

The various CSS class configuration options (errorFieldCssClass, errorLabelCssClass, successFieldCssClass, successLabelCssClass) only accept a single class name. If I try to add multiple, an error is thrown.

Describe the solution you'd like

It would be beneficial to be able to set multiple class names for these configuration options. I envision being able to specify a space delimited class list. For example (using Bootstrap 5 classes):

{
  errorFieldCssClass: 'border-danger border-2'
}

This should be fairly simple with only a small refactor to any calls to elem.classList methods. For example, in main.ts:

Just-validate/src/main.ts

Lines 1478 to 1480 in cb4a945

field.elem.classList.add(
field.config?.errorFieldCssClass || this.globalConfig.errorFieldCssClass
);

... would become something like ...

    field.elem.classList.add(
      field.config?.errorFieldCssClass?.trim()?.length
        ? ...field.config.errorFieldCssClass.split(' ').filter(cls => cls.length > 0)
        : this.globalConfig.errorFieldCssClass
    );

I turned it into a ternary because the spread operator will throw an error if the optional chaining fails, and the filter() call is just some error checking to toss out any empty array items, in case the user accidentally put multiple spaces between class names. Anyway, you get the idea.

Describe alternatives you've considered

If you wanted to get fancy, you could also accept an array of class names, in addition to the space delimited class list, but that's just icing.

 

Also, great library, btw. I just started using it.

Do you consider/accept/appreciate pull requests? I seems you may prefer to discuss a topic first and implement it yourself, which I totally understand. Just trying to get a sense of things, I may have another feature request or two on my mind. 🙂

Conflicting variable name with Underscore.js

Overview
When using JustValidate on a site that also uses Underscore.js, I'm seeing an issue with the variable var _ = Object.defineProperty (taken from https://unpkg.com/[email protected]/dist/just-validate.production.min.js). Both libraries are creating global _ variables, which can cause an error in code that is using Underscore

To Reproduce

  1. Go to the following codepen, where both JustValidate and Underscore are included
  2. View the console
  3. See Uncaught TypeError: _.defer is not a function error

Suggested action
Update global variable name to something that doesn't clash with Underscore - are there any wider considerations to this?

Error Message Target Append?

First - I LOVE THIS LIBRARY! Thank you!

There is only one feature I need. Could you please make the "rule config" so that I could target where the error is appended? This is critical for compound inputs like this:

<div class="form-group">
  <label for="oldPassword">Current Password:</label>
  <div class="input-group"> <!-- I want to target this one.  :) -->
    <input type="password" id="oldPassword" name="oldPassword" v-model="req.oldPassword" />
    <button class="btn" @click="show.oldPassword = !show.oldPassword">
        <font-awesome-icon icon="eye-slash" v-if="show.oldPassword"></font-awesome-icon>
        <font-awesome-icon icon="eye" v-else></font-awesome-icon>
    </button>
    <!-- JV currenyly appends here.  No Good.  :(  -->
  </div>
  <!-- I want it to append here instead.  :) -->
</div>

If this could also be a "global config" that would be cool too.

I hope this is a quick win?

Other than that, your library is freaking awesome! Thank you so much for creating it.

Success classes must not be applied until all validations are passed

Hello,

At present, I have a remote validation set on the element of the form. Just validate instance is also initialized with success class options.

  const toDoItemsForm = new JustValidate(".to-do-item-form", {
      errorFieldCssClass: "is-invalid",
      errorLabelCssClass: "invalid-feedback",
      successFieldCssClass: "is-valid",
      successLabelCssClass: "valid-feedback",
      focusInvalidField: true,
      lockForm: false,
      tooltip: {
        position: "top"
      },
    }).onSuccess((event) => {

    });

    toDoItemsForm.addField("[name='to_do_item[item]']", [
        {
          rule: "required",
          errorMessage: I18n.t("javascripts.validation_error_messages.to_do_items.item.required")
        },
        {
          rule: "minLength",
          value: 2,
          errorMessage: I18n.t("javascripts.validation_error_messages.to_do_items.item.min_length")
        },
        {
          validator: (item) => () => {
            $("[name='to_do_item[item]']").addClass("is-loading");
            return new Promise((resolve) => {
              if (item.length > 0) {
                if ($("[name='to_do_item[item]']").getAttribute("data-value") === item) {
                  $("[name='to_do_item[item]']").removeClass("is-loading");
                  resolve(true);
                } else {
                  axios.post($("[name='to_do_item[item]']").getAttribute("data-href"), {
                    authuenticity_token: $("meta[name=csrf-token]").content,
                    item: item
                  }, {
                    ContentType: "application/json; charset=utf-8",
                  }).then((response) => {
                    $("[name='to_do_item[item]']").removeClass("is-loading");
                    resolve(response.data.status);
                  }).catch((error) => {
                    $("[name='to_do_item[item]']").removeClass("is-loading");
                    resolve(false);
                  });
                }
              } else {
                resolve(true);
              }
            });
          },
          errorMessage: I18n.t("javascripts.validation_error_messages.to_do_items.item.exists")
        }
      ]);

Actual behaviour

In this example, success option classes are set even when API call present in validator rule is being executed but such must not happen. At present, I see that required and minLength rules are returned sucess and successFieldCssClass classes set on the element but later that class turned into errorFieldCssClass classes when validator rule returned false.

Expected Behaviour

Success classes must be set only after all the rules are executed and are returning success.

Apply validation if checkbox is checked

I would like to validate some fields (with separate rules, messages etc) as usual... but only after a checkbox is checked.
I tried with some if...else but I think I missed something.
(Hope this could be a feature in the next releases)

Any suggestions? Thanks in advance

Globalization ?

How do you validate dates, currencies in different cultures?

For example the german decimal separator is comma , while the english is dot .

Few identical forms on the page

I saw few similar issues here, still want to know if any change: i create few identical forms with identical classes on the page. Could i sort out its into js cycle or need to create individual JustValidate object for every form?

Support for element along with String selectors in addField

Is your feature request related to a problem? Please describe.
When I pass element in addField method, it throws error saying:

controller.ts:12 Error connecting controller

Error: Field selector is not valid. Please specify a string selector.
    at JustValidate.addField (just-validate.es.js? [sm]:732:13)
    at t.validateBlockedUserForm (blocked_users_controller-dbd7a6e1a7e0c96cfbb2407a377cda3204a890d09bcbca3bb0dbd8bd11a06fc3.js:34:25)
    at t.connect (blocked_users_controller-dbd7a6e1a7e0c96cfbb2407a377cda3204a890d09bcbca3bb0dbd8bd11a06fc3.js:13:10)
    at M.connect (controller.ts:12:39)
    at L.connectContextForScope (controller.ts:12:39)
    at controller.ts:12:39
    at Array.forEach (<anonymous>)
    at R.connectModule (controller.ts:12:39)
    at R.loadDefinition (controller.ts:12:39)
    at controller.ts:12:39

Describe the solution you'd like
It would be better if selector ($(selector) / document.querySelector("selector")) is available along with string like

form.addField(document.querySelector("[name='field_name']"), [

])

Describe the solution you'd like
It will be beneficial if I already have element specified somewhere inside my JS, I can pass that element directly here rather than setting string.

JustValidate call parameter / errors messages repetition.

Describe the bug
In order to create an object "validation" with JustValidate I must write ("#" + form.id) as parameter. In order to destroy a failed validation error messages I must use a fix with an array "invalidElements" or errors warnings repeat by using button.addEventListener("click", () => {...});

Expected behavior
form.id should be enough as parameter. A method is requiered for destroying errors messages in order to avoid repeating themselves without exceptions. validation.isValid()==false as conditional doesn't work as I expected. Maybe it's just my incompetence. If it is the case, I apologise :)

Javier Ulises
validator_function
form_function

Checkbox group not supported.

Single checkboxes work just fine, but if you want to have a group using an array name (name="mycheckgroup[]"), the validation half works. It shows error on last option, and requires that all fields are selected (I think that's wrong, it should just be at least one).

The big problem is the ajax event handler doesn't pass the checkbox array values though. It just ends up with a single value of "true".

I would suggest adding the same support as the radio group for this (in regards to validation).And passing array values through the handler.

I will look at putting a fix in my fork as it looks like this has gone stale at the moment.

Validator for File Field

Previously I was using another validation plugin in my application but due to it's dependency on JQuery, I was supposed to remove it from the application.

In that plugin I was having something like below for validating file field

file: {
  extension: "jpe,jpg,jpeg,png",
  type: "image/jpeg,image/png",
  minSize: 2 * 10 * 1024,
  maxSize: 2 * 1024 * 1024,
  message: "error message"
}

How can we achive something like this to validate file max, min size, extensions, etc. in Just-Validate ?

Possible set required rule via HTML without using addField

Is your feature request related to a problem? Please describe.

<form>
        <input
          required
          type="text"
          name="firstName"
          placeholder="first name"
        />

        <input
          required
          type="text"
          name="lastName"
          placeholder="last name"
        />
</form>

When I have a form like the above, I have to keep repeating using .addField().

Describe the solution you'd like
Possible to use all rules directly from HTML, then we can just do something like this below. This is useful when needing to set up multiple forms with dynamic required fields.

  new JustValidate(
    '#form',
    {
      focusInvalidField: true,
      lockForm: true,
    }
  );

Thanks!

Error Message on condition basis and show message on field if validation passed

Hi,

I came across a situation that I need to return error message on conditions basis. At present, I tried with one option validator present in library but I could not use it because it returns only one error message when function returns falsy value.

Just for an example to let you understand about the problem:

validator.addField("[name='model[field_name]']", [
  {
    rule: "required",
    errorMessage: "Field is required"
  },
  {
    validator: (fieldValue, fields) => {
      if (value < 5) {
        return false;  // different message than one specified in below errorMessage.
      } else if (value > 10) {
        return false;  // different message than one specified in below errorMessage.
      } else {
        return true; // Success message in green popover or tooltip
      }
    },
    errorMessage: "Invalid"
  }
]);

At present, I think, it is not supported to return / display message if field passed validations and somewhere in huge applications, there might be such a scenario where we need to show success message somehat like "Looks great!", etc.

and also I think, there is no provision to show different error messages on condition basis.

Dear owner, what do you think on above two scenarios ?

Few forms on one page

I have like 4 small forms on a page with similar input fields. Should i create different new JustValidate for each form?

Possible to required radiobutton ?

Is it possible to add a requirement on the radiobuttons ? There is for a gender select in a form for example..
It's possible for a checkbox but I didn't see anything for the radiobuttons..

KR

Apply `customRegex` rule only if Field is filled up with Value

Hi,

I am being forced to keep those fields mandatory if those fields are bound with rule customRegex.

Example:

If I have 3 rules:

minLength, maxLength, customRegex but not required then in this case I expect that three rules must be fired only if there is value and as the field is not mandatory, If there is not value in that text field, validation should pass. but this is happening with minLength and maxLength but not in case of customRegex.

Ideally, customRegex rule should be fired only if there is some value present for that particular field.

Let me know what do you think on this.

Thanks in advance !

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.