
# Column layout (column grouping)

If you want to change the column set at run time after setting the column set by calling setColumns() on the grid, you can call setColumns() again. However, if you want to display part of the initially set column set, regroup, or change the arrangement, you can reset the arrangement of the columns using the existing column set without calling setColumns() again.

If the ending boundary between each column is different when grouping columns, please refer to the [SPAN](https://docs.realgrid.com/guides/tip/span#main-content) document.

The column layout must be configured by specifying invisible columns as visible: false.   
If you omit the property setting, you can just list the column names in text format.

''When changing the layout with the setColumnLayout() function, row grouping is canceled.''
''After changing the layout, it must be reapplied using the groupBy() function.''

```js
const fields = [
  { fieldName: 'OrderID', dataType: 'text' },
  { fieldName: 'CustomerID', dataType: 'text' },
  { fieldName: 'EmployeeID', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CompanyName', dataType: 'text' },
  { fieldName: 'Country', dataType: 'text' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductName', dataType: 'text' },
  { fieldName: 'QuantityPerUnit', dataType: 'text' },
  { fieldName: 'Quantity', dataType: 'number' },
  { fieldName: 'UnitPrice', dataType: 'number' }
];

const columns = [
  { name: 'Country', fieldName: 'Country', type: 'data', width: '100', header: { text: 'Country' } },
  { name: 'CompanyName', fieldName: 'CompanyName', type: 'data', width: '120', styleName: 'blue-column', header: { text: 'Company Name' } },
  { name: 'UnitPrice2', fieldName: 'UnitPrice', type: 'data', width: '100', renderer: { type: 'bar', origin: 'left', barWidth: '80%' }, header: { text: 'UnitPrice2' }, footer: { expression: 'sum' } },
  { name: 'OrderID', fieldName: 'OrderID', type: 'data', width: '80', header: { text: 'Order ID' } },
  { name: 'CustomerID', fieldName: 'CustomerID', type: 'data', width: '90', header: { text: 'Customer ID' } },
  { name: 'EmployeeID', fieldName: 'EmployeeID', type: 'data', width: '90', header: { text: 'Employee ID' }, footer: { expression: 'min', groupExpression: 'min' } },
  { name: 'OrderDate', fieldName: 'OrderDate', type: 'data', width: '130', header: { text: 'Order Date' } },
  { name: 'Phone', fieldName: 'Phone', type: 'data', width: '90', renderer: { type: 'button' }, header: { text: 'Button' } },
  { name: 'Phone2', fieldName: 'Phone', type: 'data', width: '90', header: { text: 'Phone2' } },
  { name: 'ProductName', fieldName: 'ProductName', type: 'data', width: '200', header: { text: 'Product Name' } },
  { name: 'QuantityPerUnit', fieldName: 'QuantityPerUnit', type: 'data', width: '100', header: { text: 'Quantity / Unit' } },
  { name: 'Quantity', fieldName: 'Quantity', type: 'data', width: '100', header: { text: 'Quantity' }, footer: { expression: 'sum', numberFormat: '#,##0.#' } },
  { name: 'UnitPrice', fieldName: 'UnitPrice', type: 'data', width: '100', header: { text: 'Unit Price' }, footer: { expression: 'sum', numberFormat: '#,##0.#' } },
  { name: 'Country2', fieldName: 'Country', type: 'data', width: '100', header: { text: 'Country2' } }
];

const layout1 = [
  {
    name: 'companyGroup',
    direction: 'horizontal',
    items: ['Country', 'CompanyName'],
    header: { text: 'Company' }
  },
  { column: 'UnitPrice2', visible: false },
  { column: 'Phone2', visible: false },
  { column: 'Country2', visible: false },
  { column: 'ProductName', visible: false },
  { column: 'Quantity', visible: false },
  { column: 'UnitPrice', visible: false },
  { column: 'QuantityPerUnit', visible: false },
  'OrderID',
  'CustomerID',
  'EmployeeID',
  'OrderDate',
  'Phone'
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: -1
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/editor_demoData.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.setColumnLayout(layout1);
      });
  }
}, {
  fields
});

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

function showColumns() {
  gridView.layoutByName('Quantity').visible = true;
  gridView.layoutByName('UnitPrice').visible = true;
  gridView.layoutByName('QuantityPerUnit').visible = true;
}

function hideColumns() {
  gridView.layoutByName('Quantity').visible = false;
  gridView.layoutByName('UnitPrice').visible = false;
  gridView.layoutByName('QuantityPerUnit').visible = false;
}
```

```js
layout1 = [
  {
    name: "companyGroup",
    direction: "horizontal",
    //hideChildHeaders: true,
    items: [
      "Country",
      "CompanyName"
    ],
    header: {
      text: "Company",
    }
  }, 
  {column: "UnitPrice2", visible: false},//컬럼 속성 적용
  {column: "Phone2", visible: false},
  {column: "ProductName", visible: false},
  {column: "QuantityPerUnit", visible: false},
  {column: "Quantity", visible: false},
  {column: "UnitPrice", visible: false},
  {column: "Country2", visible: false},
  "OrderID", //컬럼 속성 생략시 기본값 적용
  "CustomerID",
  "EmployeeID",
  "OrderDate",
  "Phone"
];

gridView.setColumnLayout(layout1);

function showColumns() {
  gridView.layoutByName("Quantity").visible = true;
  gridView.layoutByName("UnitPrice").visible = true;
  gridView.layoutByName("QuantityPerUnit").visible = true;
}

function hideColumns() {
  gridView.layoutByName("Quantity").visible = false;
  gridView.layoutByName("UnitPrice").visible = false;
  gridView.layoutByName("QuantityPerUnit").visible = false;
}
```

---

Unlike the demo above, this demo displays only the group header by hiding the headers of columns within the group.

```js
const fields = [
  { fieldName: 'OrderID', dataType: 'text' },
  { fieldName: 'CustomerID', dataType: 'text' },
  { fieldName: 'EmployeeID', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CompanyName', dataType: 'text' },
  { fieldName: 'Country', dataType: 'text' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductName', dataType: 'text' },
  { fieldName: 'QuantityPerUnit', dataType: 'text' },
  { fieldName: 'Quantity', dataType: 'number' },
  { fieldName: 'UnitPrice', dataType: 'number' }
];

const columns = [
  { name: 'Country', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country' } },
  { name: 'CompanyName', fieldName: 'CompanyName', type: 'data', width: '120', styleName: 'blue-column', styles: { textAlignment: 'near' }, header: { text: 'Company Name' } },
  { name: 'UnitPrice2', fieldName: 'UnitPrice', type: 'data', width: '100', renderer: { type: 'bar', origin: 'left', barWidth: '80%' }, header: { text: 'UnitPrice2' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'OrderID', fieldName: 'OrderID', type: 'data', width: '80', styles: { textAlignment: 'center' }, header: { text: 'Order ID' }, footer: { expression: 'max', groupExpression: 'max' } },
  { name: 'CustomerID', fieldName: 'CustomerID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Customer ID' } },
  { name: 'EmployeeID', fieldName: 'EmployeeID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Employee ID' }, footer: { expression: 'min', groupExpression: 'min' } },
  { name: 'OrderDate', fieldName: 'OrderDate', type: 'data', width: '130', styles: { textAlignment: 'center' }, header: { text: 'Order Date' } },
  { name: 'Phone', fieldName: 'Phone', type: 'data', width: '90', renderer: { type: 'button' }, header: { text: 'Button' } },
  { name: 'Phone2', fieldName: 'Phone', type: 'data', width: '90', styles: { textAlignment: 'near' }, header: { text: 'Phone2' } },
  { name: 'ProductName', fieldName: 'ProductName', type: 'data', width: '200', styles: { textAlignment: 'near' }, header: { text: 'Product Name' } },
  { name: 'QuantityPerUnit', fieldName: 'QuantityPerUnit', type: 'data', width: '100', styles: { textAlignment: 'near' }, header: { text: 'Quantity / Unit' } },
  { name: 'Quantity', fieldName: 'Quantity', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Quantity' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'UnitPrice', fieldName: 'UnitPrice', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Unit Price' }, footer: { expression: 'avg', groupExpression: 'max', styles: { textAlignment: 'far', numberFormat: '0.00', prefix: 'AVG = ' } } },
  { name: 'Country2', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country2' } }
];

const hideChildLayout = [
  {
    name: 'companyGroup',
    direction: 'horizontal',
    hideChildHeaders: true,
    items: ['Country', 'CompanyName'],
    header: { text: 'Company' }
  },
  'OrderID',
  'CustomerID',
  'EmployeeID',
  'OrderDate',
  'Phone'
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: -1
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/editor_demoData.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.setColumnLayout(hideChildLayout);
      });
  }
}, {
  fields
});

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

```js
hideChildLayout = [
   {
     name: "companyGroup",
     direction: "horizontal",
     hideChildHeaders: true, //<<-------
     items: [
       "Country",
       "CompanyName"
     ],
     header: {
       text: "Company",
     }
   },
   "OrderID",
   "CustomerID",
   "EmployeeID",
   "OrderDate",
   "Phone"
]

gridView.setColumnLayout(hideChildLayout);
```

---

```js
const fields = [
  { fieldName: 'OrderID', dataType: 'text' },
  { fieldName: 'CustomerID', dataType: 'text' },
  { fieldName: 'EmployeeID', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CompanyName', dataType: 'text' },
  { fieldName: 'Country', dataType: 'text' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductName', dataType: 'text' },
  { fieldName: 'QuantityPerUnit', dataType: 'text' },
  { fieldName: 'Quantity', dataType: 'number' },
  { fieldName: 'UnitPrice', dataType: 'number' }
];

const columns = [
  { name: 'Country', fieldName: 'Country', type: 'data', width: '100', header: { text: 'Country' } },
  { name: 'CompanyName', fieldName: 'CompanyName', type: 'data', width: '120', styleName: 'blue-column', header: { text: 'Company Name' } },
  { name: 'UnitPrice2', fieldName: 'UnitPrice', type: 'data', width: '100', renderer: { type: 'bar', origin: 'left', barWidth: '80%' }, header: { text: 'UnitPrice2' }, footer: { expression: 'sum' } },
  { name: 'OrderID', fieldName: 'OrderID', type: 'data', width: '80', header: { text: 'Order ID' }, footer: { expression: 'max', groupExpression: 'max' } },
  { name: 'CustomerID', fieldName: 'CustomerID', type: 'data', width: '90', header: { text: 'Customer ID' } },
  { name: 'EmployeeID', fieldName: 'EmployeeID', type: 'data', width: '90', header: { text: 'Employee ID' }, footer: { expression: 'min', groupExpression: 'min' } },
  { name: 'OrderDate', fieldName: 'OrderDate', type: 'data', width: '130', header: { text: 'Order Date' } },
  { name: 'Phone', fieldName: 'Phone', type: 'data', width: '90', renderer: { type: 'button' }, header: { text: 'Button' } },
  { name: 'Phone2', fieldName: 'Phone', type: 'data', width: '90', header: { text: 'Phone2' } },
  { name: 'ProductName', fieldName: 'ProductName', type: 'data', width: '200', header: { text: 'Product Name' } },
  { name: 'QuantityPerUnit', fieldName: 'QuantityPerUnit', type: 'data', width: '100', header: { text: 'Quantity / Unit' } },
  { name: 'Quantity', fieldName: 'Quantity', type: 'data', width: '100', header: { text: 'Quantity' }, footer: { expression: 'sum' } },
  { name: 'UnitPrice', fieldName: 'UnitPrice', type: 'data', width: '100', header: { text: 'Unit Price' }, footer: { expression: 'avg', groupExpression: 'max' } },
  { name: 'Country2', fieldName: 'Country', type: 'data', width: '100', header: { text: 'Country2' } }
];

const layout2 = [
  'OrderID',
  {
    column: 'CustomerID',
    width: 200
  },
  {
    name: 'companyGroup',
    direction: 'horizontal',
    items: ['Country', 'CompanyName'],
    header: { text: 'Company' }
  },
  { column: 'EmployeeID' },
  'OrderDate',
  'Phone'
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: -1
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/editor_demoData.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.setColumnLayout(layout2);
      });
  }
}, {
  fields
});

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

