1
0
Fork 0
mirror of https://gitlab.com/bramw/baserow.git synced 2025-01-30 18:36:29 +00:00
bramw_baserow/web-frontend/modules/database/mixins/numberField.js
2025-01-02 09:19:28 +00:00

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
}
},
},
}