Select.js 3.29 KB
import template from "./Select.html";

class Select {
    props = {
        value: String,
        placeholder: String,
        onChange: Function,
        placeholder: String,
        getPopupContainer: Function,
    };

    state = {
        open: false,
        childrens: [],
        label: null,
        value: null,
        popup: null,
    };

    template = template;

    useModules = ["$compile", "$timeout"];

    constructor() {
        let option = this.state.childrens.find(function (option) {
            return option.value === this.props.value;
        });
        this.state.label = option.label;
    }

    addOption(option) {
        this.state.childrens.push(option);
    }

    handleClick(option) {
        this.state.open = !this.state.open;
        this.state.label = option.label;
        this.state.value = option.value;
        this.props.onChange({
            value: this.state.value,
        });
    }

    getOffset(ele) {
        if (!ele || ele.nodeType != 1) {
            return;
        }
        let func = this.props.getPopupContainer();
        if (typeof func === "function" && func() !== undefined) {
            return {
                top: $element[0].offsetTop,
                left: $element[0].offsetLeft,
            };
        } else {
            let rect = ele.getBoundingClientRect();
            let doc = ele.ownerDocument.documentElement;
            return {
                top: rect.top + window.pageYOffset - doc.clientTop,
                left: rect.left + window.pageXOffset - doc.clientLeft,
            };
        }
    }

    myEvent() {
        $timeout(() => {
            this.state.open = false;
            document.body.removeEventListener("click", this.myEvent);
        }, 0);
    }

    handleBlur() {
        // 事件绑定
        document.body.addEventListener("click", this.myEvent);
    }

    handleOpen(event) {
        event.stopPropagation();
        const { height, width } = $element[0].getBoundingClientRect();
        const { top, left } = this.getOffset($element[0]);
        let div = document.createElement("div");
        div.style.position = "absolute";
        div.style.left = 0;
        div.style.top = 0;
        div.style.width = "100%";
        div.appendChild(
            $compile(`<div><div ng-class="'ant-select-dropdown ant-select-dropdown--single ant-select-dropdown-placement-bottomLeft'+(!state.open?' ant-select-dropdown-hidden':'')" style="width: ${width}px; left: ${left}px; top: ${
                top + height + 2
            }px;">
            <ul class="ant-select-dropdown-menu ant-select-dropdown-menu-root ant-select-dropdown-menu-vertical">
                <li class="ant-select-dropdown-menu-item" ng-click="handleClick(option)" ng-repeat="option in state.childrens">{{option.label}}</li>
            </ul>
        </div></div>`)($scope)[0]
        );
        if (this.state.popup === null) {
            let func = this.props.getPopupContainer();
            if (typeof func === "function" && func() !== undefined) {
                $element[0].style.position = "relative";
                this.props.getPopupContainer()().appendChild(div);
            } else {
                document.body.appendChild(div);
            }
            this.state.popup = div;
        }
        this.state.open = !this.state.open;
        this.handleBlur();
    }
}