1

Implementing a Contextual Toolbar

 2 years ago
source link: https://www.textcontrol.com/blog/2022/04/22/document-editor-implementing-a-contextual-toolbar/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Implementing a Contextual Toolbar

Contextual toolbars are very helpful to provide users quick access to the most common functions and settings. A smart implementation helps to increase the productivity and user experience. This article shows how to implement a contextual toolbar to manipulate form fields in a document.

Sample Implementation

The following screen video shows the sample implementation of a contextual toolbar to select all text and to remove text from a form field:

Contextual Toolbar

Live Demo

See this demo implementation in our live demos. We added this contextual toolbar to one of the live samples.

Live Demo

The contextual toolbar can be any DIV element you design in your page or a partial view:

<div id="formFieldContextMenu" data-toggle="tooltip" data-placement="left" title="To select text, click form field again when it is active"> <img title="Selects all text" onclick="ContextMenu.select()" class="tx-context-btn" src="~/Images/SelectAll.svg" /> <img title="Removes all text" onclick="ContextMenu.removeText()" class="tx-context-btn" src="~/Images/FormFieldRemoveContent.svg" /> <input id="cmFieldName" disabled type="text" value="[Field name]" /> </div>

In case the user enters a form field, the textFieldEntered event is fired:

TXTextControl.addEventListener("textFieldEntered", attachClickEvent);

In the event handler, the context menu is shown (using the drawContextMenu method) in case the field is an editable form field:

function attachClickEvent(field) {

// remove active listeners TXTextControl.removeEventListener("textFieldClicked", selectField);

// handle only editable form text fields if (field.textField.type === "TEXTFORMFIELD" && field.textField.editable === true) {

// store current field for later comparison _currentField = field;

// set the input value document.querySelector("#cmFieldName").value = field.textField.name;

drawContextMenu(); TXTextControl.addEventListener("textFieldClicked", selectField); } }

The drawContextMenu function positions the context menu under the selected form field and shows it by changing the display CSS property:

