diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f23ac98c..48f608a06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,27 @@ # Changelog +## [2.0.8](https://github.com/primefaces/primevue/tree/2.0.8) (2020-08-27) + +[Full Changelog](https://github.com/primefaces/primevue/compare/2.0.7...2.0.8) + +**Implemented New Features and Enhancements:** + +- Add Del key support to InputNumber [\#452](https://github.com/primefaces/primevue/issues/452) +- Documentation for primeflex setup [\#434](https://github.com/primefaces/primevue/issues/434) +- InputNumber with decimals should support entering comma/decimal point [\#432](https://github.com/primefaces/primevue/issues/432) +- dismissableMask and closeOnEscape for Dialog [\#372](https://github.com/primefaces/primevue/issues/372) + +**Fixed bugs:** + +- Can't type - as first symbol into an Inputnumber [\#453](https://github.com/primefaces/primevue/issues/453) +- When autocomplete is bound to an object, float label overlaps in some circumstances [\#450](https://github.com/primefaces/primevue/issues/450) +- TreeTable template always render field value [\#445](https://github.com/primefaces/primevue/issues/445) +- Setting placeholder text for Editor / Quill component doesn't work [\#433](https://github.com/primefaces/primevue/issues/433) +- InputNumber with stacked Buttons is broken [\#431](https://github.com/primefaces/primevue/issues/431) +- Doc error on InputNumber [\#430](https://github.com/primefaces/primevue/issues/430) +- InputNumber throws error if emptied [\#429](https://github.com/primefaces/primevue/issues/429) +- Pill Text not centered [\#428](https://github.com/primefaces/primevue/issues/428) + ## [2.0.7](https://github.com/primefaces/primevue/tree/2.0.7) (2020-08-05) [Full Changelog](https://github.com/primefaces/primevue/compare/2.0.6...2.0.7) diff --git a/src/components/inputnumber/InputNumber.vue b/src/components/inputnumber/InputNumber.vue index abe0e649e..99482eb5d 100755 --- a/src/components/inputnumber/InputNumber.vue +++ b/src/components/inputnumber/InputNumber.vue @@ -111,6 +111,7 @@ export default { _suffix: null, _prefix: null, _index: null, + groupChar: '', isSpecialChar: null, timer: null, data() { @@ -118,18 +119,40 @@ export default { focused: false } }, + watch: { + locale(newValue, oldValue) { + this.updateConstructParser(newValue, oldValue); + }, + localeMatcher(newValue, oldValue) { + this.updateConstructParser(newValue, oldValue); + }, + mode(newValue, oldValue) { + this.updateConstructParser(newValue, oldValue); + }, + currency(newValue, oldValue) { + this.updateConstructParser(newValue, oldValue); + }, + currencyDisplay(newValue, oldValue) { + this.updateConstructParser(newValue, oldValue); + }, + useGrouping(newValue, oldValue) { + this.updateConstructParser(newValue, oldValue); + }, + minFractionDigits(newValue, oldValue) { + this.updateConstructParser(newValue, oldValue); + }, + maxFractionDigits(newValue, oldValue) { + this.updateConstructParser(newValue, oldValue); + }, + suffix(newValue, oldValue) { + this.updateConstructParser(newValue, oldValue); + }, + prefix(newValue, oldValue) { + this.updateConstructParser(newValue, oldValue); + } + }, created() { - this.numberFormat = new Intl.NumberFormat(this.locale, this.getOptions()); - const numerals = [...new Intl.NumberFormat(this.locale, {useGrouping: false}).format(9876543210)].reverse(); - const index = new Map(numerals.map((d, i) => [d, i])); - this._numeral = new RegExp(`[${numerals.join('')}]`, 'g'); - this._decimal = this.getDecimalExpression(); - this._group = this.getGroupingExpression(); - this._minusSign = this.getMinusSignExpression(); - this._currency = this.getCurrencyExpression(); - this._suffix = new RegExp(`[${this.suffix||''}]`, 'g'); - this._prefix = new RegExp(`[${this.prefix||''}]`, 'g'); - this._index = d => index.get(d); + this.constructParser(); }, methods: { getOptions() { @@ -143,13 +166,32 @@ export default { maximumFractionDigits: this.maxFractionDigits }; }, + constructParser() { + this.numberFormat = new Intl.NumberFormat(this.locale, this.getOptions()); + const numerals = [...new Intl.NumberFormat(this.locale, {useGrouping: false}).format(9876543210)].reverse(); + const index = new Map(numerals.map((d, i) => [d, i])); + this._numeral = new RegExp(`[${numerals.join('')}]`, 'g'); + this._decimal = this.getDecimalExpression(); + this._group = this.getGroupingExpression(); + this._minusSign = this.getMinusSignExpression(); + this._currency = this.getCurrencyExpression(); + this._suffix = new RegExp(`[${this.suffix||''}]`, 'g'); + this._prefix = new RegExp(`[${this.prefix||''}]`, 'g'); + this._index = d => index.get(d); + }, + updateConstructParser(newValue, oldValue) { + if (newValue !== oldValue) { + this.constructParser(); + } + }, getDecimalExpression() { const formatter = new Intl.NumberFormat(this.locale, {useGrouping: false}); return new RegExp(`[${formatter.format(1.1).trim().replace(this._numeral, '')}]`, 'g'); }, getGroupingExpression() { const formatter = new Intl.NumberFormat(this.locale, {useGrouping: true}); - return new RegExp(`[${formatter.format(1000).trim().replace(this._numeral, '')}]`, 'g'); + this.groupChar = formatter.format(1000000).trim().replace(this._numeral, ''); + return new RegExp(`[${this.groupChar}]`, 'g'); }, getMinusSignExpression() { const formatter = new Intl.NumberFormat(this.locale, {useGrouping: false}); @@ -224,7 +266,7 @@ export default { let currentValue = this.parseValue(this.$refs.input.$el.value) || 0; let newValue = this.validateValue(currentValue + step); - this.updateInput(newValue, 'spin'); + this.updateInput(newValue, null, 'spin'); this.updateModel(event, newValue); }, onUpButtonMouseDown(event) { @@ -344,11 +386,11 @@ export default { } } - this.updateValue(event, newValueStr, 'delete-single'); + this.updateValue(event, newValueStr, null, 'delete-single'); } else { newValueStr = this.deleteRange(inputValue, selectionStart, selectionEnd); - this.updateValue(event, newValueStr, 'delete-range'); + this.updateValue(event, newValueStr, null, 'delete-range'); } break; @@ -384,11 +426,11 @@ export default { } } - this.updateValue(event, newValueStr, 'delete-back-single'); + this.updateValue(event, newValueStr, null, 'delete-back-single'); } else { newValueStr = this.deleteRange(inputValue, selectionStart, selectionEnd); - this.updateValue(event, newValueStr, 'delete-range'); + this.updateValue(event, newValueStr, null, 'delete-range'); } break; @@ -401,9 +443,10 @@ export default { let code = event.which || event.keyCode; let char = String.fromCharCode(code); const isDecimalSign = this.isDecimalSign(char); + const isMinusSign = this.isMinusSign(char); - if ((48 <= code && code <= 57) || this.isMinusSign(char) || isDecimalSign) { - this.insert(event, char, isDecimalSign); + if ((48 <= code && code <= 57) || isMinusSign || isDecimalSign) { + this.insert(event, char, { isDecimalSign, isMinusSign }); } }, onPaste(event) { @@ -432,21 +475,33 @@ export default { return false; }, - insert(event, text, isDecimalSign = false) { + insert(event, text, sign = { isDecimalSign: false, isMinusSign: false }) { let selectionStart = this.$refs.input.$el.selectionStart; let selectionEnd = this.$refs.input.$el.selectionEnd; let inputValue = this.$refs.input.$el.value.trim(); const decimalCharIndex = inputValue.search(this._decimal); this._decimal.lastIndex = 0; + const minusCharIndex = inputValue.search(this._minusSign); + this._minusSign.lastIndex = 0; let newValueStr; - if (isDecimalSign) { + if (sign.isMinusSign) { + if (selectionStart === 0) { + newValueStr = inputValue; + if (minusCharIndex === -1 || selectionEnd !== 0) { + newValueStr = this.insertText(inputValue, text, 0, selectionEnd); + } + + this.updateValue(event, newValueStr, text, 'insert'); + } + } + else if (sign.isDecimalSign) { if (decimalCharIndex > 0 && selectionStart === decimalCharIndex) { - this.updateValue(event, inputValue, 'insert'); + this.updateValue(event, inputValue, text, 'insert'); } else if (decimalCharIndex > selectionStart && decimalCharIndex < selectionEnd) { newValueStr = this.insertText(inputValue, text, selectionStart, selectionEnd); - this.updateValue(event, newValueStr, 'insert'); + this.updateValue(event, newValueStr, text, 'insert'); } } else { @@ -455,13 +510,13 @@ export default { if (decimalCharIndex > 0 && selectionStart > decimalCharIndex) { if ((selectionStart + text.length - (decimalCharIndex + 1)) <= maxFractionDigits) { newValueStr = inputValue.slice(0, selectionStart) + text + inputValue.slice(selectionStart + text.length); - this.updateValue(event, newValueStr, 'insert'); + this.updateValue(event, newValueStr, text, 'insert'); } } else { newValueStr = this.insertText(inputValue, text, selectionStart, selectionEnd); const operation = selectionStart !== selectionEnd ? 'range-insert' : 'insert'; - this.updateValue(event, newValueStr, operation); + this.updateValue(event, newValueStr, text, operation); } } }, @@ -555,10 +610,10 @@ export default { this._group.lastIndex = 0; this._minusSign.lastIndex = 0; }, - updateValue(event, valueStr, operation) { + updateValue(event, valueStr, insertedValueStr, operation) { if (valueStr != null) { let newValue = this.parseValue(valueStr); - this.updateInput(newValue, operation); + this.updateInput(newValue, insertedValueStr, operation); } }, validateValue(value) { @@ -570,9 +625,13 @@ export default { return this.max; } + if (value === '-') { // Minus sign + return null; + } + return value; }, - updateInput(value, operation) { + updateInput(value, insertedValueStr, operation) { let inputValue = this.$refs.input.$el.value; let newValue = this.formatValue(value); let currentLength = inputValue.length; @@ -584,26 +643,36 @@ export default { this.$refs.input.$el.setSelectionRange(this.$refs.input.$el.selectionStart + 1, this.$refs.input.$el.selectionStart + 1); } else { - let selectionStart = this.$refs.input.$el.selectionEnd; + let selectionStart = this.$refs.input.$el.selectionStart; let selectionEnd = this.$refs.input.$el.selectionEnd; this.$refs.input.$el.value = newValue; let newLength = newValue.length; - if (newLength === currentLength) { + if (operation === 'range-insert') { + const startValue = this.parseValue((inputValue || '').slice(0, selectionStart)); + const startValueStr = startValue !== null ? startValue.toString() : ''; + const startExpr = startValueStr.split('').join(`(${this.groupChar})?`); + const sRegex = new RegExp(startExpr, 'g'); + sRegex.test(newValue); + + const tExpr = insertedValueStr.split('').join(`(${this.groupChar})?`); + const tRegex = new RegExp(tExpr, 'g'); + tRegex.test(newValue.slice(sRegex.lastIndex)); + + selectionEnd = sRegex.lastIndex + tRegex.lastIndex; + this.$refs.input.$el.setSelectionRange(selectionEnd, selectionEnd); + } + else if (newLength === currentLength) { if (operation === 'insert' || operation === 'delete-back-single') this.$refs.input.$el.setSelectionRange(selectionEnd + 1, selectionEnd + 1); - else if (operation === 'range-insert') - this.$refs.input.$el.setSelectionRange(selectionEnd, selectionEnd); else if (operation === 'delete-single') this.$refs.input.$el.setSelectionRange(selectionEnd - 1, selectionEnd - 1); - else if (operation === 'delete-range') - this.$refs.input.$el.setSelectionRange(selectionStart, selectionStart); - else if (operation === 'spin') - this.$refs.input.$el.setSelectionRange(selectionStart, selectionEnd); + else if (operation === 'delete-range' || operation === 'spin') + this.$refs.input.$el.setSelectionRange(selectionEnd, selectionEnd); } else if (operation === 'delete-back-single') { - let prevChar = inputValue.charAt(selectionStart - 1); - let nextChar = inputValue.charAt(selectionStart); + let prevChar = inputValue.charAt(selectionEnd - 1); + let nextChar = inputValue.charAt(selectionEnd); let diff = currentLength - newLength; let isGroupChar = this._group.test(nextChar);