This page shows how to get started with Wijmo's MultiRow control.
Getting Started
The MultiRow control extends conventional grid layouts by using multiple
rows to represent each data item.
The MultiRow control allows users to see and edit data in a tabular form,
just like other conventional grids. But, MultiRow is different from these
grids in a way that it allows you to bind each data item to multiple rows, creating
form-like interfaces that can display a large number of columns with minimal
horizontal scrolling.
The MultiRow control extends the FlexGrid control, so if you know
how to use FlexGrid, you will be able to use MultiRow in no time.
The main new property is layoutDefinition, which takes an object that
describes the layout of the grid rows and cells.
The MultiRow control is not a simple replacement for conventional grids;
it is a specialized tool that fits some particular scenarios really well.
To use the MultiRow control in your applications, add references to the
wijmo, wijmo.grid, and wijmo.grid.multirow modules, then
instantiate MultiRow controls by giving them host element on the page,
or add wj-multi-row directives if you are using AngularJS:
var multirow = new wijmo.grid.multirow.MultiRow('#multirow', {
itemsSource: appData.orders,
layoutDefinition: appData.layoutDefs.currentItem.def
});
var ldComboBox = new wijmo.input.ComboBox('#ldComboBox', {
itemsSource: appData.layoutDefs,
displayMemberPath: 'name',
selectedIndexChanged: function (s, e) {
var layoutDef = appData.layoutDefs.currentItem;
if (layoutDef) {
multirow.layoutDefinition = layoutDef.def;
setText('desc', layoutDef.description);
}
}
});
setText('desc', appData.layoutDefs.currentItem.description);
Result (live):
The layoutDefinition property specifies the layout of the cells in the
grid. It contains an array of cell group objects. Each cell group specifies
how many columns the group should span, and the cells that make up each group.
The image below illustrates how a cell group is interpreted and turned into
a grid layout:
The group spans three grid columns. It contains six cells with different spans.
When generating the layout, the grid fits as many cells as possible in each
row, and wraps to the next row when the group span is reached. The last cell in
each row is automatically expanded to fill colspan of the group.
The process is similar to wrapping of text to create a paragraph.
The same process is applied to every group in the layoutDefinition
object.
Collapsible Column Headers
By default, the MultiRow control creates column headers that span multiple
rows and shows the header for each cell defined in the layoutDefinition.
These cell-specific column headers may be used to sort or filter the data as
you would do in a conventional grid.
In some cases, you may want to collapse the column headers to a single line,
showing only the group names rather than individual cells. This saves space
at the expense of having individual cell headers. To collapse the column
headers, set the collapsedHeaders property to true. In these scenarios,
remember to set the header property on the groups in order to avoid
empty column headers.
In most of the applications, you would want to show where each record and group starts or ends.
The MultiRow control enables this by adding CSS class names to cell elements
in the first and last row/column of each group. The class names are
wj-record-start, wj-record-end, wj-group-start,
and wj-group-end.
The example below shows how you can use these class names in CSS rules to customize
the appearance of the record and group delimiters. It also shows how you can use the
standard cssClass property to customize the appearance of specific cells
within groups:
/* custom styling for a MultiRow */
.multirow-css .wj-cell.wj-record-end:not(.wj-header) {
border-bottom: 1px solid #000; /* thin black lines between records */
}
.multirow-css .wj-cell.wj-group-end {
border-right: 2px solid #00b68c; /* thick green lines between groups */
}
.multirow-css .wj-cell.id {
color: #c0c0c0;
}
.multirow-css .wj-cell.amount {
color: #014701;
font-weight: bold;
}
.multirow-css .wj-cell.email {
color: #0010c0;
text-decoration: underline;
}
Result (live):
Grouping
The MultiRow control supports CollectionView-based grouping just
like FlexGrid.
To use grouping, create a CollectionView based on the raw data and add
one or more GroupDescription objects to the GroupDescriptions array
of the collection.
var groupMultirow = new wijmo.grid.multirow.MultiRow('#groupMultirow', {
itemsSource: appData.groupedOrders,
layoutDefinition: appData.ldThreeLines,
showGroups: true,
groupHeaderFormat: '{name}: {value} ({count:n0} items)'
});
// toggle show groups
document.getElementById('cbShowGroup').addEventListener('click', function (e) {
groupMultirow.showGroups = e.target.checked;
});
// collapse/expand all
document.getElementById('btnCollapse').addEventListener('click', function (e) {
groupMultirow.collapseGroupsToLevel(0);
});
document.getElementById('btnExpand').addEventListener('click', function (e) {
groupMultirow.collapseGroupsToLevel(10);
});
Result (live):
Filtering
The MultiRow control supports filtering just like FlexGrid.
Filtering is provided by the wijmo.grid.filter.FlexGridFilter class.
To add filtering UI to MultiRow, create a FlexGridFilter and pass
MultiRow as a parameter in the constructor.
If you are using AngularJS, you can also add a filter to the grid by embedding a
wj-flex-grid-filter directive as a child of the grid's directive.
var filterMultirow = new wijmo.grid.multirow.MultiRow('#filterMultirow', {
itemsSource: appData.orders,
layoutDefinition: appData.ldThreeLines
});
var filter = new wijmo.grid.filter.FlexGridFilter(filterMultirow);
Result (live):
Row and Column Freezing
The MultiRow control allows you to freeze rows and columns so they remain
in view as the user scrolls the grid. Frozen cells can be edited and selected as
regular cells, exactly as in Excel and in the FlexGrid control.
This example allows you to toggle whether the first group of rows and columns
should be frozen.
The MultiRow control supports paging through the IPagedCollectionView interface,
which is nearly identical to the one in .NET. To enable paging, set the
IPagedCollectionView.pageSize property to the number of items you want to display
on each page, and provide a UI for navigating the pages.
In this example, we use JavaScript to show four items per page. We add navigation buttons,
and call IPagedCollectionView method in the button click directives. We use the
pageIndex and pageCount properties to show the current page and total number
of pages.
var pagedOrders = appData.pagedOrders;
var pagingMultirow = new wijmo.grid.multirow.MultiRow('#pageMultirow', {
itemsSource: pagedOrders,
layoutDefinition: appData.ldThreeLines
});
// paging buttons
document.getElementById('firstBtn').addEventListener('click', function (e) {
pagedOrders.moveToFirstPage();
});
document.getElementById('previousBtn').addEventListener('click', function (e) {
pagedOrders.moveToPreviousPage();
});
document.getElementById('nextBtn').addEventListener('click', function (e) {
pagedOrders.moveToNextPage();
});
document.getElementById('lastBtn').addEventListener('click', function (e) {
pagedOrders.moveToLastPage();
});
// update page text now and when the current page changes
updatePageText();
pagedOrders.collectionChanged.addHandler(function () {
updatePageText();
});
pagedOrders.pageChanged.addHandler(function () {
updatePageText();
});
function updatePageText() {
var text = wijmo.format('{index:n0} / {count:n0}', {
index: pagedOrders.pageIndex + 1,
count: pagedOrders.pageCount
});
setText('numBtn', text);
}
Result (live):
Adding and Deleting Records
The MultiRow control supports the allowAddNew and allowDelete
properties provided by the FlexGrid control.
Setting the allowAddNew property to true causes the grid to display a set of
'new row template' rows at the bottom of the grid.
When user starts editing a cell in the new row template, a new item is added
to the source collection. When user finishes editing the new item by moving
the selection to another row or the focus to another control, the new item is
committed.
Setting the allowDelete property to true causes the grid to monitor key presses
and to delete the current row if user presses the 'Delete' key while an entire
row is selected.