function drawContextMenu() {

$("#formFieldContextMenu").tooltip("hide");

// get the singleton context menu _divOvr = document.getElementById("formFieldContextMenu");

// retrieve the field location in the document var fldPos = _currentField.textField.bounds;

// and calculate the offset location and zoom factor var x = _textView.offsetLeft + (fldPos.location.x / 15 - _txtViewLoc.x) * _zoom; var y = _textView.offsetTop + ((fldPos.location.y / 15) + (fldPos.size.height / 15) - _txtViewLoc.y) * _zoom;

// set position and size _divOvr.style.zIndex = _textView.style.zIndex; _divOvr.style.left = x + "px"; _divOvr.style.top = y + 5 + "px"; _divOvr.style.display = "flex";

// show tooltip once if (_tooltipShown === false) { $("#formFieldContextMenu").tooltip("show"); _tooltipShown = true; } else $("#formFieldContextMenu").tooltip("disable"); }

The full JavaScript function is shown below. All functions are encapsulated in a private object ContextMenu with 2 public methods select and removeText:

var ContextMenu = (function (tx) { var _txtViewLoc = { x: 0, y: 0 }; var _divOvr; var _textView; var _zoom = 1.0; var _currentField; var _container; var _tooltipShown = false;

function drawContextMenu() {

$("#formFieldContextMenu").tooltip("hide");

// get the singleton context menu _divOvr = document.getElementById("formFieldContextMenu");

// retrieve the field location in the document var fldPos = _currentField.textField.bounds;

// and calculate the offset location and zoom factor var x = _textView.offsetLeft + (fldPos.location.x / 15 - _txtViewLoc.x) * _zoom; var y = _textView.offsetTop + ((fldPos.location.y / 15) + (fldPos.size.height / 15) - _txtViewLoc.y) * _zoom;

// set position and size _divOvr.style.zIndex = _textView.style.zIndex; _divOvr.style.left = x + "px"; _divOvr.style.top = y + 5 + "px"; _divOvr.style.display = "flex";

// show tooltip once if (_tooltipShown === false) { $("#formFieldContextMenu").tooltip("show"); _tooltipShown = true; } else $("#formFieldContextMenu").tooltip("disable"); }

function attachClickEvent(field) {

// remove active listeners TXTextControl.removeEventListener("textFieldClicked", selectField);

// handle only editable form text fields if (field.textField.type === "TEXTFORMFIELD" && field.textField.editable === true) {

// store current field for later comparison _currentField = field;

// set the input value document.querySelector("#cmFieldName").value = field.textField.name;

drawContextMenu(); TXTextControl.addEventListener("textFieldClicked", selectField); } }

function selectField(field) {

// field is given through "textFieldClicked" event if (field !== null) {

// return in case another field is clicked if (_currentField.textField.start !== field.textField.start) return;

// detach event handler TXTextControl.removeEventListener("textFieldClicked", selectField); }

// find field at input position and select it TXTextControl.formFields.getItem(function (field) {

field.getStart(function (start) { field.getLength(function (length) { TXTextControl.select(start - 1, length); }); });

}); }

function removeText() {

// get field at input position and remove text TXTextControl.formFields.getItem(function (field) { field.setText(""); }); }

function textViewLocationChangedHandler(e) { _txtViewLoc = e.location; if (!_divOvr) return; drawContextMenu() }

function zoomFactorChangedHandler(e) { _zoom = e.zoomFactor / 100.0; if (!_divOvr) return; drawContextMenu(); }

function hideContextMenu() { _currentField = null; $("#formFieldContextMenu").tooltip("hide"); _divOvr.style.display = "none"; }

function window_load() {

_textView = document.getElementById("mainCanvas"); _container = document.getElementById("txTemplateDesignerContainer");

TXTextControl.addEventListener("textControlLoaded", function () { TXTextControl.setDrawingMarkerLines(false); TXTextControl.setTextFrameMarkerLines(false);

TXTextControl.addEventListener("textViewLocationChanged", textViewLocationChangedHandler); TXTextControl.addEventListener("zoomFactorChanged", zoomFactorChangedHandler);

TXTextControl.addEventListener("textFieldEntered", attachClickEvent); TXTextControl.addEventListener("textFieldChanged", attachClickEvent); TXTextControl.addEventListener("textFieldLeft", hideContextMenu);

_divOvr = document.getElementById("formFieldContextMenu"); _container.appendChild(_divOvr);

// demo only TXTextControl.formFields.addTextFormField(2000);

});

}

window.addEventListener("load", window_load);

// exported (public) methods accessible through the ContextMenu object // usage: ContextMenu.select(); tx = {

select: function () { return selectField(null); }, removeText: function () { return removeText(); }

}

return tx;

})(ContextMenu || {});

The full implementation can be found in the demo project on GitHub.

GitHub

Download and Fork This Sample on GitHub

We proudly host our sample code on github.com/TextControl.

Please fork and contribute.

Requirements for This Sample

  • TX Text Control .NET Server for ASP.NET 30.0
  • Visual Studio 2022

Angular

Integrate true WYSIWYG document editing and reporting into Angular applications. Give your users an MS Word compatible editor to create powerful reporting templates anywhere - in any browser on any device. Combine the power of a reporting tool and an easy-to-use document editor that is fully programmable and customizable.

Learn more about Angular

Related Posts

Adding Attachments to Adobe PDF Documents using C#

by Bjoern Meyer| February 25, 2022

TX Text Control is used to create electronic document containers by embedding files in Adobe PDF documents. This tutorial shows how to add and extract attachments to and from PDF documents.

Document Viewer: Uploading Signatures

by Bjoern Meyer| February 24, 2022

The document viewer that is part of TX Text Control .NET Server for ASP.NET provides a feature to deploy forms and documents to collect electronic signatures from users. This article shows how signature images can be uploaded instead of using the signature soft-pad to draw the signature.

Impressions from BASTA! Spring 2022

by Bjoern Meyer| February 24, 2022

This week, we exhibited in-person at BASTA! Spring 2022 in Frankfurt, Germany. In this article, you will find some impressions of our booth area at the BASTA! expo.

See Text Control at DEVintersection in Las Vegas

by Bjoern Meyer| February 23, 2022

In April, DEVintersection is coming back to the MGM Grand in Las Vegas. We will be exhibiting at this conference to show our digital document processing technology.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK