Products Technologies Demo Docs Blog Support Company

Format Painter in ASP.NET Core: Building Custom Text Formatting with TX Text Control

This article demonstrates how to build a Format Painter feature using the TX Text Control Document Editor, implementing format detection, copy and paste operations, and custom style handling through the JavaScript API.

Format Painter in ASP.NET Core: Building Custom Text Formatting with TX Text Control

Anyone who has spent time in Microsoft Word knows the magic of the Format Painter: a feature that lets you copy formatting from one piece of text and apply it to another with a single click. Although Format Painter functionality exists in common web editors, developers creating custom document applications require more sophisticated formatting controls. The TX Text Control rich text editor enables developers to implement custom formatting programmatically. This article demonstrates how to build a Format Painter feature using the TX Text Control Document Editor, implementing format detection, copy and paste operations, and custom style handling through the JavaScript API.

Understanding Uniform Formatting Detection

Building a reliable Format Painter feature starts with solving one key challenge: how do you know if the selected text has consistent formatting? When users select text with mixed fonts, colors, or styles, copying that formatting creates inconsistent results. TX Text Control's isCommonSelectionValueSelected Method solves this by checking if formatting is uniform across any selection. It returns true only when all selected text shares the same formatting attributes, preventing formatting errors before they happen.

Getting Started

Learn how to create the TX Text Control rich text editor with ASP.NET Core using this guide:

Getting Started: Document Editor with ASP.NET Core

The ASP.NET Core application with TX Text Control provides rich text editing with comprehensive functionality. The JavaScript API enables further customization and integration with specialized features, such as the Format Painter. For demonstration purposes, this implementation utilizes dedicated buttons to showcase the Format Painter functionality. The complete source code for this implementation is available on the TX Text Control GitHub repository. The project includes all the code examples, along with the complete ASP.NET Core setup and JavaScript integration.

Implementing Asynchronous Format Detection

Since TX Text Control uses callback-based APIs for asynchronous operations, the implementation converts these to Promise wrappers for cleaner async/await syntax. The isCommonValueSelectedAsync function specifically handles format validation using the isCommonSelectionValueSelected Method. The implementation works as follows:

// Global variables 
let copiedFormat = null; 
let styleCounter = 1; 
let customStyles = {}; 

// Promise wrappers for TX Text Control API 
const get = (method) => 
    new Promise((resolve, reject) => 
        TXTextControl.selection[method](v => resolve(v), e => reject(e)) 
    ); 
 
const set = (method, val) => 
    new Promise((resolve, reject) => 
        TXTextControl.selection[method](val, () => resolve(), e => reject(e)) 
    ); 
 
const getLength = () => 
    new Promise((resolve, reject) => 
        TXTextControl.selection.getLength(v => resolve(v), e => reject(e)) 
    ); 
 
const selectWord = () => 
    new Promise((resolve, reject) => 
        TXTextControl.selectWord(() => resolve(), e => reject(e)) 
    ); 

// Utility function to check if selected text has uniform formatting 

function isCommonValueSelectedAsync(selection, attr) { 

  return new Promise((resolve, reject) => { 

    selection.isCommonSelectionValueSelected( 

      attr, 

      (result) => { 

        resolve(result); // true/false 

      }, 

      reject 

    ); 

  }); 

}

Copying Formatting From Text Selection

The event handler shown below validates the text selection and captures its formatting attributes only if the text selection has uniform formatting:

// Main event handler - runs when TX Text Control is fully loaded 

