All Projects → kwladyka → form-validator-cljs

kwladyka / form-validator-cljs

Licence: EPL-2.0 License
ClojureScript library to validate forms

Programming Languages

clojure
4091 projects

Projects that are alternatives of or similar to form-validator-cljs

Phrase
Clojure(Script) library for phrasing spec problems.
Stars: ✭ 275 (+428.85%)
Mutual labels:  spec, form-validation
smart-schema
A Laravel package to enable auto generation of forms
Stars: ✭ 18 (-65.38%)
Mutual labels:  form-validation
form-data-json
A zero dependency, cross browser library to easily get or set/manipulate form input values as/from a json object.
Stars: ✭ 37 (-28.85%)
Mutual labels:  form-validation
jquery.niceform
The jQuery plugin for validation and post form data to server
Stars: ✭ 16 (-69.23%)
Mutual labels:  form-validation
react-cool-form
😎 📋 React hooks for forms state and validation, less code more performant.
Stars: ✭ 246 (+373.08%)
Mutual labels:  form-validation
vue-use-form
✅ A Vue.js composition API function to validate forms
Stars: ✭ 97 (+86.54%)
Mutual labels:  form-validation
dataset
qri dataset definition
Stars: ✭ 16 (-69.23%)
Mutual labels:  spec
formalizer
React hooks based form validation made for humans.
Stars: ✭ 12 (-76.92%)
Mutual labels:  form-validation
Formulary
Declarative iOS TableView Forms in Swift (pre-SwiftUI)
Stars: ✭ 83 (+59.62%)
Mutual labels:  form-validation
react-declarative
A React form builder which interacts with a JSON endpoint to generate nested 12-column grids with input fields and automatic state management in a declarative style. Endpoint is typed by TypeScript guards (IntelliSense available). This tool is based on material-ui components, so your application will look beautiful on any device...
Stars: ✭ 17 (-67.31%)
Mutual labels:  form-validation
cp
A configurable template reuse solution for platform ui development .https://json-drived-configurable-platform.github.io/cp
Stars: ✭ 17 (-67.31%)
Mutual labels:  form-validation
valida
jQuery Plugin for client side easy form validations.
Stars: ✭ 17 (-67.31%)
Mutual labels:  form-validation
meta-schema
Little DSL to make data processing sane with clojure.spec and spec-tools
Stars: ✭ 25 (-51.92%)
Mutual labels:  spec
falcon-apispec
apispec plugin that generates OpenAPI specification (aka Swagger Docs) for Falcon web applications.
Stars: ✭ 44 (-15.38%)
Mutual labels:  spec
es-to-primitive
ECMAScript "ToPrimitive" algorithm. Provides ES5 and ES6/ES2015 versions.
Stars: ✭ 21 (-59.62%)
Mutual labels:  spec
es-abstract
ECMAScript spec abstract operations.
Stars: ✭ 86 (+65.38%)
Mutual labels:  spec
autoform
🤖📝 AutoForm is the simplest way to automatically generate fast, beautiful and standards/WCAG compliant HTML forms based on an Ecto Schema in a Phoenix Web Application to *significantly* speed up Web App Development. 🚀
Stars: ✭ 18 (-65.38%)
Mutual labels:  form-validation
wdio-spec-reporter
A WebdriverIO v4 plugin. Reporter that creates 'spec'-style reports
Stars: ✭ 20 (-61.54%)
Mutual labels:  spec
formio
Formio, form definition and binding library for Java platform
Stars: ✭ 24 (-53.85%)
Mutual labels:  form-validation
nglp-angular-material-landing-page
NGLP is an Angular Material Landing Page.
Stars: ✭ 32 (-38.46%)
Mutual labels:  form-validation

form-validator

ClojureScript library to validate forms.

Rationale

  • Move repeatable code for form validation from app to library.
  • Validate by spec and fn.
  • Custom messages. Could be "foo", {:level :warn :msg "foo"} or whatever.
  • Custom workflow. Let you choose when to show messages: on-blur / on-change / immediately after load page / ...
  • Easy and simple independent small solution. Compatible with re-frame, fulcro or whatever.
  • Work with different types of inputs, also custom ones like in material UI.
  • Base logic to make custom UI, but no UI included. No limitations.

Why? I need it myself. But I didn't find any library which satisfy me, so I wrote my own.

Read my article form validation to learn more rationales.

Tutorial and Demo

Discover it naturally by real code: https://kwladyka.github.io/form-validator-cljs/

Please keep in mind it is an example. It could easy take actions on different events on-change / on-blur / button click. All is your choice.

Add dependency

Clojars Project

Require in ns

(:require [form-validator.core :as form-validator])

Only if you use reagent

To be compatible with reagent library, needs to use reagent.core/atom instead clojure.core/atom.

(ns app.core
  (:require [reagent.core :as r]
            [form-validator.core :as form-validator]))

