Lexiconga/src/components/management/WordForm.jsx

211 lines
6.2 KiB
JavaScript

import Inferno from 'inferno';
import { Component } from 'inferno';
import PropTypes from 'prop-types';
import dictionaryData from '../../managers/DictionaryData';
import { IPAField } from './IPAField';
import { LargeTextArea } from './LargeTextArea';
import { Word } from '../../managers/Word';
export class WordForm extends Component {
constructor (props) {
super(props);
PropTypes.checkPropTypes({
word: PropTypes.object,
callback: PropTypes.func,
updateDisplay: PropTypes.func,
}, props, 'prop', 'WordForm');
this.state = {
wordName: props.word ? props.word.name : '',
wordPronunciation: props.word ? props.word.pronunciation : '',
wordPartOfSpeech: props.word ? props.word.partOfSpeech : '',
wordDefinition: props.word ? props.word.definition : '',
wordDetails: props.word ? props.word.details : '',
nameIsValid: true,
pronunciationIsValid: true,
partOfSpeechIsValid: true,
definitionIsValid: true,
detailsIsValid: true,
}
}
isValidWord () {
let nameIsValid = true,
definitionIsValid = true,
detailsIsValid = true;
if (this.state.wordName === '') {
nameIsValid = false;
}
if (this.state.wordPartOfSpeech === '') {
// popup(?) confirming no part of speech.
}
if (this.state.wordDefinition === ''
&& this.state.wordDetails === '') {
definitionIsValid = false;
detailsIsValid = false;
}
this.setState({
nameIsValid,
definitionIsValid,
detailsIsValid,
});
return nameIsValid == true && definitionIsValid == true && detailsIsValid == true;
}
submitWord () {
const word = new Word(Object.assign((this.props.word ? this.props.word : {}), {
name: this.state.wordName,
pronunciation: this.state.wordPronunciation,
partOfSpeech: this.state.wordPartOfSpeech,
definition: this.state.wordDefinition,
details: this.state.wordDetails,
}));
if (this.isValidWord()) {
// Need to trigger a WordsList re-render after success.
let wordAction;
if (this.props.word) {
wordAction = word.update()
.then(() => {
this.props.callback();
})
} else {
wordAction = word.create()
.then(() => {
this.clearForm();
});
}
wordAction.then(() => {
this.props.updateDisplay();
})
}
}
clearForm () {
this.setState({
wordName: '',
wordPronunciation: '',
wordPartOfSpeech: '',
wordDefinition: '',
wordDetails: '',
});
}
render () {
return (
<div className='box'>
<div className='field'>
<label className='label'>Word</label>
<div className='control'>
<input className={ `input${(!this.state.nameIsValid) ? ' is-danger' : ''}` }
type='text' placeholder='Required'
value={ this.state.wordName }
onChange={(event) => {
this.setState({ wordName: event.target.value });
}} />
{(!this.state.nameIsValid)
? (
<span className='help is-danger'>You must specify the word.</span>
) : null}
</div>
</div>
<IPAField value={ this.state.wordPronunciation }
onChange={ (newValue) => this.setState({ wordPronunciation: newValue }) } />
<div className='field'>
<label className='label'>Part of Speech</label>
<div className='control'>
<span className='select'>
<select value={ this.state.wordPartOfSpeech }
onChange={(event) => {
this.setState({ wordPartOfSpeech: event.target.value });
}}>
<option value=''></option>
{dictionaryData.partsOfSpeech.map((partOfSpeech) => {
return (
<option value={ partOfSpeech }>
{ partOfSpeech }
</option>
);
})}
</select>
</span>
</div>
</div>
<div className='field'>
<label className='label'>Definition</label>
<div className='control'>
<input className={ `input${(!this.state.definitionIsValid) ? ' is-danger' : ''}` }
type='text' placeholder='Equivalent word(s)'
value={ this.state.wordDefinition }
onChange={(event) => {
this.setState({ wordDefinition: event.target.value })
}} />
{(!this.state.definitionIsValid)
? (
<span className='help is-danger'>
You must at least enter a Definition if excluding Details.
</span>
) : null}
</div>
</div>
<LargeTextArea
label='Details'
value={ this.state.wordDetails }
placeholder='Explanation of word (Markdown enabled)'
isValid={ this.state.detailsIsValid }
invalidText='You must at least enter Details if excluding a Definition.'
onChange={(event) => {
this.setState({ wordDetails: event.target.value });
}} />
{this.props.word
? (
<div className='field is-grouped'>
<div className='control'>
<a className='button is-text'
onClick={() => {
this.props.callback();
}}>
Cancel
</a>
</div>
<div className='control'>
<a className='button is-primary'
onClick={() => {
this.submitWord();
}}>
Update
</a>
</div>
</div>
) : (
<div className='field'>
<div className='control'>
<a className='button is-primary'
onClick={() => {
this.submitWord();
}}>
Create
</a>
</div>
</div>
)
}
</div>
);
}
}