Skip to content

Commit 1488d2a

Browse files
fix: restrict input to numeric characters only in QuickJumper and simple mode
1 parent 7ffdf47 commit 1488d2a

File tree

3 files changed

+114
-2
lines changed

3 files changed

+114
-2
lines changed

src/Options.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,16 @@ const Options: React.FC<OptionsProps> = (props) => {
6060
: (value: string | number) => `${value} ${locale.items_per_page}`;
6161

6262
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
63-
setGoInputText(e.target.value);
63+
let value = e.target.value;
64+
65+
// Filter non-numeric characters for QuickJumper input
66+
const numericValue = value.replace(/\D/g, '');
67+
if (numericValue !== value) {
68+
e.target.value = numericValue;
69+
value = numericValue;
70+
}
71+
72+
setGoInputText(value);
6473
};
6574

6675
const handleBlur = (e: React.FocusEvent<HTMLInputElement, Element>) => {

src/Pagination.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ const Pagination: React.FC<PaginationProps> = (props) => {
145145
return value;
146146
}
147147

148+
function getValidValueForFiltered(
149+
originalValue: string,
150+
filteredValue: string,
151+
): number {
152+
// If the input was completely filtered out (non-numeric), return current value
153+
if (filteredValue === '' && originalValue !== '') {
154+
return internalInputVal;
155+
}
156+
return getValidValue({ target: { value: filteredValue } });
157+
}
158+
148159
function isValid(page: number) {
149160
return isInteger(page) && page !== current && isInteger(total) && total > 0;
150161
}
@@ -166,7 +177,16 @@ const Pagination: React.FC<PaginationProps> = (props) => {
166177
| React.KeyboardEvent<HTMLInputElement>
167178
| React.ChangeEvent<HTMLInputElement>,
168179
) {
169-
const value = getValidValue(event);
180+
const inputElement = event.target as HTMLInputElement;
181+
const originalValue = inputElement.value;
182+
183+
// Filter non-numeric characters for simple mode input
184+
const numericValue = originalValue.replace(/\D/g, '');
185+
if (numericValue !== originalValue) {
186+
inputElement.value = numericValue;
187+
}
188+
189+
const value = getValidValueForFiltered(originalValue, numericValue);
170190
if (value !== internalInputVal) {
171191
setInternalInputVal(value);
172192
}

tests/jumper.test.tsx

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,4 +270,87 @@ describe('simple quick jumper', () => {
270270
),
271271
).toBeFalsy();
272272
});
273+
274+
// https://github.com/ant-design/ant-design/issues/55637
275+
describe('QuickJumper should only accept numeric input', () => {
276+
it('should filter non-numeric characters in QuickJumper input', () => {
277+
const { container } = render(<Pagination total={100} showQuickJumper />);
278+
279+
const input = container.querySelector(
280+
'.rc-pagination-options-quick-jumper input',
281+
) as HTMLInputElement;
282+
283+
// Test typing letters with numbers
284+
fireEvent.change(input, { target: { value: 'abc123def' } });
285+
expect(input.value).toBe('123');
286+
287+
// Test decimal point (should be filtered)
288+
fireEvent.change(input, { target: { value: '12.34' } });
289+
expect(input.value).toBe('1234');
290+
291+
// Test only letters
292+
fireEvent.change(input, { target: { value: 'test' } });
293+
expect(input.value).toBe('');
294+
295+
// Test special characters
296+
fireEvent.change(input, { target: { value: '!@#$%' } });
297+
expect(input.value).toBe('');
298+
});
299+
300+
it('should filter non-numeric characters in simple mode', () => {
301+
const { container } = render(<Pagination simple total={100} />);
302+
303+
const input = container.querySelector(
304+
'.rc-pagination-simple-pager input',
305+
) as HTMLInputElement;
306+
307+
// Test typing letters with numbers
308+
fireEvent.change(input, { target: { value: 'test5page' } });
309+
expect(input.value).toBe('5');
310+
311+
// Test special characters with numbers
312+
fireEvent.change(input, { target: { value: '3@#' } });
313+
expect(input.value).toBe('3');
314+
});
315+
316+
it('should handle paste with non-numeric content', () => {
317+
const { container } = render(<Pagination total={100} showQuickJumper />);
318+
319+
const input = container.querySelector(
320+
'.rc-pagination-options-quick-jumper input',
321+
) as HTMLInputElement;
322+
323+
// Simulate paste with mixed content
324+
fireEvent.change(input, { target: { value: 'page 42!' } });
325+
expect(input.value).toBe('42');
326+
327+
// Simulate paste with only text
328+
fireEvent.change(input, { target: { value: 'goto page' } });
329+
expect(input.value).toBe('');
330+
});
331+
332+
it('should work correctly with Enter key after filtering', () => {
333+
const onChangeFn = jest.fn();
334+
const { container } = render(
335+
<Pagination
336+
onChange={onChangeFn}
337+
defaultCurrent={1}
338+
total={100}
339+
showQuickJumper
340+
/>,
341+
);
342+
343+
const input = container.querySelector(
344+
'.rc-pagination-options-quick-jumper input',
345+
) as HTMLInputElement;
346+
347+
// Type numeric value with letters
348+
fireEvent.change(input, { target: { value: 'abc5xyz' } });
349+
expect(input.value).toBe('5');
350+
351+
// Press enter
352+
fireEvent.keyUp(input, { key: 'Enter', keyCode: 13, which: 13 });
353+
expect(onChangeFn).toHaveBeenCalledWith(5, 10);
354+
});
355+
});
273356
});

0 commit comments

Comments
 (0)