;; First line in core ns or dedicated init fn is a right place
(swap! form-validator/conf #(merge % {:atom r/atom}))

TL;DR

Init form

(-> {:names->value {:email ""
                    :password ""}
     :form-spec ::spec/form
    (form-validator/init-form))

return atom contained map:

{:form-spec :app.spec/form
 :names->value {:email "" :password ""}
 :names->invalid {:email [:app.spec/form :app.spec/email] :password [:app.spec/form :app.spec/password :app.spec/password-not-empty]}
 :names->show #{}
 :names->validators {}}

Then you can use functions from ns form-validator.core:

  • event->names->value! - With on-change / on-blur input event to update values.
  • event->show-message - With on-blur / on-change input event to trigger when show messages in UI.
  • ?show-message - Get message to show in UI for input. Also to know if mark input as not valid in UI.
  • form-valid? - true / false
  • validate-form-and-show? - Call validate-form and show all messages. Use with submit button.

Specification

Init form

;; clojure.spec.alpha

(s/def ::email (s/and string? (partial re-matches #"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,63}$")))

(s/def ::password-not-empty not-empty)
(s/def ::password-length #(<= 6 (count %)))
(s/def ::password (s/and string? ::password-not-empty ::password-length))

(s/def ::form (s/keys :req-un [::email ::password]
                      :opt-un [::password-repeat]))

;; form-valiadtor

(-> {:names->value {:email ""
                    :password ""}
     :form-spec ::form
     :names->validators {:email [email-exist?]
                         :password-repeat [password-repeat? ::spec-key]}}
    (form-validator/init-form))
  • :names->value - Form inputs with values to initialize.
    Use cases: Empty values for new data form / filled values with already existed data (update form) / if input is not required by spec :opt-un it can be ommited.
  • :form-spec - Spec to validate whole form.
    Should use always, unless you don't have specs.
  • :names->validators - Vector of spec keywords and fn. Order matter.
    Use cases: When don't have spec for form / if checkbox "accept terms" is checked / fn to compare password-repeat / check if user already exist by API during registration.
  • :names->show - #{} with names of inputs to show error messages on start. Use cases: Form with already filled values.

You can use :form-spec and :names->validators together. :form-spec is checked first.

Interact with form

(init-form ...) return atom:

{:form-spec :app.spec/form
 :names->value {:email "", :password ""}
 :names->invalid {:email [::form ::form-map ::email]
                  :password [::form ::form-map ::password ::password-not-empty]}
 :names->show #{}
 :names->validators {:email #object[cljs$core$sp1], :password-repeat #object[cljs$core$sp1]}}
  • :form-spec - Init form value without any change.
  • :names->value - Values of the form.
  • :names->invalid - Invalid inputs with reasons of validation fail.
  • :names->show - Add name of the input here, when you want to show message in UI.
  • :names->validators - All validators converted to one fn which works similar to some. Check all validators for specific input one by one, unless fail or return nil.

Messages

  • :names->validators can contain ::spec-key and fn.
  • Spec always return vector of :cljs.spec.alpha/problems :via. For example [::form ::form-map ::password ::password-not-empty]. It means spec ::form refer to spec ::form-map, which refer to spec ::password, which refer to spec ::password-not-empty, which failed.
  • fn can return vectors like spec, but also strings, map or any value.
;; Check error for input name "password"
(->> {::email "Typo? It doesn't look valid."
      ::password "Minimum 6 characters and one special character !@#$%^&*."
      :password-not-equal "Repeat password has to be the same."}
     (form-validator/?show-message form :password))

Based on [::form ::form-map ::password ::password-not-empty] it is trying to find ::password-not-empty message. Map not contain message for this spec. Then try to find ::password and return message. If not find, going deeper. If not find any, return true.

If reason of fail is not a vector, then it is returning as it is. For example "cutom message" or {:level :warn :msg "This is only warning."}. This is dedicated for fn validators.

Tips & Tricks & FAQ

  • Architecture of library let you make custom UI and validation on it. You can modify atom returned by form-init, add-watch on atom, add functions on top of core functions, use your own functions instead of core ones. It is designed to let you make custom things. In most of cases you really don't need to do it. It could be useful if you want to make your module based on this one.
  • To not prevent send form with warning (not error) messages like "Password is weak. We recommend to use better password" you have to use your own form-valid? function or make two form-init (first for errors and second for warnings). I decided to not make it as part of this library, because it is individual thing for project.
  • You want to write your own functions to generate UI HTML form and inputs based on this library. UI is individual thing for project, so I decided it wouldn't be part of this library. Instead this library give solid basement, which let you to build visualisation on it.

Everything below this line is mainly for myself as a maintainer of this library.

Developing

Library has to be always check with web browsers manually! Not only automated tests. The reasons are differences between web browsers and practical aspects of usability vs imagination :)

To do it use doc branch from this repository.

After all make a commit to readme with new sha hash for deps.edn.

Tests

clj -A:test:test-once

clj -A:test:test-watch

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].