Skip to content

Commit

Permalink
feat(core): add rowHighlightCssClass & highlightRow() to SlickGrid (
Browse files Browse the repository at this point in the history
  • Loading branch information
ghiscoding authored Dec 20, 2023
1 parent 861a268 commit 33e9f2e
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 7 deletions.
4 changes: 4 additions & 0 deletions examples/example-frozen-columns.html
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ <h2>
<button id="setFrozenColumn">Set</button>
<br/><br/>
<button id="btnSelectRows">Select first 10 rows</button>
<button onclick="highlightSecondRow()">Highlight 2nd Row (750ms)</button>

<br/>

Expand Down Expand Up @@ -188,6 +189,9 @@ <h2>Demonstrates:</h2>
dataView.addItem(item);
}

function highlightSecondRow() {
grid.highlightRow(1, 750);
}

function toggleFilterRow() {
grid.setTopPanelVisibility(!grid.getOptions().showTopPanel);
Expand Down
19 changes: 19 additions & 0 deletions examples/example14-highlighting.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
<link rel="stylesheet" href="../dist/styles/css/example-demo.css" type="text/css"/>
<link rel="stylesheet" href="../dist/styles/css/slick-alpine-theme.css" type="text/css"/>
<style>
@keyframes fade {
0%, 100% { background: none }
50% { background: #e8f8d0 }
}

.load-medium {
color: orange;
font-weight: bold;
Expand All @@ -26,6 +31,11 @@
background: moccasin;
box-shadow: inset 0 0 0 1px darksalmon;
}

.slick-row.highlighting-animation {
background: #e8f8d0 !important;
animation: fade 1.5s linear;
}
</style>
</head>
<body>
Expand All @@ -52,6 +62,9 @@ <h2>Controls</h2>
<button onclick="simulateRealTimeUpdates()">Start simulation</button>
<button onclick="stopSimulation()">Stop simulation</button>
<button onclick="findCurrentServer()">Find current server</button>
<section style="margin-top: 5px">
<button onclick="highlightSecondRow()">Highlight 2nd Row (500ms)</button>
</section>
<h2>View Source:</h2>
<ul>
<li><A href="https://github.com/6pac/SlickGrid/blob/master/examples/example14-highlighting.html" target="_sourcewindow"> View the source for this example on Github</a></li>
Expand Down Expand Up @@ -161,6 +174,12 @@ <h2>View Source:</h2>
grid.scrollRowIntoView(currentServer);
grid.flashCell(currentServer, grid.getColumnIndex("server"), 100);
}

function highlightSecondRow() {
// default is: { rowHighlightCssClass: 'highlight-animate' }
grid.setOptions({ rowHighlightCssClass: 'highlighting-animation' });
grid.highlightRow(1, 500);
}
</script>
</body>
</html>
7 changes: 7 additions & 0 deletions src/models/gridOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,13 @@ export interface GridOption<C extends BaseColumn = BaseColumn> {
/** Grid row height in pixels (only type the number). Row of cell values. */
rowHeight?: number;

/**
* Defaults to "highlight-animate", a CSS class name used to simulate row highlight with an optional duration (e.g. after insert).
* Note: make sure that the duration is always lower than the duration defined in the CSS/SASS variable `$alpine-row-highlight-fade-animation`.
* Also note that the highlight is temporary and will also disappear as soon as the user starts scrolling or a `render()` is being called
*/
rowHighlightCssClass?: string;

/** Optional sanitizer function to use for sanitizing data to avoid XSS attacks */
sanitizer?: (dirtyHtml: string) => string;

Expand Down
48 changes: 41 additions & 7 deletions src/slick.grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
formatterFactory: null,
editorFactory: null,
cellFlashingCssClass: 'flashing',
rowHighlightCssClass: 'highlight-animate',
selectedCellCssClass: 'selected',
multiSelect: true,
enableTextSelectionOnCells: false,
Expand Down Expand Up @@ -319,6 +320,11 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
colDataTypeOf: undefined
};

protected _columnResizeTimer?: any;
protected _executionBlockTimer?: any;
protected _flashCellTimer?: any;
protected _highlightRowTimer?: any;

// scroller
protected th!: number; // virtual height
protected h!: number; // real scrollable height
Expand Down Expand Up @@ -2267,7 +2273,8 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
this.updateCanvasWidth(true);
this.render();
this.trigger(this.onColumnsResized, { triggeredByColumn });
setTimeout(() => { this.columnResizeDragging = false; }, 300);
clearTimeout(this._columnResizeTimer);
this._columnResizeTimer = setTimeout(() => { this.columnResizeDragging = false; }, 300);
}
})
);
Expand Down Expand Up @@ -2514,6 +2521,15 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
this.stylesheet = null;
}

