Security News
Research
Supply Chain Attack on Rspack npm Packages Injects Cryptojacking Malware
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
cerebral-forms
Advanced tools
Signals, actions and state factories to create forms
This project is still in alpha. To test alpha version check instructions in monorepo.
Cerebral forms is basically a function that creates state needed to handle validation and an action factory for validating fields. It is simple in nature, but handles all the complexity that comes with forms.
A state factory for creating form state. Used when defining initial state or dynamically with an action. You can put forms inside forms.
You can add any properties to a form where properties containing an object with a "value" property are identified as fields.
import {form} from 'cerebral-forms'
export default {
state: {
form: form({
firstName: {
// The initial value
value: '',
// Validation rules with name and arguments passed in
// with colon separation
validationRules: ['minLength:3'],
// Error messages mapped to same index as validation rule
validationMessages: ['Must be at least 3 characters long'],
// When setting isRequired to true the field will be invalid if there
// is no value. To determine if there is not value, check "isValueRules" below
isRequired: false,
// Error message when field is required but has no value
requiredMessage: null,
// Will only be valid if this other field is also valid.
// Point to a field in the model
dependsOn: 'app.myForm.repeatPassword'
// You could also add an array to dependsOn to support multiple depends
// dependsOn: ['app.myForm.repeatPassword', 'app.someOtherForm.someField']
// Some properties are default and rarely changed, but you
// are free to change them
// Set the rules for identifying a value being present. Used
// in combination with "isRequired" when field is validating
isValueRules: ['isValue'],
// Value will be copied, but you can change it. Will be set
// when using form reset
defaultValue: '',
// Some properties are created for you by the validate action factory
// which can be used in the components.
// Toggled when field is validated
hasValue: false,
// If field has been validated or not. Toggled when validated
isPristine: true,
// Toggled when field is validated
isValid: true,
// Current error message, set when field is validated
errorMessage: null,
},
lastName: {
value: '',
// Combine rules using an object
validationRules: [{
minLength: 3,
isAlpha: true
}]
}
})
}
}
Sometimes you want more control over your form. isPristine
for example changes from false to true whenever you do a validation on the field. Sometimes you might want blur events instead to show error messages to the user. You are completely free to add whatever state you need when you create your fields. An isTouched property might be used to make blur events but you can call it whatever you like, it's just state.
import {form} from 'cerebral-forms'
export default function MyAction({state}) {
state.set('some.new.form', form({
name: {
value: '',
isTouched: false // change this field onBlur to have more control over error messages
},
age: {
value: 18
}
}))
}
You can add custom props to the root to the form state.
For example if you want to show validation errors only
when submitting the form you can add a showErrors
prop
which you set true when validation fails during form submit.
import {form} from 'cerebral-forms'
export default function MyAction({state}) {
state.set('some.new.form', form({
name: {
value: '',
},
showErrors: false
}))
}
You can set a default value for a property using a factory:
import {form, getFormFields} from 'cerebral-forms'
const MyFormFactory = (formObject) => {
const myForm = form(formObject)
const fields = getFormFields(myForm)
// You can also set some special properties for the whole form
myForm.showErrors = false
fields.forEach((field) => {
field.requiredMessage = field.requiredMessage || 'This field is required'
field.someProp = field.someProp || 'Some default'
})
return myForm
}
To add a new field you simply merge a new form into the existing one.
import {form} from 'cerebral-forms'
export default function MyAction({state}) {
state.merge('path.to.form', form({
address2: {
value: ''
}
}))
}
A chain you can use to easily change a field in some form. It will automatically validate the form. Can also be composed into any other chain.
import {changeField} from 'cerebral-forms'
export default {
state: {
form: form({
firstName: {
value: ''
}
})
},
signals: {
fieldChanged: changeField
}
}
In your view code you call the signal with path to the field and the updated value:
import React from 'react'
import {connect} from 'cerebral/react'
export default connect({
form: 'someModule.form'
}, {
fieldChanged: 'someModule.fieldChanged'
},
function MyForm({form, fieldChanged}) {
return (
<div>
<h4>First name</h4>
<input
value={form.firstName.value}
onChange={(event) => fieldChanged({
field: 'someModule.form.firstName',
value: event.target.value
})}
/>
</div>
)
}
)
An action factory you can use to validate any field in any chain.
import {props} from 'cerebral/tags'
import {validateField} from 'cerebral-forms'
export default [
doThis,
// static
validateField('path.to.form.field'),
// dynamic
validateField(props`fieldPath`),
doThat
]
An action factory you can use to validate a whole form.
import {props} from 'cerebral/tags'
import {validateForm} from 'cerebral-forms'
export default [
// static
validateForm('path.to.form'),
// dynamic
validateForm(props`formPath`),
isFormValid, {
true: [
passInForm
],
false: [
setSomeErrorMessages
]
}
]
An action factory you can use to reset any form from any chain. It will replace current value with the initial or default value defined. And revalidate.
import {props} from 'cerebral/tags'
import {resetForm} from 'cerebral-forms'
export default [
doThis,
// static
resetForm('path.to.form'),
// dynamic
resetForm(props`formPath`),
doThat
]
A function that takes a form and returns the same structure with only values. Can be used wherever, though typically in actions. Often used to pass a form to server.
import {formToJSON} from 'cerebral-forms'
export default function MyAction({state, axios}) {
const formData = formToJSON(state.get('some.form'))
return axios.post('/data', formData)
}
A function that takes a form and returns an object where the key is the path to the field and the value is the field itself. Typically used to calculate the state of a form.
This examples is a function that takes a form and returns true if all fields has a value.
import {getFormFields} from 'cerebral-forms'
export default function allHasValue(form) {
const formFields = getFormFields(form)
return Object.keys(formFields).reduce((allHasValue, key) => {
if (!allHasValue || !formFields[key].hasValue) {
return false
}
return true
}, true)
}
A function that takes a form and returns only the fields that are invalid. The object keys are the path to the field and the value is the field itself.
import React from 'react'
import {connect} from 'cerebral/react'
import {getInvalidFormFields} from 'cerebral-forms'
export default connect({
form: 'someModule.form'
},
function MyForm({form}) {
const invalidFields = getInvalidFormFields(form)
return (
<ul>
{Object.keys(invalidFields).map((key) => (
<li key={key}>
{invalidFields[key].errorMessage}
</li>
))}
</ul>
)
}
)
A function that takes a form and returns true if all the fields in the form is valid. Used in both actions and components.
import React from 'react'
import {connect} from 'cerebral/react'
import {isValidForm} from 'cerebral-forms'
export default connect({
form: 'someModule.form'
},
function MyForm({form}) {
const isValid = isValidForm(form)
return (
<div>
<button disabled={!isValid}>Send form</button>
</div>
)
}
)
You can also use this function inside a chain:
import {props} from 'cerebral/tags'
import {isValidForm} from 'cerebral-forms'
export default [
// static
isValidForm('path.to.form')
// dynamic
isValidForm(props`formPath`), {
true: [],
false: []
}
]
You can attach new rules to the rules object.
import {rules} from 'cerebral-forms';
// You get passed the value of the field,
// the form it is attached to and whatever
// arg you pass after : (minLength:3)
rules.isFirstUpperCase = (value, form, arg) => {
return typeof value === 'string' && value[0] === value[0].toUpperCase()
}
FAQs
Signals, actions and state factories to create forms
The npm package cerebral-forms receives a total of 202 weekly downloads. As such, cerebral-forms popularity was classified as not popular.
We found that cerebral-forms demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.
Security News
Sonar’s acquisition of Tidelift highlights a growing industry shift toward sustainable open source funding, addressing maintainer burnout and critical software dependencies.