Skip to content

Commit

Permalink
feat(footer): add Custom Footer
Browse files Browse the repository at this point in the history
- also add minimal input bindings
  • Loading branch information
ghiscoding committed Apr 19, 2020
1 parent 39f6bcb commit 0d3e1da
Show file tree
Hide file tree
Showing 21 changed files with 381 additions and 53 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,10 @@ npm run test:watch
- [x] Shared
- [x] Sort
- [ ] Others
- [ ] Custom Footer
- [x] Custom Footer
- [ ] Dynamically Add Columns
- [ ] Grid Presets
- [ ] Pagination
- [ ] Local Pagination
- [ ] Tree Data
- [x] add Grid Demo
- [x] add Collapse/Expand All into Context Menu
Expand All @@ -147,6 +147,6 @@ npm run test:watch
- [ ] Remove any Deprecated code
- [ ] Create a Migration Guide
- [ ] Add Typings for Grid & DataView objects
- [ ] Add some bindings in the demo (e.g. pinned rows input)
- [x] Add simple input bindings in the demo (e.g. pinned rows input)
- [ ] Can we change how SlickGrid Events are called and use same signature as SlickGrid instead of CustomEvent EventData signature?
- [ ] Cannot copy text from cell since it's not selectable
30 changes: 15 additions & 15 deletions packages/common/src/global-grid-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,21 @@ export const GlobalGridOptions: GridOption = {
iconExportTextDelimitedCommand: 'fa fa-download mdi mdi-download',
width: 200,
},
// customFooterOptions: {
// dateFormat: 'yyyy-MM-dd hh:mm aaaaa\'m\'',
// hideTotalItemCount: false,
// hideLastUpdateTimestamp: true,
// footerHeight: 20,
// leftContainerClass: 'col-xs-12 col-sm-5',
// rightContainerClass: 'col-xs-6 col-sm-7',
// metricSeparator: '|',
// metricTexts: {
// items: 'items',
// of: 'of',
// itemsKey: 'ITEMS',
// ofKey: 'OF',
// }
// },
customFooterOptions: {
dateFormat: 'YYYY-DD-MM h:mm:ss a',
hideTotalItemCount: false,
hideLastUpdateTimestamp: true,
footerHeight: 20,
leftContainerClass: 'col-xs-12 col-sm-5',
rightContainerClass: 'col-xs-6 col-sm-7',
metricSeparator: '|',
metricTexts: {
items: 'items',
of: 'of',
itemsKey: 'ITEMS',
ofKey: 'OF',
}
},
dataView: {
syncGridSelection: true, // when enabled, this will preserve the row selection even after filtering/sorting/grouping
syncGridSelectionWithBackendService: false, // but disable it when using backend services
Expand Down
1 change: 1 addition & 0 deletions packages/common/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'multiple-select-adapted/src/multiple-select.js';

// Public classes.
export * from './constants';
export * from './global-grid-options';
export * from './enums/index';
export * from './interfaces/index';
Expand Down
54 changes: 54 additions & 0 deletions packages/common/src/interfaces/customFooterOption.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
export interface CustomFooterOption {
/** Optionally pass some text to be displayed on the left side (in the "left-footer" css class) */
leftFooterText?: string;

/** CSS class used for the left container */
leftContainerClass?: string;

/** Date format used when showing the "Last Update" timestamp in the metrics section. */
dateFormat?: string;

/** Defaults to 20, height of the Custom Footer in pixels (this is required and is used by the auto-resizer) */
footerHeight?: number;

/** Defaults to false, do we want to hide the last update timestamp (endTime)? */
hideLastUpdateTimestamp?: boolean;

/**
* Defaults to false, do we want to hide the metrics (right section) when the footer is displayed?
* That could be used when we want to display only the left section with custom text
*/
hideMetrics?: boolean;

/** Defaults to false, do we want to hide the total item count of the entire dataset (the count exclude any filtered data) */
hideTotalItemCount?: boolean;

/** Defaults to "|", separator between the timestamp and the total count */
metricSeparator?: string;

/** Text shown in the custom footer on the far right for the metrics */
metricTexts?: {
/** Defaults to empty string, optionally pass a text (Last Update) to display before the metrics endTime timestamp. */
lastUpdate?: string;

/** Defaults to "items", word to display at the end of the metrics to represent the items (e.g. you could change it for "users" or anything else). */
items?: string;

/** Defaults to "of", text word separator to display between the filtered items count and the total unfiltered items count (e.g.: "10 of 100 items"). */
of?: string;

// -- Translation Keys --//

/** Defaults to "ITEMS", translation key used for the word displayed at the end of the metrics to represent the items (e.g. you could change it for "users" or anything else). */
itemsKey?: string;

/** Defaults to empty string, optionally pass a translation key (internally we use "LAST_UPDATE") to display before the metrics endTime timestamp. */
lastUpdateKey?: string;

/** Defaults to "OF", translation key used for the to display between the filtered items count and the total unfiltered items count. */
ofKey?: string;
};

/** CSS class used for the right container */
rightContainerClass?: string;
}
2 changes: 1 addition & 1 deletion packages/common/src/interfaces/editor.interface.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EditorArguments } from './editorArguments.interface';
import { EditorValidatorOutput } from './editorValidatorOutput.interface';

/***
/**
* SlickGrid Editor interface, more info can be found on the SlickGrid repo
* https://github.com/6pac/SlickGrid/wiki/Writing-custom-cell-editors
*/
Expand Down
7 changes: 4 additions & 3 deletions packages/common/src/interfaces/gridOption.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import {
Column,
ColumnPicker,
ContextMenu,
CustomFooterOption,
DraggableGrouping,
EditCommand,
ExcelCopyBufferOption,
ExcelExportOption,
ExportOption,
FormatterOption,
GridMenu,
// GridState,
GridState,
HeaderButton,
HeaderMenu,
Locale,
Expand Down Expand Up @@ -102,7 +103,7 @@ export interface GridOption {
createPreHeaderPanel?: boolean;

/** Custom Footer Options */
// customFooterOptions?: CustomFooterOption;
customFooterOptions?: CustomFooterOption;

/** Data item column value extractor (getter) that can be used by the Excel like copy buffer plugin */
dataItemColumnValueExtractor?: (item: any, columnDef: Column) => any;
Expand Down Expand Up @@ -381,7 +382,7 @@ export interface GridOption {
preserveCopiedSelectionOnPaste?: boolean;

/** Query presets before grid load (filters, sorters, pagination) */
// presets?: GridState;
presets?: GridState;

/** Preselect certain rows by their row index ("enableCheckboxSelector" must be enabled) */
preselectedRows?: number[];
Expand Down
9 changes: 5 additions & 4 deletions packages/common/src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export * from './currentFilter.interface';
export * from './currentPagination.interface';
export * from './currentRowSelection.interface';
export * from './currentSorter.interface';
export * from './customFooterOption.interface';
export * from './draggableGrouping.interface';
export * from './editCommand.interface';
export * from './editor.interface';
Expand Down Expand Up @@ -51,6 +52,7 @@ export * from './filterConditionOption.interface';
export * from './flatpickrOption.interface';
export * from './formatter.interface';
export * from './formatterOption.interface';
export * from './formatterResultObject.interface';
export * from './gridMenu.interface';
export * from './gridMenuItem.interface';
export * from './gridOption.interface';
Expand All @@ -60,19 +62,19 @@ export * from './gridServiceUpdateOption.interface';
export * from './gridState.interface';
export * from './gridStateChange.interface';
export * from './grouping.interface';
export * from './formatterResultObject.interface';
export * from './groupingComparerItem.interface';
export * from './groupingFormatterItem.interface';
export * from './groupTotalsFormatter.interface';
export * from './headerButton.interface';
export * from './headerButtonItem.interface';
export * from './headerButtonOnCommandArgs.interface';
export * from './headerMenu.interface';
export * from './htmlElementPosition.interface';
export * from './jQueryUiSliderOption.interface';
export * from './jQueryUiSliderResponse.interface';
export * from './groupTotalsFormatter.interface';
export * from './locale.interface';
export * from './menuCallbackArgs.interface';
export * from './menuCommandItem.interface';
export * from './menuCommandItemCallbackArgs.interface';
export * from './menuItem.interface';
export * from './menuOptionItem.interface';
Expand All @@ -81,15 +83,14 @@ export * from './metrics.interface';
export * from './multiColumnSort.interface';
export * from './multipleSelectOption.interface';
export * from './onEventArgs.interface';
export * from './menuCommandItem.interface';
export * from './pagination.interface';
export * from './paginationChangedArgs.interface';
export * from './rowMoveManager.interface';
export * from './selectedRange.interface';
export * from './selectOption.interface';
export * from './servicePagination.interface';
export * from './slickEventData.interface';
export * from './slickEvent.interface';
export * from './slickEventData.interface';
export * from './slickEventHandler.interface';
export * from './sortChangedArgs.interface';
export * from './sorter.interface';
Expand Down
4 changes: 4 additions & 0 deletions packages/common/src/styles/_variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -570,14 +570,18 @@ $footer-font-weight: normal !default;
$footer-height: 30px !default; // if you modify this height, you also have to modify the footerHeight in the customFooterOptions
$footer-padding: 5px !default;
$footer-text-color: #808080 !default;
$footer-left-float: left !default;
$footer-left-font-style: italic !default;
$footer-left-font-weight: normal !default;
$footer-left-padding: 0px !default;
$footer-left-text-align: left !default;
$footer-left-text-color: $footer-text-color !default;
$footer-left-width: 50% !default;
$footer-right-font-style: italic !default;
$footer-right-font-weight: normal !default;
$footer-right-padding: 0px !default;
$footer-right-separator-margin: 2px !default;
$footer-right-float: right !default;
$footer-right-text-align: right !default;
$footer-right-text-color: $footer-text-color !default;
$footer-right-width: 50% !default;
4 changes: 4 additions & 0 deletions packages/common/src/styles/slick-footer.scss
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
font-weight: $footer-left-font-weight;
text-align: $footer-left-text-align;
padding: $footer-left-padding;
width: $footer-left-width;
float: $footer-left-float;
}

.right-footer.metrics {
Expand All @@ -23,6 +25,8 @@
font-weight: $footer-right-font-weight;
text-align: $footer-right-text-align;
padding: $footer-right-padding;
width: $footer-right-width;
float: $footer-right-float;
.separator {
margin: $footer-right-separator-margin;
}
Expand Down
1 change: 0 additions & 1 deletion packages/common/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
"sourceMap": true,
"allowSyntheticDefaultImports": false,
"noImplicitReturns": true,
"moduleResolution": "node",
"lib": [
"es2020",
"dom"
Expand Down
3 changes: 3 additions & 0 deletions packages/vanilla-bundle/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { VanillaGridBundle } from './vanilla-grid-bundle';
import { Aggregators, Editors, Enums, Filters, Formatters, GroupTotalFormatters, SortComparers, Utilities } from '@slickgrid-universal/common';
import { BindingService } from './services/index';

const Slicker = {
GridBundle: VanillaGridBundle,
Aggregators,
BindingService,
Editors,
Enums,
Filters,
Expand All @@ -18,4 +20,5 @@ if (typeof window !== 'undefined') {
(window as any).Slicker = Slicker;
}

export { BindingService };
export { Slicker };
75 changes: 75 additions & 0 deletions packages/vanilla-bundle/src/services/binding.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
export class BindingService {
_value: any = null;
_binding: any;
_property: string;
elementBindings: any[];

constructor(binding: { variable: any; property?: string; }) {
this._binding = binding;
this._property = binding.property;
this.elementBindings = [];
if (binding.variable.hasOwnProperty(binding.property)) {
this._value = binding.variable[binding.property];
} else {
this._value = binding.variable;
}
}

get property() {
return this._property;
}

valueGetter() {
return this._value;
}

valueSetter(val: any) {
this._value = val;
for (let i = 0; i < this.elementBindings.length; i++) {
const binding = this.elementBindings[i];
binding.element[binding.attribute] = val;
}
}

/**
* Add binding to an element by an object attribute and optionally on an event, we can do it in couple ways
* 1- if there's no event provided, it will simply replace the DOM elemnt (by an attribute), for example an innerHTML
* 2- when an event is provided, we will replace the DOM elemnt (by an attribute) every time an event is triggered
* 2.1- we could also provide an extra callback method to execute when the event is triggered
*/
bind(element: Element | null, attribute: string, eventName?: string, callback?: (val: any) => any) {
const binding = {
element,
attribute,
event: null,
};

if (element) {
if (eventName) {
element.addEventListener(eventName, () => {
const elmValue = element[attribute];
this.valueSetter(elmValue);
if (this._binding.variable.hasOwnProperty(this._binding.property)) {
this._binding.variable[this._binding.property] = this.valueGetter();
} else {
this._binding.variable = this.valueGetter();
}
if (typeof callback === 'function') {
return callback(this.valueGetter());
}
});
binding.event = eventName;
}
this.elementBindings.push(binding);
element[attribute] = this._value ?? null;
}
return this;
}

/** Unbind (remove) an event from an element */
unbind(element: Element | null, eventName: string, callback: () => void) {
if (element) {
element.removeEventListener(eventName, callback);
}
}
}
Loading

0 comments on commit 0d3e1da

Please sign in to comment.