Overview

DataGrid is a UI for both rendering and editing tabular data. It renders structured data in a table and creates editors for each cell which can update cell's data. Editing the data happens "instantly" - single click on a cell "opens" it in "edit" mode - loads cell's contents in editor. Text data (strings) is edited via textarea or input[type="text"] elements. In fact, data is always kept in them, but visually the user cannot recognize this, as when not in "edit" mode, the inputs and textareas have no backgrounds and borders.

With this interface the end user can add new rows and delete existing rows. DataGrid is fully extensible in adding more Editors, Widgets, Sort Parsers, Event Handlers, etc.

 

Include Resource Files

All files are stored under /Shared/UIComponents/Internal/DataGrid/ directory:

  • <script src="/Shared/UIComponents/Internal/DataGrid/globals.js"></script> (required)
  • <script src="/Shared/UIComponents/Internal/DataGrid/data_grid.js"></script> (required)
  • <script src="/Shared/UIComponents/Internal/DataGrid/row.js"></script> (required)
  • <script src="/Shared/UIComponents/Internal/DataGrid/db.js"></script> (optional)
  • Editors (optional, may not include if the grid is read-only)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Editors/checkbox.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Editors/date.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Editors/display_only.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Editors/fileupload.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Editors/icon_picker.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Editors/inline_base.js"></script> (required if any editor type is specified)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Editors/input.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Editors/link.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Editors/radio.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Editors/textarea.js"></script> (optional)
  • SortParsers (optional, may not include if there is no column sorting)
    • <script src="/Shared/UIComponents/Internal/DataGrid/SoftParsers/currency.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/SoftParsers/date_iso.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/SoftParsers/date_locale.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/SoftParsers/digit.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/SoftParsers/filesize.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/SoftParsers/percent.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/SoftParsers/sk_link.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/SoftParsers/text.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/SoftParsers/time.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/SoftParsers/url.js"></script> (optional)
  • Widgets (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Widgets/row_order.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Widgets/row_select.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Widgets/row_buttons.js"></script> (optional)
    • <script src="/Shared/UIComponents/Internal/DataGrid/Widgets/row_group.js"></script> (optional)

 

Usage

var my_grid = new SK.UI.DataGrid( container, options );
my_grid.loadData( data );

where:

  • container - the container DOM element. Can be String (the container's id) or the DOM element
  • options - Object
  • data - array data (database rows or array)

 

Detailed list of configuration options

Name Description Type Default Value
source_type The data source. Can be 'db' (database) or 'array'. String 'db'
columns Properties for each grid column. Each column is an Object, containing the Column Options. Array -
reorderable Whether the user will be able to reorder table rows in the grid or not. Boolean false
sortable Whether the user will be able to sort rows by a column. Boolean false
header Whether the grid has table header or not. Boolean true
header_fixed Whether the grid header is "fixed” or not (only grid content is scrollable). Boolean false
toolbars_buttons Top and bottom toolbar configuration. These are two sets (top toolbar, bottom toolbar) with options for the ToolbarManager. Object -
row_buttons Row Buttons configuration. Array [{caption : 'Delete', event : 'delete'}]
item_name The title of a single row (item). String 'Item'
new_row_position Where the newly created by the user row should be appended. Can be 'top' or 'bottom'. String 'bottom'
autohighlight Whether to highlight row on mouse enter and remove highlight on mouse leave. Boolean true
confirm_delete_row_msg Custom confirmation message shown to user when prompted to delete a row. String -
debug When set to true outputs in browser's console useful information. Useful in development only. Boolean false

 

Column options

Name Description Type Default Value
title The label of the column. Will be printed if configuration option 'header' is set to true. String -
width The width of the column in pixels. Integer -
id The id of the column. If configuration option 'source_type' is set to 'db', this id has to be the column's id. String -
hidden If set to true, the data exists in Row instance; it can be retrieved with Row.getData() and Row.getCellData(column_id), but the column won't exist in the DOM. Boolean -
sortable The id of the Sort Parser, used for the data sorting. String -
editor See editor options. Object -
validate Executes on saving the editor value. Passed arguments: [ editor ] Function -

 

Row Buttons configuration

Row buttons are Widgets. They extend Row's functionality and may have access to Row's data.

Row options are set in the Configuration Options, before grid's construction. Each row button may have the following options:

  • caption : String. The button's label.
  • event : String. The event name which will be fired when the button is clicked.
  • class : String. The button's className.

 

Methods

Base class methods

Name Description Parameters Returns
getRoot Returns the root HTML DOM element, which wraps all DataGrid DOM elements. This is different from the wrapper HTML element, used in the grid's Configuration Options - root : HTML DOM element
getTableBody Returns table body element - tbody : HTMLElement
getBody Alias of getTableBody - tbody : HTMLElement
getTableWrapper Returns parent of table body element - wrapper: HTMLElement
hasHeader Returns Boolean if there is a table header. - Boolean
hasToolbar Returns Boolean if there is a toolbar at the specified position, sent as an argument. position : String ('top' or 'bottom') Boolean
getToolbar Returns the SK.UI.ToolbarManager instance. position : String ('top' or 'bottom') Object
loadData Loads external data into the grid (database rows or array structured data). data : Database rows or Array -
unloadData Unloads grid data (empties the grid). - -
getData Retrieves grid data. (loops each row and retrieves its data, and pushes it to array) - Array (database rows or array)
getNewData Returns array of recently added rows' data - data : Database rows or Array
getModifiedData Returns array of recently modified rows' data (one or more cell values are changed) - data : Database rows or Array
getDeletedData Returns array of recently removed rows' data - data : Database rows or Array
deleteRow Deletes specific row from the grid. row: Object (DataGrid.Row instance) -
addRow Adds new row in the grid. data : Array [, position : String ('top' or 'bottom')] -
getAllRows Gets and returns all row elements in the grid. - rows : Array
getNewRows Gets and returns all new row elements in the grid (recently added). - rows : Array
getModifiedRows Gets and returns all modified row elements in the grid (recently changed). - rows : Array
getDeletedRows Gets and returns all deleted row elements in the grid (recently removed). - rows : Array
getRow Gets a single grid row by given index. index : Integer row : Object
getHeight Returns the height of the whole grid. - height : Integer
setHeight Sets the desired height to the grid. Useful in combination with Fixed Header. height : Integer -
adjustLayout Useful when header_fixed option is set to true. Sets the proper height of table-body and width of table-header. Fires onLayoutChange event. height: Integer (the desired height of the grid to set) -
enableTabindex Enables the feature: create a new row with tabindex when the last editor is focused. - -
disableTabindex Disables the feature: create a new row with tabindex when the last editor is focused. - -
scroll Useful only when header_fixed option is set to true. Scrolls the table-body to the given @direction ('top' or 'bottom'), or to the option new_row_position value. direction: String ('top' or 'bottom') DataGrid instance
countRows Returns total number of rows in the grid. - Integer
findRowsByCellValue Returns array of rows that match a passed cell value in certain column column_id : String, value : String Array
findRowByRowId Returns a row by its database row ID row_id : String row : Object or undefined
destroy Destroys the whole DataGrid. - -

 

Row methods

 

Name Description Parameters Returns
getGridInstance Returns the grid instance. - grid : Object (DataGrid.InlineEdit instance)
getData Returns row's data. - data : Object (column_id:value pairs)
setData Sets row's data. data : Object (column_id:value pairs) -
getCellData Retrieves and returns data from a specific cell in the row. column_id : String data : Mixed
setCellData Sets data to a specific cell in the row. column_id : String, data : Mixed -
getEditor Returns the editor's object instance of the specified cell in the row. column_id : String editor : Object
getEditors Returns object containing all row's editors - {column_id: editor, column_id: editor, ... } - editors : Object
getFirstEditor Returns the editor's object instance from the first editable cell of the row. - editor : Object
hasEditor Checks whether the specified cell has an Editor. column_id : String Boolean
getWidget Returns the instance of the specified Widget. column_id : String widget : Object
hasValidator Checks if the specified cell has a validator attached to it's Editor. column_id : String Boolean
setValidator Overrides the validator function of the specified cell. column_id : String, validator : Function -
getValidator Retrieves and returns the validator of th specified cell. column_id : String validator : Function or null
highlight Shows/hides row's Editors. state : Boolean -
getDomNode Returns row's HTML DOM <tr> element. - HTMLTrElement
enableAutoHighlight Enables <tr> highlight on mouse enter/leave ignoring the global autohighlight option in InlineEdit - -
disableAutoHighlight Disables <tr> highlight on mouse enter/leave ignoring the global autohighlight option in InlineEdit - -
isAutoHighlightEnabled Returns autohighlight option. - Boolean
destroy Destroys the row. - -

 

Extensions

The DataGrid's Extensions are used to spice up the interface features and functionality. Current extensions are Editors, Widgets, Sort Parsers, Local Storage, DataBase.

Editors

Editors are UI controls for editing row's data. They have the following properties:

  • onCreate : Function. Executed when the editor or widget is initialized. Passed arguments: [ editor or widget instance ]
  • type : String. The Editor's or Widget's id
  • options : Object. Contains editor's options (DOM attributes or properties)

Each editor represents one cell from the row. Different editors may have different set of options. But each editor type has the same public methods:

  • getValue - retrieves editor's value and returns it
  • setValue - set a value to the editor. Accepted arguments: [ value : String ]

Available Editors:

Editor Name ID Description
Text Field input This is a regular input[type="text"] element.
Textarea textarea Extended HTML textarea with Textarea-Autoresize feature (the textarea resizes itself depending on how much content it has).
Checkbox checkbox Regular input[type="checkbox"] element.
Radio Button radio Regular input[type="radio"] element. If name is not set explicitly in the options, the default value for the name attribute is datagrid_radio.
File Upload fileupload FileUpload component.
Display display_only Displays data in plain text/html. Implements getValue and setValue interfaces.
Date date Text field, but provided with Date Picker UI. Uses Location Formats
Icon Picker icon_picker Creates instance of IconPicker
Link link Provides LinkInterface

 

Widgets

Widgets are UI controls for extending rows' functionalities: deleting a row, reordering rows, select multiple rows, etc. Widgets also have access to the row data, and can even extend the whole grid as well.

 

Available Widgets:

Widget Name ID Description
Row Buttons row_buttons Adds buttons (instances of SK.UI.Properties.Button) to each row with different actions. Each button may have event, which is fired when the button is clicked. Handler actions can be attached to this event in the Configuration Options (see row_buttons option)
Row Order row_order If the Configuration Option reorder is set to true, this Widget adds handle at the beginning of each row by which the row can be reordered in the table.
Row Select row_select Adds a checkbox at the near end of each row in the table. This checkbox has nothing to do with row's data; it executes a callback function on its state change.
Row Group group Groups cells' values into one <td> element. Accepts Array with cells' IDs to group and a joiner (String glue), or a formatting custom function. Implements getValue and setValue interfaces.

 

Sort Parsers

Sort Parsers are custom functions for sorting different types of data. When having the Configuration Option sortable set to true, a Sort Parser must be set to each column by which we want to sort. We set a Sort Parser via the Column Option sortable, and the value is the Sort Parser's id:

  • currency
  • date_iso
  • date_locale (see LocationFormats)
  • digit
  • filesize
  • percent
  • sk_link (compares values from LinkInterface)
  • text
  • time
  • url

When sorting by column, each row is looped, the appropriate value is retrieved and the corresponding Sort Parser is used for the custom sorting function.

 

Local Storage

This extension adds a local storage feature to DataGrid, but it differs from other extension types like Editors and Widgets in the way it constructs - it has to be implemented by your DataGrid instance. Or you may create a new Class, extending DataGrid, and implementing the Local Storage:

var MyDataGrid = new Class({
   Extends        : SK.UI.DataGrid,
   Implements     : [
      SK.UI.DataGrid.Extensions.LocalStorage
   ]
});

Local Storage extension is tightly connected with the Sort Parsers. However, we can skip adding the Sort Parsers in the fat files if we do not need sorting at all.

 

Public Methods

Name Description Parameters Returns
filterLocalStorage Filters grid data. Takes into consideration the sorting. properties (Object, can have 2), properties sort{} and filters[] -

 

Sort

The sort object has 2 properties: column_id and column_type. When declared, filtered data will be also sorted depending on the values of these properties.

{
   column_id      : '123.123456',   // ID of the column
   column_type    : 'date'          // sort type of the column
}

 

Filters

The Filters Array contains Filter Groups, which are also Arrays, which contain Filter Objects:

   {
      column_id   : 'column_id',
      expression  : /regexp pattern/ // RegExp pattern or function
   }

 

All Filter Objects in a Group are OR-ed (disjunction). All Groups are AND-ed (conjunction).

 

Example of a Filters Array:

var filters     = [
   [
      // these will be OR-ed
      {
         column_id   : '11.545',
         expression  : /test/i
      },
      {
         column_id   : '11.454',
         expression  : /1234/
      }
   ],
   // All groups will be AND-ed
   [
      {
         column_id   : '11.565',
         expression  : /test/
      }
   ]
];

 

Database (DB)

In order to use this extension, you have to create your own class that extends InlineEdit and implements this extension (same like Local Storage). Or you can directly instantiate SK.UI.DataGrid.DB.

 

Public Methods

Name Description Parameters Returns
loadDatabaseData Retrieves database data and populates the grid with it. options: Object -
updateDatabase Updates the database with grid's data - deletes removed rows, updates modified cells, inserts added rows. callback_ok: Function, callback_failure: Function -

 

Events

Name Description Arguments
beforeLoadDatabaseData Fires before the database data is loaded in the grid. Data array can be modified by reference. rows: Array (of database rows)
beforeDeleteDatabaseRows Fires before removing the deleted database rows from the DB. Data array can be modified by reference. rows: Array (of database rows)
beforeUpdateDatabaseCells Fires before updating the modified cells in the DB. Data array can be modified by reference. rows: Array (of database rows)
beforeAddDatabaseRows Fires before inserting the new rows in the DB. Data array can be modified by reference. rows: Array (of database rows)

 

Extending DataGrid

The DataGrid interface has an Extension Library class, which stays as a base class of each Extension Type. Editors, Widgets, and even Sort Parsers, are all Extensions, which inherit the base Extension Library class. So in fact they are Extension Libraries.

 

The Extension Library base class has the following methods:

Name Description Parameters Returns
add Adds new Extension to the current library. extension : Object -
get Returns the specified Extension from the current library. extension_id : String extension : Object
has Returns Boolean value whether the specified Extension exists in the current library. extension_id : String Boolean

 

You have the freedom to create new DataGrid Extensions.

Create new Editor

SK.UI.DataGrid.Extensions.Editors.add({
   id       : 'editor_id', // the ID of your Editor
   type     : 'class',
   object   : new Class({
      Extends: SK.UI.DataGrid.BaseInlineEditorExtension, // must extend the base Editor class
      initialize: function(options, placeholder, row, save_callback) {
         // Here you create the DOM structure of your editor, and append it to its placeholder
         var element = this.createElement('div', options, placeholder);
         // Your Editor's logic comes here...
         // You have access to the Row instance - it is passed as the 'row' argument
         // You should attach the save_callback to an event, fired on save/update by your Editor, or add some custom functionality, which will call save_callback() on update
         element.addEvent('blur', save_callback);
         // Finally, you need to return the Editor's DOM element
         return element;
      }
   })
});

 

Create new Widget

SK.UI.DataGrid.Extensions.Widgets.add({
   id       : 'widget_id', // the ID of your Widget
   type     : 'class',
   object   : new Class({
      initialize: function(options, placeholder, row) {
         // You create your Widget structure
         var widget = new Element('div', {}).inject( placeholder );
         // options is the Object set in DataGrid's Configuration Options
         // You have access also to DataGrid.Row
      }
   })
});

 

Create new Sort Parser

SK.UI.DataGrid.Extensions.SortParsers.add({
   id: "currency", // the ID of your Sort Parser
   format: function (s) {
      // This method is executed before applying any sorting function on a column
      // It "prepares" each cell value to a format suitable for the sorting function
      // @param s : cell value (String)
      return s.replace(/[£$€]/g, "");
   },
   // return type of the "format" function
   // can be "text" (useful when sorting any type of strings) or "numeric" (useful when sorting numbers)
   type: "numeric"
});

 

Events

Name Description Arguments
onBeforeLoad Fires before the data is loaded in the grid. -
onLoad Fires when the data is loaded in the grid. -
onBeforeUnload Fires before the data is unloaded from the grid. -
onUnload Fires when the data is unloaded from the grid. -
onAdd Fires when a DataGrid.Row is created. row : DataGrid.Row
onAddNewRow Fires when a DataGrid.Row is created manually by the user. row : DataGrid.Row
onUpdate Fires when a DataGrid.Row is updated. row : DataGrid.Row
onModify Fires when a DataGrid.Row data has been modified. row : DataGrid.Row
onRestore Fires when a DataGrid.Row data has been restored to its initial state. row : DataGrid.Row
onBeforeDelete Fires before a specific DataGrid.Row is deleted. row : DataGrid.Row
onDelete Fires when a specific DataGrid.Row is deleted. row : DataGrid.Row
onReorder Fires when a DataGrid.Row is reordered. row : DataGrid.Row
onSort Fires when a sorting on a specific column is applied. column_id : String
onLayoutChange Fires when the grid changes its layout (when add/delete row(s)) grid: DataGrid instance

 

Examples

In this example we will use real data from a SK database. But we won't connect to the database - we will just hardcode this data in the same format into Array.

The grid will be editable and will have these features:

  • reordering rows
  • selecting rows
  • sorting on columns

You may download the example files attached to this page.

 

The HTML

   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
   <html>
   <head>
      <title>DataGrid Example</title>
      <script src="/Shared/Scripts/fat_properties.js" type="text/javascript"></script>

      <!-- Shared -->
      <script src="/Shared/Scripts/toolbar_manager.js" type="text/javascript"></script>
      <script src="/Shared/Scripts/MooToolsMore/Drag/Drag.js" type="text/javascript"></script>
      <script src="/Shared/Scripts/MooToolsMore/Drag/Drag.Move.js" type="text/javascript"></script>
      <script src="/Shared/Scripts/MooToolsMore/Drag/Sortables.js" type="text/javascript"></script>
      <script src="/Shared/Scripts/MooToolsExtensions/Drag/SortableTable.js" type="text/javascript"></script>
      <script src="/Shared/Scripts/MooToolsExtensions/element_implement_value.js" type="text/javascript"></script>
      <script src="/Shared/Scripts/MooToolsExtensions/element_properties_csstext.js" type="text/javascript"></script>
      <script src="/Shared/Scripts/MooToolsExtensions/textarea_autoresize.js" type="text/javascript"></script>

      <!-- DataGrid -->
      <script src="/Shared/UIComponents/Internal/DataGrid/globals.js" type="text/javascript"></script>
      <script src="/Shared/UIComponents/Internal/DataGrid/data_grid.js" type="text/javascript"></script>
      <script src="/Shared/UIComponents/Internal/DataGrid/row.js" type="text/javascript"></script>
      <script src="/Shared/UIComponents/Internal/DataGrid/Editors/inline_base.js" type="text/javascript"></script>
      <script src="/Shared/UIComponents/Internal/DataGrid/Editors/input.js" type="text/javascript"></script>
      <script src="/Shared/UIComponents/Internal/DataGrid/Editors/textarea.js" type="text/javascript"></script>
      <script src="/Shared/UIComponents/Internal/DataGrid/Widgets/row_order.js" type="text/javascript"></script>
      <script src="/Shared/UIComponents/Internal/DataGrid/Widgets/row_select.js" type="text/javascript"></script>
      <script src="/Shared/UIComponents/Internal/DataGrid/Widgets/row_buttons.js" type="text/javascript"></script>
      <script src="/Shared/UIComponents/Internal/DataGrid/SortParsers/text.js" type="text/javascript"></script>

      <!-- Sample Data -->
      <script src="Scripts/data.js" type="text/javascript"></script>

      <!-- Some styles -->
      <link rel="stylesheet" type="text/css" href="/Shared/UIComponents/Internal/DataGrid/css/grid.css">
      <link rel="stylesheet" type="text/css" href="/Shared/css/fat_properties.css">
      <link rel="stylesheet" type="text/css" href="/Apps/Appointments/css/fat_properties.css">
   </head>

   <body>
      <script type="text/javascript">
      var grid;
      window.addEvent( 'domready', function() {
         // Construct the grid
         grid = new SK.UI.DataGrid($('staff_list'), options); // options are defined in the example below
         // Fill it with data
         grid.loadData(data);
      });
      </script>
      <div class="skprops">
         <!-- This is our DataGrid wrapper. It will host the DataGrid interface -->
         <div id="staff_list" style="width: 870px; padding: 20px 10px 0px 10px"></div>
      </div>
   </body>
   </html>

 

The Sample Data

   // This is some similar data as it comes from SK database
   var data = [{
         "cells": {
            "796.12184": "id_401092",
            "796.12189": "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, ",
            "796.12202": "",
            "796.12197": "",
            "796.12193": "",
            "796.12205": "",
            "796.12187": "Mark"
         },
         "row_id": "796.1"
      },
      {
         "cells": {
            "796.12184": "id_932174",
            "796.12189": "totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. ",
            "796.12202": "",
            "796.12197": "",
            "796.12193": "",
            "796.12205": "",
            "796.12187": "John"
         },
         "row_id": "796.2"
      },
      {
         "cells": {
            "796.12184": "id_360245",
            "796.12189": "Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, ",
            "796.12202": "",
            "796.12197": "",
            "796.12193": "",
            "796.12205": "",
            "796.12187": "Erica"
         },
         "row_id": "796.3"
      },
      {
         "cells": {
            "796.12184": "id_991928",
            "796.12189": "qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. ",
            "796.12202": "",
            "796.12197": "",
            "796.12193": "",
            "796.12205": "",
            "796.12187": "Fidel"
         },
         "row_id": "796.4"
      },
      {
         "cells": {
            "796.12184": "id_733429",
            "796.12189": "Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? ",
            "796.12202": "",
            "796.12197": "",
            "796.12193": "",
            "796.12205": "",
            "796.12187": "Melisa"
         },
         "row_id": "796.5"
      },
      {
         "cells": {
            "796.12184": "id_710068",
            "796.12189": "Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?",
            "796.12202": "",
            "796.12197": "",
            "796.12193": "",
            "796.12205": "",
            "796.12187": "Sally"
         },
         "row_id": "796.6"
      },{
         "cells": {
            "796.12184": "id_401092",
            "796.12189": "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, ",
            "796.12202": "",
            "796.12197": "",
            "796.12193": "",
            "796.12205": "",
            "796.12187": "Mark"
         },
         "row_id": "796.1"
      },
      {
         "cells": {
            "796.12184": "id_932174",
            "796.12189": "totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. ",
            "796.12202": "",
            "796.12197": "",
            "796.12193": "",
            "796.12205": "",
            "796.12187": "John"
         },
         "row_id": "796.2"
      },
      {
         "cells": {
            "796.12184": "id_360245",
            "796.12189": "Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, ",
            "796.12202": "",
            "796.12197": "",
            "796.12193": "",
            "796.12205": "",
            "796.12187": "Erica"
         },
         "row_id": "796.3"
      },
      {
         "cells": {
            "796.12184": "id_991928",
            "796.12189": "qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. ",
            "796.12202": "",
            "796.12197": "",
            "796.12193": "",
            "796.12205": "",
            "796.12187": "Fidel"
         },
         "row_id": "796.4"
      }
   ];