1.2.12 • Published 4 months ago
goteti-js-forms v1.2.12
GotetiJsForms
Author: Narasimha Goteti
Goteti-JS-Forms is the TypeScript based library for generating the Forms based on JSON payload, track updates and form validations. Supports .mjs or module based javascript
Get Started
Prerequisites : NodeJS
npm i goteti-js-forms
Code Implementation
import { GtsFormHub } from 'goteti-js-forms';
// Supported BluePrints : GtsObjectBP , GtsListBP, GtsInputBP
let formFieldsBPPayload: GtsObjectBP = {
isObject: true,
name: 'registerForm',
fields: [
{
name : 'firstName',
type: 'text',
hide: false,
disable: false,
label : 'First Name',
validations: [
{
key: 'minLength', // No "_" as prefix is errors
value: 5
},{
key: '_warningOne', // add prefix "_" for warnings.
value: 3
}, {
key: 'pattern',
value: <stringRegExp or RegExp instance>,
flags: 'gi' //optional flags for pattern validation default 'g'
},
{
key: 'required' | 'min' | 'max' | 'minLength' | 'maxLength' | 'pattern' | 'email', // Supported validations
value: '<value for min, max, minLength, maxLength, pattern, email>',
flags: '<optional for pattern type>',
message: '<Error message to be shown below field if validation fails>'
}
]
}, {
name: 'username',
type: 'email',
},
{
name: 'contacts',
label: 'Contacts',
isArray: true,
init: 2,
fieldinfo:{
name: 'primarycontact',
label: 'Primary Contact',
type: 'number',
}
}
]
};
let formHub: GtsFormHub = new GtsFormHub({ // KeyValue Pair for validation functions
minLength: (validation, field)=>{ // This is error as no "_" as prefix for key
if(field.value > validation.value){
return {
minLength: "Minimum length is ${validation.value} "
}
}
},
_warningOne: (validation, field)=>{ // This is warning as "_" as prefix for key
if(field.value > validation.value){
return {
_warningOne: "Minimum length is ${validation.value} "
}
}
}
}, function onFormChange(control, actiontype, othertype, othervalue){
console.log('on Form prop value changes', arguments);
/* 'actiontype' supports the following,
1. loaded : triggers this event when form control is ready to use.
2. update : updates value, set dirty states, run validation, new hashid.
3. setValue : updates value, run validation, new hashid.
4. setValueOnly : updates value, new hashid.
5. view : 'DISABLED' | 'HIDDEN' => true / false.
6. interact: 'DIRTY' | 'TOUCHED' => true / false.
*/
}, {
submitted: false,
checkOnSubmit: true,
checkOnDirty: false,
checkOnTouch: false,
checkOnLoad: false
});
//Supported form types: GtsFormInput | GtsFormObject | GtsFormList;
// To Create the form object using the blueprint formHub.build(blueprintpayload)
let formdata = formHub.build(formFieldsBPPayload) as GtsFormObject;
// To Create the form object with updated info using the blueprint formHub.update({...updatedInfo}, blueprintpayload)
let formdata = formHub.update({firstname: 'Narasimha', contacts: ['1234567890', '9876543210']}, formFieldsBPPayload) as GtsFormObject
//To Add new record to array
formdata.prop('contacts').addToList({...formdata.prop('contacts').config.fieldinfo, name :'workcontact' label :'Work Contact', value: '1111111111'}, index_optional)
// To remove a record from array
formdata.prop('contacts').removeFromList(index_mandatory);
// To detect the changes to the form field values.
let destroyDetection = formdata.detectChanges().onChange((value, actiontype, control)=>{
if("update, setValue, setValueOnly".includes(actiontype)){
// code for after update event
}
})
onSubmit(){
formdata.submit(true);
if(formdata.isValid){
formdata.submit(false).reset(); // you can pass custom data to reset(data) with same structure;
}
}
// When change detection needs to be destroyed use "destroyDetection.destroy();"
Accessing
Field Type | Accessing methods |
---|---|
GtsFormObject | formdata.prop('firstname').value formdata.fields.firstname.value |
GtsFormList | formdata.prop(indx).value formdata.fieldsindx.value |
GtsFormInput | formdata.value |
Usage
/* Plain JavaScript */
// After adding the goteti-js-forms.js to script tag as module, 'GtsFormHub' is available on window.
window.GtsFormHub
/* Angular */
<input
type="text"
[(ngModel)]="formdata.prop('firstname').value"
*ngIf="formdata.prop('firstname').hidden"
[disabled]="formdata.prop('firstname').disabled"
/>
/* React */
destroyListners;
componentDidMount(){
destroyListners = formdata.detectChanges().onChange((value, actiontype, control)=>{
if("update, setValue, setValueOnly".includes(actiontype)){
this.setState({updatenow: new Date()})
}
})
}
componentWillUnmount(){
destroyListners.destroy();
}
(OR)
let useGotetiForms = function(masterValidation, blueprints = {}, updateobj = {}){
let [lastRender, setRender] = useState('');
let [formData, setFormData] = useState((new GtsFormHub(masterValidation)).upate(updateobj, blueprints));
let [onformReset, setOnformReset] = useState('');
useEffect(()=>{
let detectform = formData.detectChanges().onChanges((value, actiontype, control)=>{
if("update, setValue, setValueOnly".includes(actiontype)){
setRender(control.hashid);
}
})
return ()=>{
detectform && detectform.destroy();
}
}, [onformReset]);
let resetForm = ()=>{
setFormData((new GtsFormHub(masterValidation)).upate(updateobj, blueprints));
setOnFormReset(formData.hashid);
}
return [lastRender, setRender, formData, resetForm]
}
let [hashid, b , formData, resetForm] = useGotetiForms({...validations},{...blueprint},{...updatedobj});
handleEvent(e: any){
formdata.prop('firstname').value = e.target.value;
// formdata.fields.firstname.value = e.target.value;
// formdata.prop('firstname').updateValue(e.target.value); // all statuses and change detections are triggered
// formdata.prop('firstname').setValue(e.target.value); Only value is updated but change detections are not triggered;
// formdata.prop('firstname').setValueOnly(e.target.value);
//for (let item of formdata.Fields){} //'Fields' for iterating GtsFormObject & GtsFormList instances.
//for (let item in formdata.fields){} // 'fields' for iterating GtsFormObject instance.
// Access showErrors boolean: formdata.prop('firstname').showErrors
// Access Errors: formdata.prop('firstname').errors;
// Access Validity: formdata.prop('firstname').isValid;
// Access Dirty: formdata.prop('firstname').dirty;
// Access touched: formdata.prop('firstname').touched;
}
<input type="text" onChange={handleEvent}/>
Other available functions
dotNotation(object<any>, string)
GtsInterpolate(object<any>, string)
GtsProxyWatch(watchCallbackFunction, object<any>, key)
@GtsInputDebounce(delayTimeInMilliSeconds)
2. For Iterations over the GtsFormObject | GtsFormList , use 'Fields' instead of 'fields'.
ex: Angular
@for (item of formData.Fields; track item.config.name) {
<label>{{item.config.label}}<span ng-if="item.isRequired">*</span></label>
<input [(ngModel)]="item.value" [placeholder]="item.config.name"/>
<p ng-if="item.showError">
{{item.errors.required}}
</p>
}
3. Use 'showErrors' boolean to display the formData.errors , showErrors boolean works based on the checkOnDirty,checkOnTouch,checkOnSubmit configuration in GtsFormHub --> FormStatus, ex: above same code.
4. formData.detectChanges().onChanges((value, actiontype, control, othertype, othervalue)=>{
/*
'actiontype' supports the following,
1. update : updates value, set dirty states, run validation, new hashid.
2. setValue : updates value, run validation, new hashid.
3. setValueOnly : updates value, new hashid.
4. view : 'DISABLED' | 'HIDDEN' => true / false.
5. interact: 'DIRTY' | 'TOUCHED' => true / false.
*/
})
5. 'isRequired' boolean support added to GtsFormInput, GtsFormObject, GtsFormList .
6. Use 'hasErrors' instead of 'showErrors' for performance benefits.
example:
<div *ngIf="control.hasErrors">
{{control?.errors | json}}
</div>
onSubmit(){
formStatus.submitted = true;
control.fire('submit'); // This will run validations again required for submit
if(control.isValid){
// Post Calls
}
}
7. 'GtsDetectHashChangesInHostComponent' for value changes in Input host component.
example:
ngOnInit(){
destroy = GtsDetectHashChangesInHostComponent(control, ()=>{
// callback when value and its hash value changes.
}, true);
}
ngOnDestroy(){
destroy();
}
Caution
Do NOT modify the disabled / hidden boolean flags inside validators.
Licence
Open Source.
The author is not liable for any liabilities.
1.2.12
4 months ago
1.2.11
5 months ago
1.2.9
11 months ago
1.2.10
10 months ago
1.2.0
12 months ago
1.2.8
11 months ago
1.2.7
11 months ago
1.2.6
11 months ago
1.2.5
11 months ago
1.2.4
11 months ago
1.2.3
11 months ago
1.2.2
12 months ago
1.2.1
12 months ago
1.1.9
1 year ago
1.1.8
1 year ago
1.1.7
1 year ago
1.1.6
1 year ago
1.1.5
1 year ago
1.1.4
1 year ago
1.1.3
1 year ago
1.1.2
1 year ago
1.1.1
1 year ago