Mrr form validation example
by mikolalex
HTML
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/mrr@1.2.6/dist/bundle.js"></script>
<div id="container">
<!-- This element's contents will be replaced with your component. -->
</div>
Babel + JSX
const getNameErrors = a => {
if(a.length < 2){
return "Name too short!";
}
if(a.match(/[\#\$\%\@\!\~]/)){
return "No special symbols allowed!";
}
return false;
}
const getEmailErrors = a => {
if(!a.match(/.*\@.*/)){
return "Please enter valid email address!";
}
return false;
}
const and = (a, b) => a && b;
const id = a => a;
const not = a => !a;
const incr = a => a + 1;
const always = a => () => a;
const or = a => b => b || a;
const Root = mrr.withMrr({
$init: {
name: '',
email: '',
attempts: 0,
},
$log: true,
$expose: ['successfulLogin'],
successfulLogin: 'checkLoginRequest.success',
nameError: [getNameErrors, 'name', 'submit'],
emailError: [getEmailErrors , 'email', 'submit'],
formValid: [(a, b) => !a && !b, 'nameError', 'emailError'],
submission: ['split', {
'error': not,
'success': (valid, name, email) => valid && { name, email },
}, '-formValid', '-name', '-email', 'submit'],
checkLoginRequest: ['nested', (cb, { name, email }) => {
cb('loading', true);
fetch('/check-login?name=' + name + '&email=' + email)
.then(res => cb('success', res.toJSON()))
.catch(e => cb('error', e.errorMessage))
.finally(() => cb('loading', false));
}, 'submission.success'],
successMessage: [always('Congratulations!'), 'checkLoginRequest.success'],
cleanUpErrors: ['merge', 'submission.success', 'name', 'email'],
errorsShown: ['merge', {
'submit': always(true),
'cleanUpErrors': always(false),
}],
error: ['merge', {
'checkLoginRequest.error': or('Some backend error happened!'),
'cleanUpErrors': always(false),
}],
attempts: ['merge', {
'checkLoginRequest.error': (_, prev) => prev + 1,
'checkLoginRequest.success': always(0),
}, '^']
}, (state, props, $) => ( state.attempts > 10
? <div>You did too many attempts!</div>
: ( <form>
{ state.successMessage && <div>{ state.successMessage}</div> }
Enter your name: <input value={ state.name } onChange={ $('name') } />
{...