Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementation of Bootstrap grid layout into a custom field #461

Closed
toccoto opened this issue Feb 8, 2017 · 1 comment
Closed

Implementation of Bootstrap grid layout into a custom field #461

toccoto opened this issue Feb 8, 2017 · 1 comment

Comments

@toccoto
Copy link

toccoto commented Feb 8, 2017

Description

Implementation of Bootstrap grid layout into a custom field

Hey, I've been looking at this library today, but really wanted to be able to control the grid layout of Schema, independent of how it's sent. (Basically the backend will send the schema independent of order, rows and columns) I came up with this, which works. Just wondering if there is a cleaner way I'm missing or if I'm on the right track. Thanks for the help!

import React from 'react';
import SchemaForm from 'react-jsonschema-form';
import ObjectField from 'react-jsonschema-form/lib/components/fields/ObjectField';
import {retrieveSchema} from "react-jsonschema-form/lib/utils";
import {Grid, Row, Col} from 'react-bootstrap';

class GridField extends ObjectField {
  constructor(props) {
    super(props);
  }

  render() {
    const {
      uiSchema,
      errorSchema,
      idSchema,
      name,
      required,
      disabled,
      readonly,
      onBlur
    } = this.props;
    const {definitions, fields, formContext} = this.props.registry;
    const {SchemaField, TitleField, DescriptionField} = fields;
    const schema = retrieveSchema(this.props.schema, definitions);
    const title = (schema.title === undefined) ? name : schema.title;
    const order = uiSchema['ui:options'].order;
    return (
      <fieldset>
        {title ? <TitleField
            id={`${idSchema.$id}__title`}
            title={title}
            required={required}
            formContext={formContext}/> : null}
        {schema.description ?
          <DescriptionField
            id={`${idSchema.$id}__description`}
            description={schema.description}
            formContext={formContext}/> : null}
        {
          order.map((row, index) => {
            return (
              <div className="row" key={index}>
                {
                  Object.keys(row).map((name, index) => (
                    <Col {...row[name]} key={index}>
                      <SchemaField
                                   name={name}
                                   required={this.isRequired(name)}
                                   schema={schema.properties[name]}
                                   uiSchema={uiSchema[name]}
                                   errorSchema={errorSchema[name]}
                                   idSchema={idSchema[name]}
                                   formData={this.state[name]}
                                   onChange={this.onPropertyChange(name)}
                                   onBlur={onBlur}
                                   registry={this.props.registry}
                                   disabled={disabled}
                                   readonly={readonly}/>
                    </Col>
                  ))
                }
              </div>
            );
          })
        }</fieldset>
    );
  }
}

const fields = {
  grid: GridField,
};

const schema = {
  title: "Primary Applicant",
  type: "object",
  properties: {
    personal: {
      title: "",
      type: "object",
      properties: {
        first: {
          type: "string",
          title: "First"
        },
        mi: {
          type: "string",
          title: "MI"
        },
        last: {
          type: "string",
          title: "Last"
        },
        suffix: {
          type: "string",
          title: "Suffix",
          enum: ['jr', 'sr'],
          enumNames: ['JR', 'SR']
        },
        ssn: {
          type: "string",
          title: "ssn"
        },
        dob: {
          type: "string",
          title: "dob"
        }
      }
    }
  }
};

const getUiSchema = () => {

  let order = [
    {
      first: { md: 5 },
      mi: { md: 2 },
      last: { md: 5 }
    },
    {
      suffix: { md: 2 },
      ssn: { md: 5 },
      dob: { md: 5 }
    }
  ]

  return  {
    personal: {
      "ui:field": "grid",
      "ui:options": {
        "order": order
      }
    }
  }
}

export const Applicant = () => (
  <div>
    <h1>Applicant</h1>
    <SchemaForm schema={schema} uiSchema={getUiSchema()} fields={fields}/>
  </div>
);

Sorry, I couldn't get it working on jsFiddle but the end result works. I get 2 rows, with split columns.

Basically I just extend ObjectField, and add the data to split up based on the ordering info.

Any other suggestions are welcome.

@n1k0
Copy link
Collaborator

n1k0 commented Feb 13, 2017

Object fields are orderable using the ui:order uiSchema directive.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants