--- title: "How to: Bring Your Own AG Grid" slug: "how-to-bring-your-own-ag-grid" description: "Learn to create a custom Average and Rounding Operation in Unqork, integrating JavaScript for precise calculations and event handling." updated: 2025-09-30T18:25:20Z published: 2025-09-30T18:25:20Z canonical: "docs.unqork.io/how-to-bring-your-own-ag-grid" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.unqork.io/llms.txt > Use this file to discover all available pages before exploring further. # How to: Bring Your Own AG Grid This how-to guide details how to create a **custom** ([Bring Your Own](/v1/docs/introduction-to-the-bring-your-own-byo-framework)) **AG Grid component**. This BYO Unqork component uses a third-party library to embed a customizable AG Grid data table in Express View. It also acts as a wrapper, translating Unqork's data format into a format that the AG Grid library can understand and interact with. To learn more about AG Grid, view the AG Grid website: [https://www.ag-grid.com/](https://www.ag-grid.com/). > [!WARNING] > The [Bring Your Own](/v1/docs/introduction-to-the-bring-your-own-byo-framework) feature is intended for developers who have a strong understanding of the Unqork Designer Platform and JavaScript. ## BYO AG Grid Component Ideation For this example, the fictional client company "ABC" wants to implement a third-party library called **AG Grid** as a data table to use in a custom Unqork component. The component must let Creators create multiple columns that contain a key and label field. They also want the component to accept a string containing an array of objects with table data. Additionally, the company wants a custom event that emits when a user clicks on an AG Grid’s cell. As the developer assigned to this task, break down and document the client's ask into actionable sections: - **Asset Types**: What’s needed to meet the client's requirements of an averaging and rounding asset? - **Component(s)**: Does the client's request require the creation of something not currently supported in the Unqork platform? - **Event(s)**: Does the asset need to emit an event when it's used? What action should emit the event? - **Operation(s)**: Does the asset need to be manipulated by other elements using an operation? - **Inputs & Outputs**: Catalog a list of potential inputs and outputs for the asset. are typically outputs in this list. - **Libraries**: Does this asset require an external library? Does the library perform the functions requested by the client? Do Creators need to understand how to use the library in Unqork? - **Naming Scheme**: Develop a naming scheme for the asset that aligns with Unqork values and avoids conflicts with potential future custom assets. > To understand naming scheme limitations, view the Important callout in the overview of our [Bring Your Own (BYO): Understanding the manifest.json File](/v1/docs/bring-your-own-byo-understanding-the-manifestjson-file#file-specification) article. Now that the client has described the ask, create a document detailing all the potential elements the operation asset requires. ### Example Ideation Documentation The sections below detail the product requirements that meet the client's request. Developers use this information to implement the component’s JavaScript, create the manifest file and package, and package it to the Unqork Designer Platform. #### Component(s) A custom Unqork component that imports an AG Grid data table. | Component Name | Description | | --- | --- | | AG Grid | An imported AG Grid with the following configuration settings: - **Column Definitions** (Array of Objects): Contains the Key and Label fields required to map and display table data to the AG Grid. - **Key** (Field): Maps the Value field to the AG Grid column. - **Label** (Field): The header display value for the column. - **Value** (Field): Accepts an Array of table data. | #### Event(s) An event used as part of the [Events & Operations Builder](/v1/docs/operations-builder). | Parameter | Object Type | Description | | --- | --- | --- | | AG Grid Cell Clicked | `agGridCellClicked` | An event that is emitted when an end-user clicks on an AG Grid Cell. The event includes a payload with the cell value. | #### Input(s) Creators use the input fields to map and label columns. | Parameter | Object Type | Description | | --- | --- | --- | | `columnDefinitions` | array | An array of objects that defines the grid's columns. The asset developer maps these values to the AG Grid column function. The columns definition contains the following keys: - `key`: Maps the table data from the value field to the column. Corresponds to the [**Key**](/v1/docs/how-to-bring-your-own-ag-grid#components) field in the component’s configuration drawer. - `label`: Creates a header display value. Corresponds to the [**Label**](/v1/docs/how-to-bring-your-own-ag-grid#components) field in the component’s configuration drawer. Creators use these fields to define map table data to the component and label the column headers. | | `value` | string | A JSON string that represents the data for the grid's rows. Corresponds to the [**Value**](/v1/docs/how-to-bring-your-own-ag-grid#components) field in the component’s configuration drawer. | #### Libraries This component imports the AG Grid library for rendering table data. See examples of importing an AG Grid in their Get Started documentation: [https://www.ag-grid.com/javascript-data-grid/getting-started/.](https://www.ag-grid.com/javascript-data-grid/getting-started/.) | Library Name | Description | Documentation Link | | --- | --- | --- | | AG Grid | A free, open source library that provides a high-performance, feature-rich, and fully customizable Data Grid. Asset developers should perform an additional review of this library to verify it meets the client’s needs and what is required of Creators to use it. | [https://www.ag-grid.com/](https://www.ag-grid.com/) | #### Naming Scheme Verify that all naming values do not conflict with existing Unqork assets or other custom assets in the environment. > [!WARNING] > IMPORTANT > > Unqork does not enforce programmatic name spacing for custom asset types. All type values for components, operations, and events must be globally unique. If multiple custom assets share the same type, or if a custom asset uses a type that conflicts with a native Unqork type, the runtime will render or execute only the first matching definition. Doing so leads to unpredictable behavior, asset shadowing, or broken functionality—especially when bundling or importing multiple packages. > > It is the responsibility of the developer to ensure type uniqueness to prevent collisions. Component, operation, and event types require a unique name to avoid collision issues. > > To avoid namespace issues, prefix custom components with a name unique to your company or application. For example, if a company named **ABC** creates a **Card Panel** component. The component's name space could be `abcCardPanel`. | Asset Type | Asset Name | Naming Scheme | | --- | --- | --- | | Component | Ag Grid | `exAvgAndRound` | | Event / Output | AG Grid Cell Clicked | `agGridCellClicked` | | Input | Column Definition | `columnDefinitions` | | Input | Value | `value` | ## Create the `manifest.json` File The manfest.json file serves as the contract between Unqork and the AG Grid implementation. In this file, you’ll specify the AG Grid components and event properties. ```json {  "name": "AgGrid",  "version": "1.0.0",  "main": "agGrid.js",  "type": "custom",  "productType": "BYO",  "description": "AG Grid integration with Unqork",  "components": [    {      "name": "AG Grid",      "type": "agGrid",      "description": "AG Grid component for Unqork",      "model": {        "type": "object",        "properties": {          "columnDefinitions": {            "name": "Column Definitions",            "type": "array",            "description": "Column definitions for this grid (currently only supporting key and label)",            "items": {              "type": "object",              "properties": {                "key": {                  "type": "string",                  "description": "Unique key for the column"                },                "label": {                  "type": "string",                  "description": "Display label for the column"                }              }            }          },          "value": {            "name": "Grid Data (JSON)",            "type": "string",            "description": "JSON string of data for the grid"          }        },        "required": ["columnDefinitions"]      },      "events": [        {          "name": "AG Grid Cell Clicked",          "type": "agGridCellClicked",          "description": "This event is triggered when the user clicks on a grid cell.",          "stability": "STABLE"        }      ]    }  ] } ``` The following fields are used at the root level of the manifest: | Field | Type | Required | Description | | --- | --- | --- | --- | | name | string | ![Checkmark](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Documentation/UDLC_Enterprise_View_Green_Checkmark.png?sv=2026-02-06&spr=https&st=2026-11-07T20%3A53%3A45Z&se=2026-11-07T21%3A53%3A45Z&sr=c&sp=r&sig=TMoB4lui2Oy1IU780zwG9ibUvmAgWw1QQ6wcICbkT48%3D) | A unique identifier for the package. For example, `MyCompanyNameAssets`. | | version | string | ![Checkmark](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Documentation/UDLC_Enterprise_View_Green_Checkmark.png?sv=2026-02-06&spr=https&st=2026-11-07T20%3A53%3A45Z&se=2026-11-07T21%3A53%3A45Z&sr=c&sp=r&sig=TMoB4lui2Oy1IU780zwG9ibUvmAgWw1QQ6wcICbkT48%3D) | The semantic version number. For example, `1.0.0`. | | main | string | ![Checkmark](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Documentation/UDLC_Enterprise_View_Green_Checkmark.png?sv=2026-02-06&spr=https&st=2026-11-07T20%3A53%3A45Z&se=2026-11-07T21%3A53%3A45Z&sr=c&sp=r&sig=TMoB4lui2Oy1IU780zwG9ibUvmAgWw1QQ6wcICbkT48%3D) | The relative path to the JavaScript entry file. For example, `agGrid.js`. | | type | enum | ![Checkmark](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Documentation/UDLC_Enterprise_View_Green_Checkmark.png?sv=2026-02-06&spr=https&st=2026-11-07T20%3A53%3A45Z&se=2026-11-07T21%3A53%3A45Z&sr=c&sp=r&sig=TMoB4lui2Oy1IU780zwG9ibUvmAgWw1QQ6wcICbkT48%3D) | The package type. Currently, the only supported value is `custom`. | | productType | enum | ![Checkmark](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Documentation/UDLC_Enterprise_View_Green_Checkmark.png?sv=2026-02-06&spr=https&st=2026-11-07T20%3A53%3A45Z&se=2026-11-07T21%3A53%3A45Z&sr=c&sp=r&sig=TMoB4lui2Oy1IU780zwG9ibUvmAgWw1QQ6wcICbkT48%3D) | The target platform feature. Currently, the only supported value is `BYO`. | | description | string | ![Checkmark](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Documentation/UDLC_Enterprise_View_Green_Checkmark.png?sv=2026-02-06&spr=https&st=2026-11-07T20%3A53%3A45Z&se=2026-11-07T21%3A53%3A45Z&sr=c&sp=r&sig=TMoB4lui2Oy1IU780zwG9ibUvmAgWw1QQ6wcICbkT48%3D) | A description that displays in the Admin Panel after installation. | | components | array | Optional | A list of component definitions included in the package. | | events | array | Optional | List of event definitions. | ### Understanding the `components[0]` definition. This is the main definition for the AG Grid component itself. This definition includes the name, inputs, and events for the asset. | Property | Description | | --- | --- | | `name` and `type` | Define the component's name and its internal identifier. The type (`agGrid`) must match the export name in the JavaScript file (`agGrid.js`) so Unqork can link the JSON definition to the correct code. | | `model` | This object defines a custom event. It exports a model that describes the structure of the event's payload (`name` and `type`). Doing so lets other parts of the Unqork platform use and understand the event that the component emits. | | ↳ | `columnDefinitions` | This is a required property that defines the columns of the grid. The schema specifies that it must be an array of objects, where each object has a `key` (for internal use) and a `label` (for display). | | | `value` | This property is where the grid's data is provided. The schema expects a JSON `string` to define the rows of the grid. | | `events` | This section defines the custom events the component can emit. | | ↳ | `name` and `type` | These define the `agGridCellClicked` event's name and its unique identifier. | | | `description` | Explains when the event is triggered. | | | `stability` | The `STABLE` tag indicates that this event's API is reliable and will not change without warning. | ## Implement the AG Grid Component For this example, create a file called `agGrid.js`. In this file, create a component that does the following: 1. Imports the AG Grid Library. > [!NOTE] > NOTE > > Unqork does not support the JavaScript Import syntax at this time. Instead, developers must copy and paste the AG Grid code into the file. 2. Creates a Shadow DOM as part of the BYO implementation requirements. 3. Initializes the Unqork Runtime API as a part of the BYO implementation requirements. 4. Subscribes to column definitions, updating the Express View rendering to match. 5. The component subscribes to state changes for the grid's `value` property, automatically updating the component to reflect any changes configured in the [Module Builder](/v1/docs/introduction-to-the-module-builder). 6. Emits an event (`onAgGridCellClicked`) back to the Unqork runtime. Creators can configure the event using the [Operations Builder](/v1/docs/operations-builder) to trigger downstream logic. 7. Validates input data and parses it as JSON. Reducing inconsistencies with Unqork’s platform. 8. Map’s Unqork’s input format to AG Grid’s input format. 9. Exports and renders the AG Grid data into the Unqork Designer platform. Review the code example below for more information on each method: > [!NOTE] > The comments in the JavaScript below are written in the JSDoc format. For more information on JSDoc block tags (@param, @return), visit the JSDoc website: [https://jsdoc.app/](https://jsdoc.app/). ```javascript // AgGrid Import // // See import examples in AG Grid's Get Started Documentation: https://www.ag-grid.com/javascript-data-grid/getting-started/ class UnqorkAgGridComponent extends HTMLElement {  constructor() {    super()    this.attachShadow({ mode: 'open' })    this.gridOptions = {      columnDefs: [],      rowData: [],          }  }  /**   * This is the only required method to integrate with the Unqork system   *   * @param {*} api The interface to the Unqork Runtime, used for both   *                monitoring state and emitting events   */  initialize(api) {    this.config = api.state.currentState()    this.api = api    if (this.config.columnDefinitions?.length) {      const defs = this._normalizeInput(this.config.columnDefinitions)      this.gridOptions.columnDefs = this._formatColumnDefinitions(defs)    }    if (this.config.value?.length) {      this.gridOptions.rowData = this._normalizeInput(this.config.value)    }    this.renderGrid(this.shadowRoot, this.gridOptions)    this.subscribeColumnDefs()    this.subscribeData()  }  /**   * Subscribe to the source for column definitions   *   * This can be made more robust by first using   * api.state.state$('columnDefsReference') to subscribe to   * any changes to that value (i.e. the target key), and then using   * resolveByKey$ to resolve the current value of that key.   */  subscribeColumnDefs() {    this      .api      .state      .state$('columnDefinitions').subscribe((columnDefs) => {        console.log('AG Grid column definitions updated to', columnDefs)        // This _should_ be an array, but sometimes components try to set it as a        // JSON string instead, so we handle that here        const value = typeof(columnDefs) === 'string' ? JSON.parse(columnDefs) : columnDefs        this.gridOptions = {          rowData: this.gridOptions.rowData,          columnDefs: value ? this._formatColumnDefinitions(value) : [],        }        this.updateGrid(this.gridOptions)      })  }  subscribeData() {    this.api.state.state$('value').subscribe((rowData) => {      console.log('AG Grid value updated to', rowData)      // We support setting this as a JSON string or already parsed array of objects      // so handle that here      const value = typeof(rowData) === 'string' ? JSON.parse(rowData) : rowData      this.gridOptions = {        rowData: value || [],        columnDefs: this.gridOptions.columnDefs,      }      this.updateGrid(this.gridOptions)    })  }  updateGrid(gridOptions) {    console.log('Updating AG Grid', gridOptions)    this.gridApi.updateGridOptions(gridOptions)  }  async renderGrid(document, gridOptions) {    console.log('Rendering AG Grid component', {gridOptions, agGrid, windowAgGrid: window.agGrid})    document.innerHTML = this.view()    this.gridEl = document.querySelector('#myGrid')    this.gridApi = window.agGrid.createGrid(this.gridEl, gridOptions)    // Set this here so that it doesn't overridden when we update gridOptions    this.gridApi.addEventListener('cellClicked', (ev) => {      console.log('Emitting AG Grid Cell Clicked Event', ev)      this.emitCellClickedEvent(ev)    })    console.log('Created AG Grid', {      document,      gridOptions,      gridEl: this.gridEl,      gridApi: this.gridApi,    })  }  // Emit an event when a cell is clicked  // Full docs: https://www.ag-grid.com/javascript-data-grid/grid-events/#reference-selection-cellClicked  emitCellClickedEvent = (ev) => {    this.api.events.emit({      name: 'onAgGridCellClicked',      payload: ev    })  }  view() {    return `      
   `  }  /**   * Input data can be either JSON string or actual data, due to   * Unqork data constraints, so ensure it's proper data before   * using   */  _normalizeInput(val) {    return typeof(val) === 'string' ? JSON.parse(val) : val  }  /**   * We store column definitions with standard key/label properties   * But AG Grid using different property names, so we map it here   */  _formatColumnDefinitions(defs) {    return defs.map(({key, label}) => {      return {        field: key,        headerName: label ?? key      }    })  } } // This definition defines the state settings (model) for this component // It mirrors the fuller description in manifest.json and will // eventually be used to auto-generate the manifest.json JSON schema class AgGridDefinition {  columnDefsReference  dataReference } // Actual export that exposes both the view layer and the model // and is consumed by the Unqork Runtime for both configuration and // execution // All of these are `async` to allow for us to load them on demand // without impacting initial page load performance export const agGrid = {  model: async () => AgGridDefinition,  view: async () => UnqorkAgGridComponent, } // This definition describes the schema of the event that is emitted // when the user clicks on an item class CellClicked {  name = 'agGridCellClicked'  payload = {    index,    text,  } } // This export is used to expose the event to the Unqork Runtime export const agGridCellClicked = {  model: async () => CellClicked, }     ``` ### Understanding `UnqorkAGGridComponent` Class This is a web component that encapsulates all the AG Grid functionality. | Method | Description | | --- | --- | | `constructor()` | Sets up the component's internal state, including the Shadow DOM to isolate its styles and markup. It also initializes a base `gridOptions` object, which will be populated with data from Unqork. | | `initialize(api)` | The required method for Unqork integration. The Unqork Runtime calls this method to provide the component with the `api` object. This is where the component gets its initial data from Unqork's state and sets up subscriptions to listen for future changes. | | `subscribeColumnDefs()` | The `subscribeColumnDefs()` method listens for changes to the `columnDefinitions` property in the component's state. By subscribing to these changes, the method ensures the AG Grid's columns are dynamically updated to reflect the new configuration. This enables creators to use [operations](/v1/docs/operations-builder) to change the grid's columns at runtime. | | `subscribeData()` | Listens for changes to the `value` property in the component's state. By subscribing to these changes, the method ensures the AG Grid's values are dynamically updated to reflect the new configuration. This enables creators to use [operations](/v1/docs/operations-builder) to change the grid's values at runtime. | | `renderGrid(document, gridOptions)` | Handles the initial rendering of the AG Grid. It creates the HTML container for the grid, uses the AG Grid library (`window.agGrid`) to create the grid instance, and sets up a `cellClicked` event listener. | | `updateGrid(gridOptions)` | A helper function that calls AG Grid's internal API to update the grid's configuration, which is used by the subscription methods to apply changes. | | `emitCellClickedEvent(ev)` | This method is the component's output. It uses the Unqork Runtime's `api.events.emit() `function to send a custom event (`onAgGridCellClicked`) when a user clicks a cell in the grid. This allows other components or workflows in Unqork to react to the click by using the [Operations Builder](/v1/docs/operations-builder). | | `_normalizeInput(val)` | A utility method that checks if the input value is a string and, if so, parses it as JSON. This handles inconsistencies with how data might be stored in the Unqork platform. | | `_formatColumnDefinitions(defs)` | A helper method that translates the Unqork component's input format using the `key` and `label` properties into the format that AG Grid requires (`field` and `headerName`). | ### Understanding the `agGrid` and `agGridCellClicked` Exports These exports serve as the component’s manifest, providing the Unqork runtime with the necessary data to use the component. | Class | Description | | --- | --- | | `agGrid` | This object exports the `model` (the component’s data schema) and the `view` (the component itself). The Unqork platform uses this to configure the component's properties and render it correctly. | | `agGridCellClicked` | This object defines a custom event. It exports a model that describes the structure of the event's payload. For example, the `name` and `payload` when a grid cell is clicked. Doing so lets other parts of the Unqork platform use and understand the event that the component emits. | ## Create the BYO Component Package After the asset JavaScript and manifest.json files are complete, compress them into a BYO package. To compile a file using Terminal (Mac) or Command Prompt (Windows): 1. Using the command line prompt, navigate to the directory containing the `agGrid.js` and `manifest.json` files. For example, `cd C:\Users\UserName\Desktop\agGrid`. 2. Execute the following command: `tar -cvzf agGrid.tar.gz manifest.json agGrid.js`. ![Terminal window showing commands to create a tar.gz file from project files.](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Documentation/agGrid_packaging.webp?sv=2026-02-06&spr=https&st=2026-11-07T20%3A53%3A45Z&se=2026-11-07T21%3A53%3A45Z&sr=c&sp=r&sig=TMoB4lui2Oy1IU780zwG9ibUvmAgWw1QQ6wcICbkT48%3D) The `agGrid.js` file and `manifest.json` add to the `tar.gz` file in the same folder they're located in. > [!NOTE] > NOTE > > The steps above use the tar command and the following options: > > `-c`: Creates a new archive. > > `-z`: Compresses the archive using gzip. > > `-v`: Lists the files in the command line as they are added to archive. > > `-f`: Specifies the file name for the archived files. ## Upload the BYO Operation Package After creating the `agGrid.tar.gz` package, upload it to the Unqork Designer Platform using the Custom Assets Administration page: 1. From the UDesigner homepage, click **Administration**. 2. Under Assets, click **Custom Assets Administration**. 3. Click **+ Create New**. The Create Asset modal displays. 4. Under **File Upload**, click or drag the BYO Operation package from your local device to the upload window. 5. Click **Scan File**. The package details display. ![Create asset form for AgGrid version 1.0.0 with successful scan notification.](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Documentation/agGrid_createAsset.webp?sv=2026-02-06&spr=https&st=2026-11-07T20%3A53%3A45Z&se=2026-11-07T21%3A53%3A45Z&sr=c&sp=r&sig=TMoB4lui2Oy1IU780zwG9ibUvmAgWw1QQ6wcICbkT48%3D) 6. Click **Review Assets**. 7. Review the asset's details, including Components, Events, and Operations. 8. Click **Confirm & Create**. 9. Review the Library Usage Acknowledgment and Liability Agreement. Click the **☐ (checkbox)** to acknowledge the agreement. 10. Click **Create Asset**. The asset package displays in the Custom Assets’ **Packages** list. The package's individual assets display in the Assets tab's **Assets** list. The assets are now available in the Module Builder for all applications in the environment. ## Test the AG Grid Component Now that the BYO AG Grid component is in the Unqork Designer Platform, test its functionality in the Module Builder and Express View. This example assumes you are configuring a Vega (2.0) module. For this example, test the following functions: - **AG Grid Configuration Drawer:** Verify each setting is functional. - `agGridCellClicked` **Event:** Verify the event emits when clicking a cell in the grid. ### Configure the Text Field Component Use a [Text Field](/v1/docs/text-field-component) component to receive the final value created by using the BYO `agGridCellClicked` event and `SET_PROPERTY` operation. 1. In the Module Builder, drag and drop a **Text Field** component onto your canvas. 2. In the **Property ID** field, enter `output`. 3. In the **Label Text** field, enter `Cell Clicked`. 4. Click **Save Component**. ### Configure the Custom Component The Custom Component contains a list of all BYO components in the environment. Select the **AG Grid** component, then configure it to test its settings, and the custom `agGridCellClicked` event. 1. Drag and drop a **Custom Component** onto your canvas. 2. In the **Property ID** field, enter `byoAgGrid`. 3. From the **Select Component** drop-down, enter or select `AG Grid`. The component's configuration populates. 4. Click the **Add Item** button three times to create a total of four objects. 5. Configure each **Object** with the following: | Object # | Setting | Value | | --- | --- | --- | | Object 1 | Key | `make` | | Label | `Make` | | Object 2 | Key | `model` | | Label | `Model` | | Object 3 | Key | `price` | | Label | `Price` | | Object 4 | Key | `electric` | | Label | `Electric` | 6. In the **Value** field, enter the following table data: ```json [{"make":"Tesla","model":"Model Y","price":64950,"electric":true},{"make":"Ford","model":"F-Series","price":33850,"electric":false},{"make":"Toyota","model":"Corolla","price":29600,"electric":false},{"make":"Mercedes","model":"EQA","price":48890,"electric":true},{"make":"Fiat","model":"500","price":15774,"electric":false},{"make":"Nissan","model":"Juke","price":20675,"electric":false}] ``` #### Configure the byoAgGrid Event and Operation While remaining in the configuration drawer, set up the BYO `agGridCellClicked` event to trigger a Set Property operation. Configure the operation to retrieve the current selected AG Grid cell’s value. 1. Next to Events & Operations, click **Edit**. 2. From the **Select an Event** drop-down, enter or select `Cell Clicked`. This is the BYO event defined in the `agGrid.js` file. 3. Click **Add**. 4. Click **+ Add Operation**. 5. From the **Operation** Type drop-down, select `Set Property` . 6. In the **Target Key** field, enter `output`. This sends the operation’s output to the `output` Text Field component. 7. In the **Property** field, enter `value`. 8. In the **Value** field, enter `{{$event.payload.value}}`. When the end-user clicks on a cell, this dynamic value updates to the clicked cell’s value. 9. Click **Save**. 10. Click **Close**. 11. Click **Save Component**. 12. **Save** your module. module Your completed module looks like the following: ![BYO AG Grid component interface showing cell clicked and component options.](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Documentation/agGrid_ModuleBuilder(1).webp?sv=2026-02-06&spr=https&st=2026-11-07T20%3A53%3A45Z&se=2026-11-07T21%3A53%3A45Z&sr=c&sp=r&sig=TMoB4lui2Oy1IU780zwG9ibUvmAgWw1QQ6wcICbkT48%3D) ### Preview and Test the Module Finally, test your configuration and verify that the AG Grid table displays in Express View, and the `agGridCellClicked` event emits the **Set Property** operation. 1. **Preview** your module in Express View. 2. Verify the grid displays the table data contained in the Custom Component. 3. In the AG Grid, click on a **cell**. 4. In the **Cell Clicked** field, verify that the value matches the cell’s value. This verifies the `agGridCellClicked` is emitting properly. [expressView.webm](https://cdn.us.document360.io/15548f06-2fba-434c-b0c1-5df88317dbd7/Images/Documentation/agGrid_ExpressView.webm?sv=2026-02-06&spr=https&st=2026-11-07T20%3A53%3A45Z&se=2026-11-07T21%3A53%3A45Z&sr=c&sp=r&sig=TMoB4lui2Oy1IU780zwG9ibUvmAgWw1QQ6wcICbkT48%3D) If the custom asset functions as intended, then it’s ready to be used by Creators in the development of Unqork applications. If the Custom Operation generates errors or is missing features: 1. Create a copy of the current package and its contents. 2. Update the package's required files. 3. Change the package's version number. 4. Update the package by referring to the Package Management section in our [BYO Best Practices](/v1/docs/best-practices-bring-your-own-byo-framework#best-practices-bring-your-own-byo-framework) article. Also known as Unqork Users, or Designer Users; is anyone who is inside the Unqork platform. A key-value pair is a fundamental data structure where a unique "key" is associated with a specific "value," used for organizing and retrieving data efficiently, like in dictionaries or databases. A string is an object that represents a sequence of characters. Strings typically hold data represented in text form. An array is a type of object that stores one or more data types. Data types supported in arrays include numbers, strings, and objects. An object is a type of data structure that represents a single, self-contained entity that acts as a container for the characteristics of that entity. DOM (Document Object Model) events are signals or notifications that something has occurred or is occurring within a web page, often triggered by user interactions or by the browser itself. These events allow JavaScript to react to changes and interactions on a web page, making it dynamic and interactive. A UI (User Interface) Drawer is a layout panel that slides out from the side of the screen to display content. In UDesigner, components display their configuration panels in a drawer. JSON (JavaScript Object Notation) is an open standard file and data interchange format. Unqork uses JSON for submission (record) data. Rendering is the process of loading components and displaying the final result on the front-end screen. Programmatic namespacing is a way to group related code together under a common name so it doesn’t conflict with other code. It helps keep programs organized and prevents errors when different parts of a program use the same names. A runtime engine is software that runs on a computer to allow applications to execute. Rendering is the process of loading components and displaying the final result on the front-end screen. In Unqork an application is a program used to perform specific tasks. An application can be one of two types: workflow or module. Semantic HTML uses HTML elements to clearly describe their meaning, rather than just their appearance, to structure web content for better readability and accessibility for both humans and machines. An enum, or enumeration type, is a data type that consists of a set of named constants that a variable can be assigned to. Schema is a declarative language that defines the structure, content, and constraints of the data. APIs (application programming interfaces) are a set of protocols and definitions developers use to build and integrate application software. APIs act as the connective tissue between products and services. The Shadow DOM is a web standard that allows you to create encapsulated, hidden DOM subtrees for your web components. It provides a way to scope CSS styles and JavaScript behavior within a component, preventing them from leaking out and interfering with the rest of the page. Downstream logic occurs after current logic. For example, if you have components triggering in a chain, the components that are later in the chain are downstream. In JavaScript, a method is a function that is associated with an object. It is essentially a property of an object whose value is a function. Methods define actions or operations that can be performed on the object they belong to. The Document Object Model (DOM) is the data representation of objects that form the structure and content of a document on the web. The DOM represents the page. HTML (Hyper Text Markup Language) is the standard markup language for for achieving font, color, graphic, and hyperlink effects when creating web pages. Gzip is a file format and software application used for file compression and decompression. is a codeless and interoperable Unqork IDE (integrated development environment) with a new and improved user experience that allows for a seamless transition for all your applications. It features a modern user interface with new personalization, collaboration, and configuration experiences. A modal is a window that appears on top of the content you are currently viewing. The Vega (v 2.0.0) runtime is the next-generation engine of the UDesigner platform. Vega uses cutting-edge technologies to improve the Creator and end-user experience. ## Related - [Introduction to the Bring Your Own (BYO) Framework](/introduction-to-the-bring-your-own-byo-framework.md) - [Bring Your Own (BYO) 7.26 Implementation Examples](/bring-your-own-byo-726-implementation-examples.md) - [Bring Your Own (BYO): Custom Component](/bring-your-own-byo-custom-component.md)