/** Clear all highlight timers that might have been left opened */
protected clearAllTimers() {
clearTimeout(this._columnResizeTimer);
clearTimeout(this._executionBlockTimer);
clearTimeout(this._flashCellTimer);
clearTimeout(this._highlightRowTimer);
clearTimeout(this.h_editorLoader);
}

/**
* Destroy (dispose) of SlickGrid
* @param {boolean} shouldDestroyAllElements - do we want to destroy (nullify) all DOM elements as well? This help in avoiding mem leaks
Expand Down Expand Up @@ -2598,6 +2614,7 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e

Utils.emptyElement(this._container);
this._container.classList.remove(this.uid);
this.clearAllTimers();

if (shouldDestroyAllElements) {
this.destroyAllElements();
Expand Down Expand Up @@ -5065,7 +5082,8 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e

const blockAndExecute = () => {
blocked = true;
setTimeout(unblock, minPeriod_ms);
clearTimeout(this._executionBlockTimer);
this._executionBlockTimer = setTimeout(unblock, minPeriod_ms);
action.call(this);
};

Expand Down Expand Up @@ -5244,17 +5262,16 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
* Flashes the cell twice by toggling the CSS class 4 times.
* @param {Number} row A row index.
* @param {Number} cell A column index.
* @param {Number} [speed] (optional) - The milliseconds delay between the toggling calls. Defaults to 100 ms.
* @param {Number} [speed] (optional) - The milliseconds delay between the toggling calls. Defaults to 250 ms.
*/
flashCell(row: number, cell: number, speed?: number) {
speed = speed || 250;

flashCell(row: number, cell: number, speed = 250) {
const toggleCellClass = (cellNode: HTMLElement, times: number) => {
if (times < 1) {
return;
}

setTimeout(() => {
clearTimeout(this._flashCellTimer);
this._flashCellTimer = setTimeout(() => {
if (times % 2 === 0) {
cellNode.classList.add(this._options.cellFlashingCssClass || '');
} else {
Expand All @@ -5272,6 +5289,23 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
}
}

/**
* Highlight a row for a certain duration (ms) of time.
* @param {Number} row - grid row number
* @param {Number} [duration] - duration (ms), defaults to 500ms
*/
highlightRow(row: number, duration = 500) {
const rowCache = this.rowsCache[row];

if (Array.isArray(rowCache?.rowNode) && this._options.rowHighlightCssClass) {
rowCache.rowNode.forEach(node => node.classList.add(this._options.rowHighlightCssClass || ''));
clearTimeout(this._highlightRowTimer);
this._highlightRowTimer = setTimeout(() => {
rowCache.rowNode?.forEach(node => node.classList.remove(this._options.rowHighlightCssClass || ''));
}, duration);
}
}

//////////////////////////////////////////////////////////////////////////////////////////////
// Interactivity

Expand Down
2 changes: 2 additions & 0 deletions src/styles/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ $alpine-icon-size: 18px !default;

$alpine-odd-row-color: #fbfbfb !default;
$alpine-row-mouse-hover-color: #e8f4fe !default;
$alpine-row-highlight-fade-animation: 1s linear !default;
$alpine-row-highlight-background-color: darken($alpine-row-mouse-hover-color, 3%) !default;

$alpine-cell-border-color: #dae1e7 !default;
$alpine-cell-border-radius: 0 !default;
Expand Down
9 changes: 9 additions & 0 deletions src/styles/slick-alpine-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@
@import './mixins';
@import './variables';

@keyframes fade {
0%, 100% { background: none }
50% { background: var(--alpine-row-highlight-fade-animation, $alpine-row-highlight-fade-animation) }
}

// Grid Styles
#myGrid, .slick-container {
box-sizing: border-box;
Expand Down Expand Up @@ -75,6 +80,10 @@
&:hover {
background-color: var(--alpine-row-mouse-hover-color, $alpine-row-mouse-hover-color);
}
&.highlight-animate {
background: var(--alpine-row-highlight-background-color, $alpine-row-highlight-background-color) !important;
animation: fade var(--alpine-row-highlight-fade-animation, $alpine-row-highlight-fade-animation);
}
}

.slick-groupby-remove {
Expand Down

0 comments on commit 33e9f2e

Please sign in to comment.