formhandler.md 8.81 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
# $.formhandler

An interactive table component for [FormHandler][formhandler] data.

```html
<div class="formhandler" data-src="formhandler-url" data-page-size="10"></div>
<script>
$('.formhandler').formhandler({
  pageSize: 20
})
</script>
```

Options can passed via an options dict, and over-ridden using `data-` attributes.
In the above example, `data-page-size="10"` over-rides `pageSize: 20`.

[formhandler]: https://learn.gramener.com/guide/formhandler/

## $.formhandler options

The full list of options is below. Simple options can be specified as `data-` attributes as well.

- `src`: [FormHandler][formhandler] URL endpoint
- `data`: Array of objects. Dataset for formhandler table. If both `src` and `data` are provided, `data` takes priority.
- `namespace`: (Optional) If the URL has `?name:key=value`, the filter
  `key=value` only applies to formhandlers with namespace as `name`.
  Filters without a namespace like `?key=value` will apply to all formhandlers.
- `columns`: comma-separated column names to display, or a list of objects with these keys:
    - `name`: column name. `"*"` is a special column placeholder for "all columns" (options given for `"*"` are applied for all columns)
    - `title`: for header display. Defaults to the same value as `name`
    - `type`: `text` (default) / `number` / `date`. Data type. Determines filters to be used
    - `format`: string / function that returns formatted cell display value.
      - function accepts an object with these keys:
        - `name`: column name
        - `value`: cell data value
        - `row`: row data
        - `index`: row index
        - `data`: the dataset from `src`
      - strings specify a numeral.js format if the value is a number (you must include numeral.js)
      - strings specify a moment.js format if the value is a date (you must include moment.js)
    - `editable`: `true` (default) / `false`. When `true`, edit and save buttons appears at end of each row.
    - `template`: string template / function that renders the cell.
      - function accepts an object with these keys:
        - `name`: column name
        - `value`: cell data value
        - `format`: formatted cell display value
        - `link`: cell link value (if applicable)
        - `index`: row index
        - `row`: row data
        - `data`: the dataset from `src`
      - string template can use the above variables
    - `sort`: `true` / `false` / operators dict with:
      - `{'': 'Sort ascending', '-': 'Sort descending'}` (default)
    - `filters`: `true` (default) / `false` / operators dict with:
      - `{'', 'Equals...', '!', 'Does not equal...', ...}`.
        The default list of operators is based on the auto-detected type of the column.
    - `link`: string / function that generates a link for this each cell.
      - If no `link:` is specified, clicking on the cell filters by that cell.
      - If `link:` is a function, opens a new window with the URL as `fn(args)`.
        - function accepts an object with these keys:
          - `name`: column name
          - `value`: cell data value
          - `format`: formatted cell display value
          - `index`: row index
          - `row`: row data
          - `data`: the dataset from `src`
        Example: `function(args) { return 'https://example.org/city/' + args.value }`
      - If `link:` is a string, opens a new window with the string URL interpolated as a lodash template with an object (mentioned above) as data.
        Example: `"https://example.org/city/<%- value >"`
    - `hideable`: `true` (default) / `false`. Show or hide `Hide` option in header dropdown
    - `hide`: `true` / `false` (default). Hides the column
    - `unique`: TODO: {dict of query parameter and display value} or [list of values] or function?
- `edit`: Shows the Edit control. Can be `true` / `false` (default). Can also pass an object.
  - `done`: function that gets called after saving the edited row.
- `add`: Show the Add control. Can be `true` / `false` (default). Can also pass an object.
  - `done`: function that gets called after saving the new row.
- `actions`: A list of objects. you need not add it to actions
  - `{{action}}`: a function() that gets triggered on clicking the element with `data-action='{{action}}` attribute. The value of `data-action` attribute must match with key `{{action}}` in `actions`.
      - function accepts an object with these keys:
        - `row`: row data
        - `index`: index of the row in the dataset from `src`
      Example:
      - `highlight_row`: `function(obj) { $(obj.row).addClass('.yellow_color')}`. Either a new column can be defined in `columns:` (example: {`name`: `Additional Col`}) with cell_template having an element with data attribute as `data-action='highlight_row'` or can use an existing column but with custom template that has an element with data attribute as `data-action='highlight_row'`.
  - Note: DELETE operation is executed on a row if an element has data attribute `data-action='delete'`. If `delete` action is given in `actions`, the function given for `delete` is executed on click of an element with `data-action='delete'` instead od executing DELETE operation.