```js
layout2 = [
   "OrderID",
   {
       column: "CustomerID",
       width: 200
   },
   {
       name: "companyGroup",
       direction: "horizontal",
       items: [
           "Country",
           "CompanyName"
       ],
       header: {
           text: "Company"
       }
   },
   {
       column: "EmployeeID"
   },
   "OrderDate",
   "Phone"
];

gridView.setColumnLayout(layout2);
```

---

```js
const fields = [
  { fieldName: 'OrderID', dataType: 'text' },
  { fieldName: 'CustomerID', dataType: 'text' },
  { fieldName: 'EmployeeID', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CompanyName', dataType: 'text' },
  { fieldName: 'Country', dataType: 'text' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductName', dataType: 'text' },
  { fieldName: 'QuantityPerUnit', dataType: 'text' },
  { fieldName: 'Quantity', dataType: 'number' },
  { fieldName: 'UnitPrice', dataType: 'number' }
];

const columns = [
  { name: 'Country', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country' } },
  { name: 'CompanyName', fieldName: 'CompanyName', type: 'data', width: '120', styleName: 'blue-column', styles: { textAlignment: 'near' }, header: { text: 'Company Name' } },
  { name: 'UnitPrice2', fieldName: 'UnitPrice', type: 'data', width: '100', renderer: { type: 'bar', origin: 'left', barWidth: '80%' }, header: { text: 'UnitPrice2' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'OrderID', fieldName: 'OrderID', type: 'data', width: '80', styles: { textAlignment: 'center' }, header: { text: 'Order ID' }, footer: { expression: 'max', groupExpression: 'max' } },
  { name: 'CustomerID', fieldName: 'CustomerID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Customer ID' } },
  { name: 'EmployeeID', fieldName: 'EmployeeID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Employee ID' }, footer: { expression: 'min', groupExpression: 'min' } },
  { name: 'OrderDate', fieldName: 'OrderDate', type: 'data', width: '130', styles: { textAlignment: 'center' }, header: { text: 'Order Date' } },
  { name: 'Phone', fieldName: 'Phone', type: 'data', width: '90', renderer: { type: 'button' }, header: { text: 'Button' } },
  { name: 'Phone2', fieldName: 'Phone', type: 'data', width: '90', styles: { textAlignment: 'near' }, header: { text: 'Phone2' } },
  { name: 'ProductName', fieldName: 'ProductName', type: 'data', width: '200', styles: { textAlignment: 'near' }, header: { text: 'Product Name' } },
  { name: 'QuantityPerUnit', fieldName: 'QuantityPerUnit', type: 'data', width: '100', styles: { textAlignment: 'near' }, header: { text: 'Quantity / Unit' } },
  { name: 'Quantity', fieldName: 'Quantity', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Quantity' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'UnitPrice', fieldName: 'UnitPrice', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Unit Price' }, footer: { expression: 'avg', groupExpression: 'max', styles: { textAlignment: 'far', numberFormat: '0.00', prefix: 'AVG = ' } } },
  { name: 'Country2', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country2' } }
];

const layout3 = [
  'OrderID',
  'CustomerID',
  {
    name: 'companyGroup',
    direction: 'vertical',
    width: 250,
    items: ['Country', 'CompanyName'],
    header: { text: 'Company' }
  },
  'EmployeeID',
  'OrderDate',
  'Phone'
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: -1
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/editor_demoData.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.setColumnLayout(layout3);
      });
  }
}, {
  fields
});

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

```js
layout3 = [
   "OrderID",
   "CustomerID",
   {
     name: "companyGroup",
     direction: "vertical",
     width: 250,
     items: [
       "Country",
       "CompanyName"
     ],
     header: {
       text: "Company"
     }
   },
   "EmployeeID",
   "OrderDate",
   "Phone"
];

gridView.setColumnLayout(layout3);
```

---

```js
const fields = [
  { fieldName: 'OrderID', dataType: 'text' },
  { fieldName: 'CustomerID', dataType: 'text' },
  { fieldName: 'EmployeeID', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CompanyName', dataType: 'text' },
  { fieldName: 'Country', dataType: 'text' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductName', dataType: 'text' },
  { fieldName: 'QuantityPerUnit', dataType: 'text' },
  { fieldName: 'Quantity', dataType: 'number' },
  { fieldName: 'UnitPrice', dataType: 'number' }
];

const columns = [
  { name: 'Country', fieldName: 'Country', type: 'data', width: '100', header: { text: 'Country' } },
  { name: 'CompanyName', fieldName: 'CompanyName', type: 'data', width: '120', styleName: 'blue-column', header: { text: 'Company Name' } },
  { name: 'UnitPrice2', fieldName: 'UnitPrice', type: 'data', width: '100', renderer: { type: 'bar', origin: 'left', barWidth: '80%' }, header: { text: 'UnitPrice2' }, footer: { expression: 'sum' } },
  { name: 'OrderID', fieldName: 'OrderID', type: 'data', width: '80', header: { text: 'Order ID' }, footer: { expression: 'max', groupExpression: 'max' } },
  { name: 'CustomerID', fieldName: 'CustomerID', type: 'data', width: '90', header: { text: 'Customer ID' } },
  { name: 'EmployeeID', fieldName: 'EmployeeID', type: 'data', width: '90', header: { text: 'Employee ID' }, footer: { expression: 'min', groupExpression: 'min' } },
  { name: 'OrderDate', fieldName: 'OrderDate', type: 'data', width: '130', header: { text: 'Order Date' } },
  { name: 'Phone', fieldName: 'Phone', type: 'data', width: '90', renderer: { type: 'button' }, header: { text: 'Button' } },
  { name: 'Phone2', fieldName: 'Phone', type: 'data', width: '90', header: { text: 'Phone2' } },
  { name: 'ProductName', fieldName: 'ProductName', type: 'data', width: '200', header: { text: 'Product Name' } },
  { name: 'QuantityPerUnit', fieldName: 'QuantityPerUnit', type: 'data', width: '100', header: { text: 'Quantity / Unit' } },
  { name: 'Quantity', fieldName: 'Quantity', type: 'data', width: '100', header: { text: 'Quantity' }, footer: { expression: 'sum' } },
  { name: 'UnitPrice', fieldName: 'UnitPrice', type: 'data', width: '100', header: { text: 'Unit Price' }, footer: { expression: 'avg', groupExpression: 'max' } },
  { name: 'Country2', fieldName: 'Country', type: 'data', width: '100', header: { text: 'Country2' } }
];

const layout4 = [
  'OrderID',
  'CustomerID',
  {
    name: 'companyGroup',
    direction: 'vertical',
    width: 250,
    items: [
      {
        name: 'countryGroup',
        direction: 'horizontal',
        items: [
          { column: 'Country', width: 100 },
          { column: 'Phone', width: 100 }
        ],
        header: { text: 'Country Group' }
      },
      'CompanyName'
    ],
    header: { text: 'Company Group' }
  },
  'EmployeeID',
  'OrderDate',
  'Phone2'
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: -1
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/editor_demoData.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.setColumnLayout(layout4);
      });
  }
}, {
  fields
});

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

```js
layout4 = [
   "OrderID",
   "CustomerID",
   {
     name: "companyGroup",
     direction: "vertical",
     width: 250,
     items: [
     {
       name: "countryGroup",
       direction: "horizontal",
       items: [
         {
           column: "Country",
           width: 100
         },
         {
           column: "Phone",
           width: 100
         }
       ],
       header: {
         text: "Country Group"
       }
     },
       "CompanyName"
     ],
     header: {
       text: "Company Group"
     }
   },
   "EmployeeID",
   "OrderDate",
   "Phone2"
];


gridView.setColumnLayout(layout4);
```

---

```js
const fields = [
  { fieldName: 'OrderID', dataType: 'text' },
  { fieldName: 'CustomerID', dataType: 'text' },
  { fieldName: 'EmployeeID', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CompanyName', dataType: 'text' },
  { fieldName: 'Country', dataType: 'text' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductName', dataType: 'text' },
  { fieldName: 'QuantityPerUnit', dataType: 'text' },
  { fieldName: 'Quantity', dataType: 'number' },
  { fieldName: 'UnitPrice', dataType: 'number' }
];

const columns = [
  { name: 'Country', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country' } },
  { name: 'CompanyName', fieldName: 'CompanyName', type: 'data', width: '120', styleName: 'blue-column', styles: { textAlignment: 'near' }, header: { text: 'Company Name' } },
  { name: 'UnitPrice2', fieldName: 'UnitPrice', type: 'data', width: '100', renderer: { type: 'bar', origin: 'left', barWidth: '80%' }, header: { text: 'UnitPrice2' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'OrderID', fieldName: 'OrderID', type: 'data', width: '80', styles: { textAlignment: 'center' }, header: { text: 'Order ID' }, footer: { expression: 'max', groupExpression: 'max' } },
  { name: 'CustomerID', fieldName: 'CustomerID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Customer ID' } },
  { name: 'EmployeeID', fieldName: 'EmployeeID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Employee ID' }, footer: { expression: 'min', groupExpression: 'min' } },
  { name: 'OrderDate', fieldName: 'OrderDate', type: 'data', width: '130', styles: { textAlignment: 'center' }, header: { text: 'Order Date' } },
  { name: 'Phone', fieldName: 'Phone', type: 'data', width: '90', renderer: { type: 'button' }, header: { text: 'Button' } },
  { name: 'Phone2', fieldName: 'Phone', type: 'data', width: '90', styles: { textAlignment: 'near' }, header: { text: 'Phone2' } },
  { name: 'ProductName', fieldName: 'ProductName', type: 'data', width: '200', styles: { textAlignment: 'near' }, header: { text: 'Product Name' } },
  { name: 'QuantityPerUnit', fieldName: 'QuantityPerUnit', type: 'data', width: '100', styles: { textAlignment: 'near' }, header: { text: 'Quantity / Unit' } },
  { name: 'Quantity', fieldName: 'Quantity', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Quantity' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'UnitPrice', fieldName: 'UnitPrice', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Unit Price' }, footer: { expression: 'avg', groupExpression: 'max', styles: { textAlignment: 'far', numberFormat: '0.00', prefix: 'AVG = ' } } },
  { name: 'Country2', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country2' } }
];

const layout5 = [
  {
    name: 'Group1',
    direction: 'horizontal',
    width: 200,
    items: [
      {
        name: 'Group2',
        direction: 'vertical',
        items: [{ column: 'OrderID', width: 100 }]
      },
      {
        name: 'Group3',
        direction: 'vertical',
        items: [{ column: 'CustomerID', width: 100 }]
      }
    ]
  },
  {
    name: 'Group4',
    direction: 'vertical',
    width: 100,
    header: {},
    items: [{ column: 'Country' }]
  },
  'OrderDate',
  'EmployeeID',
  'Phone'
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: -1
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/editor_demoData.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.setColumnLayout(layout5);
      });
  }
}, {
  fields
});

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

```js
layout5 = [{
     name: "Group1",
     direction: "horizontal",
     width: 200,
     items: [{
         name: "Group2",
         direction: "vertical",
         items: [{
             column: "OrderID",
             width: 100
         }]
     }, {
         name: "Group3",
         direction: "vertical",
         items: [{
             column: "CustomerID",
             width: 100
         }]
     }]
}, {
     name: "Group4",
     direction: "vertical",
     width: 100,
     items: [{
         column: "Country"
     }]
},
"OrderDate",
"EmployeeID",
"Phone"
];

