Skip to content

Commit

Permalink
feat: add final rowspan implementation (ghiscoding#1798)
Browse files Browse the repository at this point in the history
* feat: add final rowspan implementation
  • Loading branch information
ghiscoding authored Jan 18, 2025
1 parent 8b02e06 commit 5d0f58e
Show file tree
Hide file tree
Showing 30 changed files with 2,760 additions and 278 deletions.
1 change: 1 addition & 0 deletions docs/TOC.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
* [Column Picker](grid-functionalities/Column-Picker.md)
* [Composite Editor Modal](grid-functionalities/Composite-Editor-Modal.md)
* [Custom Tooltip](grid-functionalities/custom-tooltip.md)
* [Column & Row Spanning](grid-functionalities/column-row-spanning.md)
* [Context Menu](grid-functionalities/Context-Menu.md)
* [Custom Footer](grid-functionalities/Custom-Footer.md)
* [Excel Copy Buffer Plugin](grid-functionalities/excel-copy-buffer.md)
Expand Down
54 changes: 54 additions & 0 deletions docs/grid-functionalities/column-row-spanning.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
### Description
You can use Colspan and/or Rowspan by using the DataView Item Metadata Provider, however please note that row spanning is under a flag because of its small perf hit (`rowspan` requires an initial loop through of all row item metadata to map all row span).

### Demo

#### Colspan / Rowspan
[Employee Timesheets](https://ghiscoding.github.io/slickgrid-universal/#/example32) / [Demo Component](https://github.com/ghiscoding/slickgrid-universal/blob/master/examples/webpack-demo-vanilla-bundle/src/examples/example32.ts)

[Large Dataset](https://ghiscoding.github.io/slickgrid-universal/#/example33) / [Demo Component](https://github.com/ghiscoding/slickgrid-universal/blob/master/examples/webpack-demo-vanilla-bundle/src/examples/example33.ts)

### Basic Usage

##### Component

```ts
import { Column, CompositeEditorModalType } from '@slickgrid-universal/common';
import { SlickCompositeEditorComponent } from '@slickgrid-universal/composite-editor-component';

example class MyExample {
gridOptions: GridOption;
columnDefinitions: Column[];
dataset: any[];

// metadata can be dynamic too, it doesn't have to be preset
metadata: ItemMetadata | Record<number, ItemMetadata> = {
0: {
columns: {
1: { rowspan: 2 },
2: { colspan: 2 },
10: { colspan: 3, rowspan: 10 },
13: { colspan: 2 },
17: { colspan: 2, rowspan: 2 },
},
}
};

defineGrid() {
this.columnDefinitions = [ /*...*/ ];

this.gridOptions.value = {
enableCellNavigation: true,
enableCellRowSpan: true, // required for rowspan to work
dataView: {
globalItemMetadataProvider: {
getRowMetadata: (_item, row) => {
return this.metadata[row];
},
},
},
rowTopOffsetRenderType: 'top', // rowspan doesn't render well with 'transform', default is 'top'
};
}
}
```
4 changes: 4 additions & 0 deletions examples/vite-demo-vanilla-bundle/src/app-routing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ import Example28 from './examples/example28.js';
import Example29 from './examples/example29.js';
import Example30 from './examples/example30.js';
import Example31 from './examples/example31.js';
import Example32 from './examples/example32.js';
import Example33 from './examples/example33.js';

export class AppRouting {
constructor(private config: RouterConfig) {
Expand Down Expand Up @@ -69,6 +71,8 @@ export class AppRouting {
{ route: 'example29', name: 'example29', view: './examples/example29.html', viewModel: Example29, title: 'Example29' },
{ route: 'example30', name: 'example30', view: './examples/example30.html', viewModel: Example30, title: 'Example30' },
{ route: 'example31', name: 'example31', view: './examples/example31.html', viewModel: Example31, title: 'Example31' },
{ route: 'example32', name: 'example32', view: './examples/example32.html', viewModel: Example32, title: 'Example32' },
{ route: 'example33', name: 'example33', view: './examples/example33.html', viewModel: Example33, title: 'Example33' },
{ route: '', redirect: 'example01' },
{ route: '**', redirect: 'example01' },
];
Expand Down
2 changes: 2 additions & 0 deletions examples/vite-demo-vanilla-bundle/src/app.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ <h4 class="is-size-4 has-text-white">Slickgrid-Universal</h4>

<div class="navbar-dropdown">
<a class="navbar-item" onclick.delegate="loadRoute('example31')"> Example31 - Create Grid from CSV </a>
<a class="navbar-item" onclick.delegate="loadRoute('example32')"> Example32 - Colspan/Rowspan (timesheets) </a>
<a class="navbar-item" onclick.delegate="loadRoute('example33')"> Example33 - Colspan/Rowspan (large dataset)</a>
</div>
</div>
</div>
Expand Down
18 changes: 18 additions & 0 deletions examples/vite-demo-vanilla-bundle/src/examples/example14.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ <h4 class="title is-4">Container Width (1000px)</h4>
</p>
</div>

<div class="column field has-addons is-narrow">
<p class="control">
<button
class="button is-small"
onclick.delegate="handleNavigateBottom()"
data-test="navigate-bottom"
title="Navigate to Bottom of Grid"
>
<span class="mdi mdi-arrow-down"></span>
</button>
</p>
<p class="control">
<button class="button is-small" onclick.delegate="handleNavigateTop()" data-test="navigate-top" title="Navigate to Top of Grid">
<span class="mdi mdi-arrow-down mdi-rotate-180"></span>
</button>
</p>
</div>

<div class="column field has-addons is-narrow">
<p class="control">
<button class="button is-small" onclick.delegate="toggleGridEditReadonly()" data-test="toggle-readonly-btn">
Expand Down
8 changes: 8 additions & 0 deletions examples/vite-demo-vanilla-bundle/src/examples/example14.ts
Original file line number Diff line number Diff line change
Expand Up @@ -699,6 +699,14 @@ export default class Example14 {
return tmpArray;
}

handleNavigateBottom() {
this.sgb.slickGrid?.navigateBottom();
}

handleNavigateTop() {
this.sgb.slickGrid?.navigateTop();
}

handleOnGridStateChanged(event) {
// console.log('handleOnGridStateChanged', event?.detail ?? '')
const gridStateChanges: GridStateChange = event?.detail;
Expand Down
73 changes: 73 additions & 0 deletions examples/vite-demo-vanilla-bundle/src/examples/example32.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<h3 class="title is-3">
Example 32 - colspan/rowspan - Employees Timesheets
<div class="subtitle code-link">
<span class="is-size-6">see</span>
<a
class="is-size-5"
target="_blank"
href="https://github.com/ghiscoding/slickgrid-universal/blob/master/examples/vite-demo-vanilla-bundle/src/examples/example32.ts"
>
<span class="mdi mdi-link-variant"></span> code
</a>
</div>
</h3>

<div class="columns">
<div class="column">
<p class="italic example-details">
<b>NOTES</b>: <code>rowspan</code> is an opt-in feature, because of its small perf hit (it needs to loop through all row metadatas to
map all rowspan), and requires the <code>enableCellRowSpan</code> grid option to be enabled to work properly. The
<code>colspan</code>/<code>rowspan</code> are both using DataView item metadata and are both based on row indexes and will
<b>not</b> keep the row in sync with the data. It is really up to you the user to update the metadata logic of how and where the cells
should span when a side effect kicks in. (i.e: Filtering/Sorting/Paging/Column Reorder... will <b>not</b> change/update the spanning
in the grid by itself and that is why they these features are all disabled in this example). Also, column/row freezing (pinning) are
also not supported, or at least not recommended unless you know exactly what you're doing (like in this demo here because we know our
pinning doesn't intersect)! Any freezing column/row that could intersect with a <code>colspan</code>/<code>rowspan</code>
<b>will cause problems</b>.
</p>
</div>
</div>

<section class="mb-2">
<div class="row mb-1">
<button class="button is-small" data-test="goto-up" onclick.delegate="navigateUp()" title="from an active cell, navigate to cell above">
<span class="mdi mdi-chevron-down mdi-rotate-180"></span>
Navigate Up Cell
</button>
<button
class="button is-small"
data-test="goto-down"
onclick.delegate="navigateDown()"
title="from an active cell, navigate to cell below"
>
<span class="mdi mdi-chevron-down"></span>
Navigate Down Cell
</button>
<button
class="button is-small"
data-test="goto-prev"
onclick.delegate="navigatePrev()"
title="from an active cell, navigate to previous left cell"
>
<span class="mdi mdi-chevron-down mdi-rotate-90"></span>
Navigate to Left Cell
</button>
<button
class="button is-small"
data-test="goto-next"
onclick.delegate="navigateNext()"
title="from an active cell, navigate to next right cell"
>
<span class="mdi mdi-chevron-down mdi-rotate-270"></span>
Navigate to Right Cell
</button>
<button class="button is-small mx-1" onclick.delegate="toggleEditing()" data-test="toggle-editing">
<span class="mdi mdi-pencil-outline"></span>
<span>Toggle Editing: <span id="isEditable" class="text-italic" textcontent.bind="isEditable">false</span></span>
</button>
</div>
</section>

<div class="grid-container grid32-container">
<div class="grid32"></div>
</div>
28 changes: 28 additions & 0 deletions examples/vite-demo-vanilla-bundle/src/examples/example32.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
.grid32 {
--slick-border-color: #d4d4d4;
// --slick-cell-border-left: 1px solid var(--slick-border-color);
--slick-header-menu-display: none;
--slick-header-column-height: 20px;
--slick-grid-border-color: #d4d4d4;
--slick-row-selected-color: #d4ebfd;

--slick-row-mouse-hover-box-shadow: 0;
--slick-cell-odd-background-color: #fff;
// --slick-cell-border-top: 0;
--slick-cell-border-right: 1px solid var(--slick-border-color);
--slick-cell-border-bottom: 1px solid var(--slick-border-color);
// --slick-cell-border-left: 1px;
--slick-cell-box-shadow: none;
--slick-row-mouse-hover-color: #fff;
--slick-cell-display: flex;

.slick-cell.rowspan {
background: white;
z-index: 9;
}
.slick-cell {
display: flex;
align-items: center;
/* justify-content: center; */
}
}
Loading

0 comments on commit 5d0f58e

Please sign in to comment.