<commit_before>/**
 * Created by clstrfvck on 17/06/2017.
 */
import React, {Component} from "react"
import PropTypes from "prop-types"
const css = require("./PriceListDropdown.scss")
import { CaretDown, CaretUp } from "../../Icons"

class Dropdown extends Component {
    constructor(props){
        super(props)
        this.state = {
            open: false,
            options: [],
            filter: '',
            focus: false,
        }
        this.getOwnOpts = this.getOwnOpts.bind(this)
        this.returnSelectedValue = this.returnSelectedValue.bind(this)
        this.updateFilterTerm = this.updateFilterTerm.bind(this)
        this.toggle = this.toggle.bind(this)
        this.kPress = this.kPress.bind(this)
    }

    /**
     *  Required props:[name, prevValue, getOwnOps(name), returnValue(name, value)]
     */

    toggle(v) {
        this.setState({
            ...this.state,
            open: v=='force' ? false : !this.state.open,
        })
        if(this.state.options.length===0) this.getOwnOpts()
    }

    updateFilterTerm(event) {
        //Listen to value change and pass it to state for as a keyword to filter options by
        this.setState({
            filter: event.target.value.length>0 ? event.target.value : false
        }, console.log(this.state))
    }

    filterOption({value}, against) {
        //predicate expression to check for pre-fix match against search term
        if(against){
            return value.indexOf(against)>=0
        } else {
            return true
        }
    }
    kPress(event) {
        if(event.key === 'Enter'){
            if(this.state.options.map(n=>n.value).indexOf(event.target.value)>=0){
                this.returnSelectedValue(event.target.value)
                this.Input.blur()
            }
        }
    }

    returnSelectedValue(value) {
        console.log('returning '+value);
        this.setState({
            ...this.state,
            filter: value,
        })
        this.props.returnValue(this.props.name, value)
        this.toggle();
    }

    getOwnOpts() {
        //currently simulating async request
        //options: this.props.getOpts(this.props.name) that returns an array.
        //key generation will be handled in map function below.
        setTimeout(()=>{
            let sampleOptions = ['foo','bar', 'baz', 'qux','foo','bar', 'baz', 'qux','foo','bar', 'baz', 'qux']
            this.setState({
                ...this.state,
                options: sampleOptions.map(i=>({value: i, key: uuid()}))
            })
        }, 300)
    }

    render(){
        return(
            <div className="PriceListDropdown__wrapper">
                <div className={`PriceListDropdown__clickables ${this.state.open ? 'open' : null}`} onClick={this.toggle}>
                    <input className="PriceListDropdown__text"
                           placeholder={this.props.prevValue || 'prevvalue?!?'}
                           onKeyPress={this.kPress}
                           onChange={this.updateFilterTerm}
                           onBlur={()=>this.toggle('force')}
                           value={this.state.filter}
                           ref={(input) => {this.Input = input}}
                    />

                    <div className='PriceListDropdown__icon'>
                        {this.state.open ? <CaretUp/>:<CaretDown/>}
                    </div>
                </div>
                {this.state.open ?
                    <div className="PriceListDropdown__content">
                        {this.state.options === [] ? <PriceListDropdownContent loading={true} /> : null}
                        {this.state.options.filter((v)=>this.filterOption(v, this.state.filter)).map(n =>
                            <PriceListDropdownContent value={n.value} key={n.key} click={this.returnSelectedValue}/>)}
                    </div> :
                    null}
            </div>
        )
    }
}
export const PriceListDropdownContent = props => {
    return (
        <div
            className={
                `PriceListDropdown__option-wrapper
                ${props.loading ? 'option-loading ':null}
                ${props.more ? 'option-more': null}`
            }
            onClick={()=>props.click(props.value)}>
            {props.loading ? 'Laen...' : props.more ? "Veel.." : props.value}
        </div>)
}


///to be imported from Utils module once in sync with master:
const uuid = () => {
    var i, random;
    var uuid = '';
    for (i = 0; i < 32; i++) {
        random = Math.random() * 16 | 0;
        if (i === 8 || i === 12 || i === 16 || i === 20) {
            uuid += '-';
        }

        uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random)).toString(16);
    }

    return uuid;
}
Dropdown.propTypes = {
    name: PropTypes.string,
    prevValue: PropTypes.string,
    returnValues: PropTypes.func,
    getOpts: PropTypes.func
}

export default Dropdown<commit_msg>Some minor work on dropdown component. Removed onblur listener as it was causing dropdown option returns to not trigger as option components dismounted before their callback was invoked 💩<commit_after>/**
 * Created by clstrfvck on 17/06/2017.
 */
