fix: show formatted percent, currency & float only when not focused
(cherry picked from commit 32f3aaf38f131f2636c69d72a7b077f25595add7)
This commit is contained in:
parent
20e970d90f
commit
24c86aa70a
1
frontend/components.d.ts
vendored
1
frontend/components.d.ts
vendored
@ -114,6 +114,7 @@ declare module 'vue' {
|
|||||||
FileVideoIcon: typeof import('./src/components/Icons/FileVideoIcon.vue')['default']
|
FileVideoIcon: typeof import('./src/components/Icons/FileVideoIcon.vue')['default']
|
||||||
Filter: typeof import('./src/components/Filter.vue')['default']
|
Filter: typeof import('./src/components/Filter.vue')['default']
|
||||||
FilterIcon: typeof import('./src/components/Icons/FilterIcon.vue')['default']
|
FilterIcon: typeof import('./src/components/Icons/FilterIcon.vue')['default']
|
||||||
|
FormattedInput: typeof import('./src/components/Controls/FormattedInput.vue')['default']
|
||||||
FrappeCloudIcon: typeof import('./src/components/Icons/FrappeCloudIcon.vue')['default']
|
FrappeCloudIcon: typeof import('./src/components/Icons/FrappeCloudIcon.vue')['default']
|
||||||
GenderIcon: typeof import('./src/components/Icons/GenderIcon.vue')['default']
|
GenderIcon: typeof import('./src/components/Icons/GenderIcon.vue')['default']
|
||||||
GeneralSettings: typeof import('./src/components/Settings/GeneralSettings.vue')['default']
|
GeneralSettings: typeof import('./src/components/Settings/GeneralSettings.vue')['default']
|
||||||
|
|||||||
29
frontend/src/components/Controls/FormattedInput.vue
Normal file
29
frontend/src/components/Controls/FormattedInput.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<FormControl
|
||||||
|
:value="displayValue"
|
||||||
|
@focus="isFocused = true"
|
||||||
|
@blur="isFocused = false"
|
||||||
|
v-bind="$attrs"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { FormControl } from 'frappe-ui'
|
||||||
|
import { ref, computed } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
value: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
formattedValue: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const isFocused = ref(false)
|
||||||
|
|
||||||
|
const displayValue = computed(() => {
|
||||||
|
return isFocused.value ? props.value : props.formattedValue
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@ -207,38 +207,41 @@
|
|||||||
@change="(e) => fieldChange(e.target.value, field, row)"
|
@change="(e) => fieldChange(e.target.value, field, row)"
|
||||||
/>
|
/>
|
||||||
<FormControl
|
<FormControl
|
||||||
v-else-if="['Int'].includes(field.fieldtype)"
|
v-else-if="field.fieldtype === 'Int'"
|
||||||
class="[&_input]:text-right"
|
class="[&_input]:text-right"
|
||||||
type="number"
|
type="text"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
:value="row[field.fieldname]"
|
:value="row[field.fieldname]"
|
||||||
:disabled="Boolean(field.read_only)"
|
:disabled="Boolean(field.read_only)"
|
||||||
@change="fieldChange($event.target.value, field, row)"
|
@change="fieldChange($event.target.value, field, row)"
|
||||||
/>
|
/>
|
||||||
<FormControl
|
<FormattedInput
|
||||||
v-else-if="field.fieldtype === 'Percent'"
|
v-else-if="field.fieldtype === 'Percent'"
|
||||||
class="[&_input]:text-right"
|
class="[&_input]:text-right"
|
||||||
type="text"
|
type="text"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
:value="getFormattedPercent(field.fieldname, row)"
|
:value="getFloatWithPrecision(field.fieldname, row)"
|
||||||
|
:formattedValue="row[field.fieldname] + '%'"
|
||||||
:disabled="Boolean(field.read_only)"
|
:disabled="Boolean(field.read_only)"
|
||||||
@change="fieldChange(flt($event.target.value), field, row)"
|
@change="fieldChange(flt($event.target.value), field, row)"
|
||||||
/>
|
/>
|
||||||
<FormControl
|
<FormattedInput
|
||||||
v-else-if="field.fieldtype === 'Float'"
|
v-else-if="field.fieldtype === 'Float'"
|
||||||
class="[&_input]:text-right"
|
class="[&_input]:text-right"
|
||||||
type="text"
|
type="text"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
:value="getFormattedFloat(field.fieldname, row)"
|
:value="getFloatWithPrecision(field.fieldname, row)"
|
||||||
|
:formattedValue="row[field.fieldname]"
|
||||||
:disabled="Boolean(field.read_only)"
|
:disabled="Boolean(field.read_only)"
|
||||||
@change="fieldChange(flt($event.target.value), field, row)"
|
@change="fieldChange(flt($event.target.value), field, row)"
|
||||||
/>
|
/>
|
||||||
<FormControl
|
<FormattedInput
|
||||||
v-else-if="field.fieldtype === 'Currency'"
|
v-else-if="field.fieldtype === 'Currency'"
|
||||||
class="[&_input]:text-right"
|
class="[&_input]:text-right"
|
||||||
type="text"
|
type="text"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
:value="
|
:value="getCurrencyWithPrecision(field.fieldname, row)"
|
||||||
|
:formattedValue="
|
||||||
getFormattedCurrency(field.fieldname, row, parentDoc)
|
getFormattedCurrency(field.fieldname, row, parentDoc)
|
||||||
"
|
"
|
||||||
:disabled="Boolean(field.read_only)"
|
:disabled="Boolean(field.read_only)"
|
||||||
@ -312,6 +315,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import FormattedInput from '@/components/Controls/FormattedInput.vue'
|
||||||
import GridFieldsEditorModal from '@/components/Controls/GridFieldsEditorModal.vue'
|
import GridFieldsEditorModal from '@/components/Controls/GridFieldsEditorModal.vue'
|
||||||
import GridRowFieldsModal from '@/components/Controls/GridRowFieldsModal.vue'
|
import GridRowFieldsModal from '@/components/Controls/GridRowFieldsModal.vue'
|
||||||
import GridRowModal from '@/components/Controls/GridRowModal.vue'
|
import GridRowModal from '@/components/Controls/GridRowModal.vue'
|
||||||
@ -361,8 +365,8 @@ const triggerOnRowRemove = inject('triggerOnRowRemove')
|
|||||||
const {
|
const {
|
||||||
getGridViewSettings,
|
getGridViewSettings,
|
||||||
getFields,
|
getFields,
|
||||||
getFormattedPercent,
|
getFloatWithPrecision,
|
||||||
getFormattedFloat,
|
getCurrencyWithPrecision,
|
||||||
getFormattedCurrency,
|
getFormattedCurrency,
|
||||||
getGridSettings,
|
getGridSettings,
|
||||||
} = getMeta(props.doctype)
|
} = getMeta(props.doctype)
|
||||||
|
|||||||
@ -39,6 +39,18 @@ export function getMeta(doctype) {
|
|||||||
return formatNumber(doc[fieldname], '', precision)
|
return formatNumber(doc[fieldname], '', precision)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getFloatWithPrecision(fieldname, doc) {
|
||||||
|
let df = doctypeMeta[doctype]?.fields.find((f) => f.fieldname == fieldname)
|
||||||
|
let precision = df?.precision || null
|
||||||
|
return formatNumber(doc[fieldname], '', precision)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getCurrencyWithPrecision(fieldname, doc) {
|
||||||
|
let df = doctypeMeta[doctype]?.fields.find((f) => f.fieldname == fieldname)
|
||||||
|
let precision = df?.precision || null
|
||||||
|
return formatCurrency(doc[fieldname], '', '', precision)
|
||||||
|
}
|
||||||
|
|
||||||
function getFormattedCurrency(fieldname, doc, parentDoc = null) {
|
function getFormattedCurrency(fieldname, doc, parentDoc = null) {
|
||||||
let currency = window.sysdefaults.currency || 'USD'
|
let currency = window.sysdefaults.currency || 'USD'
|
||||||
let df = doctypeMeta[doctype]?.fields.find((f) => f.fieldname == fieldname)
|
let df = doctypeMeta[doctype]?.fields.find((f) => f.fieldname == fieldname)
|
||||||
@ -129,6 +141,8 @@ export function getMeta(doctype) {
|
|||||||
getGridSettings,
|
getGridSettings,
|
||||||
getGridViewSettings,
|
getGridViewSettings,
|
||||||
saveUserSettings,
|
saveUserSettings,
|
||||||
|
getFloatWithPrecision,
|
||||||
|
getCurrencyWithPrecision,
|
||||||
getFormattedFloat,
|
getFormattedFloat,
|
||||||
getFormattedPercent,
|
getFormattedPercent,
|
||||||
getFormattedCurrency,
|
getFormattedCurrency,
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
import { get } from '@vueuse/core'
|
|
||||||
|
|
||||||
const NUMBER_FORMAT_INFO = {
|
const NUMBER_FORMAT_INFO = {
|
||||||
'#,###.##': { decimalStr: '.', groupSep: ',' },
|
'#,###.##': { decimalStr: '.', groupSep: ',' },
|
||||||
'#.###,##': { decimalStr: ',', groupSep: '.' },
|
'#.###,##': { decimalStr: ',', groupSep: '.' },
|
||||||
@ -183,10 +181,13 @@ export function formatCurrency(value, format, currency = 'USD', precision = 2) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
format = getNumberFormat(format)
|
format = getNumberFormat(format)
|
||||||
let symbol = getCurrencySymbol(currency)
|
|
||||||
|
|
||||||
if (symbol) {
|
if (currency) {
|
||||||
return __(symbol) + ' ' + formatNumber(value, format, precision)
|
let symbol = getCurrencySymbol(currency)
|
||||||
|
|
||||||
|
if (symbol) {
|
||||||
|
return __(symbol) + ' ' + formatNumber(value, format, precision)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatNumber(value, format, precision)
|
return formatNumber(value, format, precision)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user