Skip to content

Latest commit

 

History

History
142 lines (127 loc) · 7.45 KB

File metadata and controls

142 lines (127 loc) · 7.45 KB

Editable List

A component used for creating editable CRUD lists.

Usage

import

import { EditableList } from '@folio/stripes-smart-components';

set some data...

    const contentData = [
      {
        id: 1,
        name: 'Item 1',
      },
      {
        id: 2,
        name: 'Item 2',
      }
    ];

Use the EditableList component in your jsx

<EditableList contentData={contentData} createButtonLabel="+ Add new" visibleFields={['name']} onUpdate={this.handleUpdate} onDelete={this.handleDelete} onCreate={this.handleCreate} />

Configuration (props)

Name type description default required
canCreate boolean Determines if the '+ New' button is active. true no
contentData array of objects Array of objects to be rendered as list items. yes
nameKey string The key that uniquely names listed objects: defaults to 'name'. no
onCreate function Callback for creating new list items. no
onUpdate function Callback for saving record. no
onDelete function Callback for saving edited list items. no
label string The text for the H3 tag in the header of the component no
createButtonLabel string Label for the 'Add' button + Add new no
visibleFields array of strings Array of fields to render. These will also be editable. yes
itemTemplate object Object where each key's value is the default value for that field: { resourceType: 'book' } {} no
uniqueField string Fieldname that includes the unique identifier for the list. id yes
actionSuppression object Object containing properties of list action names: delete, edit and values of sentinel functions that return booleans based on object properties. { delete: () => false, edit: () => false } no
actionProps object Object containing properties of list action names: 'delete', 'edit' and values of sentinel functions that return objects to destructure onto the action button props. { delete: (item) => {return { disabled: item.item.inUse } } }
isEmptyMessage string Message to display for an empty list. no
readOnlyFields array of strings Array of non-editable columns - good for displaying meta information within the row. no
getReadOnlyFieldsForItem function Function that takes a row item as an argument and returns an array of non-editable columns. Can be used when different fields need to be editale based on item data. Values returned from this prop will be used together with values from readOnlyFields. no
formatter object Allows custom content/components to be displayed in the grid. see example below. no
columnMapping object Allows custom column names to be applied in case they differ from the properties of contentData's objects no
fieldComponents object Allows custom components for edit mode to be used. Fields not supplied will use a <TextField> by default no
hideCreateButton boolean Hides create button false no
columnWidths object Allows custom column widths to be set. If you use this, be sure to set a width for an 'actions' column as part of this object. no
id string Used as a basic suffix for id attributes throughout the component.
editable boolean Used as a flag for the component to be editable or not editable (without '+ New' button and column 'actions'). true no
withDeleteConfirmation boolean Should user be asked to confirm delete action false no
confirmationHeading function/string/node Confirmation modal heading. If it's a function - it will be called with id of the deleted item. yes
confirmationMessage function/string/node Confirmation modal message. If it's a function - it will be called with id of the deleted item. yes
confirmationCancelLabel string/node Confirmation modal cancel button label default label no
confirmationConfirmLabel string/node Confirmation modal confirm button label default label no

Custom Field Components

Many times a <TextField> won't be adequate for the value that needs to be edited, so to provide your own <Field>, using the fieldComponents prop is the way to accomplish this. It accepts an object with keys corresponding to visibleFields that contain render functions. The functions will be provided an object with a fieldProps key that can be spread on the <Field> for convenience (it applies name and aria-label props). Other provided props are listed after the example.

Say we want to set up one of our fields (color) to use a <Select> instead of the default <TextField>:

// define the custom components, being sure to pass in the appropriate props for redux-form to work and for *accessibility*.

this.fieldComponents = {
      color: ({fieldProps}) => (
        <Field
        { ...fieldProps } // spread fieldProps to apply 'name' and 'aria-label' props.
        component={Select}
        marginBottom0
        dataOptions={[
          {label: 'orange', value: 'orange'},
          {label: 'blue', value: 'blue'},
          {label: 'red', value: 'red'},
        ]}/>
      )
    }

    // ... later in the JSX...

    <EditableList
      columnMapping={{
        id: "Identifier",
        name: "title",
      }}
      contentData={this.contentData}
      visibleFields={[
        "id",
        "name",
        "color",
      ]}
      fieldComponents={
        this.fieldComponents
      }
    />

Render props provided to fieldComponent function

Name description
fieldProps contains name (required by <Field>) and aria-label props.
fieldIndex the index of the field on the row.
rowIndex the index of the editable item within the list.
name the lone string key of the field (same as provided in the visibleFields prop).
mappedName the name for the column used in columnMapping, if any (otherwise, same as name.)

Using formatters for custom data

Sometimes the data alone just won't serve what you need and it needs to be formatted in some certain way. The formatter prop allows for custom rendering of data. Each key of the formatter object should correspond with a field from visibleFields that you'd like to render custom content for. The function will be passed the data object for the particular item of the list, so multiple data points can be used to affect the display. In this example, the lastUpdated column will be made to display a custom component <RenderLastUpdated>, but the function could also simply return a string. There's no actual lastUpdated property within the contentData array's objects - formatters can be used to add completely custom columns.

//basic array for contentData
const contentData = [
  { group: "group0", desc: "desc0" }
  { group: "group1", desc: "desc1" }
  { group: "group2", desc: "desc2" }
]

// set up formatter
    const formatter = {
      lastUpdated: item => (<RenderLastUpdated                  // this component uses other data in the objects to match the user info with the date
        lastUpdated={item.lastUpdatedDate}
        user={item.lastEditingUser}
      />
      ),
    };

// later in JSX...
    <EditableList
      contentData={this.props.resources.groups.records || []}
      visibleFields={['group', 'desc', 'lastUpdated',]}
      columnMapping={{ desc: 'Description', lastUpdated: 'Last Updated', }}   // set column headers text
      readOnlyFields={['lastUpdated']}                                        // set formatter-controlled field as read-only
      {...otherProps}
      formatter={formatter}
    />