Expand All

Basics

Formatting

Context menu

Drag n Drop

Spreadsheet

Tabs

Export

Layouts

RTL Layout

Rows

Paging

Big data

Columns

Cells

Inline editing

Row Grouping

Pivot

Sorting

Filter

Selections

Nesting / Row details

Tree grid

Charts

Angular

React React

Vue Vue

Knockout

;

Rich Batch editing

Introduction

This example extends the Batch Editing demo by adding support for rich styles and rich objects such as media files, images, and hyperlinks.

Users can add, update, and delete multiple records and styles directly within the grid, with full undo and redo capabilities for unlimited steps.

Once the edits are finalized, all changes are committed to the server in a single transaction, ensuring data consistency and efficiency.

The server responds with the updated rows, including assigned primary key values (e.g., Product ID) for any newly inserted records.


Table Structure

CREATE TABLE Product (
    ProductID INT PRIMARY KEY,                 -- Primary key
    ProductName NVARCHAR(255) NOT NULL,        -- Product name
    Image VARCHAR(MAX) NULL,                   -- Base64-encoded image
    QuantityPerUnit NVARCHAR(255) NULL,        -- Packaging details
    UnitPrice DECIMAL(18, 2) NULL,             -- Price per unit
    UnitsInStock SMALLINT NULL,                -- Current stock
    UnitsOnOrder SMALLINT NULL,                -- Pending orders
    ReorderLevel SMALLINT NULL,                -- Restock threshold
    Discontinued BIT NOT NULL,                 -- Active/Inactive flag

    -- Fields to support rich editing in PQGrid
    pq_cellattr NVARCHAR(MAX) NULL,            
    pq_cellprop NVARCHAR(MAX) NULL,
    pq_cellstyle NVARCHAR(MAX) NULL
);
  

Field definitions and data types may vary depending on the SQL database in use.

In this example, product images are stored in the Image column as Base64 strings for simplicity. Alternatively, images can be stored in a binary format, but they must be converted to Base64 when rendering inside the grid.


Post Variables (Request)

The grid posts a consolidated list to the server (via the saveChanges function in this example), regardless of the server-side environment.

This list is obtained by calling the API: grid.getChanges({ format: 'byVal' })

The returned list object contains three sublists: addList, deleteList, and updateList.


list: {
  addList: [
    {
      field1: value1,
      field2: value2,
      pq_cellattr: {...},
      pq_cellprop: {...},
      pq_cellstyle: {...}
    },
    {
      field1: value1,
      field2: value2,
      pq_cellattr: {...},
      pq_cellprop: {...},
      pq_cellstyle: {...}
    }
    // ...
  ],
  deleteList: [
    { id: 10 },
    { id: 29 }
    // ...
  ],
  updateList: [
    {
      id: 3,
      field1: value1,
      field2: value2,
      pq_cellattr: {...},
      pq_cellprop: {...},
      pq_cellstyle: {...}
    },
    {
      id: 7,
      field1: value1,
      field2: value2,
      pq_cellattr: {...},
      pq_cellprop: {...},
      pq_cellstyle: {...}
    }
    // ...
  ]
}
  

Here, id refers to the primary key of the records, which is ProductID in this example.

Tip: Open your browser’s developer network console to inspect the sample request and response payloads in real time.


Server side ( Response )

The server processes the received list and returns a response in the same structure.

The main difference between the request and the response lies in the addList: the server assigns primary key values (id) to the newly inserted rows.

Repetition of records in the other lists acts as confirmation for the grid.commit() method, indicating that the server successfully processed those records.


list: {
  addList: [
    {
      id: 1000,
      field1: value1,
      field2: value2,
      pq_cellattr: {...},
      pq_cellprop: {...},
      pq_cellstyle: {...}
    },
    {
      id: 1001,
      field1: value1,
      field2: value2,
      pq_cellattr: {...},
      pq_cellprop: {...},
      pq_cellstyle: {...}
    }
    // ...
  ],
  deleteList: [
    { id: 10 },
    { id: 29 }
    // ...
  ],
  updateList: [
    {
      id: 3,
      field1: value1,
      field2: value2,
      pq_cellattr: {...},
      pq_cellprop: {...},
      pq_cellstyle: {...}
    },
    {
      id: 7,
      field1: value1,
      field2: value2,
      pq_cellattr: {...},
      pq_cellprop: {...},
      pq_cellstyle: {...}
    }
    // ...
  ]
}