fix: comma input behavior

This commit is contained in:
puriphatt 2024-12-25 15:47:25 +07:00
parent 61501dba8d
commit 889d4afbf5
6 changed files with 113 additions and 50 deletions

View file

@ -10,9 +10,13 @@ const price = defineModel<number>('price');
const vatIncluded = defineModel<boolean>('vatIncluded'); const vatIncluded = defineModel<boolean>('vatIncluded');
const calcVat = defineModel<boolean>('calcVat'); const calcVat = defineModel<boolean>('calcVat');
const price4Show = ref(''); const price4Show = ref<string>(commaInput(price.value?.toString() || '0'));
const agentPrice4Show = ref(''); const agentPrice4Show = ref<string>(
const serviceCharge4Show = ref(''); commaInput(agentPrice.value?.toString() || '0'),
);
const serviceCharge4Show = ref<string>(
commaInput(serviceCharge.value?.toString() || '0'),
);
const column = [ const column = [
{ {
@ -194,17 +198,21 @@ withDefaults(
:borderless="readonly" :borderless="readonly"
hide-bottom-space hide-bottom-space
input-class="text-right" input-class="text-right"
debounce="500" :model-value="price4Show"
:model-value="commaInput(price?.toString() || '0')" @blur="
() => {
price = Number(price4Show.replace(/,/g, ''));
if (price % 1 === 0) {
const [, dec] = price4Show.split('.');
if (!dec) {
price4Show += '.00';
}
}
}
"
@update:model-value=" @update:model-value="
(v) => { (v) => {
if (typeof v === 'string') price4Show = commaInput(v); price4Show = commaInput(v?.toString() || '0', 'string');
const x = parseFloat(
price4Show && typeof price4Show === 'string'
? price4Show.replace(/,/g, '')
: '',
);
price = x;
} }
" "
/> />
@ -218,17 +226,24 @@ withDefaults(
:borderless="readonly" :borderless="readonly"
hide-bottom-space hide-bottom-space
input-class="text-right" input-class="text-right"
debounce="500" :model-value="agentPrice4Show"
:model-value="commaInput(agentPrice?.toString() || '0')" @blur="
() => {
agentPrice = Number(agentPrice4Show.replace(/,/g, ''));
if (agentPrice % 1 === 0) {
const [, dec] = agentPrice4Show.split('.');
if (!dec) {
agentPrice4Show += '.00';
}
}
}
"
@update:model-value=" @update:model-value="
(v) => { (v) => {
if (typeof v === 'string') agentPrice4Show = commaInput(v); agentPrice4Show = commaInput(
const x = parseFloat( v?.toString() || '0',
agentPrice4Show && typeof agentPrice4Show === 'string' 'string',
? agentPrice4Show.replace(/,/g, '')
: '',
); );
agentPrice = x;
} }
" "
/> />
@ -242,19 +257,26 @@ withDefaults(
:borderless="readonly" :borderless="readonly"
input-class="text-right" input-class="text-right"
hide-bottom-space hide-bottom-space
debounce="500" :model-value="serviceCharge4Show"
:model-value="commaInput(serviceCharge?.toString() || '0')" @blur="
() => {
serviceCharge = Number(
serviceCharge4Show.replace(/,/g, ''),
);
if (serviceCharge % 1 === 0) {
const [, dec] = serviceCharge4Show.split('.');
if (!dec) {
serviceCharge4Show += '.00';
}
}
}
"
@update:model-value=" @update:model-value="
(v) => { (v) => {
if (typeof v === 'string') serviceCharge4Show = commaInput(
serviceCharge4Show = commaInput(v); v?.toString() || '0',
const x = parseFloat( 'string',
serviceCharge4Show &&
typeof serviceCharge4Show === 'string'
? serviceCharge4Show.replace(/,/g, '')
: '',
); );
serviceCharge = x;
} }
" "
/> />

View file

@ -394,22 +394,30 @@ watch(
outlined outlined
input-class="text-right" input-class="text-right"
style="width: 90px" style="width: 90px"
debounce="500"
:model-value=" :model-value="
commaInput(props.row.discount.toString() || '0') discount4Show[props.rowIndex] ||
commaInput(props.row.discount?.toString() || '0')
"
@blur="
() => {
props.row.discount = Number(
discount4Show[props.rowIndex].replace(/,/g, ''),
);
if (props.row.discount % 1 === 0) {
const [, dec] =
discount4Show[props.rowIndex].split('.');
if (!dec) {
discount4Show[props.rowIndex] += '.00';
}
}
}
" "
@update:model-value=" @update:model-value="
(v) => { (v) => {
if (typeof v === 'string') discount4Show[props.rowIndex] = commaInput(
discount4Show[props.rowIndex] = commaInput(v); v?.toString() || '0',
const x = parseFloat( 'string',
discount4Show[props.rowIndex] &&
typeof discount4Show[props.rowIndex] === 'string'
? discount4Show[props.rowIndex].replace(/,/g, '')
: '',
); );
props.row.discount = x;
$emit('updateTable', props.row);
} }
" "
/> />

View file

@ -2,7 +2,7 @@
import { QTableProps } from 'quasar'; import { QTableProps } from 'quasar';
import { dateFormat } from 'src/utils/datetime'; import { dateFormat } from 'src/utils/datetime';
import { formatNumberDecimal, commaInput } from 'stores/utils'; import { formatNumberDecimal } from 'stores/utils';
import BadgeComponent from 'components/BadgeComponent.vue'; import BadgeComponent from 'components/BadgeComponent.vue';
import KebabAction from 'components/shared/KebabAction.vue'; import KebabAction from 'components/shared/KebabAction.vue';

View file

@ -1,7 +1,11 @@
<script setup lang="ts"> <script setup lang="ts">
import { QSelect } from 'quasar'; import { QSelect } from 'quasar';
import { onMounted, ref, watch, capitalize } from 'vue'; import { onMounted, ref, watch, capitalize } from 'vue';
import { selectFilterOptionRefMod, commaInput } from 'stores/utils'; import {
selectFilterOptionRefMod,
commaInput,
formatNumberWithCommas,
} from 'stores/utils';
import { calculateAge, disabledAfterToday } from 'src/utils/datetime'; import { calculateAge, disabledAfterToday } from 'src/utils/datetime';
import useOptionStore from 'src/stores/options'; import useOptionStore from 'src/stores/options';
@ -236,9 +240,21 @@ watch(
:label="$t('customer.form.authorizedCapital')" :label="$t('customer.form.authorizedCapital')"
for="input-authorized-capital" for="input-authorized-capital"
:model-value="authorizedCapital" :model-value="authorizedCapital"
@blur="
() => {
let val = authorizedCapital.replace(/[^0-9.]/g, '');
if (!val.includes('.')) val = val + '.00';
val = formatNumberWithCommas(val);
authorizedCapital = val;
}
"
@update:model-value=" @update:model-value="
(v) => { (v) => {
if (typeof v === 'string') if (
isNaN(Number(typeof v === 'string' ? v.replace(/,/g, '') : v))
) {
authorizedCapital = '0';
} else if (typeof v === 'string')
authorizedCapital = commaInput(v, 'string'); authorizedCapital = commaInput(v, 'string');
} }
" "

View file

@ -1,5 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { selectFilterOptionRefMod, commaInput } from 'stores/utils'; import {
selectFilterOptionRefMod,
commaInput,
formatNumberWithCommas,
} from 'stores/utils';
import { onMounted, watch } from 'vue'; import { onMounted, watch } from 'vue';
import { ref } from 'vue'; import { ref } from 'vue';
import { useI18n } from 'vue-i18n'; import { useI18n } from 'vue-i18n';
@ -19,7 +23,6 @@ const wageRateText = defineModel<string>('wageRateText', { default: '0' });
const rate = ref<string>(commaInput(wageRate.value?.toString() || '0')); const rate = ref<string>(commaInput(wageRate.value?.toString() || '0'));
const wageRate4Show = ref('');
const typeBusinessOption = ref([]); const typeBusinessOption = ref([]);
const typeBusinessENOption = ref([]); const typeBusinessENOption = ref([]);
const jobPositionOption = ref([]); const jobPositionOption = ref([]);
@ -314,12 +317,19 @@ let jobPositionENFilter = selectFilterOptionRefMod(
class="col-md-3 col-6" class="col-md-3 col-6"
:label="$t('customer.form.payRate')" :label="$t('customer.form.payRate')"
:model-value="rate?.toString()" :model-value="rate?.toString()"
@blur="
() => {
let val = rate.replace(/[^0-9.]/g, '');
if (!val.includes('.')) val = val + '.00';
val = formatNumberWithCommas(val);
rate = val;
}
"
@update:model-value=" @update:model-value="
(v) => { (v) => {
if (typeof v === 'string') { if (isNaN(Number(typeof v === 'string' ? v.replace(/,/g, '') : v))) {
console.log(v); rate = '0';
rate = commaInput(v, 'string'); } else if (typeof v === 'string') rate = commaInput(v, 'string');
}
} }
" "
/> />

View file

@ -461,6 +461,7 @@ export function commaInput(
const integerPart = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); const integerPart = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
const decimalPart = parts[1]?.slice(0, 2) || (type === 'number' && '00'); const decimalPart = parts[1]?.slice(0, 2) || (type === 'number' && '00');
if (integerPart === 'NaN') return '0';
return integerPart + (decimalPart ? `.${decimalPart}` : ''); return integerPart + (decimalPart ? `.${decimalPart}` : '');
} }
@ -491,6 +492,12 @@ export function calculateDaysUntilExpire(expireDate: Date): number {
return diffInDays; return diffInDays;
} }
export function formatNumberWithCommas(value: string) {
const [integer, decimal] = value.split('.');
const integerWithCommas = integer.replace(/\B(?=(\d{3})+(?!\d))/g, ',');
return decimal ? `${integerWithCommas}.${decimal}` : integerWithCommas;
}
export function createDataRefBase<T>( export function createDataRefBase<T>(
defaultPage = 1, defaultPage = 1,
defaultPageMax = 1, defaultPageMax = 1,