Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Live Character Counter — PCF Control (React + Fluent UI)

A lightweight virtual PCF (PowerApps Component Framework) control for Microsoft Dynamics 365 / Model-Driven Power Apps that adds a live, per-keystroke character counter to any single-line text field, with configurable warning and limit thresholds.

Unlike the classic approach of using a form OnChange JavaScript web resource (which only updates on blur, i.e. when the field loses focus), this control updates on every keystroke using React's onChange, giving users real-time feedback as they type.

✨ Features

  • Live updates — counter refreshes on every keystroke, not just on blur.
  • Two-tier visual feedback — neutral color by default, warning color at a configurable threshold, and a limit color when the max length is reached.
  • Focus-aware state sync — solves a common PCF race condition where the platform's updateView cycle can overwrite what the user is actively typing (dropped characters, jumping cursor). While the field has focus, the control trusts only its own local state; it re-syncs with the platform value on blur.
  • Fully configurablemaxLength and warnAt are exposed as control properties (set from the form designer), not hardcoded.
  • Virtual control — shares React/Fluent platform libraries with the host app instead of bundling its own copy, resulting in a smaller footprint.

🧠 Why this exists

Standard Dynamics 365 fields don't give users any visual indication of how close they are to a character limit until they hit it and get a blocking error. This control closes that gap with a simple, non-intrusive counter — commonly requested for fields like descriptions, notes, or comments where users tend to write long free-text content.

📦 Project Structure

LiveCharCounter/
├── ControlManifest.Input.xml   # PCF manifest (properties, resources)
├── index.ts                    # PCF lifecycle (init/updateView/getOutputs/destroy)
├── LiveCharCounterComponent.tsx # React component (the actual UI + logic)
└── css/
    └── LiveCharCounter.css     # Minimal styling

🔧 Control Properties

Property Type Usage
textValue SingleLine.Text (bound) The field value the control is attached to
maxLength Whole.None (input) Maximum allowed characters (e.g. 850)
warnAt Whole.None (input) Character count at which the warning color kicks in (e.g. 800)

🚀 Getting Started

Prerequisites

Build & Test locally

# from the solution root, after pac pcf init has been run once
npm install
npm run build
npm start            # opens the PCF test harness in the browser

Deploy to an environment (Sandbox first!)

pac auth create --url https://<your-org>.crm.dynamics.com
pac pcf push --publisher-prefix <your_prefix>

Then, on the target form:

  1. Open the form in the classic form designer.
  2. Select the target field → Components+ Add Component.
  3. Choose this control, set maxLength / warnAt, and save & publish.

Production release

For managed deployment, package the control inside a Solution project (pac solution init + pac solution add-reference) and build a Managed solution zip via dotnet build /p:configuration=Release, then import it with pac solution import.

↩️ Rollback

Removing the control is non-destructive: on the form, go to the field's Components panel and remove it. This does not affect the field's data type or any stored values — the field simply reverts to the default text input.

🛡️ Known Issue Fixed: Dropped Characters / Cursor Jump

An earlier iteration of this control exhibited a subtle bug: fast typing could drop spaces and cause the cursor to jump. Root cause was a race condition between the component's local React state and the PCF updateView lifecycle — each onChange triggered notifyOutputChanged, which caused the framework to call updateView again with a slightly stale value, and a useEffect would overwrite local state before the newly typed character was committed.

Fix: an isFocusedRef pattern — while the field has focus, external updates from context.parameters are ignored; the component trusts its own local state exclusively. Synchronization with the platform value happens only onBlur.

📄 License

MIT — see LICENSE.

About

Virtual PCF control (React + Fluent UI) with a live, per-keystroke character counter for Dynamics 365 / Power Apps text fields.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages