如何调整 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>);
}
我正在使用 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>);
}