Dynamic CRUD Data Grid Library - appendGrid

File Size: 197 KB
Views Total: 88224
Last Update:
Publish Date:
Official Website: Go to website
License: MIT
Dynamic CRUD Data Grid Library - appendGrid

appendGrid is a powerful JavaScript/jQuery CRUD table plugin that turns the standard html table into a dynamic and editable data grid.

You can add, remove, edit, move up, move down records row by row such like filled spreadsheet.

Impornt Note: The Ver.2 has removed jQuery and jQuery UI dependencies.

You might also like:


  • Compatible with several jQuery UI widget (Removed since Ver.2)
  • Allows you to get value of a control in a row or changing it
  • Allows to create custom type of control to fit every situation
  • Allows to validate form controls using jQuery Validation Plugin
  • Large Data Set supported
  • Compatible with 3rd front-end frameworks such like Bootstrap, Bulma, Foundation, etc.
  • Compatible with 3rd iconic fonts such as Font Awesome, Material Icons, etc.

Basic Usage (ver.2):

1. Install and import the appendGrid library into the document.

$ npm install jquery.appendgrid --save
<script src="dist/appendGrid.js"></script>

2. Or from a CDN.

<script src="https://unpkg.com/[email protected]/dist/AppendGrid.js"></script>

3. Create an empty table element on the webpage.

<table id="tblAppendGrid"></table>

4. Create a new appendGrid instance with several options.

window.myAppendGrid = new AppendGrid({
  element: document.getElementById("tblAppendGrid"),
  uiFramework: "bulma", // ui framework
  iconFramework: "fontawesome5", // iconic font
  columns: [
    name: "company",
    display: "Company" },

    name: "name",
    display: "Contact Person" },

    name: "country",
    display: "Country",
    type: "select",
    ctrlOptions: [
    "Hong Kong",
    "United Kingdom",
    "United States"] },

    name: "isNPO",
    display: "NPO?",
    type: "checkbox",
    cellClass: "has-text-centered" },

    name: "orderPlaced",
    display: "Order Placed",
    type: "number",
    ctrlAttr: {
      min: 0,
      max: 10000 } },

    name: "memberSince",
    display: "Member Since",
    type: "date",
    ctrlAttr: {
      maxlength: 10 } },

    name: "uid",
    type: "hidden",
    value: "0" }],

  sectionClasses: {
    table: 'is-narrow is-fullwidth' } 

5. Push your own tabular data to the table.

    uid: "d4c74a61-a24e-429f-9db0-3cf3aaa22425",
    name: "Monique Zebedee",
    company: "Welch LLC",
    country: "Japan",
    memberSince: "2012-02-18",
    orderPlaced: 111,
    level: "Bronze",
    isNPO: true },

    uid: "afdf285d-da5c-4fa8-9225-201c858a173d",
    name: "Daryle McLaren",
    company: "Bogisich Group",
    country: "United States",
    memberSince: "2016-10-08",
    orderPlaced: 261,
    level: "Diamond",
    isNPO: false },

    uid: "202a8afb-130b-476b-b415-c659f21a73e7",
    name: "Glori Spellecy",
    company: "Grady and Sons",
    country: "Germany",
    memberSince: "2014-07-28",
    orderPlaced: 282,
    level: "Gold",
    isNPO: false },

    uid: "08c9adee-abdd-43d5-866d-ce540be19be8",
    name: "Blondy Boggis",
    company: "Eichmann, Parker and Herzog",
    country: "Malaysia",
    memberSince: "2010-08-17",
    orderPlaced: 308,
    level: "Platinum",
    isNPO: true },

    uid: "57644023-cd0c-47ec-a556-fd8d4e21a4e7",
    name: "Batholomew Zecchii",
    company: "Corwin-Fahey",
    country: "Malaysia",
    memberSince: "2016-09-20",
    orderPlaced: 881,
    level: "Gold",
    isNPO: true },

    uid: "38e08e8a-c7eb-41eb-9191-6bb2df1fd39b",
    name: "Paulie Poel",
    company: "MacGyver, Rohan and West",
    country: "United Kingdom",
    memberSince: "2016-12-26",
    orderPlaced: 387,
    level: "Silver",
    isNPO: false },

    uid: "d7bf56d4-f955-4dca-b3db-b30eab590028",
    name: "Jessica Levett",
    company: "Lind, O'Kon and Hamill",
    country: "United States",
    memberSince: "2015-04-26",
    orderPlaced: 984,
    level: "Gold",
    isNPO: false },

    uid: "b9075764-5228-4ca7-9435-7c362ce097e5",
    name: "Fonsie Spring",
    company: "McKenzie, Block and Wiegand",
    country: "Japan",
    memberSince: "2013-11-08",
    orderPlaced: 875,
    level: "Silver",
    isNPO: false }

6. All default options to customize the data grid.

// The UniqueIndex accumulate counter
uniqueIndex: 0,

// The row order array
rowOrder: [],

// Indicate data is loaded or not
isDataLoaded: false,

// Visible column count for internal calculation
visibleCount: 0,

// Total colSpan count after excluding `hideRowNumColumn` and not generating last column
finalColSpan: 0,

// Indicate to hide last column or not
hideLastColumn: false,

// The element ID of the `appendGrid` wrapper
wrapperId: null,

// Indicate calculate width or not
// calculateWidth: true,
// Settings
settings: null,

// The table element
tbWhole: null,

// The table body element
tbBody: null,

// Icon Framework object to be used:
// fontawesome5, ionicon4, materialdesignicons
// openiconic, typicons2, or default
iconFramework: null,

// UI Framework object to be used:
// bootstrap4, bulma,
// foundation, or default
uiFramework: null

// The total number of empty rows generated when init the grid. This will be ignored if `initData` is assigned.
initRows: 3,

// The maximum number of rows allowed in this grid.
maxRowsAllowed: 0,

// An array of data to be filled after initialized the grid.
initData: null,

// Array of column options.
columns: null,

// Labels or messages used in grid.
i18n: null,

// The ID prefix of controls generated inside the grid. Table ID will be used if not defined.
idPrefix: null,

// Hide the buttons at the end of rows or bottom of grid.
hideButtons: null,

// Hide the row number column.
hideRowNumColumn: false,

// Generate row buttom column in the front of input columns.
rowButtonsInFront: false,

// The extra class names for table sections.
sectionClasses: null,

// Adding extra button(s) at the end of rows.
customRowButtons: null,

// Adding extra button(s) at the bottom of grid.
customFooterButtons: null,

// Use the sub panel or not
useSubPanel: false,

// Maintain the scroll position after appended or removed last row.
maintainScroll: false,

// The maximum height of grid content, scroll bar will be display when the height is greater than this value.
maxBodyHeight: 0,

// Auto calculate the column width when scroll bar on table body is in use.
autoColumnWidth: true

7. Default columns options.

// Type of column control.
type: 'text',

// Name of column.
name: null,

// Default value.
value: null,

// Display text on the header section.
display: null,

// Extra CSS setting to be added to display text.
displayCss: null,

// Tooltip for column head.
displayTooltip: null,

// The `colspan` setting on the column header.
headerSpan: 1,

// Extra CSS setting to be added to the control container table cell.
cellCss: null,

// Extra attributes to be added to the control.
ctrlAttr: null,

// Extra properties to be added to the control.
ctrlProp: null,

// Extra CSS to be added to the control.
ctrlCss: null,

// Extra name of class to be added to the control.
ctrlClass: null,

// The available option for building `select` type control.
ctrlOptions: null,

// Options for initalize jQuery UI widget.
uiOption: null,

// Options for initalize jQuery UI tooltip.
uiTooltip: null,

// Let column resizable by using jQuery UI Resizable Interaction.
resizable: false,

// Show or hide column after initialized.
invisible: false,

// The value to compare for indentify this column value is empty.
emptyCriteria: null,

// Callback function to build custom type control.
customBuilder: null,

// Callback function to get control value.
customGetter: null,

// Callback function to set control value.
customSetter: null,

// The `OnClick` event callback of control.
onClick: null,

// The `OnChange` event callback of control.
onChange: null

8. Default callbacks.

// The callback function for format the HTML name of generated controls.
nameFormatter: null,

// The callback function to be triggered after all data loaded to grid.
dataLoaded: null,

// The callback function to be triggered after data loaded to a row.
rowDataLoaded: null,

// The callback function to be triggered after new row appended.
afterRowAppended: null,

// The callback function to be triggered after new row inserted.
afterRowInserted: null,

// The callback function to be triggered after grid row swapped.
afterRowSwapped: null,

// The callback function to be triggered before grid row remove.
beforeRowRemove: null,

// The callback function to be triggered after grid row removed.
afterRowRemoved: null,

// The callback function to be triggered after grid row dragged.
afterRowDragged: null,

// The callback function for generating sub panel content.
subPanelBuilder: null,

// The callback function for getting values from sub panel. Used for `getAllValue` method.
subPanelGetter: null,

