mirror of
https://gitlab.com/bramw/baserow.git
synced 2025-01-30 18:36:29 +00:00
128 lines
4 KiB
JavaScript
128 lines
4 KiB
JavaScript
import BigNumber from 'bignumber.js'
|
|
import {
|
|
formatNumberValue,
|
|
parseNumberValue,
|
|
getNumberFormatOptions,
|
|
} from '@baserow/modules/database/utils/number'
|
|
|
|
/**
|
|
* This mixin contains some method overrides for validating and formatting the
|
|
* number field. This mixin is used in both the GridViewFieldNumber and
|
|
* RowEditFieldNumber components. All methods requires the field to be passed as
|
|
* they can be used in functional components.
|
|
*/
|
|
export default {
|
|
data() {
|
|
return {
|
|
formattedValue: '',
|
|
focused: false,
|
|
roundDecimals: true,
|
|
}
|
|
},
|
|
methods: {
|
|
updateFormattedValue(field, value) {
|
|
this.formattedValue = this.formatNumberValue(field, value)
|
|
},
|
|
formatNumberValue(field, value) {
|
|
return formatNumberValue(field, value, true, this.roundDecimals)
|
|
},
|
|
/*
|
|
* This method is similar to formatNumberValue, but it returns the value as a
|
|
* string without the number prefix, suffix and thousand separator. This is
|
|
* useful when the value is being edited and the user should only see the
|
|
* decimal separator.
|
|
*/
|
|
formatNumberValueForEdit(field, value) {
|
|
const withThousandSeparator = false
|
|
return formatNumberValue(
|
|
field,
|
|
value,
|
|
withThousandSeparator,
|
|
this.roundDecimals
|
|
)
|
|
},
|
|
parseNumberValue(field, value) {
|
|
return parseNumberValue(field, value, this.roundDecimals)
|
|
},
|
|
getNumberFormatOptions(field) {
|
|
return getNumberFormatOptions(field)
|
|
},
|
|
onInput(field, event) {
|
|
this.updateCopy(field, event.target.value)
|
|
},
|
|
onFocus() {
|
|
this.focused = true
|
|
this.copy = this.formatNumberValueForEdit(this.field, this.copy)
|
|
},
|
|
onBlur() {
|
|
this.focused = false
|
|
this.updateFormattedValue(this.field, this.copy)
|
|
},
|
|
onKeyPress(event) {
|
|
if (!this.isValidChar(event.key)) {
|
|
return event.preventDefault()
|
|
}
|
|
},
|
|
isValidChar(char) {
|
|
const validChars = []
|
|
if (this.field.number_negative) {
|
|
validChars.push('-')
|
|
}
|
|
// Allow any non-digit character in the number prefix and suffix.
|
|
const {
|
|
numberPrefix,
|
|
numberSuffix,
|
|
decimalSeparator,
|
|
thousandSeparator,
|
|
} = this.getNumberFormatOptions(this.field)
|
|
validChars.push(...numberPrefix.split(''), ...numberSuffix.split(''))
|
|
// Allow the decimal separator and the thousands separator.
|
|
validChars.push(decimalSeparator, thousandSeparator)
|
|
return /\d/.test(char) || validChars.includes(char)
|
|
},
|
|
prepareCopy(value) {
|
|
// FIXME: This function is called with value that can be either a number or the string
|
|
// representation of a number. It if's a string, it's not in the field format, so
|
|
// we need to parse it first
|
|
if (value == null || value === '') {
|
|
return ''
|
|
}
|
|
return this.formatNumberValueForEdit(this.field, new BigNumber(value))
|
|
},
|
|
prepareValue(copy) {
|
|
return this.parseNumberValue(this.field, copy)
|
|
},
|
|
beforeSave(copy) {
|
|
return this.parseNumberValue(this.field, copy)
|
|
},
|
|
afterSave(value) {
|
|
this.updateFormattedValue(this.field, this.prepareCopy(value))
|
|
},
|
|
getStartEditIndex(field, value) {
|
|
if (value == null || value === '') {
|
|
return 0
|
|
}
|
|
|
|
const { decimalSeparator, numberSuffix } =
|
|
this.getNumberFormatOptions(field)
|
|
const decimalSeparatorIndex = value.indexOf(decimalSeparator)
|
|
const suffixIndex = numberSuffix ? value.indexOf(numberSuffix) : -1
|
|
return decimalSeparatorIndex !== -1
|
|
? decimalSeparatorIndex
|
|
: suffixIndex !== -1
|
|
? suffixIndex
|
|
: value.length
|
|
},
|
|
updateCopy(field, newCopy) {
|
|
if (newCopy == null || newCopy === '') {
|
|
this.copy = ''
|
|
return
|
|
}
|
|
const newNumber = this.parseNumberValue(field, newCopy)
|
|
const prevNumber = this.parseNumberValue(field, this.copy)
|
|
if (newNumber !== prevNumber) {
|
|
this.copy = newCopy
|
|
}
|
|
},
|
|
},
|
|
}
|