Skip to content

Commit ce43570

Browse files
committed
Fix for bug 691
1 parent aaa3c4c commit ce43570

File tree

3 files changed

+82
-16
lines changed

3 files changed

+82
-16
lines changed

example/src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class App extends React.Component {
2121
return (
2222
<div>
2323
<div className="example">
24+
<NumericFormat prefix='100-' suffix={"000 USD"} />
2425
<h3>Prefix and thousand separator : Format currency as text</h3>
2526
<NumericFormat value={2456981} displayType="text" thousandSeparator={true} prefix="$" />
2627
</div>

src/numeric_format.tsx

Lines changed: 51 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -136,24 +136,56 @@ export function removeFormatting<BaseType = InputAttributes>(
136136
value = value.substring(0, start) + separator + value.substring(start + 1, value.length);
137137
}
138138

139-
let hasNegation = false;
139+
const stripNegation = (value: string, start: number, end: number) => {
140+
/**
141+
* if prefix starts with - the number hast to have two - at the start
142+
* if suffix starts with - and the value length is same as suffix length, then the - sign is from the suffix
143+
* In other cases, if the value starts with - then it is a negation
144+
*/
145+
let hasNegation = false;
146+
let hasDoubleNegation = false;
147+
if (prefix.startsWith('-')) hasNegation = !value.startsWith('--');
148+
else if (value.startsWith('--')) {
149+
hasNegation = false;
150+
hasDoubleNegation = true;
151+
} else if (suffix.startsWith('-') && value.length === suffix.length) hasNegation = false;
152+
else if (value[0] === '-') hasNegation = true;
153+
154+
let charsToRemove = hasNegation ? 1 : 0;
155+
if (hasDoubleNegation) charsToRemove = 2;
156+
157+
// remove negation/double negation from start to simplify prefix logic as negation comes before prefix
158+
if (charsToRemove) {
159+
value = value.substring(charsToRemove);
160+
161+
// account for the removal of the negation for start and end index
162+
start -= charsToRemove;
163+
end -= charsToRemove;
164+
}
140165

141-
/**
142-
* if prefix starts with - the number hast to have two - at the start
143-
* if suffix starts with - and the value length is same as suffix length, then the - sign is from the suffix
144-
* In other cases, if the value starts with - then it is a negation
145-
*/
146-
if (prefix.startsWith('-')) hasNegation = value.startsWith('--');
147-
else if (suffix.startsWith('-') && value.length === suffix.length) hasNegation = false;
148-
else if (value[0] === '-') hasNegation = true;
166+
return { value, start, end, hasNegation };
167+
};
149168

150-
// remove negation from start to simplify prefix logic as negation comes before prefix
151-
if (hasNegation) {
152-
value = value.substring(1);
169+
const toMetadata = stripNegation(value, start, end);
170+
const { hasNegation } = toMetadata;
171+
({ value, start, end } = toMetadata);
153172

154-
// account for the removal of the negation for start and end index
155-
start -= 1;
156-
end -= 1;
173+
const {
174+
start: fromStart,
175+
end: fromEnd,
176+
value: lastValue,
177+
} = stripNegation(changeMeta.lastValue, from.start, from.end);
178+
179+
// if only prefix and suffix part is updated reset the value to last value
180+
// if the changed range is from suffix in the updated value, and the the suffix starts with the same characters, allow the change
181+
const updatedSuffixPart = value.substring(start, end);
182+
if (
183+
value.length &&
184+
lastValue.length &&
185+
(fromStart > lastValue.length - suffix.length || fromEnd < prefix.length) &&
186+
!(updatedSuffixPart && suffix.startsWith(updatedSuffixPart))
187+
) {
188+
value = lastValue;
157189
}
158190

159191
/**
@@ -167,7 +199,7 @@ export function removeFormatting<BaseType = InputAttributes>(
167199
else if (start < prefix.length) startIndex = start;
168200
value = value.substring(startIndex);
169201

170-
// account for deleted prefix for end index
202+
// account for deleted prefix for end
171203
end -= startIndex;
172204

173205
/**
@@ -180,6 +212,9 @@ export function removeFormatting<BaseType = InputAttributes>(
180212
const suffixStartIndex = value.length - suffix.length;
181213

182214
if (value.endsWith(suffix)) endIndex = suffixStartIndex;
215+
// if the suffix is removed from the end
216+
else if (end > suffixStartIndex) endIndex = end;
217+
// if the suffix is removed from start
183218
else if (end > value.length - suffix.length) endIndex = end;
184219

185220
value = value.substring(0, endIndex);

test/library/input_numeric_format.spec.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,36 @@ describe('Test NumberFormat as input with numeric format options', () => {
685685
expect(wrapper.find('input').prop('value')).toEqual('0.00000001');
686686
});
687687

688+
describe('should handle if only partial prefix or suffix is removed using double click select and the remove. #694', () => {
689+
it('while changing suffix', () => {
690+
const wrapper = mount(<NumericFormat prefix="100-" value={1} suffix="000 USD" />);
691+
692+
simulateKeyInput(wrapper.find('input'), '2', 9, 12);
693+
expect(wrapper.find('input').prop('value')).toEqual('100-1000 USD');
694+
});
695+
696+
it('while changing prefix', () => {
697+
const wrapper = mount(<NumericFormat prefix="100-" value={1} suffix="000 USD" />);
698+
699+
simulateKeyInput(wrapper.find('input'), '2', 0, 2);
700+
expect(wrapper.find('input').prop('value')).toEqual('100-1000 USD');
701+
});
702+
703+
it('while deleting suffix', () => {
704+
const wrapper = mount(<NumericFormat prefix="100-" value={1} suffix="000 USD" />);
705+
706+
simulateKeyInput(wrapper.find('input'), 'Backspace', 9, 12);
707+
expect(wrapper.find('input').prop('value')).toEqual('100-1000 USD');
708+
});
709+
710+
fit('while deleting prefix', () => {
711+
const wrapper = mount(<NumericFormat prefix="100-" value={1} suffix="000 USD" />);
712+
713+
simulateKeyInput(wrapper.find('input'), 'Backspace', 0, 3);
714+
expect(wrapper.find('input').prop('value')).toEqual('100-1000 USD');
715+
});
716+
});
717+
688718
describe('Test thousand group style', () => {
689719
it('should format on english style thousand grouping', () => {
690720
const wrapper = mount(<NumericFormat thousandSeparator={true} value={12345678} />);

0 commit comments

Comments
 (0)