Scrolling zooming in EJ2 TypeScript Document editor control

26 Nov 202324 minutes to read

The Document Editor renders the document as page by page. You can scroll through the pages by mouse wheel or touch interactions. You can also scroll through the page by using ‘scrollToPage()’ method of Document Editor instance. Refer to the following code example.

import { DocumentEditor } from '@syncfusion/ej2-documenteditor';

let documenteditor: DocumentEditor = new DocumentEditor({
    isReadOnly: false, height: '370px'
});
documenteditor.appendTo('#DocumentEditor');
//Open default document in DocumentEditor
onLoadDefault();
documenteditor.scrollToPage(2);

function onLoadDefault(): void {
    let defaultDocument: object = {
        "sections": [
            {
                "blocks": [
                    {
                        "paragraphFormat": {
                            "styleName": "Normal"
                        },
                        "inlines": [
                            {
                                "text": "First page"
                            }
                        ]
                    }
                ],
                "headersFooters": {},
            },
            {
                "blocks": [
                    {
                        "paragraphFormat": {
                            "styleName": "Normal"
                        },
                        "inlines": [
                            {
                                "text": "Second page"
                            }
                        ]
                    }
                ],
                "headersFooters": {},
            }
        ],
        "characterFormat": {},
        "paragraphFormat": {},
        "background": {
            "color": "#FFFFFFFF"
        },
        "styles": [
            {
                "type": "Paragraph",
                "name": "Normal",
                "next": "Normal"
            },
            {
                "type": "Character",
                "name": "Default Paragraph Font"
            }
        ]
    }
    documenteditor.open(JSON.stringify(defaultDocument));
    documenteditor.focusIn();
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-documenteditor/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-buttons/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-base/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-dropdowns/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-inputs/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-lists/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-navigations/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-popups/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-splitbuttons/styles/fabric.css" rel="stylesheet" /> 

    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='DocumentEditor'>
        </div>
        <div id='page-fit-type-div'></div>
    </div>
</body>

</html>

Calling this method brings the specified page into view but doesn’t move selection. Hence this method will work by default. That is, it works even if selection is not enabled.

In case, if you wish to move the selection to any page in Document Editor and bring it into view, you can use ‘goToPage()’ method of selection instance. Refer to the following code example.

import { DocumentEditor } from '@syncfusion/ej2-documenteditor';
//Initialize the Document Editor component.
let documenteditor: DocumentEditor = new DocumentEditor({
    isReadOnly: false, height: '370px', serviceUrl: 'https://services.syncfusion.com/js/production/api/documenteditor/'
});
documenteditor.enableAllModules();
documenteditor.appendTo('#DocumentEditor');
onLoadDefaultDocument();
documenteditor.viewer.selection.goToPage(3);

function onLoadDefaultDocument(): void {
    let defaultDocument: object = {
        "sections": [
            {
                "blocks": [
                    {
                        "paragraphFormat": {
                            "styleName": "Normal"
                        },
                        "inlines": [
                            {
                                "text": "First page"
                            }
                        ]
                    }
                ],
                "headersFooters": {},
            },
            {
                "blocks": [
                    {
                        "paragraphFormat": {
                            "styleName": "Normal"
                        },
                        "inlines": [
                            {
                                "text": "Second page"
                            }
                        ]
                    }
                ],
                "headersFooters": {},
            },
            {
                "blocks": [
                    {
                        "paragraphFormat": {
                            "styleName": "Normal"
                        },
                        "inlines": [
                            {
                                "text": "Third page"
                            }
                        ]
                    }
                ],
                "headersFooters": {},
            }
        ],
        "characterFormat": {},
        "paragraphFormat": {},
        "background": {
            "color": "#FFFFFFFF"
        },
        "styles": [
            {
                "type": "Paragraph",
                "name": "Normal",
                "next": "Normal"
            },
            {
                "type": "Character",
                "name": "Default Paragraph Font"
            }
        ]
    }
    documenteditor.open(JSON.stringify(defaultDocument));
    documenteditor.focusIn();
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-documenteditor/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-buttons/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-base/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-dropdowns/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-inputs/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-lists/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-navigations/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-popups/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-splitbuttons/styles/fabric.css" rel="stylesheet" /> 

    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='DocumentEditor'>
        </div>
        <div id='page-fit-type-div'></div>
    </div>
</body>

</html>

Zooming

You can scale the contents in Document Editor ranging from 10% to 500% of the actual size. You can achieve this using mouse or touch interactions. You can also use ‘zoomFactor’ property of Document Editor instance. The value can be specified in a range from 0.1 to 5. Refer to the following code example.

import { DocumentEditor } from '@syncfusion/ej2-documenteditor';

//Initialize the Document Editor module.
let documenteditor: DocumentEditor = new DocumentEditor({
    isReadOnly: false, serviceUrl: 'https://services.syncfusion.com/js/production/api/documenteditor/'
});

// Enable all the built in modules.
documenteditor.enableAllModules();

documenteditor.appendTo('#DocumentEditor');
//set zoom factor.
documenteditor.zoomFactor = 3;

Page Fit Type

Apart from specifying the zoom factor as value, the Document Editor provides option to specify page fit options such as fit to full page or fit to page width. You can set this option using ‘fitPage’ method of Document Editor instance. Refer to the following code example.

import { DocumentEditor } from '@syncfusion/ej2-documenteditor';
//Initialize the Document Editor module.
let documenteditor: DocumentEditor = new DocumentEditor({
    isReadOnly: false, serviceUrl: 'https://services.syncfusion.com/js/production/api/documenteditor/'
});

// Enable all the built in modules.
documenteditor.enableAllModules();

documenteditor.appendTo('#DocumentEditor');
//Set zoom factor to fit page width.
documenteditor.fitPage('FitPageWidth');

Zoom option using UI

The following code example shows how to provide zoom options in Document Editor.

import { DocumentEditor } from '@syncfusion/ej2-documenteditor';
import { createElement } from '@syncfusion/ej2-base';
import { DropDownButton, ItemModel, MenuEventArgs } from '@syncfusion/ej2-splitbuttons';

let documenteditor: DocumentEditor = new DocumentEditor({
    isReadOnly: false, height: '370px', serviceUrl: 'https://services.syncfusion.com/js/production/api/documenteditor/'
});
documenteditor.enableAllModules();

documenteditor.appendTo('#DocumentEditor');

let statusBarDiv = document.getElementById('page-fit-type-div');
let startPage: number = 1;
let label: HTMLElement = createElement('label', { styles: 'margin-top: 6px;margin-right: 2px' });
label.textContent = 'Page ';
statusBarDiv.appendChild(label);
let pageNumberLabel = createElement('label', { id: 'documenteditor_page_no', styles: 'text-transform:capitalize;white-space:pre;overflow:hidden;user-select:none;cursor:text;height:17px;max-width:150px' });
let editablePageNumber = createElement('div', { id: 'editablePageNumber', styles: 'border: 1px solid #F1F1F1;display: inline-flex;height: 17px;padding: 0px 4px;', className: 'single-line e-de-pagenumber-text' });
editablePageNumber.appendChild(pageNumberLabel);
updatePageNumber();
statusBarDiv.appendChild(editablePageNumber);
editablePageNumber.setAttribute('title', 'The current page number in the document. Click or tap to navigate specific page.');
let label1: HTMLElement = createElement('label', { id: 'documenteditor_pagecount', styles: 'margin-left:2px;letter-spacing: 1.05px;' });
label1.textContent = 'of';
statusBarDiv.appendChild(label1);
let pageCount = createElement('label', { id: 'documenteditor_pagecount', styles: 'margin-left:6px;letter-spacing: 1.05px;' });
updatePageCount();
statusBarDiv.appendChild(pageCount);
let editorPageCount = undefined;
let zoom: DropDownButton;
let zoomBtn: HTMLButtonElement = createElement('button', {
    id: 'documenteditor-zoom',
    // tslint:disable-next-line:max-line-length
    className: 'e-de-statusbar-zoom'
}) as HTMLButtonElement;
statusBarDiv.appendChild(zoomBtn);
zoomBtn.setAttribute('title', 'Zoom level. Click or tap to open the Zoom options.');

let items: ItemModel[] = [
    {
        text: '200%',
    },
    {
        text: '175%',
    },
    {
        text: '150%',
    },
    {
        text: '125%',
    },
    {
        text: '100%',
    },
    {
        text: '75%',
    },
    {
        text: '50%',
    },
    {
        text: '25%',
    },
    {
        separator: true
    },
    {
        text: 'Fit one page'
    },
    {
        text: 'Fit page width',
    },
];
zoom = new DropDownButton({ content: '100%', items: items, select: onZoom }, zoomBtn);
editablePageNumber.addEventListener('click', updateDocumentEditorPageNumber);
editablePageNumber.addEventListener('keydown', onKeyDown);
editablePageNumber.addEventListener('blur', onBlur);

//Update page number on `viewChange` event
documenteditor.viewChange = (e): void => {
    updatePageNumberOnViewChange(e);
};

//Update page count on `contentChange` event.
documenteditor.contentChange = (): void => {
    //Set page count
    updatePageCount();
};

function updatePageNumberOnViewChange(args) {
    if (documenteditor.selection
        && documenteditor.selection.startPage >= args.startPage && documenteditor.selection.startPage <= args.endPage) {
        startPage = documenteditor.selection.startPage;
    } else {
        startPage = args.startPage;
    }
    updatePageNumber();
}

function onBlur() {
    if (editablePageNumber.textContent === '' || parseInt(editablePageNumber.textContent, 0) > editorPageCount) {
        updatePageNumber();
    }
    editablePageNumber.contentEditable = 'false';
}

function onKeyDown(e) {
    if (e.which === 13) {
        e.preventDefault();
        let pageNumber: number = parseInt(editablePageNumber.textContent, 0);
        if (pageNumber > editorPageCount) {
            updatePageNumber();
        } else {
            if (documenteditor.selection) {
                documenteditor.selection.goToPage(parseInt(editablePageNumber.textContent, 0));
            } else {
                documenteditor.scrollToPage(parseInt(editablePageNumber.textContent, 0));
            }
        }
        editablePageNumber.contentEditable = 'false';
        if (editablePageNumber.textContent === '') {
            updatePageNumber();
        }
    }
    if (e.which > 64) {
        e.preventDefault();
    }
}

//Update zoom factor.
function onZoom(args) {
    setZoomValue(args.item.text);
    updateZoomContent();
}
function setZoomValue(text) {
    if (text.match('Fit one page')) {
        documenteditor.fitPage('FitOnePage');
    } else if (text.match('Fit page width')) {
        documenteditor.fitPage('FitPageWidth');
    } else {
        documenteditor.zoomFactor = parseInt(text, 0) / 100;
    }
}
function updateZoomContent() {
    zoom.content = Math.round(documenteditor.zoomFactor * 100) + '%';
}
function updatePageNumber() {
    pageNumberLabel.textContent = startPage.toString();
}
function updatePageCount() {
    editorPageCount = documenteditor.pageCount;
    pageCount.textContent = editorPageCount.toString();
}
function updateDocumentEditorPageNumber() {
    let editablePageNumber = document.getElementById('editablePageNumber');
    editablePageNumber.contentEditable = 'true';
    editablePageNumber.focus();
    window.getSelection().selectAllChildren(editablePageNumber);
}
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-documenteditor/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-buttons/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-base/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-dropdowns/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-inputs/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-lists/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-navigations/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-popups/styles/fabric.css" rel="stylesheet" />
    <link href="https://cdn.syncfusion.com/ej2/25.1.35/ej2-splitbuttons/styles/fabric.css" rel="stylesheet" /> 

    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='DocumentEditor'>
        </div>
        <div id='page-fit-type-div'></div>
    </div>
</body>

</html>