Tutorial: Demo Application Typescript

Demo Application Typescript

Starting with DotImage 11.2 Web Document Viewer supports a module loaders. It can be used as an Asynchronous Module Definition (AMD) or the CommonJS module. You can read more about this functionality in the previous tutorial Setup dependencies.

Since version 11.2.0.2 Web Document Viewer has a TypeScript declaration file in the package contents. These new features allows using of Web Document Viewer in TypeScript projects, such as Angular.

In this topic, we will provide two examples of using the Atalasoft Web Document Viewer in the TypeScript projects. In the first sample, we describe the creation of an ASP.NET Core 2.1 application, in which TypeScript file will be used to manage the Web Document Viewer and Web Document Thumbnailer controls. Then the client-side of application will be compiled using webpack package. This sample is quite similar to the described in Setup dependencies, we outline some things, which are specific for using the TypeScript. The second part of the article will tell you how to create an ASP.NET Core application using Angular for building a client part of the project. The projects created as a result of this tutorial do not claim to be full-fledged applications and it is not supposed to give you the solutions that are ready to deploy. Once you have succeeded in building the example projects, you can begin modifying it to fit your organization.

Simple TypeScript application

In this sample, we will use the webpack package to build the client part of the application.

Set up a project and configure a server-side

The server-side configuration in this case is the same as it is described in the Demo Application (ASP.NET Core). So to configure it, you should repeat the following steps from this tutorial:

  1. Create a new empty ASP.NET Core Web Application (.NET Framework) in Visual Studio.
  2. Add NuGet packages for server-side.
  3. Prepare Startup class.
  4. Add the necessary decoders to Program.cs file.
  5. If it is necessary, tune-up the application by adding the Response caching, Response compression or CORS support

Client-side configuration

Install npm packages

The first step in the client-side configuration is to install the necessary npm packages, include webpack, TypeScript, Atalasoft Web Document Viewer and some auxiliary packages. To do that create a package.json from npm Configuration file template in the root folder of the Visual Studio project and change it to look like this:

{
  "name": "atalasoft-typescript-tutorial",
  "version": "1.0.0",
  "description": "Demo application",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "Atalasoft",
  "devDependencies": {
    "@types/jquery": "^3.5.1",
    "@types/webpack-env": "^1.15.2",
    "css-loader": "^2.1.1",
    "mini-css-extract-plugin": "^0.5.0",
    "style-loader": "^0.23.1",
    "ts-loader": "^8.0.1",
    "typescript": "^3.9.7",
    "url-loader": "^1.1.2",
    "web-document-viewer": "^11.4.0",
    "webpack": "^4.44.1",
    "webpack-cli": "^3.3.12"
  }
}

After you save this file, all specified npm packages will be loaded and installed by Visual Studio. Some packages are familiar to you from Setup dependencies tutorial, some are specific for TypeScript:

  • typescript - TypeScript compiler.
  • ts-loader - TypeScript loader for webpack.
  • @types/jquery and @types/webpack-env - declaration packages for jquery and webpack modules. They represent a mechanism for supplying the type's information from JavaScript written modules for TypeScript.

TypeScript configuration

The next step is to configure the TypeScript part of the project. Create the new folder Scripts in the root of the Visual Studio project and add the new file tsconfig.json to it using the TypeScript JSON Configuration File template. This file will contain the settings for the TypeScript compiler. Let's set up a simple configuration for our project:

{
  "compilerOptions": {
    "outDir": "./dist/",
    "noImplicitAny": false,
    "noEmitOnError": true,
    "removeComments": false,
    "sourceMap": true,
    "module": "CommonJS",
    "target": "es5",
    "types": [
      "webpack-env"
    ]
  },
  "exclude": [
    "node_modules",
    "wwwroot"
  ]
}

Note See TypeScript's documentation to learn more about tsconfig.json configuration options.

Create the new file app.ts in the Scripts folder using the TypeScript File template. In this file we will determine the behavior of the web viewing control: initialization, connection settings to the right middleware, events handling, and so forth. Add the following TypeScript code to this file:

import * as Atalasoft from "web-document-viewer";
import * as jQuery from "jquery";

require('web-document-viewer/atalaWebDocumentViewer.css');
require('jquery-ui-dist/jquery-ui.css');

let maxUploadSizeMb = 1;
let handler = 'wdv';
let viewer = new Atalasoft.Controls.WebDocumentViewer({
    parent: jQuery('#viewer'),
    toolbarparent: jQuery('.atala-document-toolbar'),
    allowforms: true,
    allowannotations: true,
    allowtext: true,
    savepath: 'saved',
    serverurl: handler,
    direction: Atalasoft.Utils.ScrollDirection.Vertical,
    upload: {
        enabled: true,
        uploadpath: 'uploaded',
        allowedfiletypes: '.jpg,.pdf,.png,.jpeg,image/tiff',
        allowedmaxfilesize: maxUploadSizeMb * 1024 * 1024,
        allowmultiplefiles: true,
        allowdragdrop: true,
        filesuploadconcurrency: 2
    },
});

let thumb = new Atalasoft.Controls.WebDocumentThumbnailer({
    parent: jQuery('#thumb'),
    serverurl: handler,
    maxwidth: 240,
    minwidth: 60,
    viewer: viewer,
    allowannotations: true,
    allowforms: true,
    showthumbcaption: true,
    thumbcaptionformat: 'p. {0}',
    documenturl: 'images/sample.pdf'
});

In this code the first two lines import web-document-viewer and jquery as the UMD modules to the TypeScript application. The next two lines are needed to give webpack a signal to search the CSS files in web-document-viewer and jquery modules and add them to the CSS file which will be bundled by webpack.

Note The option tags 'value' property points to real files in 'wwwroot/images' folder. Thus, you need to create this folder and to add manually files with the same names to this folder.

Webpack configuration

Now let's configure webpack to handle TypeScript. For this, we create a configuration file for webpack and place it in the project root.

webpack.config.js

const path = require('path');
var extractCss = require('mini-css-extract-plugin');

module.exports = {
    entry: './Scripts/app.ts',
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: 'ts-loader',
                exclude: /node_modules/
            },
            {
                test: /\.css$/,
                loader: [extractCss.loader, 'css-loader']
            },
            {
                test: /\.(png|gif)$/,
                loader: 'url-loader'
            }
        ],
    },
    resolve: {
        extensions: ['.tsx', '.ts', '.js'],
        alias: {
            'jquery-ui': 'jquery-ui-dist/jquery-ui',
            'webDocumentViewer': 'web-document-viewer/atalaWebDocumentViewer',
            'jquery': 'jquery/dist/jquery',
            'raphael': 'raphael/raphael',
            'clipboard': 'clipboard/dist/clipboard'
        }
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'wwwroot/scripts')
    },
    plugins: [
        new extractCss({filename: 'bundle.css'})
    ],
    optimization: {
        minimize: false,
    },
    devtool: 'inline-source-map'
};

This will direct webpack to enter through ./Scripts/app.ts, load all .ts and .tsx files through the ts-loader, and output a bundle.js file in wwwroot/scripts directory. Also, webpack should find the used CSS files, combine and output a bundle.css to the same output directory.

Setup UI

We just need to add the UI to the application. Create index.html file in the wwwroot folder using HTML Page template and modify it in the following way:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Type Script Sample</title>
    <script src="scripts/bundle.js" defer="defer"></script>

    <link href="scripts/bundle.css" rel="stylesheet" />
</head>
<body>
<h1>Web Document Viewer Demo</h1>
    <div style="width: 900px;">
            <div class="atala-document-toolbar"></div>
            <div id="thumb" class="atala-document-thumbnailer" style="width: 180px; height: 600px; display: inline-block;"></div>
            <div id="viewer" class="atala-document-container" style="width: 710px; height: 600px; display: inline-block;"></div>
    </div>
</body>
</html>

Build project and run

To build the client-side scripts, open the command line, navigate to the project root folder and run the command npx webpack. As a result of the operation, the files ./wwwroot/scripts/bundle.js and ./wwwroot/scripts/bundle.css will be created. These files will contain all scripts and styles necessary for our application. Press F5 in Visual Studio to launch the entire application.

Angular application

In this sample we will build a client-side of application using the Angular framework.

Configure Server-side

As in the previous example, let's start from creating the new empty ASP.NET Core Web Application (.NET Framework) in Visual Studio.

Add NuGet packages for server-side

Then add the Atalasoft.dotImage.WebControls.Core.x86 NuGet package. If you plan to run your application on a 64-bit server, you should use the package Atalasoft.dotImage.WebControls.Core.x64.

By default, the new ASP.NET Core does not have any support for working with Angular. To integrate Angular into ASP.NET Core project we need to install Microsoft.AspNetCore.SpaServices.Extensions Nuget package.

Configure Program.cs file

As usually, add a PdfDecoder for rendering PDF files by writing the next line of code at the beginning of Program.Main method in Program.cs file:

RegisteredDecoders.Decoders.Add(new PdfDecoder());

Configure Startup.cs file

At first, add the call for method AddSpaStaticFiles() to the ConfigureServices() method:

services.AddSpaStaticFiles(configuration =>
{
    configuration.RootPath = "wdv-app/dist";
});

This service allows to work with the static files of the Angular application. The parameter configuration.RootPath defines the location of these files. Later we will configure the Angular application to place his compiled javascript files to this directory.

Then, change the code of Configure() method on the following:

public void Configure(IApplicationBuilder app, IWebHostEnviornment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            if (!env.IsDevelopment())
            {
                app.UseSpaStaticFiles();
            }

            app.Map("/wdv", wdvApp => { wdvApp.RunWebDocumentViewerMiddleware(); });

            app.UseSpa(spa =>
            {
                spa.Options.SourcePath = "wdv-app";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
        }

If development is complete and the application is already being deployed, the method app.UseSpaStaticFiles() is called. This method redirects the requests to the Angular application. The method app.UseSpa() allows to send a default web page index.html in response to requests. This method should be the last in the pipe. If the app is in development mode, ASP .NET Core application will start Angular CLI server by the spa.UseAngularCliServer(npmScript: "start") method. As a parameter, the method accepts the command from package.json file. We will configure this command later, when we will configure Angular CLI server.

That is all with server part of our application

Configure client-side

The client part of our application will be built by Angular. At first, we need to install Angular CLI globally, so open the command prompt and run this command (node.js should be installed):

npm install -g @angular/cli

Create Angular application skeleton

The next step is to create the new Angular project. First, in a command prompt navigate to the project folder and run the following command:

ng new wdv-app

The Angular CLI will ask some questions: choose the default answers. The all necessary Angular npm packages and other dependencies will be installed and an initial skeleton of application will be created in the wdv-app subfolder. This can take a few minutes.

Note As it was mentioned in the section which is devoted to server-side configuration, ASP.NET Core application will look for the necessaryAngular files in the wdv-app folder and it subfolders. So it is important to give to the new Angular application the same name as we used at in the server-side configuration.

Install Web Document Viewer package

To install Web Document Viewer package the npm can be used.

npm install web-document-viewer

Note You should navigate to wdv-app folder before this command execution.

Configure Angular components

In Angular world the common practice to split application to small components, each focused on a specific task or workflow. It helps to keep application to be maintainable as it grows. The application already has one component, which is called main component. Let's create a separate component for Web Document Viewer. To do this navigate to the wdv-app folder, which was created by ng new command and run the following command in the terminal:

ng generate component doc-viewer

Note See Angular documentation to learn more about the components.

Main component

Now, when all necessary packages for client path are installed, we can configure our application. At first, remove all from file wdv-app\src\app\app.component.html and when add the following code:

<app-doc-viewer style="width: 100%; height: 600px;"></app-doc-viewer>

This code set the boundaries of doc-viewer component inside the main component.

In the file wdv-app\src\app\app.component.ts replace the generated title to Web Document Viewer Demo. That's all with main configuration, let's move on to doc-viewer component configuration.

Add UI

Replace the contents of doc-viewer.component.html by the following code:

<h1>Web Document Viewer Demo</h1>
<form id="WDVForm" runat="server">
    <div id="mainContainer" >
        <div id="thumbContainer">
            <h4>Select File to display:</h4>
            <select (change)="changeFile($event.target.value)">
                <option *ngFor="let file of files" [value] = "file.source">{{ file.name }}</option>
            </select>
            <div id="thumbLeft" class="atala-document-thumbnailer"></div>
        </div>
        <div>
            <div class="atala-document-toolbar"></div>
            <div class="atala-document-container" id="viewer"></div>
        </div>
    </div>
</form>

Also add the following lines to the file doc-viewer.component.css to add the necessary styles for Web Document Viewer:

div#mainContainer {
    display: flex;
    flex-direction:row;
    justify-content: flex-start;
}

div#thumbContainer {
    display: flex;
    flex-direction: column;
}

.atala-document-thumbnailer{
    width: 240px;
    height: 700px;
    float: left;
}

.atala-document-toolbar{
    width: 800px;
}

.atala-document-container{
    width: 800px;
    height: 600px;
}

Configure the control

The configuration of web viewing control can be done with block of TypeScript code which should be placed to doc-viewer.component.ts file. Open this file and add the imports for jquery and web-document-viewer to the top of the file.

import * as jQuery from 'jquery';
import * as Atalasoft from 'web-document-viewer';

Then change the code of DocViewerComponent that it will look like this:

export class DocViewerComponent implements OnInit {
    files = files;
    maxUploadSizeMb: number;
    handler: string;
    viewer: Atalasoft.Controls.WebDocumentViewer;
    thumb: Atalasoft.Controls.WebDocumentThumbnailer;

    constructor() {
        this.maxUploadSizeMb = 1;
        this.handler = 'wdv';
     }

  ngOnInit(): void {
    this.viewer = new Atalasoft.Controls.WebDocumentViewer({
            parent: jQuery('#viewer'),
            toolbarparent: jQuery('.atala-document-toolbar'),
            allowforms: true,
            allowannotations: true,
            allowtext: true,
            savepath: 'saved',
            serverurl: this.handler,
            direction: Atalasoft.Utils.ScrollDirection.Vertical,
            upload: {
                enabled: true,
                uploadpath: 'uploaded',
                allowedfiletypes: '.jpg,.pdf,.png,.jpeg,image/tiff',
                allowedmaxfilesize: this.maxUploadSizeMb * 1024 * 1024,
                allowmultiplefiles: true,
                allowdragdrop: true,
                filesuploadconcurrency: 2
            },
            annotations: {
                stamps: [
                    {
                        name: 'Approved',
                        type: Atalasoft.Annotations.AnnotationTypes.stamp,
                        fill: {
                            color: 'green',
                            opacity: 0.5
                        },
                        outline: {
                            color: '#43BC6F'
                        },
                        text: {
                            value: 'This document has been approved',
                            align: 'left',
                            font: {
                                bold: false,
                                color: '#B9C89D',
                                family: 'Georgia',
                                size: 24
                            }
                        }

                    },
                    {
                        name: 'Approved2',
                        type: Atalasoft.Annotations.AnnotationTypes,
                        fill: {
                                color: 'green',
                                opacity: 0.5
                            },
                        outline: {
                                color: 'Black'
                            },
                        text: {
                                value: 'Approved',
                                align: 'left',
                                font: {
                                    bold: false,
                                    color: 'black',
                                    family: 'Arial',
                                    size: 24
                                }
                            },
                        cornerradius: 50,
                        burn: false
                    }
                ]
            },
        });

    this.thumb = new Atalasoft.Controls.WebDocumentThumbnailer({
        parent: jQuery('#thumbLeft'),
        serverurl: this.handler,
        maxwidth: 240,
        minwidth: 60,
        viewer: this.viewer,
        allowannotations: true,
        allowforms: true,
        allowdragdrop: true,
        showthumbcaption: true,
        thumbcaptionformat: 'p. {0}',
        tabular: true,
        documenturl: 'images/Test.pdf',
    });
  }

  changeFile(path: string) {
    this.thumb.openUrl(path);
  }
}

You can notice that Web Document Viewer is defined by TypeScript as a regular module. As web-document-viewer package is shipped with slightly modified jquery package called as jquery-ui-dist, so it is necessary to tell the Angular module loader to search for jquery module in the folder node_modules/jquery-ui-dist. To do this, we need to slightly modify the file tsconfig.json in the root folder of Angular application. Add the following setting to the compilerOptions section of this file:

"paths": {
      "jquery-ui":["node_modules/jquery-ui-dist/jquery-ui.min.js"]
    }

Add image files

We should provide our application with files to display and specify where to search them. We can do it in the following way: at first, create a subdirectory of wwwroot with name images and place few test files here (We placed files Test.pdf and Test.tif here). Then in the wdv-app\src\app directory create the file files.ts with the following content:

export const files = [
    {
        name: 'Test.pdf',
        source: 'images/Test.pdf'
    },
    {
        name: 'Test.tif',
        source: 'images/Test.tif'
    }
];

After that we tell doc-viewer component where to search our file list. Add the following line to the doc-viewer.component.ts file.

import {files} from '../files';

Add styles

The last thing that we should to do is to import CSS styles from jquery-ui-dist and web-document-viewer packages to our project. One of the ways this can be done is coping files wdv-app\node_modules\jquery-ui-dist\jquery-ui.min.css and wdv-app\node_modules\web-document-viewer\atalaWebDocumentViewer.css to the wdv-app\src\assets folder (Also copy the wdv-app\node_modules\web-document-viewer\images folder here). Then add the following lines to the wdv-app\src\index.html file:

<link rel="stylesheet" href="./assets/atalaWebDocumentViewer.css">
<link rel="stylesheet" href="./assets/jquery-ui.min.css">

Now the client-side part is ready and you can try it out separately by running ng serve from the command line. It will compile the Angular project and run the Angular CLI server. Then open the browser and navigate to http://localhost:4200/ (the default destination for Angular server). The browser should show Web Document Viewer UI, but without the opened document.

To run the entire application start Asp.NET Core application from Visual Studio.