Skip to content

Commit

Permalink
feat: add column reorderable option to optionally lock a column (#983)
Browse files Browse the repository at this point in the history
* feat: add column `reorderable` option to optionally lock a column
- we can take advantage of SortableJS `filter` option which can be used to filter column header with a certain CSS class. When using `reorderable: false` on a column, SlickGrid will add configurable CSS class to the column header which will be filtered out by SortableJS hence locking the column from being reorderable
- new options available:
  - Column: `reorderable` (defaults to true)
  - Grid Option: `unorderableColumnCssClass` (defaults to "unorderable")
  - CSS/SASS variable for Alpine Theme: `$alpine-header-unorderable-bg-color` (replace `$` with `--` for CSS var)
  • Loading branch information
ghiscoding authored Jan 20, 2024
1 parent 4a49239 commit fbcac63
Show file tree
Hide file tree
Showing 12 changed files with 62 additions and 24 deletions.
3 changes: 2 additions & 1 deletion examples/example-row-detail-selection-and-move.html
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ <h3>Selected Titles:</h3>
var fakeNames = ['John Doe', 'Jane Doe', 'Chuck Norris', 'Bumblebee', 'Jackie Chan', 'Elvis Presley', 'Bob Marley', 'Mohammed Ali', 'Bruce Lee', 'Rocky Balboa'];

var columns = [
{ id: "sel", name: "#", field: "num", behavior: "select", cssClass: "cell-selection", width: 40, resizable: false, selectable: false },
{ id: "sel", name: "#", field: "num", behavior: "select", cssClass: "cell-selection", width: 40, reorderable: false, resizable: false, selectable: false },
{ id: "title", name: "Title", field: "title", width: 110, cssClass: "cell-title", sortable: true },
{ id: "duration", name: "Duration", field: "duration", width: 75, sortable: true },
{ id: "%", name: "% Complete", field: "percentComplete", width: 95, resizable: false, formatter: Slick.Formatters.PercentCompleteBar, sortable: true },
Expand Down Expand Up @@ -258,6 +258,7 @@ <h3>Selected Titles:</h3>
rowMovePlugin = new Slick.RowMoveManager({
cssClass: 'sgi sgi-drag',
cancelEditOnDrag: true,
// reorderable: true,
singleRowMove: true,
disableRowSelection: true,
hideRowMoveShadow: false, // defaults to true
Expand Down
3 changes: 3 additions & 0 deletions src/models/checkboxSelectorOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export interface CheckboxSelectorOption {
*/
name?: string;

/** Defaults to false, makes the column reorderable to another position in the grid. */
reorderable?: boolean;

/** Defaults to "Select/Deselect All", provide a tooltip that will be shown over the "Select All" checkbox */
toolTip?: string;

Expand Down
6 changes: 6 additions & 0 deletions src/models/column.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ export interface Column<TData = any> {
/** column previous width */
previousWidth?: number;

/**
* Defaults to true, makes the column reorderable to another position in the grid.
* NOTE: Works best when used as first or last columns of the grid (e.g.: row selection checkbox as first column).
*/
reorderable?: boolean;

/** Should we re-render when onResize is being triggered? */
rerenderOnResize?: boolean;

Expand Down
3 changes: 3 additions & 0 deletions src/models/gridOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ export interface GridOption<C extends BaseColumn = BaseColumn> {
*/
enableColumnReorder?: boolean | ColumnReorderFunction<C>;

/** Defaults to "unorderable", a CSS class name that will be added to the column classes when the column cannot be reordered. */
unorderableColumnCssClass?: string;

/**
* Defaults to true, do we want to allow passing HTML string to cell/row rendering by using `innerHTML`.
* When this is enabled and input is a string, it will use `innerHTML = 'some html'` to render the input, however when disable it will use `textContent = 'some html'`.
Expand Down
3 changes: 3 additions & 0 deletions src/models/rowDetailViewOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ export interface RowDetailViewOption {
*/
parent?: any;

/** Defaults to false, makes the column reorderable to another position in the grid. */
reorderable?: boolean;

/** Defaults to false, when True will open the row detail on a row click (from any column) */
useRowClick?: boolean;

Expand Down
3 changes: 3 additions & 0 deletions src/models/rowMoveManagerOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export interface RowMoveManagerOption {
/** Defaults to True, do we want to hide the row move shadow of what we're dragging? */
hideRowMoveShadow?: boolean;

/** Defaults to false, makes the column reorderable to another position in the grid. */
reorderable?: boolean;

/** Defaults to 0, optional left margin of the row move shadown element when enabled */
rowMoveShadowMarginLeft?: number | string;

Expand Down
2 changes: 2 additions & 0 deletions src/plugins/slick.checkboxselectcolumn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export class SlickCheckboxSelectColumn<T = any> implements SlickPlugin {
name: '',
toolTip: 'Select/Deselect All',
width: 30,
reorderable: false,
applySelectOnAllPages: false, // defaults to false, when that is enabled the "Select All" will be applied to all pages (when using Pagination)
hideInColumnTitleRow: false,
hideInFilterHeaderRow: true
Expand Down Expand Up @@ -365,6 +366,7 @@ export class SlickCheckboxSelectColumn<T = any> implements SlickPlugin {
getColumnDefinition() {
return {
id: this._options.columnId,
reorderable: this._options.reorderable,
name: (this._options.hideSelectAllCheckbox || this._options.hideInColumnTitleRow)
? this._options.name || ''
: this.createCheckboxElement(`header-selector${this._selectAll_UID}`),
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/slick.rowdetailview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ export class SlickRowDetailView {
keyPrefix: '_',
loadOnce: false,
collapseAllOnSort: true,
reorderable: false,
saveDetailViewOnScroll: true,
singleRowExpand: false,
useSimpleViewportCalc: false,
Expand Down Expand Up @@ -615,6 +616,7 @@ export class SlickRowDetailView {
return {
id: this._options.columnId,
name: '',
reorderable: this._options.reorderable,
toolTip: this._options.toolTip,
field: 'sel',
width: this._options.width,
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/slick.rowmovemanager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export class SlickRowMoveManager {
cancelEditOnDrag: false,
disableRowSelection: false,
hideRowMoveShadow: true,
reorderable: false,
rowMoveShadowMarginTop: 0,
rowMoveShadowMarginLeft: 0,
rowMoveShadowOpacity: 0.95,
Expand Down Expand Up @@ -238,6 +239,7 @@ export class SlickRowMoveManager {
name: '',
field: 'move',
behavior: 'selectAndMove',
reorderable: this._options.reorderable,
excludeFromColumnPicker: true,
excludeFromGridMenu: true,
excludeFromHeaderMenu: true,
Expand Down
22 changes: 16 additions & 6 deletions src/slick.grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
suppressActiveCellChangeOnEdit: false,
enableCellNavigation: true,
enableColumnReorder: true,
unorderableColumnCssClass: 'unorderable',
asyncEditorLoading: false,
asyncEditorLoadDelay: 100,
forceFitColumns: false,
Expand Down Expand Up @@ -290,16 +291,17 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e

protected _columnDefaults = {
name: '',
resizable: true,
sortable: false,
minWidth: 30,
maxWidth: undefined,
rerenderOnResize: false,
headerCssClass: null,
defaultSortAsc: true,
focusable: true,
hidden: false,
minWidth: 30,
maxWidth: undefined,
rerenderOnResize: false,
reorderable: true,
resizable: true,
sortable: false,
selectable: true,
hidden: false
} as Partial<C>;

protected _columnAutosizeDefaults: AutoSize = {
Expand Down Expand Up @@ -1621,6 +1623,9 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
if (m.toolTip) {
header.title = m.toolTip;
}
if (!m.reorderable) {
header.classList.add(this._options.unorderableColumnCssClass!);
}
const colNameElm = Utils.createDomElement('span', { className: 'slick-column-name' }, header);
this.applyHtmlCode(colNameElm, m.name as string);

Expand Down Expand Up @@ -1825,6 +1830,11 @@ export class SlickGrid<TData = any, C extends Column<TData> = Column<TData>, O e
dragoverBubble: false,
revertClone: true,
scroll: !this.hasFrozenColumns(), // enable auto-scroll
// lock unorderable columns by using a combo of filter + onMove
filter: `.${this._options.unorderableColumnCssClass}`,
onMove: (event: MouseEvent & { related: HTMLElement; }) => {
return !event.related.classList.contains(this._options.unorderableColumnCssClass as string);
},
onStart: (e: { item: any; originalEvent: MouseEvent; }) => {
canDragScroll = !this.hasFrozenColumns() ||
Utils.offset(e.item)!.left > Utils.offset(this._viewportScrollContainerX)!.left;
Expand Down
1 change: 1 addition & 0 deletions src/styles/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ $alpine-header-display: inline-flex !default;
$alpine-header-border-color: $alpine-border-color !default;
$alpine-header-border-width: 0 !default;
$alpine-header-bg-color: #f8f8f8 !default;
$alpine-header-unorderable-bg-color: darken($alpine-header-bg-color, 3%) !default;
$alpine-header-color: #181d1f !default;
$alpine-header-font-weight: bold !default;
$alpine-header-text-align: left !default;
Expand Down
36 changes: 19 additions & 17 deletions src/styles/slick-alpine-theme.scss
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,21 @@
}

.slick-header-column {
height: var(--alpine-header-column-height, $alpine-header-column-height); // header with 2 rows, just double the height
line-height: var(--alpine-header-column-line-height, $alpine-header-column-line-height);
position: relative;
overflow: hidden;
margin: 0;
padding: 4px;
border-style: solid;
border-width: var(--alpine-header-border-width, $alpine-header-border-width);
border-color: var(--alpine-header-border-color, $alpine-header-border-color);
vertical-align: var(--alpine-header-vertical-align, $alpine-header-vertical-align);
display: var(--alpine-header-display, $alpine-header-display);
align-items: var(--alpine-header-align-items, $alpine-header-align-items);
justify-content: var(--alpine-header-justify-content, $alpine-header-justify-content);
white-space: pre-wrap;

.slick-header-menubutton {
cursor: pointer;
display: none;
Expand Down Expand Up @@ -301,23 +316,6 @@
}
}

&.slick-header-column {
height: var(--alpine-header-column-height, $alpine-header-column-height); // header with 2 rows, just double the height
line-height: var(--alpine-header-column-line-height, $alpine-header-column-line-height);
position: relative;
overflow: hidden;
margin: 0;
padding: 4px;
border-style: solid;
border-width: var(--alpine-header-border-width, $alpine-header-border-width);
border-color: var(--alpine-header-border-color, $alpine-header-border-color);
vertical-align: var(--alpine-header-vertical-align, $alpine-header-vertical-align);
display: var(--alpine-header-display, $alpine-header-display);
align-items: var(--alpine-header-align-items, $alpine-header-align-items);
justify-content: var(--alpine-header-justify-content, $alpine-header-justify-content);
white-space: pre-wrap;
}

.slick-sort-indicator,
.slick-sort-indicator-numbered {
color: var(--alpine-sort-indicator-color, $alpine-sort-indicator-color);
Expand Down Expand Up @@ -346,6 +344,10 @@
.slick-sort-indicator-numbered {
font-size: var(--alpine-sort-numbered-font-size, $alpine-sort-numbered-font-size);
}

&.unorderable {
background-color: var(--alpine-header-unorderable-bg-color, $alpine-header-unorderable-bg-color);
}
}

.slick-header-columns {
Expand Down

0 comments on commit fbcac63

Please sign in to comment.