mini-check
Version:
137 lines (133 loc) • 5.06 kB
JavaScript
import Taro from "@tarojs/taro-h5";
import Nerv from "nervjs";
import _toString from 'lodash/toString';
import { View, Text, Input } from '@tarojs/components';
import { CustomLabel, ItemExtra, UnEditeableView } from '../index';
import classnames from 'classnames';
import { AtIcon } from 'taro-ui';
import './index.scss';
// 实现两数相加并保留小数点后最短尾数
function addNum(num1, num2) {
let sq1, sq2;
console.log('num1', num1);
console.log('num2', num2);
try {
sq1 = _toString(num1).split('.')[1].length;
} catch (e) {
sq1 = 0;
}
try {
sq2 = _toString(num2).split('.')[1].length;
} catch (e) {
sq2 = 0;
}
const m = Math.pow(10, Math.max(sq1, sq2));
return (Math.round(num1 * m) + Math.round(num2 * m)) / m;
}
class Digit extends Taro.Component {
render() {
const { itemExtra, editable, addonAfter, term, value, onChange, help, required, min = -9999, max = 9999, step = 1, precision = 0, defaultValue, onView, hidden, listItemChildren } = this.props;
const inputOnChange = e => {
if (editable) {
return;
}
let inputValue = e.target.value;
const reg = /(^[\-0-9][0-9]*(.[0-9]+)?)$/;
if (reg.test(inputValue) || inputValue.includes('.')) {
const newValue = handleValue(inputValue);
onChange(newValue);
return newValue;
} else {
onChange('');
return '';
}
};
const handleValue = value => {
let resultValue = value;
if (resultValue > max) {
resultValue = max;
}
if (resultValue < min) {
resultValue = min;
}
// if (resultValue && !Number(resultValue)) {
// resultValue = parseFloat(String(resultValue)) || min
// }
if (precision && resultValue && String(resultValue).includes('.')) {
if (String(resultValue).split('.').length <= 2) {
const valuePrecision = String(resultValue).split('.')[1];
if (isNaN(Number(valuePrecision))) {
resultValue = String(resultValue).split('.')[0];
} else if (valuePrecision.length > precision) {
resultValue = String(resultValue).split('.')[0] + '.' + String(resultValue).split('.')[1].slice(0, precision);
}
} else {
resultValue = String(resultValue).split('.')[0] + '.' + String(resultValue).split('.')[1].slice(0, precision);
}
} else {
resultValue = String(resultValue).split('.')[0];
}
resultValue = parseValue(String(resultValue));
return resultValue;
};
const parseValue = num => {
// if (num === '') return '0'
if (num === '' || num.startsWith('-00')) {
return '0';
}
const numStr = _toString(num);
if (numStr.indexOf('0') === 0 && numStr.indexOf('.') === -1) {
// 处理01变成1,并且不处理1.
return _toString(parseFloat(num));
}
return _toString(num);
};
const handleClick = clickType => {
const lowThanMin = clickType === 'minus' && showValue <= min;
const overThanMax = clickType === 'plus' && showValue >= max;
if (lowThanMin || overThanMax || disabled) {
return;
}
const deltaValue = clickType === 'minus' ? -step : step;
let newValue = addNum(Number(value || 0), deltaValue);
onChange(newValue);
};
const disabled = editable === undefined || editable === true ? false : true;
const showValue = value !== undefined ? value : defaultValue || 0;
if (hidden) {
return null;
}
if (editable === false || editable === undefined && onView) {
return <UnEditeableView term={term} help={help} value={showValue} addonAfter={addonAfter} listItemChildren={listItemChildren} />;
}
const minusBtnCls = classnames('minus', {
'disabled': showValue <= min || disabled
});
const plusBtnCls = classnames('plus', {
'disabled': showValue >= max || disabled
});
const containerCLs = classnames(['digit-container', listItemChildren ? 'item-container' : 'item-container-margin']);
const inputCls = classnames('input', precision && precision >= 5 ? 'precision' : '');
return <View className={containerCLs}>
<View className="digit-content">
<CustomLabel term={term} help={help} required={required} />
<View className="digit-inputNumber">
<View className={minusBtnCls} onClick={() => handleClick('minus')}>
<AtIcon value="subtract" size={14} />
</View>
<Input className={inputCls} type="digit" value={String(showValue)} onInput={inputOnChange} disabled={disabled} />
<View className={plusBtnCls} onClick={() => handleClick('plus')}>
<AtIcon value="add" size={14} />
</View>
<View className="digit-addonAfter">
<Text>{addonAfter}</Text>
</View>
</View>
</View>
{itemExtra && <View className="digit-item-extra-wrap">
<ItemExtra text={itemExtra} />
</View>}
</View>;
}
}
export default Digit;