Custom Field Renderers

Contact your Skuid representative to access this feature.

Field renderers are how Skuid renders the data of an individual field within a component—particularly the Form and Table components. Skuid builders may create custom field renderers by writing JavaScript snippets, which allow you to display field data in ways Skuid’s standard field renderers may not be able to while also retaining the context and structure provided by an existing Form or Table component.

If you need to parse the data into a specific format, or use HTML to properly display data within a component, but do not require the extensive capabilities of a whole new component, custom field renderers are a useful tool. They could be used to display an embedded video, represent field values as icons, or style field elements in ways the DSS does not currently support.

Prerequisites and Concepts

Creating custom field renderers requires a degree of knowledge in several areas related to JavaScript. This topic assumes you’re already familiar with the concepts covered in the UI code topic.

Usage

Create a snippet

Field renderers are JavaScript snippets that can be created from the App Composer.

  1. Click the JavaScript tab in the Elements pane.

  2. Click add Add Javascript resource and configure

    • Resource type: Field Renderer.
    • Custom field renderer name: Enter an appropriate name describing your field renderers.
    • Snippet body: Edit to include your field renderer JavaScript code.

By creating a snippet in this way, Skuid supplies the boilerplate code with all necessary parameters for a functioning field renderer. This code may be altered as needed as long as the snippet returns a FieldRenderer with the return keyword.

Warning

If there are multiple child nodes within your mode functions, be sure to see how to designate distinguishable children below within the UI code topic.

Assign the field renderer

To assign a field renderer to a field within a component:

  1. Click the field within the target component within the canvas.
  2. Change the Display as property to Custom.
  3. Select the field renderer you wish to assign within the Custom field renderer field.

Rendering strategies

The readModeStrategy and editModeStrategy parameters determine how Skuid will attempt to render the DOM nodes described in the read and edit parameters. The render strategy chosen for these modes affects how you must describe your field renderers.

Note

For more information on the differences between these strategies, see the UI Code topic.

Two render strategies are available for general use:

  • Virtual: Utilizes the virtual DOM and the maquette library to quickly render and re-render components. Similar to the rendering used by Skuid’s own Ink components, and compatible with the Design System Studio. To use this render strategy, enter "virtual" as the value for the parameter. When using virtual rendering for custom field renderers, you’ll need to write in HyperScript notation.
  • Element: Renders and re-renders components by directly manipulating the DOM. Similar to v1’s custom field renderers. To use this render strategy, enter "element" as the value for the parameter.

The virtual rendering strategy is considered best practice and is advised in almost all field renderer use cases. This strategy leads to performance improvements and cleaner code. In contrast, the element rendering strategy’s direct DOM manipulation is more taxing on the browser. However, it can allow for quick conversion of v1 field renderers or other UI elements written in jQuery-esque syntax

read and edit mode functions

After selecting a render strategy, the read and edit parameters are written as functions that determine either the virtual DOM node (VNode) or DOM node that will be rendered when the field enters the appropriate mode. The rendering strategy selected above determines how these mode functions must be written.

Note

Regardless of rendering strategy, custom field renderers are very neutral in their behaviors by default, meaning some of the features of Skuid’s default field renderers (e.g., triggering the row updated event on value changes) are not automatically triggered with custom field renderers. However, this event is included in the boilerplate code supplied for the virtual rendering strategy.

The fieldComponent parameter and context

Regardless of render strategy, the read and edit mode methods both receive fieldComponent as their parameter. This is the actual field element within the Form or Table component.

One of the most important functions available within the fieldComponent’s CPI is getContext(). This retrieves the context object of the current field. Using the information available in this object is the key to creating a dynamic, custom field renderer.

  • context.element: The DOM element displayed when the element rendering strategy is used
  • context.field: The field itself as a JavaScript object
  • context.model: The model of the field, as a skuid.model.Model object
  • context.row: The row of the field, as a JavaScript object
  • context.value: The value of the field

It can often be helpful to assign these to variables using destructuring in read and edit functions:

1
2
3
4
5
6
7
read: function (fieldComponent) {
  let h = fieldComponent.h,
    context = fieldComponent.cpi.getContext();
    // Destructure one or more of these variables this way.
    let { element, field, model, row, value } = context;
    console.log(value); // This would be now be equivalent to context.value.
    ...

Warning

Always ensure child nodes within your mode functions are distinguishable. See the related section in the UI Code topic for more info.

Additional data grid mode features with dataGridOptions

The Table component’s data grid mode has several additional options that determine how a field cell responds to an end user’s actions. These options are passed into the field renderer through with dataGridOptions.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
dataGridOptions: {
  needsFocusToEdit: true,
  onCopy(fieldComponent) {
    // Custom copy logic code
  },
  onCut(fieldComponent) {
    // Custom cut logic code
  },
  onPaste(fieldComponent, text) {
    // Custom paste logic code
  }
}
  • needsFocusToEdit: Determines whether or not the cell is disabled until the user focuses on it—i.e. requiring the user double click to edit its value. This defaults to true, but this may not be desirable for all fields types For example, end users typically want to interact with boolean checkboxes without focusing the cell first.

  • onCopy and onCut: Determine what happens when the end user copies or cuts the cell, respectively. The fieldComponent calling the renderer is passed into these methods as the first argument.

    Errors thrown within these methods are caught and shown at runtime as toast messages. For example, a password field could prevent copying values with new Error("Can't copy passwords");

1
2
3
4
5
6
onCopy(fieldComponent) {
  throw new Error("Can't copy passwords");
},
onCut(fieldComponent) {
  throw new Error("Can't cut passwords");
}
  • onPaste: Determines what happens when the end user pastes within the cell. The fieldComponent calling the renderer is passed into the method as the first argument, and the field’s value is passed in as its second argument (text), so that value can be used for custom paste logic.

When using the virtual rendering strategy

If using the virtual rendering strategy, functions must be written in HyperScript syntax and then must return the result of that HyperScript function.

CSS definitions are passed in as key-value pairs in the styles object. These keys can be camelCase or strings that reflect the kebab-case name of the CSS property. For example, the following styles settings will result in the same CSS values.

1
2
3
4
5
6
styles: {
  fontSize: "20px",
}
styles: {
  "font-size": "20px",
}

Using the element rendering strategy

In contrast to virtual rendering, which requires a HyperScript node be returned, element rendering instead looks to the fieldComponent’s context.element attribute, which is by default an empty div.

Changes to this DOM element must be made using standard DOM element APIs and properties. Additional elements must be made using other DOM manipulation APIs like document.createElement() or jQuery functions a la skuid.$, and then appended to the context.element.

After creating the DOM element, the context.element parameter must then be set to that newly created node. Style variants are not applied.

Troubleshooting

Because custom field renderer implementations vary widely by use case, troubleshooting custom code can often be a bit more involved than Skuid’s declarative options. If you’re seeing issues with your field renderers, be sure to try the following:

  • Test the runtime of your field renderer and look for errors in the browser console.
  • Try console.log(variable) statements to see the state of variables at different points in the field renderer. This can be particularly helpful for context.
  • Consider adding debugger statement as breakpoints.
  • If your field renderer has multiple VNodes and you’re seeing odd UI behavior, always ensure those VNodes have unique keys.