Advertisement
Someluck

ProductVariableSelect.jsx

Jun 17th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, {Component} from "react";
  2. import _ from 'lodash';
  3.  
  4. class ProductVariableSelect extends Component {
  5.     constructor(props) {
  6.         super(props);
  7.  
  8.         this.state = {
  9.             value: this.props.value
  10.         };
  11.  
  12.         this.onChange = this.onChange.bind(this);
  13.         this.resetValue = this.resetValue.bind(this);
  14.         this.resetSelect = this.resetSelect.bind(this);
  15.     }
  16.  
  17.     static checkForRequired(isRequired) {
  18.         if (isRequired) {
  19.             return <span className="required-label">Required *</span>
  20.         }
  21.     }
  22.  
  23.     static renderMultiSelect(values, isRequired) {
  24.         const availableValues = _.filter(values, value => {
  25.             return value.includeValue.state.isAvailable || value.includeValue.state.isAssigned;
  26.         });
  27.  
  28.         if (isRequired) {
  29.             return values.map((value, i) => {
  30.                 return <option key={i} value={value.includeValue.value}>{value.text}</option>
  31.             })
  32.         }
  33.  
  34.         return availableValues.map((value, i) => {
  35.             return <option key={i} value={value.includeValue.value}>{value.text}</option>
  36.         })
  37.     }
  38.  
  39.     static renderSimpleSelect(values, isRequired) {
  40.         const availableValues = _.filter(values, value => {
  41.             return value.state.isAvailable || value.state.isAssigned;
  42.         });
  43.  
  44.         if (isRequired) {
  45.             return values.map((value, i) => {
  46.                 return <option key={i} value={value.value}>{value.text}</option>
  47.             });
  48.         }
  49.  
  50.         return availableValues.map((value, i) => {
  51.             return <option key={i} value={value.value}>{value.text}</option>
  52.         });
  53.     }
  54.  
  55.     static renderLabel(variable, isRequired) {
  56.         return (
  57.             <label>
  58.                 {variable.text}
  59.                 {ProductVariableSelect.checkForRequired(isRequired)}
  60.             </label>
  61.         );
  62.     }
  63.  
  64.     static calculateRange(decimalPlaces, variable) {
  65.         const available = _.filter(variable.values, value => {
  66.             return value.state.isAvailable;
  67.         });
  68.         const assigned = _.find(variable.values, value => {
  69.             return value.state.isAssigned;
  70.         });
  71.         let min = _.min(available.map(value => {
  72.             return _.isUndefined(value.lower) ? value.value : value.lower;
  73.         }));
  74.         let max = _.max(available.map(value => {
  75.             return _.isUndefined(value.upper) ? value.value : value.upper;
  76.         }));
  77.         let step = "1";
  78.  
  79.         if (decimalPlaces > 0) {
  80.             step = "0." + "0".repeat(decimalPlaces - 1) + "1";
  81.         }
  82.  
  83.         if (assigned) {
  84.             min = assigned.value < min ? assigned.value : min;
  85.             max = assigned.value > max ? assigned.value : max;
  86.         }
  87.  
  88.         return { min, max, step };
  89.     }
  90.  
  91.     getRules() {
  92.         const { variable } = this.props;
  93.         return new Map(variable.properties.map(prop => {
  94.             return [prop.name, prop.value];
  95.         }));
  96.     }
  97.  
  98.     resetValue() {
  99.         this.setState({
  100.             value: ''
  101.         });
  102.     }
  103.  
  104.     renderNumberInput(rules, variable) {
  105.         const { min, max, step } = ProductVariableSelect.calculateRange(rules.get('DecimalPlace'), variable);
  106.         const placeholder = min + " - " + max;
  107.  
  108.         return (
  109.             <div className="form-group">
  110.                 {ProductVariableSelect.renderLabel(variable, rules.get("Required"))}
  111.                 <input className="form-control"
  112.                        placeholder={placeholder}
  113.                        onChange={this.onChange}
  114.                        type="number"
  115.                        required={rules.get("Required")}
  116.                        disabled={rules.get("ReadOnly")}
  117.                        min={min}
  118.                        max={max}
  119.                        step={step}
  120.                        value={this.state.value}/>
  121.             </div>
  122.         )
  123.     }
  124.  
  125.     resetSelect(isRequired) {
  126.         const { onChange, onRequiredChange, variable } = this.props;
  127.         const blankValue = {
  128.             variable: {
  129.                 name: variable.id,
  130.                 value: ""
  131.             }
  132.         };
  133.  
  134.         this.resetValue();
  135.  
  136.         if (isRequired) {
  137.             return onRequiredChange(blankValue)
  138.         }
  139.  
  140.         onChange(blankValue);
  141.     }
  142.  
  143.     renderSelect(rules, variable) {
  144.         const isMultiple = variable.isMultivalued;
  145.         const isRequired = rules.get("Required");
  146.         const isReadOnly = rules.get("ReadOnly");
  147.  
  148.         return (
  149.             <div className="form-group">
  150.                 {ProductVariableSelect.renderLabel(variable, rules.get("Required"))}
  151.                 <select className="form-control"
  152.                         onChange={e => this.onChange(e, isRequired)}
  153.                         value={this.state.value}
  154.                         readOnly={isReadOnly}
  155.                         required={isRequired}>
  156.                     <option value="">Choose...</option>
  157.                     {isMultiple ? ProductVariableSelect.renderMultiSelect(variable.values, isRequired) : ProductVariableSelect.renderSimpleSelect(variable.values, isRequired)}
  158.                 </select>
  159.  
  160.                 {(() => {
  161.                     if (this.state.value !== "") {
  162.                         return (
  163.                             <button type="button" className="close" aria-label="Close"
  164.                                     onClick={() => this.resetSelect(isRequired)}>
  165.                                 <span aria-hidden="true">&times;</span>
  166.                             </button>
  167.                         )
  168.                     }
  169.                 })()}
  170.  
  171.             </div>
  172.         )
  173.     }
  174.  
  175.     renderVariable(variable) {
  176.         const rules = new Map(variable.properties.map(prop => {
  177.             return [prop.name, prop.value];
  178.         }));
  179.  
  180.         this.state.rules = rules;
  181.         const isShown = rules.get("Show");
  182.         const isSelectBox = variable.type === "String";
  183.         const isNumberInput = variable.type === "Number";
  184.  
  185.         if (!isShown) return;
  186.  
  187.         if (isSelectBox) {
  188.             return this.renderSelect(rules, variable);
  189.         } else if (isNumberInput) {
  190.             return this.renderNumberInput(rules, variable);
  191.         }
  192.     }
  193.  
  194.     onChange(e, isRequired) {
  195.         const { target } = e;
  196.         const { onChange, onRequiredChange, variable } = this.props;
  197.         const changedState = {
  198.             recalculated: false
  199.         };
  200.  
  201.         this.setState({ value: target.value });
  202.  
  203.         let value = {
  204.             variable: {
  205.                 name: variable.id,
  206.                 value: target.value
  207.             },
  208.             text: {
  209.                 name: variable.text
  210.             }
  211.         };
  212.  
  213.         if (target.nodeName === "SELECT") {
  214.             value.text.value = target.options[target.selectedIndex].text
  215.         } else {
  216.             value.text.value = target.value
  217.         }
  218.  
  219.         if (isRequired) {
  220.             return onRequiredChange(value);
  221.         }
  222.  
  223.         onChange(value, changedState);
  224.     }
  225.  
  226.     render() {
  227.         return (
  228.             <span>{this.renderVariable(this.props.variable)}</span>
  229.         )
  230.     }
  231. }
  232.  
  233. export default ProductVariableSelect;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement