Search results

Integration with toolbar in Angular Signature component

29 Sep 2022 / 4 minutes to read

The Signature component integrates with the toolbar and the interaction performed using the change event of the toolbar. In that, canUndo, canRedo and isEmpty methods were used to enable/disable undo, redo, and clear buttons.

Source
Preview
app.component.ts
app.module.ts
main.ts
Copied to clipboard
import { Component, ViewChild } from '@angular/core';
import { addClass, createElement, getComponent } from '@syncfusion/ej2-base';
import { SignatureComponent } from '@syncfusion/ej2-angular-inputs';
import { SplitButton, ItemModel, MenuEventArgs, DropDownButton } from '@syncfusion/ej2-splitbuttons';
import { ClickEventArgs } from '@syncfusion/ej2-navigations';
import { Button, ChangeEventArgs, CheckBox } from '@syncfusion/ej2-buttons';
import { ColorPicker, ColorPickerEventArgs, NumericTextBox, PaletteTileEventArgs, Signature, SignatureFileType } from '@syncfusion/ej2-inputs';
import { debugOutputAstAsTypeScript } from '@angular/compiler';
import { DropDownList } from '@syncfusion/ej2-angular-dropdowns';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

@Component({
    selector: 'app-root',
    template: `<div id="signature-toolbar-control">
        <ejs-toolbar id="toolbar" (created)="onCreate($event)" (clicked)="clicked($event)" width="100%">
            <e-items>
                <e-item text='Undo' prefixIcon='e-icons e-undo' tooltipText='Undo (Ctrl + Z)'></e-item>
                <e-item text='Redo' prefixIcon='e-icons e-redo' tooltipText='Redo (Ctrl + Y)'></e-item>
                <e-item type='Separator'></e-item>
                <e-item tooltipText= 'Save (Ctrl + S)' type='Button' template= '<button id="save-option"></button>'>
                </e-item>
                <e-item type='Separator'></e-item>
                <e-item tooltipText= 'Stroke Color' template= '<input id="stroke-color" type="color"/>'>
                </e-item>
                <e-item type='Separator'></e-item>
                <e-item tooltipText= 'Background Color' type= 'Input' template= '<input id="bg-color" type="color"/>'></e-item>
                <e-item type='Separator'></e-item>
                <e-item tooltipText= 'Stroke Width' type= 'Input' template= '<input id="stroke-width" type="text"/>'></e-item>
                <e-item type='Separator'></e-item>
                <e-item text= 'Clear' prefixIcon= 'e-sign-icons e-clear' tooltipText= 'Clear'></e-item>
                <e-item tooltipText= 'Disabled' type='Input' template='<input id="chkelement1" type="checkbox"/>' align='Right'></e-item>
            </e-items>
        </ejs-toolbar>
        <div id="signature-control">
            <canvas ejs-signature #signature id="signature" [maxStrokeWidth]="strokeWidth" style="height: 100%; width: 100%;" (change)="change()"></canvas>
        </div>
    </div>`
})
export class AppComponent {
    @ViewChild('signature') signature: SignatureComponent;
    public strokeWidth: number = 2;
    public items: ItemModel[] = [
    {
        text: 'Png'
    },
    {
        text: 'Jpeg'
    },
    {
        text: 'Svg'
    }];

    public templateCheckbox1: any = new CheckBox({
        label: 'Disabled',
        checked: false,
        change: (args: ChangeEventArgs) => {
            this.signature.disabled = args.checked;
        }
    });

    public change(): void {
        let saveBtn: SplitButton = getComponent(document.getElementById("save-option"), 'split-btn');
        if (!this.signature.isEmpty()) {
            this.clearButton();
           saveBtn.disabled = false;
        }
        this.updateUndoRedo();
    }
    public onCreate (e: any) {
        this.templateCheckbox1.appendTo('#chkelement1');
        let ddl: DropDownList = new DropDownList({
            dataSource:  [1, 2, 3, 4, 5],
            width: '60',
            value: 2,
            change: function(args) {
                let signature: Signature = getComponent(document.getElementById("signature"), 'signature');
                signature.maxStrokeWidth = args.value;
            }
        });
        ddl.appendTo('#stroke-width');
        new SplitButton({
            iconCss: 'e-sign-icons e-save',
            items: this.items,
            content: 'Save',
            select: (args: MenuEventArgs) => {
                this.signature.save(args.item.text as SignatureFileType, 'Signature');
            },
            disabled: true
        }, '#save-option');
        let strokeColor: ColorPicker = new ColorPicker({
            modeSwitcher: false,
            columns: 4,
            presetColors: {
                'custom': ['#000000', '#e91e63', '#9c27b0', '#673ab7', '#2196f3', '#03a9f4', '#00bcd4',
                '#009688', '#8bc34a', '#cddc39', '#ffeb3b', '#ffc107']
            },
            beforeTileRender: (args: PaletteTileEventArgs) => {
                args.element.classList.add('e-circle-palette');
                args.element.appendChild(createElement('span', { className: 'e-circle-selection' }));
            },
            showButtons: false,
            mode: 'Palette',
            cssClass: 'e-stroke-color',
            change: (args: ColorPickerEventArgs) => {
                if (this.signature.disabled) {
                    return;
                }
                let selElem: HTMLElement = strokeColor.element.nextElementSibling.querySelector('.e-selected-color') as HTMLElement;
                selElem.style.borderBottomColor = args.currentValue.rgba;
                this.signature.strokeColor = args.currentValue.rgba;
            }
        });
        strokeColor.appendTo('#stroke-color');
        let bgColor: ColorPicker = new ColorPicker({
            modeSwitcher: false,
            columns: 4,
            noColor: true,
            presetColors: {
                'custom': ['#ffffff', '#f44336', '#e91e63', '#9c27b0', '#673ab7', '#2196f3', '#03a9f4', '#00bcd4',
                '#009688', '#8bc34a', '#cddc39', '#ffeb3b']
            },
            beforeTileRender: (args: PaletteTileEventArgs) => {
                args.element.classList.add('e-circle-palette');
                args.element.appendChild(createElement('span', { className: 'e-circle-selection' }));
            },
            showButtons: false,
            mode: 'Palette',
            cssClass: 'e-bg-color',
            change: (args:ColorPickerEventArgs) => {
                if (this.signature.disabled) {
                    return;
                }
                let selElem: HTMLElement = bgColor.element.nextElementSibling.querySelector('.e-selected-color') as HTMLElement;
                this.signature.backgroundColor = args.currentValue.rgba;
                selElem.style.borderBottomColor = args.currentValue.rgba;
            }
        });
        bgColor.appendTo('#bg-color');
        addClass([strokeColor.element.nextElementSibling.querySelector('.e-selected-color')], 'e-sign-icons');
        addClass([bgColor.element.nextElementSibling.querySelector('.e-selected-color')], 'e-sign-icons');
        document.getElementById('save-option').addEventListener('click', this.saveBtnClick);
        this.clearButton();
        let toolbarlItems: NodeListOf<Element> = document.querySelectorAll('.e-toolbar .e-toolbar-items .e-toolbar-item .e-tbar-btn.e-tbtn-txt');
        for (var i = 0; i < toolbarlItems.length; i++) {
            if (toolbarlItems[i].children[0].classList.contains('e-undo')) {
                let undoButton: Button = getComponent(toolbarlItems[i] as HTMLElement, 'btn');
                undoButton.disabled = true;
            }
            if (toolbarlItems[i].children[0].classList.contains('e-redo')) {
                let redoButton: Button = getComponent(toolbarlItems[i] as HTMLElement, 'btn');
                redoButton.disabled = true;
            }
        }
    }

    public clicked(args: ClickEventArgs): void {
        let saveBtn: SplitButton = getComponent(document.getElementById("save-option"), 'split-btn');
        if (this.signature.disabled && args.item.tooltipText != 'Disabled') {
            return;
        }
        switch (args.item.tooltipText) {
            case 'Undo (Ctrl + Z)':
                if (this.signature.canUndo()) {
                    this.signature.undo();
                    this.updateUndoRedo();
                    this.updateSaveBtn();
                }
                break;
            case 'Redo (Ctrl + Y)':
                if (this.signature.canRedo()) {
                    this.signature.redo();
                    this.updateUndoRedo();
                    this.updateSaveBtn();
                }
                break;
            case 'Clear':
                this.signature.clear();
                if (this.signature.isEmpty) {
                    this.clearButton();
                    saveBtn.disabled = true;
                }
                break;
        }
    }

    public saveBtnClick(): void {
        let signature: Signature = getComponent(document.getElementById("signature"), 'signature');
        signature.save();
    }

    public clearButton() {
        let tlItems: NodeListOf<Element> = document.querySelectorAll('.e-toolbar .e-toolbar-items .e-toolbar-item .e-tbar-btn.e-tbtn-txt');
        for (var i = 0; i < tlItems.length; i++) {
            if (tlItems[i].children[0].classList.contains('e-clear')) {
                let clrBtn: Button = getComponent(tlItems[i] as HTMLElement, 'btn');
                if (this.signature.isEmpty()) {
                    clrBtn.disabled = true;
                } else {
                    clrBtn.disabled = false;
                }
            }
        }
    }

    public updateSaveBtn() {
        let saveBtn: SplitButton = getComponent(document.getElementById("save-option"), 'split-btn');
        if (this.signature.isEmpty()) {
            saveBtn.disabled = true;
        }
    }

    public updateUndoRedo() {
        let undoButton: Button; let redoButton: Button
        let tlItems: NodeListOf<Element> = document.querySelectorAll('.e-toolbar .e-toolbar-items .e-toolbar-item .e-tbar-btn.e-tbtn-txt');
        for (var i = 0; i < tlItems.length; i++) {
            if (tlItems[i].children[0].classList.contains('e-undo')) {
                undoButton = getComponent(tlItems[i] as HTMLElement, 'btn');
            }
            if (tlItems[i].children[0].classList.contains('e-redo')) {
                redoButton = getComponent(tlItems[i] as HTMLElement, 'btn');
            }
        }
        if (this.signature.canUndo()) {
            undoButton.disabled = false;
        } else {
            undoButton.disabled = true;
        }
        if (this.signature.canRedo()) {
            redoButton.disabled = false;
        } else {
            redoButton.disabled = true;
        }
    }
}
Copied to clipboard
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { SignatureComponent } from '@syncfusion/ej2-angular-inputs';
import { DropDownListModule } from '@syncfusion/ej2-angular-dropdowns';
import { SplitButtonModule } from '@syncfusion/ej2-angular-splitbuttons';
import { ColorPickerComponent } from '@syncfusion/ej2-angular-inputs';
import { ToolbarModule } from '@syncfusion/ej2-angular-navigations';
import { ButtonModule } from '@syncfusion/ej2-angular-buttons';
import { enableRipple } from '@syncfusion/ej2-base';

enableRipple(true);

/**
 * Module
 */
@NgModule({
    imports: [
        BrowserModule,FormsModule, DropDownListModule, SplitButtonModule, ToolbarModule, ButtonModule
    ],
    declarations: [AppComponent, SignatureComponent, ColorPickerComponent],
    bootstrap: [AppComponent]
})
export class AppModule { }
Copied to clipboard
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { enableProdMode } from '@angular/core';
import { AppModule } from './app.module';

enableProdMode();
platformBrowserDynamic().bootstrapModule(AppModule);