Skip to content

Commit 5a79cfb

Browse files
mx-kshitijgjulivan
authored andcommitted
fix: user can now add page number manually
1 parent 9ead46d commit 5a79cfb

File tree

3 files changed

+88
-4
lines changed

3 files changed

+88
-4
lines changed

packages/pluggableWidgets/document-viewer-web/components/PDFViewer.tsx

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,73 @@ const PDFViewer: DocRendererElement = (props: DocumentRendererProps) => {
3535
const [numberOfPages, setNumberOfPages] = useState<number>(1);
3636
const { zoomLevel, zoomIn, zoomOut, reset } = useZoomScale();
3737
const [currentPage, setCurrentPage] = useState<number>(1);
38+
const [pageInputValue, setPageInputValue] = useState<string>("1");
3839
const [pdfUrl, setPdfUrl] = useState<string | null>(null);
3940

4041
const onDownloadClick = useCallback(() => {
4142
downloadFile(file.value?.uri);
4243
}, [file]);
4344

45+
const handlePageInputChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
46+
const value = event.target.value;
47+
// Allow only numbers and empty string
48+
if (value === "" || /^\d+$/.test(value)) {
49+
setPageInputValue(value);
50+
}
51+
}, []);
52+
53+
const validateAndSetPage = useCallback(() => {
54+
const pageNumber = parseInt(pageInputValue, 10);
55+
if (!isNaN(pageNumber) && pageNumber >= 1 && pageNumber <= numberOfPages) {
56+
setCurrentPage(pageNumber);
57+
} else {
58+
// Reset to current page if invalid input
59+
setPageInputValue(currentPage.toString());
60+
}
61+
}, [pageInputValue, numberOfPages, currentPage]);
62+
63+
const handlePageInputSubmit = useCallback(
64+
(event: React.FormEvent) => {
65+
event.preventDefault();
66+
validateAndSetPage();
67+
},
68+
[validateAndSetPage]
69+
);
70+
71+
const handlePageInputBlur = useCallback(() => {
72+
validateAndSetPage();
73+
}, [validateAndSetPage]);
74+
75+
const handlePageInputKeyDown = useCallback(
76+
(event: React.KeyboardEvent<HTMLInputElement>) => {
77+
if (event.key === "Enter") {
78+
event.preventDefault();
79+
validateAndSetPage();
80+
}
81+
// Prevent non-numeric characters except backspace, delete, arrow keys, etc.
82+
if (
83+
!/[\d]/.test(event.key) &&
84+
!["Backspace", "Delete", "ArrowLeft", "ArrowRight", "Home", "End", "Tab"].includes(event.key) &&
85+
!event.ctrlKey &&
86+
!event.metaKey
87+
) {
88+
event.preventDefault();
89+
}
90+
},
91+
[validateAndSetPage]
92+
);
93+
4494
useEffect(() => {
4595
if (file.status === "available" && file.value.uri) {
4696
setPdfUrl(file.value.uri);
4797
}
4898
}, [file, file.status, file.value?.uri]);
4999

100+
// Sync page input value with current page
101+
useEffect(() => {
102+
setPageInputValue(currentPage.toString());
103+
}, [currentPage]);
104+
50105
function onDocumentLoadSuccess({ numPages }: { numPages: number }): void {
51106
setNumberOfPages(numPages);
52107
}
@@ -69,11 +124,27 @@ const PDFViewer: DocRendererElement = (props: DocumentRendererProps) => {
69124
aria-label={"Go to previous page"}
70125
title={"Go to previous page"}
71126
></button>
72-
<span>
73-
{currentPage} / {numberOfPages}
74-
</span>
127+
<div className="widget-document-viewer-page-input">
128+
<form onSubmit={handlePageInputSubmit}>
129+
<input
130+
type="text"
131+
inputMode="numeric"
132+
pattern="[0-9]*"
133+
value={pageInputValue}
134+
onChange={handlePageInputChange}
135+
onKeyDown={handlePageInputKeyDown}
136+
onBlur={handlePageInputBlur}
137+
className="form-control widget-document-viewer-page-number-input"
138+
aria-label="Page number"
139+
title={`Go to page (1-${numberOfPages})`}
140+
placeholder={currentPage.toString()}
141+
/>
142+
</form>
143+
<span className="widget-document-viewer-total-pages">/ {numberOfPages}</span>
144+
</div>
75145
<button
76146
onClick={() => setCurrentPage(prev => Math.min(prev + 1, numberOfPages))}
147+
disabled={currentPage >= numberOfPages}
77148
className="icons icon-Right btn btn-icon-only"
78149
aria-label={"Go to next page"}
79150
title={"Go to next page"}

packages/pluggableWidgets/document-viewer-web/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@mendix/document-viewer-web",
33
"widgetName": "DocumentViewer",
4-
"version": "1.1.1",
4+
"version": "1.1.2",
55
"description": "View PDF and other document types",
66
"copyright": "© Mendix Technology BV 2025. All rights reserved.",
77
"license": "Apache-2.0",

packages/pluggableWidgets/document-viewer-web/ui/documentViewer.scss

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,3 +87,16 @@ div.widget-document-viewer {
8787
background-position: right;
8888
}
8989
}
90+
91+
.widget-document-viewer-page-input {
92+
display: flex;
93+
flex-direction: row;
94+
align-items: center;
95+
}
96+
97+
.widget-document-viewer-page-input .widget-document-viewer-page-number-input {
98+
padding: 3px 3px !important;
99+
text-align: center;
100+
margin-right: 5px;
101+
width: 5ch;
102+
}

0 commit comments

Comments
 (0)