- `table`: Shows the table control. Can be:
  - `true`: displays a table (default)
  - `'grid'`: renders a grid instead of a table
  - `false`: disables the table (and shows nothing for the main content)
- `count`: Shows the number of rows. Can be `true` (default) / `false`
- `page`: Shows the page control. Can be `true` (default) / `false`.
- `pageSize`: page size. Defaults to 100
- `size`: Shows the page size control. Can be `true` (default) / `false`
- `sizeValues`: Allowed page size values. Defaults to `[10, 20, 50, 100, 500, 1000]`
- `export`: Shows the export control. Can be `true` (default) / `false`
- `exportFormats`: {xlsx: 'Excel'}
- `filters`: Shows the applied filters control. Can be `true` (default) / `false`
- `transform`: an optional function() that modifies data. It accepts a dict that has keys:
    - `data`: the FormHandler data
    - `meta`: the FormHandler metadata from the `FH-*` HTTP headers
    - `args`: the URL query parameters passed to the FormHandler
    - `options`: the options applicable to the FormHandler
    - returns a dict with modified values of `data` and `meta`
- `icon`: if `table: 'grid'` is used, display an icon. string / function that renders the cell.
    - function accepts an object with these keys:
      - `row`: row data
      - `data`: the dataset from `src`
      - `index`: index of the row in the dataset from `src`
  Example:
    - `icon: 'fa fa-home fa-3x'` renders a FontAwesome home icon
    - `icon: './path/to/image.png'` renders the image specified
    - `icon: function(args) { return args.row['image_link'] }` renders an image with `src` attribute as the value from column name `image_link`

**Advanced**. Each component can have a target which specifies a selector. For
e.g., to render the export button somewhere else, use
`data-export-target=".navbar-export"`. This replaces the `.navbar-export`
contents with the export button. (It searches within the table container for
`.navbar-export` first, and if not found, searches everywhere.) Available
targets are:
- `tableTarget`
- `countTarget`
- `pageTarget`
- `sizeTarget`
- `exportTarget`
- `filtersTarget`
- `searchTarget`

**Advanced**: Each component's template string can be over-ridden. For example,
`data-search-template="<input type='search'>"` will replace the search template
with a simple input. Available template strings are:
- `tableTemplate`
- `countTemplate`
- `pageTemplate`
- `sizeTemplate`
- `exportTemplate`
- `filtersTemplate`
- `searchTemplate`
- `rowTemplate`, which can be a string template or function
  - function accepts an object with these keys:
    - `row`: row data
    - `index`: row index
    - `data`: the dataset from `src`
  - string template can use the above variables

Features to be implemented:

- Loading indicator
- Full text search
- URL targets other than '#', e.g. pushState

## $.formhandler events

- `load` is fired on the source when the template is rendered. Attributes:
    - `formdata`: the FormHandler data
    - `meta`: the FormHandler metadata
    - `args`: the URL query parameters passed to the request
    - `options`: applied options to the FormHandler

  Note: Make sure `load` event listener is attached before calling `$.formhandler()`

## $.formhandler examples

Render a table using the FormHandler at `./data`:

```html
<div class="formhandler" data-src="./data"></div>
<script>
  $('.formhandler').formhandler()
</script>
```

Customize cell rendering to display a chart in a cell:

```html
<div class="formhandler" data-src="./data"></div>
<script>
  $('.formhandler').formhandler({
    columns: [
      {name: '*'},
      {
        name: 'c1',
        format: function (o) {
          return '<svg height="10" width="10"><circle cx="5" cy="5" r="' + o.c1 / 10 + '" fill="red"></circle></svg>'
        }
      }
    }
  })
</script>
```