Search code examples
redux-formadmin-on-rest

How to richly style AOR Edit page


Have to create an edit Page editing a number of parameters on an instance of a'tale' resource.

However adding any element such as an MUI Card or even a div, is causing the app to freeze in various ways.

These are the approaches I have tried.

1) Adding a card component or placing my elements within a div for styling

export const EditorEditTale = (props) => {
  return (
  <Edit {...props} title="Tale Editor">
    <SimpleForm >
      <div>
        <Image />
        <TaleCardHeader props={ props } style={taleCardHeaderStyle.editor} />
      </div>
    </SimpleForm>
  </Edit>
  )
};

This is causing nothing to render.

Second approach, assuming that the record and basePath arent getting propagated to the children completely. Trying to use component like below.

const Input = ({record, basePath}) => {
  return (
    <div>
      <LongTextInput source="taleText" />
    </div>
  )
}

This is causing the page to not render with everything in some kind of locking loop with the error - cannot read property touched of undefined.

How should I create a custom Edit page with a complex inputs and styling.

Required design

UPDATE: Been trying to write a custom form to substitute the SimpleForm component with no luck so far.


Solution

  • To create a custom form you can follow these steps:

    1. make an exact copy of SimpleForm to your project.
    2. rename SimpleForm to what you want.
    3. fix all the relative imports.
    4. test the new form until it works.

    I made a minimum working form based on current master branch's SimpleForm

    import React, { Children, Component } from 'react';
    import PropTypes from 'prop-types';
    import { reduxForm, Field } from 'redux-form';
    import { connect } from 'react-redux';
    import compose from 'recompose/compose';
    import getDefaultValues from 'admin-on-rest/mui/form/getDefaultValues';
    import FormField from 'admin-on-rest/mui/form/FormField';
    import Toolbar from 'admin-on-rest/mui/form/Toolbar';
    
    const formStyle = { padding: '0 1em 1em 1em' };
    
    export class PostForm extends Component {
        handleSubmitWithRedirect = (redirect = this.props.redirect) => this.props.handleSubmit(values => this.props.save(values, redirect));
    
        render() {
            const { children, invalid, record, resource, basePath, submitOnEnter, toolbar } = this.props;
            return (
                <form className="simple-form">
                    <Field name="name_of_a_field" component="input" />
                    {toolbar && React.cloneElement(toolbar, {
                        handleSubmitWithRedirect: this.handleSubmitWithRedirect,
                        invalid,
                        submitOnEnter,
                    })}
                </form>
            );
        }
    }
    
    PostForm.propTypes = {
        basePath: PropTypes.string,
        children: PropTypes.node,
        defaultValue: PropTypes.oneOfType([
            PropTypes.object,
            PropTypes.func,
        ]),
        handleSubmit: PropTypes.func, // passed by redux-form
        invalid: PropTypes.bool,
        record: PropTypes.object,
        resource: PropTypes.string,
        redirect: PropTypes.oneOfType([
            PropTypes.string,
            PropTypes.bool,
        ]),
        save: PropTypes.func, // the handler defined in the parent, which triggers the REST submission
        submitOnEnter: PropTypes.bool,
        toolbar: PropTypes.element,
        validate: PropTypes.func,
    };
    
    PostForm.defaultProps = {
        submitOnEnter: true,
        toolbar: <Toolbar />,
    };
    
    const enhance = compose(
        connect((state, props) => ({
            initialValues: getDefaultValues(state, props),
        })),
        reduxForm({
            form: 'record-form',
            enableReinitialize: true,
        }),
    );
    
    export default enhance(PostForm);
    

    The above code works for AOR's example.

    I hope this helps.

    (import might be slightly different when you have AOR as npm dependency :

    import getDefaultValues from 'admin-on-rest/lib/mui/form/getDefaultValues';
    import FormField from 'admin-on-rest/lib/mui/form/FormField';
    import Toolbar from 'admin-on-rest/lib/mui/form/Toolbar';
    

    )