goteti-js-forms
v1.2.10
Published
Author: Narasimha Goteti
Downloads
64
Maintainers
Readme
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
}
})
// 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.fields[indx].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.