{"id":4498,"url":"https://github.com/unexge/foect","last_synced_at":"2025-08-04T01:32:36.574Z","repository":{"id":57239620,"uuid":"85470970","full_name":"unexge/foect","owner":"unexge","description":"Simple form validation library for React Native.","archived":false,"fork":false,"pushed_at":"2020-03-07T08:00:51.000Z","size":92,"stargazers_count":38,"open_issues_count":4,"forks_count":12,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-11-24T10:09:55.039Z","etag":null,"topics":["form","react","react-native","validation"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unexge.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-19T11:32:30.000Z","updated_at":"2022-11-11T12:32:44.000Z","dependencies_parsed_at":"2022-08-30T00:11:26.069Z","dependency_job_id":null,"html_url":"https://github.com/unexge/foect","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unexge%2Ffoect","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unexge%2Ffoect/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unexge%2Ffoect/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unexge%2Ffoect/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unexge","download_url":"https://codeload.github.com/unexge/foect/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":228201769,"owners_count":17884321,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["form","react","react-native","validation"],"created_at":"2024-01-05T20:17:14.420Z","updated_at":"2024-12-07T08:30:42.127Z","avatar_url":"https://github.com/unexge.png","language":"TypeScript","readme":"Foect \n[![Build Status](https://travis-ci.org/unexge/foect.svg?branch=master)](https://travis-ci.org/unexge/foect)\n[![npm version](https://badge.fury.io/js/foect.svg)](https://badge.fury.io/js/foect)\n----\nSimple form validation library for React Native.\n\n## Installing\nNpm\n```\nnpm i --save foect\n```\n\nYarn\n```\nyarn add foect\n```\n\n## Quick Start\n```jsx\nimport { TextInput, Text, View, Button } from 'react-native';\nimport Foect from 'foect';\n\n// ...\n\n\u003cFoect.Form\n  defaultValue={{\n    email: 'john@doe.com'\n  }}\n  onValidSubmit={model =\u003e {\n    console.log(model); // { fullName: 'John Doe', email: 'john@doe.com' ... }\n  }}\n\u003e\n  { /* you can use form for triggering submit or checking form state(form.isSubmitted, form.isValid, ...) */ }\n  { form =\u003e (\n    \u003cView\u003e\n      { /* every Foect.Control must have a name and optionally validation rules */ }\n      \u003cFoect.Control name=\"fullName\" required minLength={2} maxLength={32}\u003e\n        { /* you can use control for getting/setting it's value, checking/updating(control.isValid, control.markAsTouched(), ...) it's state, checking it's errors(control.errors.required) */ }\n        { control =\u003e (\n          \u003cView\u003e\n            \u003cText\u003eFull Name\u003c/Text\u003e\n\n            \u003cTextInput\n              style={{height: 40, borderColor: 'gray', borderWidth: 1}}\n              { /* mark control as touched on blur */ }\n              onBlur={control.markAsTouched}\n              { /* update control's value */ }\n              onChangeText={(text) =\u003e control.onChange(text)}\n              { /* get control's value */ }\n              value={control.value}\n            /\u003e\n\n            { /* check control state and show error if necessary */ }\n            { control.isTouched \u0026\u0026\n              control.isInvalid \u0026\u0026 \n              \u003cText style={{ color: 'red' }}\u003ePlease enter your name.\u003c/Text\u003e }\n          \u003c/View\u003e\n        ) }\n      \u003c/Foect.Control\u003e\n\n      \u003cFoect.Control name=\"password\" required pattern={/(?=^.{8,}$)((?=.*\\d)|(?=.*\\W+))(?![.\\n])(?=.*[A-Z])(?=.*[a-z]).*$/}\u003e\n        { control =\u003e (\n          \u003cView\u003e\n            \u003cText\u003ePassword\u003c/Text\u003e\n\n            \u003cTextInput\n              style={{height: 40, borderColor: 'gray', borderWidth: 1}}\n              secureTextEntry={true}\n              onBlur={control.markAsTouched}\n              onChangeText={(text) =\u003e control.onChange(text)}\n              value={control.value}\n            /\u003e\n\n            { control.isTouched \u0026\u0026\n              control.isInvalid \u0026\u0026 \n              \u003cView\u003e\n                { control.errors.pattern ?\n                  \u003cText style={{ color: 'red' }}\u003ePlease provide a strong password.\u003c/Text\u003e : \n                  \u003cText style={{ color: 'red' }}\u003ePlease enter your password.\u003c/Text\u003e }\n              \u003c/View\u003e }\n          \u003c/View\u003e\n        ) }\n      \u003c/Foect.Control\u003e\n\n      \u003cFoect.Control name=\"email\" required email\u003e\n        { control =\u003e (\n          \u003cView\u003e\n            \u003cText\u003eEmail\u003c/Text\u003e\n\n            \u003cTextInput\n              style={{height: 40, borderColor: 'gray', borderWidth: 1}}\n              keyboardType=\"email-address\"\n              onBlur={control.markAsTouched}\n              onChangeText={(text) =\u003e control.onChange(text)}\n              value={control.value}\n            /\u003e\n\n            { control.isTouched \u0026\u0026\n              control.isInvalid \u0026\u0026 \n              \u003cView\u003e\n                \u003cText\u003e{control.value} is not a valid email.\u003c/Text\u003e\n              \u003c/View\u003e }\n          \u003c/View\u003e\n        ) }\n      \u003c/Foect.Control\u003e\n\n      { /* submit form */ }\n      \u003cButton disabled={form.isInvalid} onPress={() =\u003e form.submit()} title=\"Register\" /\u003e\n    \u003c/View\u003e\n  ) }\n\u003c/Foect.Form\u003e\n```\n\n## Documentation\n\n### Types\n```ts\ntype Status = 'INIT' | 'VALID' | 'INVALID';\n```\n```ts\ntype Model = { [key: string]: any };\n// { firstName: 'John', lastName: 'Doe' }\n```\n```ts\ntype Errors = { [key: string]: boolean };\n// { required: true, email: true }\ntype FormErrors = { [name: string]: Errors };\n// { firstName: { required: true, minLength: true } }\n```\n```ts\ntype Validator = (value: any, config?: any, control?: Control) =\u003e ValidatorResult;\ntype ValidatorResult = null | Errors;\n```\n\n### Props\n#### Form\n* `children: (form: Form) =\u003e Element` child renderer function.\n* `defaultValue?: Model` default values for form.\n* `onChange?: (model: Model) =\u003e void` callback called on value change.\n* `onValidSubmit?: (model: Model) =\u003e void` callback called on valid submit.\n* `onInvalidSubmit?: (errors: FormErrors, model: Model) =\u003e void` callback called on invalid submit.\n\n#### Control\n* `children: (control: Control) =\u003e Element` child renderer function.\n* `name: string` control name.\n* `[validator: string]: any;` validation rules for control.\n\n### APIs\n#### Form\n* `status: Status` form status.\n* `errors: FormErrors` form errors.\n* `isValid: boolean` is form valid.\n* `isInvalid: boolean` is form invalid.\n* `isSubmitted: boolean` is form submitted.\n\n* `addControl(name: string, control: Control): void` adds a new control to form.\n* `removeControl(name: string): void` removes a control from form.\n* `getValue(name: string): any` returns value of a control.\n* `setValue(name: string, value: any): void` sets value for a control.\n* `getErrors(name: string): Status` returns errors of a control.\n* `setErrors(name: string, errors: Errors): void` sets errors for a control.\n* `validateControl(name: string): void` validates a control and updates control state, errors.\n* `getStatus(name: string): Status` returns status of a control.\n* `update(): void` force updates form and all child controls.\n* `submit(): void` submits the form. calls `onInvalidSubmit` or `onValidSubmit` callback if provided.\n\n#### Control\n* `value: any` control value.\n* `form: Form` control's form.\n* `status: Status` control status.\n* `errors: Errors` control errors.\n* `isValid: boolean` is control valid.\n* `isInvalid: boolean` is control invalid.\n* `isTouched: boolean` is control touched.\n* `isUntouched: boolean` is control untouched.\n\n* `onChange(value: any): void` updates control's value.\n* `markAsTouched(): void` marks control as touched.\n* `markAsUntouched(): void` marks control as untouched.\n* `runValidation(value: any): Errors` runs validation with a value and returns errors.\n\n#### Validators\n\n##### Default validators\n| Validator        | Options        |\n| -------------    |:-------------:|\n| required         | - |\n| minLength        | `length: number` |\n| maxLength        | `length: number` |\n| pattern          | `pattern: RegExp` |\n| email            | - |\n| equalToControl   | `controlName: string` |\n| callback         | `(value: any, control: Control) =\u003e boolean` |\n\nOptions are passed via props\n```jsx\n\u003cFoect.Control\n  name=\"password2\"\n  myValidator={{foo: 'bar'}}\n\u003e\n```\nwith this definition, `myValidator` called with `('value of the input', {foo: 'bar'}, controlRef)`\n\nYou can add your own validators via `Foect.Validators.add`.\nValidators must return null on valid value and object with errors on invalid value. For example:\n```ts\nFoect.Validators.add('equalToControl', (val: any, controlName: string, control: Control) =\u003e {\n  if (null === val) {\n    return null;\n  }\n\n  return val === control.form.getValue(controlName) ? null : { equalToControl: true };\n})\n```\n\n* `Foect.Validators.add(validatorName: string, fn: Validator): void` adds a new validator.\n* `Foect.Validators.get(validatorName: string): Validator` returns a validator.\n* `Foect.Validators.has(validatorName: string): boolean` returns whether a validator exists.\n* `Foect.Validators.delete(validatorName: string): void` deletes a validator.\n\n----\nInspired by [Angular Forms](https://github.com/angular/angular/tree/master/packages/forms).\n","funding_links":[],"categories":["Components"],"sub_categories":["Forms"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funexge%2Ffoect","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funexge%2Ffoect","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funexge%2Ffoect/lists"}