gridView.setColumnLayout(layout5);
```

---

```js
const fields = [
  { fieldName: 'OrderID', dataType: 'text' },
  { fieldName: 'CustomerID', dataType: 'text' },
  { fieldName: 'EmployeeID', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CompanyName', dataType: 'text' },
  { fieldName: 'Country', dataType: 'text' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductName', dataType: 'text' },
  { fieldName: 'QuantityPerUnit', dataType: 'text' },
  { fieldName: 'Quantity', dataType: 'number' },
  { fieldName: 'UnitPrice', dataType: 'number' }
];

const columns = [
  { name: 'Country', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country' } },
  { name: 'CompanyName', fieldName: 'CompanyName', type: 'data', width: '120', styleName: 'blue-column', styles: { textAlignment: 'near' }, header: { text: 'Company Name' } },
  { name: 'UnitPrice2', fieldName: 'UnitPrice', type: 'data', width: '100', renderer: { type: 'bar', origin: 'left', barWidth: '80%' }, header: { text: 'UnitPrice2' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'OrderID', fieldName: 'OrderID', type: 'data', width: '80', styles: { textAlignment: 'center' }, header: { text: 'Order ID' }, footer: { expression: 'max', groupExpression: 'max' } },
  { name: 'CustomerID', fieldName: 'CustomerID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Customer ID' } },
  { name: 'EmployeeID', fieldName: 'EmployeeID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Employee ID' }, footer: { expression: 'min', groupExpression: 'min' } },
  { name: 'OrderDate', fieldName: 'OrderDate', type: 'data', width: '130', styles: { textAlignment: 'center' }, header: { text: 'Order Date' } },
  { name: 'Phone', fieldName: 'Phone', type: 'data', width: '90', renderer: { type: 'button' }, header: { text: 'Button' } },
  { name: 'Phone2', fieldName: 'Phone', type: 'data', width: '90', styles: { textAlignment: 'near' }, header: { text: 'Phone2' } },
  { name: 'ProductName', fieldName: 'ProductName', type: 'data', width: '200', styles: { textAlignment: 'near' }, header: { text: 'Product Name' } },
  { name: 'QuantityPerUnit', fieldName: 'QuantityPerUnit', type: 'data', width: '100', styles: { textAlignment: 'near' }, header: { text: 'Quantity / Unit' } },
  { name: 'Quantity', fieldName: 'Quantity', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Quantity' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'UnitPrice', fieldName: 'UnitPrice', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Unit Price' }, footer: { expression: 'avg', groupExpression: 'max', styles: { textAlignment: 'far', numberFormat: '0.00', prefix: 'AVG = ' } } },
  { name: 'Country2', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country2' } }
];

const layout6 = [
  {
    name: 'Group1',
    direction: 'horizontal',
    width: 200,
    items: [
      {
        name: 'Group2',
        direction: 'vertical',
        items: [{ column: 'OrderID', width: 100 }]
      },
      {
        name: 'Group3',
        direction: 'vertical',
        items: [{ column: 'CustomerID', width: 100 }]
      }
    ]
  },
  {
    name: 'Group4',
    direction: 'horizontal',
    width: 200,
    items: [
      {
        name: 'Group2',
        direction: 'vertical',
        header: { visible: false },
        items: [{ column: 'Country', width: 100 }]
      },
      {
        name: 'Group3',
        direction: 'vertical',
        header: { visible: false },
        items: [{ column: 'OrderDate', width: 100 }]
      }
    ]
  },
  'EmployeeID',
  'Phone'
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: -1
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/editor_demoData.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.setColumnLayout(layout6);
      });
  }
}, {
  fields
});

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