// The callback function to be triggered when row(s) is/are adding to grid but the maximum number of rows allowed is reached.
maxNumRowsReached: null

9. API methods.

// Append a specified number of rows or row data to the grid
  { "foo": "1A", "bar": "2019-01-01" },
  { "foo": "2A", "bar": "2019-02-02" },
  { "foo": "3A", "bar": "2019-03-03" },

// Gets the control (DOM element) generated by specified column name and row index
myAppendGrid.getCellCtrl(name, index);

// Gets the control (DOM element) generated by specified column name and unique index.
myAppendGrid.getCellCtrlByUniqueIndex(name, uniqueindex);

// Gets an array of columns

// Gets the control value on specified column and row index of first element in the set of matched elements.
myAppendGrid.getCtrlValue(name, index);

// Gets the number of rows

// Gets the unique index array of the grid.

// Gets the row index by unique index.

// Gets the unique index by row index.

// Gets all control values of specified row index of current grid.

// Gets all control values of current grid.

// Inserts a specified number of row or row data above the specified rowIndex.
myAppendGrid.insertRow(number/data, index);

// Checks if the row is empty

// Loads records to the current grid. 

// Moves the row down.

// Moves the row up

// Removes the row

// Sets the control value on specified column and row index of current grid.
myAppendGrid.setCtrlValue(name, index, value);

// Removes all empty rows in the grid. 

More Example:


v2.1.1 (2022-12-12)

  • Supported FontAwesome 6.

v2.1.0 (2021-09-03)

  • Supported Bootstrap 5.

v2.0.8 (2020-10-08)

  • Fixed issue on not assigning ctrlClass to some of the column type.

v2.0.7 (2020-09-16)

v2.0.6 (2020-03-12)

  • Bugs fixed

v2.0.5 (2019-12-20)

  • Migrated maxRowsAllowed option from v1 that limited the maximum allowed rows of grid.
  • Migrated maxNumRowsReached callback from v1 that notify user when maximum allowed rows reached.

v2.0.4 (2019-09-25)

  • initData or initRows will be handled after grid initialized.

v2.0.3 (2019-06-17)

  • initData or initRows will be handled after grid initialized.
  • Fixed a problem that numeric zero value cannot be set by using setCtrlValue method.
  • Added readonly column type for bootstrap4 and bulma UI framework.
  • Removed wrapper DIV element on table. It was used for Fixed Header feature but we can use other libraries such as jquery.floatThead for that.
  • Added sizing uiParams for bootstrap4 and bulma UI framework.
  • Added ctrlAdded callback function that to be executed after control generated and added to table cell.
  • Removed wrapper which can be done by using ctrlAdded callback with more customization.

v2.0.2 (2019-05-09)

  • Fixed a problem on generating unusable AppendGrid.js file.

v2.0.1 (2019-05-08)

  • Added iconParams for customize icons used within the grid.
  • Modified to support display as callback method.
  • Modified the data type of uniqueIndex of event callback argument to number format.
  • Reimplemented headerSpan from v1.
  • Reimplemented grid callbacks from v1.
  • Reimplemented empty grid message from v1.

v2.0.0 (2019-04-26)

  • Removed jQuery UI dependency.
  • Compatible with Bootstrap 4.
  • Rewritten in ES 6.

v1.7.1 (2017-09-14)

  • Fixed a problem on get/set values on select element with multiple attribute

v1.7.0 (2017-09-10)

  • Fixed jQuery UI Button issues on jQuery UI v1.12.
  • jQuery UI v1.12 will become minimum requirement as it had some breaking changes that incompatible with its previous version.

v1.6.3 (2017-02-28)

  • Fixed a problem that column width is not correct when no command buttons visible at the end of row.

v1.6.2 (2016-02-21)

  • Fixed a problem that calculation on column width is wrong when maxBodyHeight is used with Bootstrap.

v1.6.1 (2015-09-25)

  • Fixed a problem that uniqueIndex become undefined in afterRowDragged callback.

v1.6.0 (2015-08-06)

  • Added maxBodyHeight option to limit the maximum height on table body and vertical scrollbar will be displayed when this height limit is reached.
  • Fixed a problem that buttonClasses is not working.

v1.5.2 (2015-02-28)

  • Fixed a problem that nameFormatter is not working on hidden type columns.

