Skip to content
Snippets Groups Projects
Slider.tsx 6.31 KiB
Newer Older
Glenn Vorhes's avatar
Glenn Vorhes committed
/**
 * Created by glenn on 7/6/2017.
 */

Glenn Vorhes's avatar
Glenn Vorhes committed
import React = require("react");

Glenn Vorhes's avatar
Glenn Vorhes committed
import makeGuid from '../util/makeGuid';
Glenn Vorhes's avatar
Glenn Vorhes committed
import {ChangeEvent} from "react";
import {get_browser} from '../util/get_browser';
Glenn Vorhes's avatar
Glenn Vorhes committed
type iSlider = {
Glenn Vorhes's avatar
Glenn Vorhes committed
    change: (d: number) => any;
    steps?: number;
    animate?: boolean;
Glenn Vorhes's avatar
Glenn Vorhes committed
    defaultAnimationInterval?: number;
Glenn Vorhes's avatar
Glenn Vorhes committed
    value?: number;
}

glennvorhes's avatar
glennvorhes committed
export class Slider extends React.Component<iSlider, {}> {
Glenn Vorhes's avatar
Glenn Vorhes committed
    static defaultProps = {
        steps: null,
        animate: null,
        defaultAnimationInterval: null,
        value: null
    };


Glenn Vorhes's avatar
Glenn Vorhes committed
    private uid: string;
    private startUid: string;
    private stopUid: string;
Glenn Vorhes's avatar
Glenn Vorhes committed
    private previousUid: string;
    private nextUid: string;
    private intervalUid: string;
    private el: HTMLInputElement;
    private previousButton: HTMLButtonElement;
    private nextButton: HTMLButtonElement;
    private startButton: HTMLButtonElement;
    private stopButton: HTMLButtonElement;
Glenn Vorhes's avatar
Glenn Vorhes committed
    private intervalSelect: HTMLSelectElement;
    private interval: number;
    private running: boolean;
    private minVal: number;
    private maxVal: number;
    private step: number;
Glenn Vorhes's avatar
Glenn Vorhes committed

Glenn Vorhes's avatar
Glenn Vorhes committed
    constructor(props: iSlider, context: Object) {
Glenn Vorhes's avatar
Glenn Vorhes committed
        super(props, context);
        this.uid = makeGuid();
        this.startUid = makeGuid();
        this.stopUid = makeGuid();
Glenn Vorhes's avatar
Glenn Vorhes committed
        this.intervalUid = makeGuid();
Glenn Vorhes's avatar
Glenn Vorhes committed
        this.previousUid = makeGuid();
        this.nextUid = makeGuid();
Glenn Vorhes's avatar
Glenn Vorhes committed
        this.running = false;
    }

    componentDidMount() {
        this.el = document.getElementById(this.uid) as HTMLInputElement;
        this.minVal = parseFloat(this.el.min);
        this.maxVal = parseFloat(this.el.max);
        this.step = parseFloat(this.el.step);
        this.startButton = document.getElementById(this.startUid) as HTMLButtonElement;
        this.stopButton = document.getElementById(this.stopUid) as HTMLButtonElement;
Glenn Vorhes's avatar
Glenn Vorhes committed
        if (this.props.animate) {
Glenn Vorhes's avatar
Glenn Vorhes committed
            this.stopButton.style.display = 'none';
        }
Glenn Vorhes's avatar
Glenn Vorhes committed
        this.previousButton = document.getElementById(this.previousUid) as HTMLButtonElement;
        this.nextButton = document.getElementById(this.nextUid) as HTMLButtonElement;
Glenn Vorhes's avatar
Glenn Vorhes committed
        this.intervalSelect = document.getElementById(this.intervalUid) as HTMLSelectElement;
Glenn Vorhes's avatar
Glenn Vorhes committed
        if (get_browser().name.toUpperCase().indexOf('IE') > -1) {
            this.el.onchange = (e) => {
                this.props.change(parseFloat(e.target['value']))
            }
        }
Glenn Vorhes's avatar
Glenn Vorhes committed
    }

    updateRunning() {
        this.el.disabled = this.running;

        this.startButton.style.display = this.running ? 'none' : '';
        this.stopButton.style.display = this.running ? '' : 'none';

Glenn Vorhes's avatar
Glenn Vorhes committed
        this.nextButton.disabled = this.running;
        this.previousButton.disabled = this.running;
Glenn Vorhes's avatar
Glenn Vorhes committed
    }

    startAnimate() {
        this.running = true;
        this.updateRunning();
        this.interval = setInterval(() => {
            let val = parseFloat(this.el.value);
            val += this.step;
            if (val > this.maxVal) {
                val = this.minVal
            }

            this.el.value = val.toString();
            this.props.change(val);
        }, parseInt(this.intervalSelect.value));
    }