```js
layout6 = [{
     name: "Group1",
     direction: "horizontal",
     width: 200,
     items: [{
         name: "Group2",
         direction: "vertical",
         items: [{
             column: "OrderID",
             width: 100
         }]
     }, {
         name: "Group3",
         direction: "vertical",
         items: [{
             column: "CustomerID",
             width: 100
         }]
     }]
}, {
     name: "Group4",
     direction: "horizontal",
     width: 200,
     items: [{
         name: "Group2",
         direction: "vertical",
         header: {visible: false},
         items: [{
             column: "Country",
            
             width: 100
         }]
     }, {
         name: "Group3",
         direction: "vertical",
         header: {visible: false},
         items: [{
             column: "OrderDate",
           
             width: 100
         }]
     }]
},
"EmployeeID",
"Phone"
];

gridView.setColumnLayout(layout6);
```


---

```js
const fields = [
  { fieldName: 'OrderID', dataType: 'text' },
  { fieldName: 'CustomerID', dataType: 'text' },
  { fieldName: 'EmployeeID', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CompanyName', dataType: 'text' },
  { fieldName: 'Country', dataType: 'text' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductName', dataType: 'text' },
  { fieldName: 'QuantityPerUnit', dataType: 'text' },
  { fieldName: 'Quantity', dataType: 'number' },
  { fieldName: 'UnitPrice', dataType: 'number' }
];

const columns = [
  { name: 'Country', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country' } },
  { name: 'CompanyName', fieldName: 'CompanyName', type: 'data', width: '120', styleName: 'blue-column', styles: { textAlignment: 'near' }, header: { text: 'Company Name' } },
  { name: 'UnitPrice2', fieldName: 'UnitPrice', type: 'data', width: '100', renderer: { type: 'bar', origin: 'left', barWidth: '80%' }, header: { text: 'UnitPrice2' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'OrderID', fieldName: 'OrderID', type: 'data', width: '80', styles: { textAlignment: 'center' }, header: { text: 'Order ID' }, footer: { expression: 'max', groupExpression: 'max' } },
  { name: 'CustomerID', fieldName: 'CustomerID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Customer ID' } },
  { name: 'EmployeeID', fieldName: 'EmployeeID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Employee ID' }, footer: { expression: 'min', groupExpression: 'min' } },
  { name: 'OrderDate', fieldName: 'OrderDate', type: 'data', width: '130', styles: { textAlignment: 'center' }, header: { text: 'Order Date' } },
  { name: 'Phone', fieldName: 'Phone', type: 'data', width: '90', renderer: { type: 'button' }, header: { text: 'Button' } },
  { name: 'Phone2', fieldName: 'Phone', type: 'data', width: '90', styles: { textAlignment: 'near' }, header: { text: 'Phone2' } },
  { name: 'ProductName', fieldName: 'ProductName', type: 'data', width: '200', styles: { textAlignment: 'near' }, header: { text: 'Product Name' } },
  { name: 'QuantityPerUnit', fieldName: 'QuantityPerUnit', type: 'data', width: '100', styles: { textAlignment: 'near' }, header: { text: 'Quantity / Unit' } },
  { name: 'Quantity', fieldName: 'Quantity', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Quantity' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'UnitPrice', fieldName: 'UnitPrice', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Unit Price' }, footer: { expression: 'avg', groupExpression: 'max', styles: { textAlignment: 'far', numberFormat: '0.00', prefix: 'AVG = ' } } },
  { name: 'Country2', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country2' } }
];

const layout = [
  {
    name: 'Group1',
    direction: 'horizontal',
    items: [
      {
        name: 'OrderID',
        items: ['OrderID'],
        header: { visible: false }
      },
      {
        name: 'CustomerID',
        items: ['CustomerID'],
        header: { visible: false }
      }
    ],
    header: { text: 'Group1' }
  },
  {
    name: 'Group2',
    direction: 'horizontal',
    items: [
      {
        name: 'Group3',
        items: ['Country', 'OrderDate']
      },
      {
        name: 'Group4',
        items: ['EmployeeID', 'Phone']
      }
    ],
    header: { text: 'Group2' }
  }
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: -1
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/editor_demoData.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.setColumnLayout(layout);
      });
  }
}, {
  fields
});

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

```js
layout = [
   {
     name: 'Group1',
     direction: 'horizontal',
     items: [
       {
         name: 'OrderID',
         items: ['OrderID'],
         header: { visible: false },
       },
       {
         name: 'CustomerID',
         items: ['CustomerID'],
         header: { visible: false },
       },
     ],
     header: { text: 'Group1' },
   },
   {
     name: 'Group2',
     direction: 'horizontal',
     items: [
       {
         name: 'Group3',
         items: ['Country', 'OrderDate'],
       },
       {
         name: 'Group4',
         items: ['EmployeeID','Phone']
        }
     ],
     header: {text:"Group2"}
   },
]


gridView.setColumnLayout(layout);
```

#### Merge group headers vertically

Headers are merged into the number of group header rows as many as the value set in header.rows.

```js
const fields = [
  { fieldName: 'OrderID', dataType: 'text' },
  { fieldName: 'CustomerID', dataType: 'text' },
  { fieldName: 'EmployeeID', dataType: 'text' },
  { fieldName: 'OrderDate', dataType: 'datetime', datetimeFormat: 'yyyy-MM-dd', amText: 'AM', pmText: 'PM' },
  { fieldName: 'CompanyName', dataType: 'text' },
  { fieldName: 'Country', dataType: 'text' },
  { fieldName: 'Phone', dataType: 'text' },
  { fieldName: 'ProductName', dataType: 'text' },
  { fieldName: 'QuantityPerUnit', dataType: 'text' },
  { fieldName: 'Quantity', dataType: 'number' },
  { fieldName: 'UnitPrice', dataType: 'number' }
];

const columns = [
  { name: 'Country', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country' } },
  { name: 'CompanyName', fieldName: 'CompanyName', type: 'data', width: '120', styleName: 'blue-column', styles: { textAlignment: 'near' }, header: { text: 'Company Name' } },
  { name: 'UnitPrice2', fieldName: 'UnitPrice', type: 'data', width: '100', renderer: { type: 'bar', origin: 'left', barWidth: '80%' }, header: { text: 'UnitPrice2' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'OrderID', fieldName: 'OrderID', type: 'data', width: '80', styles: { textAlignment: 'center' }, header: { text: 'Order ID' }, footer: { expression: 'max', groupExpression: 'max' } },
  { name: 'CustomerID', fieldName: 'CustomerID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Customer ID' } },
  { name: 'EmployeeID', fieldName: 'EmployeeID', type: 'data', width: '90', styles: { textAlignment: 'center' }, header: { text: 'Employee ID' }, footer: { expression: 'min', groupExpression: 'min' } },
  { name: 'OrderDate', fieldName: 'OrderDate', type: 'data', width: '130', styles: { textAlignment: 'center' }, header: { text: 'Order Date' } },
  { name: 'Phone', fieldName: 'Phone', type: 'data', width: '90', renderer: { type: 'button' }, header: { text: 'Button' } },
  { name: 'Phone2', fieldName: 'Phone', type: 'data', width: '90', styles: { textAlignment: 'near' }, header: { text: 'Phone2' } },
  { name: 'ProductName', fieldName: 'ProductName', type: 'data', width: '200', styles: { textAlignment: 'near' }, header: { text: 'Product Name' } },
  { name: 'QuantityPerUnit', fieldName: 'QuantityPerUnit', type: 'data', width: '100', styles: { textAlignment: 'near' }, header: { text: 'Quantity / Unit' } },
  { name: 'Quantity', fieldName: 'Quantity', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Quantity' }, footer: { expression: 'sum', styles: { textAlignment: 'far', numberFormat: '#,000' } } },
  { name: 'UnitPrice', fieldName: 'UnitPrice', type: 'data', width: '100', styles: { textAlignment: 'far' }, header: { text: 'Unit Price' }, footer: { expression: 'avg', groupExpression: 'max', styles: { textAlignment: 'far', numberFormat: '0.00', prefix: 'AVG = ' } } },
  { name: 'Country2', fieldName: 'Country', type: 'data', width: '100', styles: { textAlignment: 'center' }, header: { text: 'Country2' } }
];

const layout = [
  {
    name: 'Group1',
    direction: 'horizontal',
    items: [
      {
        name: 'OrderID',
        items: ['OrderID'],
        header: { visible: false }
      },
      {
        name: 'CustomerID',
        items: ['CustomerID'],
        header: { visible: false }
      }
    ],
    header: { text: 'Group1', rows: 2 } // rows: 2 demonstrates vertical header merging
  },
  {
    name: 'Group2',
    direction: 'horizontal',
    items: [
      {
        name: 'Group3',
        items: ['Country', 'OrderDate']
      },
      {
        name: 'Group4',
        items: ['EmployeeID', 'Phone']
      }
    ],
    header: { text: 'Group2' }
  }
];

const { gridView, dataProvider } = RealGrid.createGrid('realgrid', {
  columns,
  header: {
    height: -1
  },
  display: {
    rowHeight: 36,
    emptyMessage: 'No data to display.'
  },
  edit: {
    insertable: true,
    appendable: true
  },
  footer: {
    height: 40
  },
  stateBar: {
    width: 16
  },
  onInitialized: (grid) => {
    fetch('/data/en/editor_demoData.json')
      .then(response => response.json())
      .then(data => {
        grid.getDataSource().setRows(data);
        grid.setColumnLayout(layout);
      });
  }
}, {
  fields
});

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

```js
layout = [
  {
    name: 'Group1',
    direction: 'horizontal',
    items: [
      {
        name: 'OrderID',
        items: ['OrderID'],
        header: { visible: false },
      },
      {
        name: 'CustomerID',
        items: ['CustomerID'],
        header: { visible: false },
      },
    ],
    header: { text: 'Group1', rows: 2},
  },
  {
    name: 'Group2',
    direction: 'horizontal',
    items: [
      {
        name: 'Group3',
        items: ['Country', 'OrderDate'],
      },
      {
        name: 'Group4',
        items: ['EmployeeID','Phone']
      }
    ],
    header: {text:"Group2"}
  },
]


gridView.setColumnLayout(layout);
```