import React, {Component} from "react"
import PropTypes from "prop-types"
const css = require("./PriceListDropdown.scss")
import { CaretDown, CaretUp } from "../../Icons"

class Dropdown extends Component {
    constructor(props){
        super(props)
        this.state = {
            open: false,
            options: [],
            filter: '',
            focus: false,
        }
        this.getOwnOpts = this.getOwnOpts.bind(this)
        this.returnSelectedValue = this.returnSelectedValue.bind(this)
        this.updateFilterTerm = this.updateFilterTerm.bind(this)
        this.toggle = this.toggle.bind(this)
        this.kPress = this.kPress.bind(this)
    }

    /**
     *  Required props:[name, prevValue, getOwnOps(name), returnValue(name, value)]
     */

    toggle(o) {
        //pass in 'force' to force close
        this.setState({
            ...this.state,
            open: o == 'force' ? false : !this.state.open,
        })
        if(this.state.options.length===0) this.getOwnOpts()
    }

    updateFilterTerm(event) {
        //Listen to value change and pass it to state for as a keyword to filter options by
        this.setState({
            filter: event.target.value.length>0 ? event.target.value : false
        })
    }

    filterOption({value}, against) {
        //predicate expression to check for pre-fix match against search term
        if(against){
            return value.indexOf(against)>=0
        } else {
            return true
        }
    }
    kPress(event) {
        if(event.key === 'Enter'){
            if(this.state.options.map(n=>n.value).indexOf(event.target.value)>=0){
                this.returnSelectedValue(event.target.value)
                this.Input.blur()
            }
        }
    }

    returnSelectedValue(value) {
        this.setState({
            ...this.state,
            filter: value,
        })
        this.props.returnValue(this.props.name, value)
        this.toggle();
    }

    getOwnOpts() {
        //currently simulating async request
        //options: this.props.getOpts(this.props.name) that returns an array.
        //key generation will be handled in map function below.
        setTimeout(()=>{
            let sampleOptions = ['foo','bar', 'baz', 'qux','foo','bar', 'baz', 'qux','foo','bar', 'baz', 'qux']
            this.setState({
                ...this.state,
                options: sampleOptions.map(i=>({value: i, key: uuid()}))
            })
        }, 300)
    }

    render(){
        return(
            <div className="PriceListDropdown__wrapper">
                <div className={`PriceListDropdown__clickables ${this.state.open ? 'open' : null}`} onClick={this.toggle}>
                    <input className="PriceListDropdown__text"
                           placeholder={this.props.prevValue || 'prevvalue?!?'}
                           onKeyPress={this.kPress}
                           onChange={this.updateFilterTerm}
                           value={this.state.filter}
                           ref={(input) => {this.Input = input}}
                    />

                    <div className='PriceListDropdown__icon'>
                        {this.state.open ? <CaretUp/>:<CaretDown/>}
                    </div>
                </div>
                {this.state.open ?
                    <div className="PriceListDropdown__content">
                        {this.state.options === [] ? <PriceListDropdownContent loading={true} /> : null}
                        {this.state.options.filter((v)=>this.filterOption(v, this.state.filter)).map(n =>
                            <PriceListDropdownContent value={n.value} key={n.key} click={this.returnSelectedValue}/>)}
                    </div> :
                    null}
            </div>
        )
    }
}
export const PriceListDropdownContent = props => {
    return (
        <div
            className={
                `PriceListDropdown__option-wrapper
                ${props.loading ? 'option-loading ':null}
                ${props.more ? 'option-more': null}`
            }
            onClick={()=>props.click(props.value)}>
            {props.loading ? 'Laen...' : props.more ? "Veel.." : props.value}
        </div>)
}


///to be imported from Utils module once in sync with master:
const uuid = () => {
    var i, random;
    var uuid = '';
    for (i = 0; i < 32; i++) {
        random = Math.random() * 16 | 0;
        if (i === 8 || i === 12 || i === 16 || i === 20) {
            uuid += '-';
        }

        uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random)).toString(16);
    }

    return uuid;
}
Dropdown.propTypes = {
    name: PropTypes.string,
    prevValue: PropTypes.string,
    returnValues: PropTypes.func,
    getOpts: PropTypes.func
}

export default Dropdown
{'fraction_non_alphanumeric': 0.1394510118212783, 'fraction_numerical': 0.007413344019234622, 'mean_word_length': 1.713509105735254, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2369824', 'n_tokens_mistral': 2877, 'n_tokens_neox': 2775, 'n_words': 596}