v1.5.1 (2014-12-21)

  • Added maxRowsAllowed option and maxNumRowsReached callback function to limit the number of rows allowed. 
  • Added maintainScroll option to scroll the page after appended or removed last row.
  • Removed unnecessary coding so that appendGrid requires jQuery UI Core, Widget and Button components only for all standard features. But you will not able to use Datepicker or other jQuery UI widgets.

v1.5.0 (2014-10-12)

  • Added useSubPanel option to enable the sub panal mode. Users can generated extra elements to the under each of the normal appendGrid row. Please notice that useSubPanel is not compatible with rowDragging feature. (Thanks iannos for naming)
  • Added subPanelBuilder and subPanelGetter callback function that required for sub panel.
  • Added subPanel option for sectionClasses.
  • The long-awaited sub grid feature is available by make use of sub panel!
  • Added rowCountName option for changing the key name of row count variable for the result of getAllValue method.
  • Parameter order of rowDataLoaded method is changed.
  • Performaced improve by changing the use of insertRow and insertCell javascript function to appendChild.

v1.4.2 (2014-10-02)

  • caption and display can be fully customized by passing a callback function. (Thanks iannos for suggestion)
  • Added captionTooltip and displayTooltip that make use of jQuery UI tooltip for generate tooltip on caption or column header text. (Thanks iannos for suggestion)
  • Added sectionClasses that can specify CSS classes to different table section. (Thanks iannos for suggestion)
  • Added emptyCriteria option to identify a row is empty. Also, isRowEmpty and removeEmptyRows methods are added that make use of this changes. (Thanks iannos for suggestion)
  • Added support on generating select element with optgroup support. You can also specify the title attribute for each option. (Thanks iannos for suggestion)
  • Added rowDataLoaded callback function that will be useful when loading data into a row with controls with dynamic content, such as cascading drop down list.

v1.4.1 (2014-08-10)

  • Added afterRowDragged callback function to be triggered after grid row dragged. (Thanks for PolarbearDK's work)
  • Added nameFormatter callback function for format the HTML name of generated controls. (Thanks iannos for suggestion)

v1.4.0 (2014-07-16)

  • Added invisible option and showColumn / hideColumn / isColumnInvisible methods for changing / checking visibility of columns.
  • Added resizable option that allow column resizable.
  • Added getColumn method to get columns array used for grid initialization.
  • [Important] You are allowed to call appendGrid methods by passing ONE element in jQuery object only. It will not be affected if you are already using ID, such as $("tblAppendGrid"), as jQuery selector.

v1.3.6 (2014-06-28)

  • Added getCellCtrl and getCellCtrlByUniqueIndex methods for retrieving generated control for further customization.

v1.3.5 (2014-04-23)

  • update.

v1.3.4 (2014-03-27)

  • update.

v1.3.3 (2014-03-27)

  • Added rowBottonsInFront option to allow generating row buttons in the front of input columns.

v1.3.2 (2014-03-09)

  • Added headerSpan to allow header cell column span. (Thanks Rajeevgandhi for suggestion)
  • Allowed to pass array of data to appendRow and insertRow method. (Thanks mailivore for suggestion)
  • Fixed a problem that empty row message will not be displayed when passing empty array to load method. (Thanks mailivore for reporting)

v1.3.1 (2014-01-27)

  • Removed firstCellWidth and lastCellWidth parameters
  • Added customFooterButtons option that allow adding extra buttons to the bottom of grid
  • The last column will not be displayed if all buttons are hidden

v1.3.0 (2014-01-21)

  • Added hideButtons option that allow hiding each buttons individually and removed hideMoveUpDown option
  • Added customRowButtons option that allow adding extra buttons at the last cell of each row
  • Added hideRowNumColumn option that allow to not generating the row number column
  • Added a message to be displayed when the grid is empty (Thanks mailivore for above ideas)

v1.2.3 (2014-01-17)

  • Fixed a problem on setting default value on hidden type columns

v1.2.2 (2014-01-03)

  • Fixed a problem on serializing hidden type columns

v1.2.1 (2013-12-23)

  • Added buttonClasses initial parameters

v1.2.0 (2013-11-16)

  • Added drag & drop support
  • Added rowDragging and hideMoveUpDown initial parameters

v1.1.3 (2013-10-30)

  • Fixed a problem that `i18n` parameter not working even correct values passed in

v1.1.2 (2013-05-19)

  • Fixed a problem on generating ui-datepicker columns

v1.1.0 (2013-04-16)

  • Added support to HTML5 input type such as date/time/email
  • Added ctrlProp column parameter


This awesome jQuery plugin is developed by hkalbertl. For more Advanced Usages, please check the demo page or visit the official website.