roseworx
Version:
Front end css and js framework
177 lines (149 loc) • 4.21 kB
JavaScript
import { rwxCore, rwxComponent } from '../rwxCore';
class rwxForms extends rwxCore {
constructor()
{
super({selector:'[rwx-form]', canHaveManualControl:false, autoClass:false, resource: 'rwxForms'});
}
execute(el)
{
return new rwxForm(el);
}
customSubmitFn(id, submitFunction)
{
if(!this.validateParameter(submitFunction, 'function', 'customSubmitFn'))return;
const IME = this.getIME(id);
if(IME)IME.customSubmit = submitFunction;
}
}
class rwxForm extends rwxComponent {
constructor(el)
{
super({element: el})
this.submitButton = this.el.querySelector("button[type='submit']");
this.validEls = {};
this.events = []
this.getInputs().map((el)=>{
this.determineValid(el);
this.touched(el);
const blurev = (e) =>{
el.type == "checkbox" ? this.addValidClass(this.validCheckbox(el, e.target.checked), el) : this.addValidClass(this.validInput(el, e.target.value), el);
}
el.addEventListener('blur', blurev);
const validEvent = (el.type=="checkbox" || el.tagName=="SELECT" || el.type=="radio") ? 'change' : 'keyup';
const validEventEvent = (e) => {
this.determineValid(el);
if(this.submitButton)this.submitButton.disabled = !this.isFormValid();
}
el.addEventListener(validEvent, validEventEvent);
this.events.push([{
type: 'blur',
ev: blurev
},
{
type: validEvent,
ev: validEventEvent
}
]);
return;
});
if(this.submitButton)this.submitButton.disabled = !this.isFormValid();
this.submitFn = (ev) => {
if(!this.isFormValid())
{
ev.preventDefault();
return;
}
if(this.customSubmit){
ev.preventDefault();
const finalObject = {};
this.getInputs().map((i)=>{
let name = i.getAttribute('name');
if(name){
finalObject[name] = i.type=="checkbox" ? i.checked : i.value;
}
return;
})
this.customSubmit(finalObject);
}
}
this.submitFn = this.submitFn.bind(this);
this.el.addEventListener('submit', this.submitFn)
}
cleanUp()
{
this.el.removeEventListener('submit', this.submitFn);
this.getInputs().map((inp, i)=>{
this.events[i].map((e)=>inp.removeEventListener(e.type, e.ev));
this.submitButton.disabled = false;
return false;
})
}
getInputs()
{
return [...this.el.querySelectorAll("input"), ...this.el.querySelectorAll('textarea'), ...this.el.querySelectorAll('select')];
}
determineValid(el)
{
let isValid;
if(el.type == "checkbox"){isValid = this.validCheckbox(el, el.checked);}
else if(el.type == "radio"){isValid = this.validRadio(el, el.checked);}
else{isValid = this.validInput(el, el.value);}
this.validEls[this.getUniqueAttribute(el)] = isValid;
}
isFormValid()
{
return (Object.entries(this.validEls).every((ve)=>ve[1]===true));
}
getUniqueAttribute(el)
{
if(el.type=="radio" && el.parentNode.parentNode.classList.contains('rwx-form-radio-group')) return el.parentNode.parentNode.id;
return el.id || el.name;
}
touched(el)
{
el.addEventListener('focus', ()=>{
el.parentNode.classList.add('touched');
})
}
addValidClass(b, el)
{
if(this.isTouched(el))
{
b ? el.parentNode.classList.add('valid') : el.parentNode.classList.remove('valid');
b ? el.parentNode.classList.remove('invalid') : el.parentNode.classList.add('invalid');
}
}
isTouched(el)
{
return el.parentNode.classList.contains('touched');
}
isRequired(el)
{
return el.parentNode.classList.contains('required');
}
validRadio(el, value)
{
const required = this.isRequired(el);
const required2 = el.parentNode.parentNode.classList.contains('required');
return (required || required2) ? value==true : true;
}
validInput(el, value)
{
const required = this.isRequired(el);
if(el.type === 'email')
{
return required ? this.validEmail(value) : true;
}
return required ? value.length > 0 : true;
}
validEmail(value)
{
var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return re.test(value);
}
validCheckbox(el, value)
{
return this.isRequired(el) ? value===true : true;
}
}
export default new rwxForms();