
# Item model

A grid item is a display model in which one row of a DataProvider or the header or footer of a RowGrouping group is displayed as one line in a grid or tree.

#### Item Model

Each item has an index value in the order in which it is displayed, and most functions in RealGrid are executed by passing this index value.
However, items that are not displayed, such as hidden RowGroup items or hidden Tree items, cannot be accessed through this index.
For these cases, we provide functions that return item model information inside the grid and use that information to obtain other model information.

#### Item model types and returns

The types of item models are as follows.

```js
var ItemType = {
   ROW: "row", // data row
   GROUP: "group", // Group (displayed as group header)
   FOOTER: "footer", // group Footer
   TREE: "tree" // tree node (also "group")
};
```

Item model information is returned in the form below.

```js
{
     type: "row", // ItemType
     itemIndex: 0, // item index
     dataRow: -1, // Data row connected to the item. -1 if type is not "row"
     checked: false, // Whether item is checked
     id: 0, // internal use ID,
     parentId: 0, // internal use ID,
     footerId: 0, // Internally used ID
};
```

When calling model-related API and specifying extended as true, the following information is added to the extended model information returned.

```js
level: 2, // Level in the hierarchy, starting from 1
childIndex: 0, // Order in parent model
```

#### Get item model

```js
RealGrid.setLocale('en');

const fields = [
  { fieldName: 'KorName', dataType: 'text' },
  { fieldName: 'Gender', dataType: 'text' },
  { fieldName: 'Age', dataType: 'number' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductId', dataType: 'text' },
  { fieldName: 'KorCountry', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CardNumber', dataType: 'text' },
  { fieldName: 'Monetary', dataType: 'text' },
  { fieldName: 'StartDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'EndDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'ToMonth', dataType: 'number' },
  { fieldName: 'Month', dataType: 'number' },
  { fieldName: 'Year', dataType: 'number' },
  { fieldName: 'InterestRate', dataType: 'number' },
  { fieldName: 'SaveCost', dataType: 'number' },
  { fieldName: 'SaveMaturity', dataType: 'number' },
  { fieldName: 'CurrentSave', dataType: 'number' }
];

const columns = [
  { name: 'KorName', fieldName: 'KorName', width: '60', header: { text: 'Name' } },
  { name: 'Gender', fieldName: 'Gender', width: '40', header: { text: 'Gender' } },
  { name: 'Age', fieldName: 'Age', width: '40', header: { text: 'Age' }, styleName: 'right-column' },
  { name: 'Phone', fieldName: 'Phone', width: '100', header: { text: 'Phone' } },
  { name: 'ProductId', fieldName: 'ProductId', width: '120', header: { text: 'Product Code' } },
  { name: 'KorCountry', fieldName: 'KorCountry', width: '100', header: { text: 'Country' } },
  { name: 'OrderDate', fieldName: 'OrderDate', width: '100', header: { text: 'Order Date' } },
  { name: 'CardNumber', fieldName: 'CardNumber', width: '140', header: { text: 'Card No.' } },
  { name: 'Monetary', fieldName: 'Monetary', width: '40', header: { text: 'Monetary' } },
  { name: 'StartDate', fieldName: 'StartDate', width: '100', header: { text: 'Start Date' } },
  { name: 'EndDate', fieldName: 'EndDate', width: '100', header: { text: 'End Date' } },
  { name: 'ToMonth', fieldName: 'ToMonth', width: '50', header: { text: 'Pay Cnt.' }, styleName: 'right-column' },
  { name: 'Month', fieldName: 'Month', width: '50', header: { text: 'Residuum' }, styleName: 'right-column' },
  { name: 'InterestRate', fieldName: 'InterestRate', width: '50', numberFormat: '0.00', header: { text: 'Interest Rate' }, styleName: 'right-column' },
  { name: 'SaveCost', fieldName: 'SaveCost', width: '80', numberFormat: '#,##0', header: { text: 'Payment' }, footer: { text: 'Total =>' }, styleName: 'right-column' },
  { name: 'SaveMaturity', fieldName: 'SaveMaturity', width: '80', numberFormat: '#,##0', header: { text: 'Save Maturity' }, footer: { text: 'Total', expression: 'sum', groupExpression: 'sum' }, styleName: 'right-column' },
  { name: 'CurrentSave', fieldName: 'CurrentSave', width: '80', numberFormat: '#,##0', header: { text: 'Currency Save' }, styleName: 'right-column' }
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: { height: 40 },
  display: { rowHeight: 36, emptyMessage: 'There is no data to display.' },
  edit: { insertable: true, appendable: true },
  footer: { height: 40 },
  stateBar: { width: 16 },
  groupPanel: { visible: true },
  onInitialized: (grid) => {
    fetch('/data/en/en/simple_data.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
      });
  }
}, {
  fields
});

window.gridView = gridView;
window.dataProvider = dataProvider;

function btnGetModel() {
  const extended = document.getElementById('chkExtendedModel').checked;
  const itemIndex = gridView.getCurrent().itemIndex;
  const item = gridView.getModel(itemIndex, extended);
  alert(JSON.stringify(item));
}

function btnGetParentModel() {
  const extended = document.getElementById('chkExtendedModel').checked;
  const idx = gridView.getCurrent();
  const item = gridView.getModel(idx.itemIndex);
  const parent = gridView.getParentModel(item, extended);
  alert(JSON.stringify(item));
  if (parent) {
    idx.itemIndex = parent.itemIndex;
    gridView.setCurrent(idx);
  }
}

function btnGetRootModel() {
  const extended = document.getElementById('chkExtendedModel').checked;
  const idx = gridView.getCurrent();
  const item = gridView.getModel(idx.itemIndex);
  const root = gridView.getRootModel(item, extended);
  alert(JSON.stringify(root));
  if (root) {
    idx.itemIndex = root.itemIndex;
    gridView.setCurrent(idx);
  }
}

function btnGetChildModels() {
  const extended = document.getElementById('chkExtendedModel').checked;
  const itemIndex = gridView.getCurrent().itemIndex;
  const item = gridView.getModel(itemIndex);
  if (item) {
    const children = gridView.getChildModels(item, extended);
    alert(JSON.stringify(children));
  }
}

function btnGetChildModel() {
  const extended = document.getElementById('chkExtendedModel').checked;
  const itemIndex = gridView.getCurrent().itemIndex;
  const group = gridView.getModelAs(itemIndex, 'group');
  if (group && group.count > 0) {
    const item = gridView.getChildModel(group, 0, extended);
    alert(JSON.stringify(item));
  }
}

function btnGetModels() {
  const extended = document.getElementById('chkExtendedModel').checked;
  const items = gridView.getModels([0, 1, 2], extended);
  alert(JSON.stringify(items));
}

function btnGetModelOfRow() {
  const extended = document.getElementById('chkExtendedModel').checked;
  const row = gridView.getCurrent().dataRow;
  const item = gridView.getModelOfRow(row, extended);
  alert(JSON.stringify(item));
}

function btnGetModelsOfRows() {
  const extended = document.getElementById('chkExtendedModel').checked;
  const items = gridView.getModelsOfRows([0, 1, 2], extended);
  alert(JSON.stringify(items));
}

function btnGetGroupSummary() {
  const idx = gridView.getCurrent();
  const item = gridView.getModelAs(idx.itemIndex, 'row');

  if (item) {
    const group = gridView.getParentModel(item);

    if (group && idx.fieldIndex >= 0) {
      const summary = gridView.getGroupSummary(group, idx.fieldIndex);
      if (summary) {
        alert(JSON.stringify(summary));
      }
    }
  }
}

function btnExpandModel() {
  const recursive = false;
  const force = false;
  const itemIndex = gridView.getCurrent().itemIndex;
  const group = gridView.getModelAs(itemIndex, 'group');
  if (group) {
    gridView.expandModel(group, recursive, force);
  }
}

function btnCollapseModel() {
  const recursive = false;
  const itemIndex = gridView.getCurrent().itemIndex;
  const group = gridView.getModelAs(itemIndex, 'group');
  if (group) {
    gridView.collapseModel(group, recursive);
  }
}
```

The [getModel()](/refs/Class/GridBase#getmodel) function returns the item model corresponding to the item index.

```js
var extended = $("#chkExtendedModel").is(":checked");
var itemIndex = gridView.getCurrent().itemIndex;
var item = gridView.getModel(itemIndex, extended);
alert(JSON.stringify(item));
```

The [getParentModel()](/refs/Class/GridBase#getparentmodel) function returns the parent item model of the item model.

```js
var extended = $("#chkExtendedModel").is(":checked");
var idx = gridView.getCurrent();
var item = gridView.getModel(idx.itemIndex);
var parent = gridView.getParentModel(item, extended);
alert(JSON.stringify(item));
if (parent) {
   idx.itemIndex = parent.itemIndex;
   gridView.setCurrent(idx);
}
```

The [getRootModel()](/refs/Class/GridBase#getrootmodel) function returns the item model's top-level ancestor item model.

```js
var extended = $("#chkExtendedModel").is(":checked");
var idx = gridView.getCurrent();
var item = gridView.getModel(idx.itemIndex);
var root = gridView.getRootModel(item, extended);
console.log(JSON.stringify(root));
alert(JSON.stringify(root));
if (root) {
   idx.itemIndex = root.itemIndex;
   gridView.setCurrent(idx);
}
```

The [getChildModels()](/refs/Class/GridBase#getchildmodels) function returns child item models immediately below the item model.

```js
var extended = $("#chkExtendedModel").is(":checked");
var itemIndex = gridView.getCurrent().itemIndex;
var item = gridView.getModel(itemIndex);
if (item) {
   var children = gridView.getChildModels(item, extended);
   alert(JSON.stringify(children));
}
```
 
The [getChildModel()](/refs/Class/GridBase#getchildmodel) function returns the child item model of the item model.

```js
var extended = $("#chkExtendedModel").is(":checked");
var itemIndex = gridView.getCurrent().itemIndex;
var group = gridView.getModelAs(itemIndex, "group");
if (group && group.count > 0) {
   var item = gridView.getChildModel(group, 0, extended);
   alert(JSON.stringify(item));
}
```

The [getModels()](/refs/Class/GridBase#getmodels) function returns item models corresponding to the specified item indices as an array.

```js
var extended = $("#chkExtendedModel").is(":checked");
var items = gridView.getModels([0, 1, 2], extended);
var s = JSON.stringify(items);
alert(JSON.stringify(s));
```

The [getModelOfRow()](/refs/Class/GridBase#getmodelofrow) function returns the item model corresponding to the specified data row.

```js
var extended = $("#chkExtendedModel").is(":checked");
var row = gridView.getCurrent().dataRow;
var item = gridView.getModelOfRow(row, extended);
alert(JSON.stringify(item));
```

The [getModelsOfRows()](/refs/Class/GridBase#getmodelsofrows) function returns item models corresponding to the specified data rows as an array.

```js
var extended = $("#chkExtendedModel").is(":checked");
var items = gridView.getModelsOfRows([0, 1, 2], extended);
var s = JSON.stringify(items);
alert(JSON.stringify(s));
```

[getGroupSummary](/refs/Class/GridBase#getgroupsummary) Returns the sum information of the specified group item model.

```js
var idx = gridView.getCurrent();
var item = gridView.getModelAs(idx.itemIndex, "row");

if (item) {
   var group = gridView.getParentModel(item);

   if (group && idx.fieldIndex >= 0) {
     var summary = gridView.getGroupSummary(group, idx.fieldIndex);
     if (summary) {
       alert(JSON.stringify(summary));
     }
   }
}
```

Expands the specified group item model.

```js
var recursive = $("#chkExpandRecursive").is(":checked");
var force = $("#chkExpandForce").is(":checked");
var itemIndex = gridView.getCurrent().itemIndex;
var group = gridView.getModelAs(itemIndex, "group");
if (group) {
   gridView.expandModel(group, recursive, force);
}
```

collapseModel Collapses the specified group item model.

```js
var recursive = $("#chkCollapseRecursive").is(":checked");
var itemIndex = gridView.getCurrent().itemIndex;
var group = gridView.getModelAs(itemIndex, "group");
if (group) {
   gridView.collapseModel(group, recursive);
}
```

#### `Caution`

- Functions that return a large number of item models use memory or
​This can be a burden in terms of speed, so if it can be solved with an item index, you must use index functions.
   In particular, extended model information is not a stored value, but is calculated and retrieved each time, so it can cause more burden.
- The model returned from functions will be passed as a parameter to another function, so property values should not be modified.
   In particular, internally used IDs should not be used as meaningful values.
- The item model of the grid or tree is frequently updated when data changes, new row grouping is performed, or for other reasons.
   In most cases, saving the returned item model for reuse outside of a function is pointless and can be dangerous.