0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2025-12-24 14:12:40 +00:00

Merge pull request #2488 from Gazook89/Field-Validation-System-2

Field validation system 2
This commit is contained in:
Trevor Buckner
2022-11-17 21:58:54 -05:00
committed by GitHub
3 changed files with 70 additions and 8 deletions

View File

@@ -9,6 +9,7 @@ const Nav = require('naturalcrit/nav/nav.jsx');
const StringArrayEditor = require('../stringArrayEditor/stringArrayEditor.jsx');
const Themes = require('themes/themes.json');
const validations = require('./validations.js')
const SYSTEMS = ['5e', '4e', '3.5e', 'Pathfinder'];
@@ -22,6 +23,7 @@ const MetadataEditor = createClass({
editId : null,
title : '',
description : '',
thumbnail : '',
tags : [],
published : false,
authors : [],
@@ -51,11 +53,30 @@ const MetadataEditor = createClass({
},
handleFieldChange : function(name, e){
this.props.onChange({
...this.props.metadata,
[name] : e.target.value
});
e.persist();
// load validation rules, and check input value against them
const inputRules = validations[name] ?? [];
const validationErr = inputRules.map((rule)=>rule(e.target.value)).filter(Boolean);
// if no validation rules, save to props
if(validationErr.length === 0){
e.target.setCustomValidity('');
this.props.onChange({
...this.props.metadata,
[name] : e.target.value
});
} else {
// if validation issues, display built-in browser error popup with each error.
console.log(validationErr);
const errMessage = validationErr.map((err)=>{
return `- ${err}`;
}).join('\n');
e.target.setCustomValidity(errMessage);
e.target.reportValidity();
};
},
handleSystem : function(system, e){
if(e.target.checked){
this.props.metadata.systems.push(system);
@@ -64,6 +85,7 @@ const MetadataEditor = createClass({
}
this.props.onChange(this.props.metadata);
},
handleRenderer : function(renderer, e){
if(e.target.checked){
this.props.metadata.renderer = renderer;
@@ -228,21 +250,21 @@ const MetadataEditor = createClass({
<div className='field title'>
<label>title</label>
<input type='text' className='value'
value={this.props.metadata.title}
defaultValue={this.props.metadata.title}
onChange={(e)=>this.handleFieldChange('title', e)} />
</div>
<div className='field-group'>
<div className='field-column'>
<div className='field description'>
<label>description</label>
<textarea value={this.props.metadata.description} className='value'
<textarea defaultValue={this.props.metadata.description} className='value'
onChange={(e)=>this.handleFieldChange('description', e)} />
</div>
<div className='field thumbnail'>
<label>thumbnail</label>
<input type='text'
value={this.props.metadata.thumbnail}
placeholder='my.thumbnail.url'
defaultValue={this.props.metadata.thumbnail}
placeholder='https://my.thumbnail.url'
className='value'
onChange={(e)=>this.handleFieldChange('thumbnail', e)} />
<button className='display' onClick={this.toggleThumbnailDisplay}>

View File

@@ -42,6 +42,12 @@
&>.value{
flex : 1 1 auto;
width : 50px;
&:invalid {
background : #ffb9b9;
}
}
input[type='text'], textarea {
border : 1px solid gray;
}
&.thumbnail{
height : 1.4em;

View File

@@ -0,0 +1,34 @@
module.exports = {
title : [
(value)=>{
return value?.length > 100 ? 'Max title length of 100 characters' : null;
}
],
description : [
(value)=>{
return value?.length > 500 ? 'Max description length of 500 characters.' : null;
}
],
thumbnail : [
(value)=>{
return value?.length > 256 ? 'Max URL length of 256 characters.' : null;
},
(value)=>{
if(value?.length == 0){return null;}
try {
Boolean(new URL(value));
return null;
} catch (e) {
return 'Must be a valid URL';
}
}
],
language : [
(value)=>{
return new RegExp(/[a-z]{2,3}(-.*)?/).test(value || '') === false ? 'Invalid language code.' : null;
}
]
};