Skip to content

Instantly share code, notes, and snippets.

@domtalbot
Created March 21, 2018 14:32
Show Gist options
  • Select an option

  • Save domtalbot/2411707e8bb36bf3cae2d2f1dd6bddd4 to your computer and use it in GitHub Desktop.

Select an option

Save domtalbot/2411707e8bb36bf3cae2d2f1dd6bddd4 to your computer and use it in GitHub Desktop.

Revisions

  1. domtalbot created this gist Mar 21, 2018.
    169 changes: 169 additions & 0 deletions control.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,169 @@
    import React from 'react';
    import PropTypes from 'prop-types';
    import { connect } from 'react-redux';
    import { Map } from 'immutable';
    import CMS from 'netlify-cms';

    export default class DynamicControl extends React.Component {
    static propTypes = {
    onChange: PropTypes.func.isRequired,
    onAddAsset: PropTypes.func.isRequired,
    onRemoveAsset: PropTypes.func.isRequired,
    getAsset: PropTypes.func.isRequired,
    value: PropTypes.oneOfType([
    PropTypes.node,
    PropTypes.object,
    PropTypes.bool,
    ]),
    field: PropTypes.object,
    forID: PropTypes.string,
    dynamicWidgets: PropTypes.object
    };

    constructor(props) {
    super(props);

    // this.props.value = Map({
    // 'slide': 'string',
    // 'slide_selected': 'Hey! Change me'
    // });

    const fieldValue = this.props.value && Map.isMap(this.props.value) ?
    this.props.value.get(this.props.field.get('name')) :
    '';

    if (!fieldValue) {
    this.state = {
    widget: null,
    };
    } else {
    this.state = {
    widget: CMS.getWidget(fieldValue),
    };
    }
    }

    handleChange = (e) => {
    this.props.onChange(Map().set(e.target.id, e.target.value));

    if (!e.target.value) {
    this.setState({
    widget: null,
    });
    } else {
    this.setState({
    widget: CMS.getWidget(e.target.value),
    });
    }
    };

    altChange = (target, val) => {
    this.props.onChange(this.props.value.set(target, val));
    }

    linkChange = (target, val) => {
    this.props.onChange(this.props.value.set(target, val));
    }

    render() {
    const { field, value, forID, onChange, onAddAsset, onRemoveAsset, getAsset } = this.props;
    const { widget } = this.state;

    const name = field.get('name');
    const selectedName = `${ field.get('name') }_selected`;
    const selectedNameAlt = `${ field.get('name') }_selected_alt`;
    const selectedNameLink = `${ field.get('name') }_selected_link`;

    const fieldValue = value && Map.isMap(value) ?
    value.get(name || '') :
    '';

    const fieldValueSelected = value && Map.isMap(value) ?
    value.get(selectedName || '') :
    '';

    const fieldValueSelectedAlt = value && Map.isMap(value) ?
    value.get(selectedNameAlt || '') :
    '';

    const fieldValueSelectedLink = value && Map.isMap(value) ?
    value.get(selectedNameLink || '') :
    '';

    let options = field.get('dynamicWidgets').map((option) => {
    if (typeof option === 'string') {
    return { label: option, value: option };
    }
    return option;
    });

    options = options.insert(0, {
    label: 'Please Select',
    value: '',
    });

    return (
    <div>
    <div>
    <select id={forID} value={fieldValue || ''} onChange={this.handleChange}>
    {options.map((option, idx) => <option key={idx} value={option.value}>
    {option.label}
    </option>)}
    </select>
    </div>
    <div>
    {
    widget ?
    <div key={selectedName}>
    <div key={selectedName}>
    <label htmlFor={selectedName}>{`${ field.get('label') } Data`}</label>
    {
    React.createElement(widget.control, {
    id: selectedName,
    field,
    value: '',
    onChange: (val, metadata) => {
    onChange((value || Map()).set(selectedName, val), metadata);
    },
    onAddAsset,
    onRemoveAsset,
    getAsset,
    forID: selectedName,
    })
    }
    </div>
    </div>
    :
    ''
    }
    </div>
    <div>
    {
    fieldValue === 'image' ?
    <div key={selectedNameAlt}>
    <div key={selectedNameAlt}>
    <label htmlFor={selectedNameAlt}>{`${ field.get('label') } Data Alt`}</label>
    <input type="text" id={selectedNameAlt} value={fieldValueSelectedAlt || ''} onChange={(e) => { this.altChange(selectedNameAlt, e.target.value) }}/>
    </div>
    </div>
    :
    ''
    }
    </div>
    <div>
    {
    fieldValue === 'string' ?
    <div key={selectedNameLink}>
    <div key={selectedNameLink}>
    <label htmlFor={selectedNameLink}>{`${field.get('label')} Data Link`}</label>
    <input type="text" id={selectedNameLink} value={fieldValueSelectedLink || ''} onChange={(e) => { this.linkChange(selectedNameLink, e.target.value) }} />
    </div>
    </div>
    :
    ''
    }
    </div>
    </div>
    );
    }
    }