TXTextControl.addEventListener("textControlLoaded", () => { 

  

  // Get references to all UI elements 

  const copyFormatButton = document.getElementById("copyFormatButton"); 

  const pasteFormatButton = document.getElementById("pasteFormatButton"); 

  const createStyleButton = document.getElementById("createStyleButton"); 

  const customStylesDropdown = document.getElementById("customStylesDropdown"); 

  const applyStyleButton = document.getElementById("applyStyleButton"); 

  

  // Copy formatting from selected text 

  copyFormatButton.addEventListener("click", async () => { 

    // Validate that selection has uniform formatting 

    const isUniform = await isCommonValueSelectedAsync( 

      TXTextControl.selection, 

      TXTextControl.Selection.Attribute.All 

    ); 

  

    if (isUniform) { 

      // Capture all formatting attributes from current selection 

      copiedFormat = { 

        baseline: await get("getBaseline"), 

        bold: await get("getBold"), 

        fontName: await get("getFontName"), 

        fontSize: await get("getFontSize"), 

        foreColor: await get("getForeColor"), 

        italic: await get("getItalic"), 

        strikeout: await get("getStrikeout"), 

        textBackColor: await get("getTextBackColor"), 

        underline: await get("getUnderline") 

      }; 

  

      pasteFormatButton.disabled = false; 

      console.log("Format copied successfully."); 

    } else { 

      alert("Please select text with uniform formatting to copy the format."); 

    } 

  });

Applying Formatting to Text Selections

The paste handler applies the previously copied formatting to the target selection with all the captured attributes, as shown in this code:

// Apply previously copied formatting to current selection 

pasteFormatButton.addEventListener("click", async () => { 

  if (!copiedFormat) { 

      pasteFormatButton.disabled = true; 

      return; 

  } 

  

  try { 

    // Apply all captured formatting attributes to current selection 

    await set("setBaseline", copiedFormat.baseline); 

    await set("setBold", copiedFormat.bold); 

    await set("setFontName", copiedFormat.fontName); 

    await set("setFontSize", copiedFormat.fontSize); 

    await set("setForeColor", copiedFormat.foreColor); 

    await set("setItalic", copiedFormat.italic); 

    await set("setStrikeout", copiedFormat.strikeout); 

    await set("setTextBackColor", copiedFormat.textBackColor); 

    await set("setUnderline", copiedFormat.underline); 

  

    console.log("Format pasted successfully."); 

  } catch (err) { 

    alert("Paste failed: " + err.message); 

    console.error(err); 

  } 

});

Copying and applying formatting

Creating Custom Styles and Adding Them to TX Text Control's Style Collection

This section shows how to create reusable styles that become part of TX Text Control's style collection. Unlike the copy and paste formatting covered earlier, creating custom styles defines inline or paragraph formatting rules that can be reapplied across the document or in future editing sessions. The created custom styles are added to the Document Editor's "Styles" dropdown in the ribbon.

TX Text Control supports both inline and paragraph styles, which serve different formatting purposes:

  • Paragraph styles apply formatting to entire paragraphs.
  • Inline styles apply character-level formatting to selected text portions within paragraphs.

This implementation uses inline styles because the format painter feature captures character-level formatting properties. Formatting is applied to selected text portions rather than entire paragraphs. The following code shows how to create styles and add them to TX Text Control's style collection:

// Create a reusable style from selected text formatting 

createStyleButton.addEventListener("click", async () => { 

  try { 

    // Validate uniform formatting before creating style 

    const isUniform = await isCommonValueSelectedAsync( 

      TXTextControl.selection, 

      TXTextControl.Selection.Attribute.All 

    ); 

  

    if (!isUniform) { 

      alert("Please select text with uniform formatting to create a style."); 

      return; 

    } 

  

    // Capture current selection's formatting 

    const currentFormat = { 

      baseline: await get("getBaseline"), 

      bold: await get("getBold"), 

      fontName: await get("getFontName"), 

      fontSize: await get("getFontSize"), 

      foreColor: await get("getForeColor"), 

      italic: await get("getItalic"), 

      strikeout: await get("getStrikeout"), 

      textBackColor: await get("getTextBackColor"), 

      underline: await get("getUnderline") 

    }; 

  

    // Generate unique style name and create the style 

    const styleName = "CustomStyle" + styleCounter++; 

    // Add the created style in TX Text Control's inline styles collection 

    const addedStyle = await addStyle(styleName, currentFormat, "inline"); 

  

    if (addedStyle) { 

      // Store for dropdown usage and add to UI 

      customStyles[styleName] = { ...currentFormat }; 

      addStyleToDropdown(styleName); 

  

    } 

  

    alert(`Custom style '${styleName}' created successfully!`); 

  } catch (err) { 

    alert("Style creation failed: " + err.message); 

    console.error(err); 

  } 

});

Note: TX Text Control's FormattingStyle.setFontSize Method requires font sizes in twips (1/20th of a point). The ptToTwips helper function converts point values to twips, ensuring programmatically created styles display at the correct font size.

// Convert font size from points to twips (required by TX Text Control) 

function ptToTwips(pt) { 

  return pt * 20; 

} 

  

// Function to create a new inline style in TX Text Control's style collection 

function addStyle(styleName, format) { 

    return new Promise((resolve, reject) => { 

        TXTextControl.inlineStyles.add( 

            styleName, 

            (style) => { 

                // Apply formatting values to the new style 

                style.setFontName(format.fontName); 

                style.setFontSize(ptToTwips(format.fontSize)); // Convert to twips 

                style.setForeColor(format.foreColor); 

                style.setBold(format.bold); 

                style.setItalic(format.italic); 

                style.setUnderline(format.underline); 

                style.setStrikeout(format.strikeout); 

                style.setBaseline(format.baseline); 

                style.setTextBackColor(format.textBackColor); 

                resolve(style); 

            }, 

            (error) => reject(error) 

        ); 

    }); 

}

Creating custom styles

TX Text Control Style Collection

Conclusion

This article demonstrates how to build a professional Format Painter feature for ASP.NET applications using TX Text Control's JavaScript API. The implementation uses the isCommonSelectionValueSelected Method to ensure uniform formatting detection. It also includes complete functionality for copying and pasting formats, creating custom styles, and adding them to the TX Text Control style collection using inline styles. This approach provides developers with a practical foundation for implementing sophisticated text formatting in web-based applications.

Stay in the loop!

Subscribe to the newsletter to receive the latest updates.

Also See

This post references the following in the documentation:

  • Javascript: Selection.isCommonSelectionValueSelected Method
  • Javascript: InlineStyleCollection Object
  • Javascript: ParagraphStyleCollection Object

GitHub

Download and Fork This Sample on GitHub

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

Please fork and contribute.

Download ZIP

Open on GitHub

Open in Visual Studio

Requirements for this sample

  • TX Text Control .NET Server 33.0
  • Visual Studio 2022

Related Posts

AngularASP.NETJavaScript

Observe When the Reporting Preview Tab is Active Using MutationObserver

This article shows how to observe when the Reporting Preview tab is active using MutationObserver. The Reporting Preview tab is a feature of the TX Text Control Document Editor that allows you to…


AngularASP.NETJavaScript

Building an ASP.NET Core Backend Application to Host the Document Editor and…

This article explains how to create an ASP.NET Core backend application to host the Document Editor and Document Viewer. This backend application is required to provide the required functionality…


JavaScriptASP.NET CoreDocument Editor

Getting Started: Document Editor with JavaScript

This article shows how to use the TX Text Control document editor in a pure HTML and JavaScript environment.


ASP.NETASP.NET CoreDocument Editor

Getting Started Video Tutorial: Document Editor in ASP.NET Core C# on Linux

This video tutorial shows how to use the Document Editor in an ASP.NET Core application using C# and deploy on Linux using Docker. This tutorial is part of the TX Text Control Getting Started…


ASP.NETJavaScriptASP.NET Core

Add JavaScript to PDFs with TX Text Control in C# .NET: Time-Based Alerts…

In this article, we explore how to enrich PDF documents with JavaScript using TX Text Control in C# .NET. Read on to learn how to create time-based alerts that trigger actions based on specific…