mirror of
https://github.com/strapi/strapi.git
synced 2025-11-01 18:33:55 +00:00
handle nested forms
This commit is contained in:
parent
0a4d5fd021
commit
2e83559b58
@ -23,7 +23,11 @@ class EditForm extends React.Component { // eslint-disable-line react/prefer-sta
|
||||
}
|
||||
return (
|
||||
<div key={key}>
|
||||
<EditFormSection section={section} values={this.props.values} handleChange={this.props.handleChange} />
|
||||
<EditFormSection
|
||||
section={section}
|
||||
values={this.props.values}
|
||||
handleChange={this.props.handleChange}
|
||||
/>
|
||||
{line}
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -9,12 +9,15 @@ import { map, isEmpty } from 'lodash';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
// HOC Form
|
||||
import WithFormSection from 'components/WithFormSection';
|
||||
// nested form
|
||||
import EditFormSectionNested from 'components/EditFormSectionNested';
|
||||
|
||||
class EditFormSection extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
render() {
|
||||
const sectionName = isEmpty(this.props.section.name) ? '' : <FormattedMessage {...{id: this.props.section.name}} />;
|
||||
// get the styles from the WithFormSection HOC
|
||||
// get the styles from the WithFormSection HOC
|
||||
const styles = this.props.styles;
|
||||
|
||||
return (
|
||||
<div className={styles.editFormSection}>
|
||||
<div className="container-fluid">
|
||||
@ -25,10 +28,22 @@ class EditFormSection extends React.Component { // eslint-disable-line react/pre
|
||||
</span>
|
||||
</div>
|
||||
<form>
|
||||
{map(this.props.section.items, (item, key) => (
|
||||
this.props.renderInput( item, key)
|
||||
// this.props.renderInput(this.props.section.items, item, key)
|
||||
))}
|
||||
{map(this.props.section.items, (item, key) => {
|
||||
|
||||
if (this.props.showNestedForm) {
|
||||
return (
|
||||
<div key={key}>
|
||||
{this.props.renderInput(item, key)}
|
||||
<EditFormSectionNested
|
||||
section={item.items}
|
||||
values={this.props.values}
|
||||
handleChange={this.props.handleChange}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
return this.props.renderInput(item, key);
|
||||
})}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@ -38,9 +53,12 @@ class EditFormSection extends React.Component { // eslint-disable-line react/pre
|
||||
}
|
||||
|
||||
EditFormSection.propTypes = {
|
||||
handleChange: React.PropTypes.func,
|
||||
renderInput: React.PropTypes.func,
|
||||
section: React.PropTypes.object,
|
||||
showNestedForm: React.PropTypes.bool,
|
||||
styles: React.PropTypes.object,
|
||||
values: React.PropTypes.object,
|
||||
};
|
||||
|
||||
export default WithFormSection(EditFormSection); // eslint-disable-line new-cap
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
/**
|
||||
*
|
||||
* EditFormSectionNested
|
||||
*
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { map } from 'lodash';
|
||||
|
||||
// HOC
|
||||
import WithFormSection from 'components/WithFormSection';
|
||||
|
||||
class EditFormSectionNested extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
{map(this.props.section, (item, key) => (
|
||||
this.props.renderInput(item, key)
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
EditFormSectionNested.propTypes = {
|
||||
renderInput: React.PropTypes.func,
|
||||
section: React.PropTypes.oneOfType([
|
||||
React.PropTypes.array,
|
||||
React.PropTypes.object,
|
||||
]),
|
||||
};
|
||||
|
||||
export default WithFormSection(EditFormSectionNested); // eslint-disable-line new-cap
|
||||
@ -0,0 +1,11 @@
|
||||
// import EditFormSectionNested from '../index';
|
||||
|
||||
import expect from 'expect';
|
||||
// import { shallow } from 'enzyme';
|
||||
// import React from 'react';
|
||||
|
||||
describe('<EditFormSectionNested />', () => {
|
||||
it('Expect to have unit tests specified', () => {
|
||||
expect(true).toEqual(false);
|
||||
});
|
||||
});
|
||||
@ -161,7 +161,7 @@ InputText.propTypes = {
|
||||
styles: React.PropTypes.object,
|
||||
target: React.PropTypes.string.isRequired,
|
||||
validations: React.PropTypes.object.isRequired,
|
||||
value: React.PropTypes.string.isRequired,
|
||||
value: React.PropTypes.string,
|
||||
}
|
||||
|
||||
export default WithInput(InputText); // eslint-disable-line new-cap
|
||||
|
||||
@ -74,7 +74,7 @@ class InputToggle extends React.Component { // eslint-disable-line react/prefer-
|
||||
InputToggle.propTypes = {
|
||||
customBootstrapClass: React.PropTypes.string,
|
||||
handleChange: React.PropTypes.func.isRequired,
|
||||
isChecked: React.PropTypes.bool.isRequired,
|
||||
isChecked: React.PropTypes.bool,
|
||||
name: React.PropTypes.string,
|
||||
target: React.PropTypes.string.isRequired,
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { forEach, has } from 'lodash';
|
||||
import { forEach, has, isObject } from 'lodash';
|
||||
|
||||
import InputNumber from 'components/InputNumber';
|
||||
import InputText from 'components/InputText';
|
||||
@ -18,9 +18,11 @@ import styles from './styles.scss';
|
||||
|
||||
const WithFormSection = (InnerComponent) => class extends React.Component {
|
||||
static propTypes = {
|
||||
checkForNestedForm: React.PropTypes.bool,
|
||||
handleChange: React.PropTypes.func.isRequired,
|
||||
section: React.PropTypes.object,
|
||||
section: React.PropTypes.oneOfType([
|
||||
React.PropTypes.object,
|
||||
React.PropTypes.array,
|
||||
]),
|
||||
values: React.PropTypes.object,
|
||||
}
|
||||
|
||||
@ -33,40 +35,43 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
|
||||
};
|
||||
}
|
||||
|
||||
handleChange = ({ target }) => {
|
||||
componentDidMount() {
|
||||
// check if there is inside a section an input that requires nested input to display it on the entire line
|
||||
if (isObject(this.props.section)) {
|
||||
this.checkForNestedForm(this.props);
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.section !== this.props.section) {
|
||||
this.setState({ showNestedForm: false, hasNestedInput: false, inputWithNestedForm: '' });
|
||||
if (isObject(nextProps.section)) {
|
||||
this.checkForNestedForm(nextProps);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
checkForNestedForm(props) {
|
||||
forEach(props.section.items, (input) => {
|
||||
if(has(input, 'items')) {
|
||||
this.setState({ hasNestedInput: true, inputWithNestedForm: input.target })
|
||||
|
||||
if (props.values[input.target]) {
|
||||
this.setState({ showNestedForm: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
handleChange = ({ target }) => {
|
||||
// display nestedForm if the selected input has a nested form
|
||||
if (target.id === this.state.inputWithNestedForm) {
|
||||
this.setState({ showNestedForm: true });
|
||||
} else {
|
||||
this.setState({ showNestedForm: false });
|
||||
if (target.name === this.state.inputWithNestedForm) {
|
||||
this.setState({ showNestedForm: target.value });
|
||||
}
|
||||
|
||||
this.props.handleChange({ target });
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// check if there is inside a section an input that requires nested input to display it on the entire line
|
||||
if (this.props.checkForNestedForm) {
|
||||
forEach(this.props.section.items, (items) => {
|
||||
forEach(items, (item) => {
|
||||
forEach(item, (input) => {
|
||||
|
||||
if (has(input, 'items')) {
|
||||
// store the name of the input that has a nested form
|
||||
this.setState({ hasNestedInput: true, inputWithNestedForm: input.name });
|
||||
|
||||
// showNestedForm if the selected input has a nested form
|
||||
if (items.value === input.value) {
|
||||
this.setState({ showNestedForm: true });
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
renderInput = (props, key) => {
|
||||
const inputs = {
|
||||
string: InputText,
|
||||
@ -80,14 +85,14 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
|
||||
// retrieve options for the select input
|
||||
const selectOptions = props.type === 'enum' || props.type === 'select' ? props.items : [];
|
||||
|
||||
// check if the input has a nested form so it is display on the entire line
|
||||
// check if the input has a nested form so it is displayed on the entire line
|
||||
const customBootstrapClass = this.state.hasNestedInput ?
|
||||
// bootstrap class to make the input display on the entire line
|
||||
// bootstrap class to make the input displayed on the entire line
|
||||
'col-md-6 offset-md-6 pull-md-6' :
|
||||
// if the input hasn't a nested form but the config requires him to be displayed differently
|
||||
config[props.target] || '';
|
||||
|
||||
// custom handle change props for nested input form
|
||||
// custom handleChange props for nested input form
|
||||
const handleChange = this.state.hasNestedInput ? this.handleChange : this.props.handleChange;
|
||||
return (
|
||||
<Input
|
||||
@ -108,6 +113,7 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
|
||||
return (
|
||||
<InnerComponent
|
||||
{...this.props}
|
||||
showNestedForm={this.state.showNestedForm}
|
||||
renderInput={this.renderInput}
|
||||
styles={styles}
|
||||
/>
|
||||
@ -116,5 +122,3 @@ const WithFormSection = (InnerComponent) => class extends React.Component {
|
||||
}
|
||||
|
||||
export default WithFormSection;
|
||||
|
||||
// Object {name: "form.security.item.xframe.allow-from", value: "ALLOW-FROM", items: Array(1)}
|
||||
|
||||
@ -295,9 +295,6 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
|
||||
// custom rendering for PopUpForm
|
||||
const renderPopUpForm = this.props.params.slug === 'languages' ? this.renderPopUpFormLanguage : false;
|
||||
|
||||
// TODO remove temporary condition to handle nestedForm rendering
|
||||
const checkForNestedForm = this.props.params.slug !== 'languages'
|
||||
|
||||
let renderRow = false;
|
||||
|
||||
if (this.props.params.slug === 'languages') {
|
||||
@ -324,7 +321,6 @@ export class Home extends React.Component { // eslint-disable-line react/prefer-
|
||||
handleListPopUpSubmit={this.addLanguage}
|
||||
selectOptions={selectOptions}
|
||||
renderPopUpForm={renderPopUpForm}
|
||||
checkForNestedForm={checkForNestedForm}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -42,6 +42,7 @@ export function* deleteLanguage(action) {
|
||||
yield put(languageActiontSucceded());
|
||||
|
||||
} catch(error) {
|
||||
console.log(error);
|
||||
window.Strapi.notification.error('An Error occured');
|
||||
}
|
||||
}
|
||||
@ -58,6 +59,7 @@ export function* fetchConfig(action) {
|
||||
yield put(configFetchSucceded(data));
|
||||
|
||||
} catch(error) {
|
||||
console.log(error);
|
||||
window.Strapi.notification.error('An error occurred ');
|
||||
}
|
||||
}
|
||||
@ -109,6 +111,7 @@ export function* postLanguage() {
|
||||
yield put(languageActiontSucceded());
|
||||
|
||||
} catch(error) {
|
||||
console.log(error);
|
||||
// TODO handle error i18n
|
||||
window.Strapi.notification.error(error);
|
||||
}
|
||||
|
||||
@ -128,7 +128,7 @@ module.exports = {
|
||||
description: 'form.security.description',
|
||||
sections: [
|
||||
{
|
||||
name: 'form.security.item.csrf',
|
||||
name: 'form.security.item.session',
|
||||
items: [
|
||||
{
|
||||
name: 'form.security.item.session.enabled',
|
||||
@ -235,13 +235,13 @@ module.exports = {
|
||||
items: [
|
||||
{
|
||||
name: 'form.security.item.hsts.enabled',
|
||||
target: 'security.p3p.enabled',
|
||||
target: 'security.hsts.enabled',
|
||||
type: 'boolean',
|
||||
value: _.get(strapi.config, `environments.${env}.security.hsts.enabled`, null),
|
||||
items: [
|
||||
{
|
||||
name: 'form.security.item.p3p.maxAge',
|
||||
target: 'security.p3p.maxAge',
|
||||
name: 'form.security.item.hsts.maxAge',
|
||||
target: 'security.hsts.maxAge',
|
||||
type: 'number',
|
||||
value: _.get(strapi.config, `environments.${env}.security.hsts.maxAge`, null),
|
||||
validations: {
|
||||
@ -249,15 +249,15 @@ module.exports = {
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'form.security.item.p3p.includeSubDomains',
|
||||
target: 'security.p3p.includeSubDomains',
|
||||
name: 'form.security.item.hsts.includeSubDomains',
|
||||
target: 'security.hsts.includeSubDomains',
|
||||
type: 'boolean',
|
||||
value: _.get(strapi.config, `environments.${env}.security.hsts.includeSubDomains`, null),
|
||||
validations: {}
|
||||
},
|
||||
{
|
||||
name: 'form.security.item.p3p.preload',
|
||||
target: 'security.p3p.preload',
|
||||
name: 'form.security.item.hsts.preload',
|
||||
target: 'security.hsts.preload',
|
||||
type: 'boolean',
|
||||
value: _.get(strapi.config, `environments.${env}.security.hsts.preload`, null),
|
||||
validations: {}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user