    stopAnimate() {
        clearInterval(this.interval);
        this.running = false;
        this.updateRunning();
    }

Glenn Vorhes's avatar
Glenn Vorhes committed
    restartAnimate() {
        if (this.running) {
Glenn Vorhes's avatar
Glenn Vorhes committed
            this.stopAnimate();
            this.startAnimate();
        }
    }

Glenn Vorhes's avatar
Glenn Vorhes committed
    increment(v: number) {
        let val = parseFloat(this.el.value);
        val = v > 0 ? val + this.step : val - this.step;
        this.el.value = val.toString();
        this.props.change(val);
    }

Glenn Vorhes's avatar
Glenn Vorhes committed
    render() {
        let attrs = {
            id: this.uid,
            min: 0,
            type: 'range',
Glenn Vorhes's avatar
Glenn Vorhes committed
            onChange: (evt: ChangeEvent<HTMLInputElement>) => {
                this.props.change(parseFloat(evt.target.value))
            },
            style: {width: '100%', padding: '4px 0'},
            max: "100",
Glenn Vorhes's avatar
Glenn Vorhes committed
            step: '0.1',
Glenn Vorhes's avatar
Glenn Vorhes committed
            value: this.props.value ? this.props.value.toString() : '0',
Glenn Vorhes's avatar
Glenn Vorhes committed
            defaultValue: "0"
Glenn Vorhes's avatar
Glenn Vorhes committed
        if (this.props.steps) {
            attrs.max = this.props.steps.toString();
            attrs.step = '1';
        }

Glenn Vorhes's avatar
Glenn Vorhes committed
        if (this.props.value) {
Glenn Vorhes's avatar
Glenn Vorhes committed
            delete attrs.defaultValue;
Glenn Vorhes's avatar
Glenn Vorhes committed
        } else {
Glenn Vorhes's avatar
Glenn Vorhes committed
            delete attrs.value;
Glenn Vorhes's avatar
Glenn Vorhes committed
        }

Glenn Vorhes's avatar
Glenn Vorhes committed
        let start = null;
        let stop = null;
Glenn Vorhes's avatar
Glenn Vorhes committed
        let previous = null;
        let next = null;
Glenn Vorhes's avatar
Glenn Vorhes committed
        let intervalSelect = null;

Glenn Vorhes's avatar
Glenn Vorhes committed
        let interval = "200";

Glenn Vorhes's avatar
Glenn Vorhes committed
        if (this.props.defaultAnimationInterval) {
Glenn Vorhes's avatar
Glenn Vorhes committed
            interval = this.props.defaultAnimationInterval.toFixed();
        }

Glenn Vorhes's avatar
Glenn Vorhes committed
        if (this.props.animate) {
Glenn Vorhes's avatar
Glenn Vorhes committed
            previous = <button id={this.previousUid} className="react-slider-previous" onClick={() => {
                this.increment(-1)
Glenn Vorhes's avatar
Glenn Vorhes committed
            }} title="Previous"/>;
Glenn Vorhes's avatar
Glenn Vorhes committed

            next = <button id={this.nextUid} className="react-slider-next" onClick={() => {
                this.increment(1)
Glenn Vorhes's avatar
Glenn Vorhes committed
            }} title="Next"/>;
Glenn Vorhes's avatar
Glenn Vorhes committed

            start = <button id={this.startUid} className="react-slider-start" onClick={() => {
Glenn Vorhes's avatar
Glenn Vorhes committed
                this.startAnimate()
Glenn Vorhes's avatar
Glenn Vorhes committed
            }} title="Start"/>;
Glenn Vorhes's avatar
Glenn Vorhes committed

            stop = <button id={this.stopUid} className="react-slider-stop" onClick={() => {
Glenn Vorhes's avatar
Glenn Vorhes committed
                this.stopAnimate()
Glenn Vorhes's avatar
Glenn Vorhes committed
            }} title="Stop"/>;
Glenn Vorhes's avatar
Glenn Vorhes committed

            intervalSelect = <span>
Glenn Vorhes's avatar
Glenn Vorhes committed

Glenn Vorhes's avatar
Glenn Vorhes committed
            <label style={{fontWeight: 'bold', marginRight: '3px'}}>Interval (s)</label>
Glenn Vorhes's avatar
Glenn Vorhes committed
            <select defaultValue={interval} id={this.intervalUid} onChange={() => {
Glenn Vorhes's avatar
Glenn Vorhes committed
                this.restartAnimate()
            }}>
Glenn Vorhes's avatar
Glenn Vorhes committed
                <option value="100">0.1</option>
                <option value="200">0.2</option>
                <option value="300">0.3</option>
                <option value="400">0.4</option>
                <option value="500">0.5</option>
                <option value="600">0.6</option>
                <option value="700">0.7</option>
                <option value="800">0.8</option>
                <option value="900">0.9</option>
                <option value="1000">1.0</option>
            </select>
            </span>;
        }

        return <div className="react-slider">
Glenn Vorhes's avatar
Glenn Vorhes committed
            <input {...attrs}/>
            <div className="react-slider-controls" style={{textAlign: 'center'}}>
                {previous}{start}{stop}{next}{intervalSelect}
            </div>
Glenn Vorhes's avatar
Glenn Vorhes committed
        </div>
    }