如何调整 SpinButton 的有效输入检查方法?

How to adjust valid input check method for SpinButton?

我正在使用 Office UI Fabric 并实现了 SpinButton。有某种自动验证可以防止我使用数字以外的任何东西作为输入。问题是,我什至不能使用减号。 我该如何更改?

我尝试实现我自己的 onValidate() 方法,以取消默认方法,即使它被调用,它也不会阻止 SpinButton 输入与数字不同时被删除

onValidate={() => console.log('Validate meeee')}

整个SpinButton长这样(混了JS):

static getNumericBox(formField: EntityFormField, onChange: EntityFormControlOnChangeType): JSX.Element {
        let rangeFrom: number = -999999;
        let rangeTo: number = 999999;

        const controlParams = EntityFormHelpers.getNumericControlParams(formField.controlType);

        if (controlParams) {
            rangeFrom = controlParams.rangeFrom;
            rangeTo = controlParams.rangeTo;
        }

        return (
            <React.Fragment key={formField.fieldName}>
                <SpinButton
                    key={formField.fieldName}
                    className={'NumericBox ' + this.getValidationClassName(formField)}
                    label={formField.displayName}
                    labelPosition={Position.top}
                    componentRef={(component: any) => {
                        if (component) {
                            const inputElement = component._input.current;
                            const labelElement = inputElement.parentElement.previousSibling.firstChild;

                            if (formField.validation.isRequired && !formField.displayOnly) {
                                labelElement.setAttribute('required', '');
                            }

                            inputElement.value = formField.value;


                            inputElement.onkeydown = (event: any) => {
                                if (event.target.value.toString().length > rangeTo.toString().length + 1 && event.target.value.toString().length > rangeFrom.toString().length + 1) {
                                    event.preventDefault();
                                    event.stopPropagation();
                                }
                            };


                            inputElement.onkeyup = (event: any) => {
                                let numberValue = Number(event.target.value);
                                if (!numberValue) {
                                    numberValue = formField.validation.isRequired ? Number(0) : null;
                                }
                                onChange(formField.fieldName, numberValue);
                            };
                        }
                    }}

                    onValidate={() => console.log('Validate meeee')}

                    onIncrement={(value: string) => {
                        if (Number(value) + 1 > rangeTo) {
                            formField.value = value;
                        } else {
                            value = String(+value + 1);
                            onChange(formField.fieldName, value);
                            formField.value = value;
                        }
                    }}



                    onDecrement={(value: string) => {
                        if (Number(value) - 1 < rangeFrom) {
                            formField.value = value;
                        } else {
                            value = String(+value - 1);
                            onChange(formField.fieldName, value);
                            formField.value = value;
                        }
                    }}                    

                    value={formField.value}
                    min={rangeFrom}
                    max={rangeTo}
                    step={1}
                    onBlur={(event: any) => {
                        const numberValue = Number(event.target.value);
                        if (numberValue) {
                            if (numberValue < rangeFrom) {
                                onChange(formField.fieldName, rangeFrom);
                            }
                            else if (numberValue > rangeTo) {
                                onChange(formField.fieldName, rangeTo);
                            }
                        }
                    }}
                    disabled={formField.displayOnly}
                />
                {this.getDescriptionControl(formField)}
            </React.Fragment>);
    }

问题出在 onkeyup 方法中。只要按下一个键,一切都会继续覆盖。稍微摆弄一下就解决了整个问题。

如果有人感兴趣,这里是最终的工作状态:

static getNumericBox(formField: EntityFormField, onChange: EntityFormControlOnChangeType): JSX.Element {
        let rangeFrom: number = -999999;
        let rangeTo: number = 999999;

        const controlParams = EntityFormHelpers.getNumericControlParams(formField.controlType);

        if (controlParams) {
            rangeFrom = controlParams.rangeFrom;
            rangeTo = controlParams.rangeTo;
        }

        return (
            <React.Fragment key={formField.fieldName}>
                <SpinButton
                    key={formField.fieldName}
                    className={'NumericBox ' + this.getValidationClassName(formField)}
                    label={formField.displayName}
                    labelPosition={Position.top}
                    componentRef={(component: any) => {
                        if (component) {
                            const inputElement = component._input.current;
                            const labelElement = inputElement.parentElement.previousSibling.firstChild;

                            if (formField.validation.isRequired && !formField.displayOnly) {
                                labelElement.setAttribute('required', '');
                            }

                            inputElement.value = formField.value;


                            inputElement.onkeydown = (event: any) => {
                                if (event.target.value.toString().length > rangeTo.toString().length + 1 && event.target.value.toString().length > rangeFrom.toString().length + 1) {
                                    event.preventDefault();
                                    event.stopPropagation();
                                }
                            };

                            inputElement.onkeyup = (event: any) => {
                                const isValidKeyCode =
                                    event.which === KeyCodes.up ||
                                    event.which === KeyCodes.down ||
                                    event.which === KeyCodes.left ||
                                    event.which === KeyCodes.right ||
                                    event.which === KeyCodes.backspace ||
                                    event.which === KeyCodes.del ||
                                    event.which === KeyCodes.a && event.ctrlKey ||
                                    event.which === KeyCodes.x && event.ctrlKey ||
                                    event.which === KeyCodes.c && event.ctrlKey ||
                                    event.which === KeyCodes.v && event.ctrlKey ||
                                    event.which === KeyCodes.subtract ||
                                    event.which === KeyCodes.dash;

                                const isValidNumberKeyCode = (
                                    (event.which >= KeyCodes.zero && event.which <= KeyCodes.nine) ||
                                    (event.which >= KeyCodes.zero_numpad && event.which <= KeyCodes.nine_numpad)
                                );

                                if (!isValidKeyCode && !isValidNumberKeyCode) {
                                    onChange(formField.fieldName, null);
                                } else if (event.target.value === "-") {
                                    return;
                                } else {
                                    let numberValue = parseInt(event.target.value);
                                    if (!numberValue && numberValue !== 0) {
                                        numberValue = formField.validation.isRequired ? +"0" : null;
                                    }
                                    onChange(formField.fieldName, numberValue);
                                }

                            };
                        }
                    }}

                    onIncrement={(value: string) => {
                        if (Number(value) + 1 > rangeTo) {
                            formField.value = value;
                        } else {
                            value = String(+value + 1);
                            onChange(formField.fieldName, value);
                            formField.value = value;
                        }
                    }}



                    onDecrement={(value: string) => {
                        if (Number(value) - 1 < rangeFrom) {
                            formField.value = value;
                        } else {
                            value = String(+value - 1);
                            onChange(formField.fieldName, value);
                            formField.value = value;
                        }
                    }}                    

                    value={formField.value}
                    min={rangeFrom}
                    max={rangeTo}
                    step={1}
                    onBlur={(event: any) => {
                        const numberValue = Number(event.target.value);
                        if (numberValue) {
                            if (numberValue < rangeFrom) {
                                onChange(formField.fieldName, rangeFrom);
                            }
                            else if (numberValue > rangeTo) {
                                onChange(formField.fieldName, rangeTo);
                            }
                        }
                    }}
                    disabled={formField.displayOnly}
                />
                {this.getDescriptionControl(formField)}
            </React.Fragment>);
    }