Multi-row editing

Enabling an end user to be able to select multiple rows in a DataTable and group edit the values is a very powerful feature and can greatly simplify complex editing interactions, allowing data updates to be performed very quickly. The ability to create and edit multiple rows was introduced in Editor 1.5 and this document provides an overview of how it operates from end user and developer points of view.

End user

Multi-row editing in Editor starts with providing the end user the ability to select multiple rows in the table - this is done by the Select extension for DataTables that provides complex row selection options. In its default mode of operation (setting the select option to true) Select performs in the same way as an operating system's file selection by mouse works - specifically you can select a single item by clicking on it, range select by holding the shift key while clicking an item and toggle the selection of individual items by holding the cmd/ctrl key while clicking (the select.style option provides other options in addition to this row selection style).

Once an end user has selected the rows they wish to edit they can then click the table's Edit button (or otherwise trigger the edit() method if you are not using the default buttons).

User Interface

The user interface presented to the end user provides a slightly simplified editing environment for the items being edited in that the item values cannot be edited individually, but rather the value can only be changed collectively (i.e. the field's value is applied to all items - see the API information below if you need the ability to set item values individually).

Setting a common value for all items is not always desirable, so Editor will automatically determine which items share a common value for each field in the form and which items have different values. The result of this check directly affects the form that the end user will see:

  • For fields where all items being edited share the same value the standard input element for that field is shown.
  • For fields where the items have one or more different values an information message is shown.

When the multi-value information message is shown (i18n.multi.title) the data submitted to the server will be the original individual values for each item. If the user decides to edit a field's value they can click that message and the standard field input will be shown, allowing a value to be entered that will be collectively assigned to all items. The user also has the option to return to the original multi-value state if they activated the edit by mistake.

This method of editing multiple items provides the ability to easily edit a common value for a single field, while retaining the individual values for other fields (for example you might have a "Completed" field which can be updated without effecting the other values of the items being edited).

Example

Consider the following image:

Multi-row editing UI

It shows a DataTable with two rows being edited. There are two fields with common values (last name and location) and two fields with differing values (first name and phone #) - note how these two latter fields show a Multiple values information message.

Submitting the form to the server in that state would result in the individual values for those fields being submitted. If we were to click on the "First name" multi-value information notice we could enter a value and that value would be common to both items being edited.

All of the examples available on this site are capable of multi-row editing (Editor requires no additional configuration options to allow multi-row editing, it is a core feature of the software). Try experimenting with the various options available!

Selecting cells and columns

Multi-item editing in Editor is not limited to just rows, but also columns and cells can be selected and edited. Again the Select extension is used to provide the item selection options and the end user can toggle between what items are being selected through the selectRows, selectColumns and selectCells button types that Select provides.

Furthermore, it is possible for multiple different items to be selected at the same time and edited together (for example a row and a column could be selected and edited at the same time). This can make it easy for the end user to perform very complex data updates with the minimum of time and effort.

Developers

Editor's core UI provides comprehensive multi-row editing support as discussed above, but as with the rest of Editor, to truly unlock its potential its API can be used to perform complex data manipulation. For example, while the UI provides the option to set a common value for the items being edited or retain the existing multiple values, the API provides the ability to set different values for the items being edited and submit them to the server.

The key API methods for multi-row editing are:

  • multiGet() - Get the values for one or more fields
  • multiSet() - Set the values for one or more fields
  • field().multiGet() - Get a field's value for an individual item, or all items being edited
  • field().multiSet() - Set a field's value for an individual item, or for all items being edited
  • field().isMultiValue() - Determine if the field has a common value for all items being edited or not.

Note also that there is an impact on the non-multi-row editing aware methods (val() and field().val() for example):

  • Getting a value - if there is a common value then that value is returned, however if the value is not common to all items being edited undefined is returned.
  • Setting a value - the value is set as common to all items being edited.

Data format

To fully understand Editor's multi-row editing abilities, it is necessary to understand the data structure Editor uses for the values in each field. The data is stored in an object where the row's id is used as the parameter key, while the value stored in the parameter's value. This data object can be accessed using the field().multiGet() method.

Consider for example an Editor instance that has a field called 'first_name' and two rows are being edited (id's 'row_12' and 'row_41'):

editor.field( 'first_name' ).multiGet();
// Result:
//  {
//      "row_12": "Allan",
//      "row_41": "Charlie"
//  }

editor.field( 'first_name' ).val()
// Result:
//  undefined

Note that using field().val() returns undefined as the two different values cannot be represented without the multi-item object.

To set the value for an individual item we can use the field().multiSet() method:

editor.field( 'first_name' ).multiSet( 'row_41', 'John' );

editor.field( 'first_name' ).multiGet();
// Result:
//  {
//      "row_12": "Allan",
//      "row_41": "John"
//  }

editor.field( 'first_name' ).val()
// Result:
//  undefined

Equally we can set a common value by not passing a row id parameter to the field().multiSet() method:

editor.field( 'first_name' ).multiSet( 'Fred' );

editor.field( 'first_name' ).multiGet();
// Result:
//  {
//      "row_12": "Fred",
//      "row_41": "Fred"
//  }

editor.field( 'first_name' ).val()
// Result:
//  "Fred"

Extending this to multiple fields can be done using the multiGet() and multiSet() methods.

Please note that there is no val() or field().val() equivalent for multi-row editing as the arguments could potentially be ambiguous. Hence why the get and set operations must be separated into two different methods.

Create new rows

Multi-row actions are limited to only editing in Editor, 1.0+ has supported multi-row deletion, but alongside the multi-row editing of 1.5 it is also possible to create multiple rows with a single call. The number of rows to be created is defined by the optional count parameter given to the create() method.

When using multi-row editing field values can be addressed individually through the row id, as discussed above - however, when creating new rows the rows do not have ids assigned until submitted to the server, so the rows are assigned indexes 0...N where N is the number of rows being created.

When creating multiple rows the UI behaviour is identical to the edit behaviour - i.e. input values via the UI are assigned to all items being created. Therefore, the API is far more likely to be useful when creating multiple rows.