@wavemaker/app-ng-runtime 11.15.4-rc.250 → 11.15.5-rc.253
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/base/bundles/index.umd.js +4 -13
- package/components/base/esm2022/utils/widget-utils.mjs +5 -4
- package/components/base/esm2022/widgets/common/base/base.component.mjs +1 -11
- package/components/base/fesm2022/index.mjs +4 -13
- package/components/base/fesm2022/index.mjs.map +1 -1
- package/components/containers/tabs/bundles/index.umd.js +1 -1
- package/components/containers/tabs/esm2022/tabs.animator.mjs +2 -2
- package/components/containers/tabs/fesm2022/index.mjs +1 -1
- package/components/containers/tabs/fesm2022/index.mjs.map +1 -1
- package/components/data/form/bundles/index.umd.js +6 -3
- package/components/data/form/esm2022/form.component.mjs +5 -2
- package/components/data/form/esm2022/live-form/live-form.directive.mjs +3 -3
- package/components/data/form/fesm2022/index.mjs +6 -3
- package/components/data/form/fesm2022/index.mjs.map +1 -1
- package/components/data/form/live-form/live-form.directive.d.ts +1 -1
- package/components/data/list/bundles/index.umd.js +6 -0
- package/components/data/list/esm2022/list.component.mjs +7 -1
- package/components/data/list/fesm2022/index.mjs +6 -0
- package/components/data/list/fesm2022/index.mjs.map +1 -1
- package/components/data/pagination/bundles/index.umd.js +45 -7
- package/components/data/pagination/esm2022/pagination.component.mjs +46 -8
- package/components/data/pagination/fesm2022/index.mjs +45 -7
- package/components/data/pagination/fesm2022/index.mjs.map +1 -1
- package/components/data/pagination/pagination.component.d.ts +1 -0
- package/components/data/table/bundles/index.umd.js +228 -20
- package/components/data/table/esm2022/table-column/table-column.directive.mjs +6 -1
- package/components/data/table/esm2022/table-cud.directive.mjs +14 -3
- package/components/data/table/esm2022/table-filter.directive.mjs +6 -1
- package/components/data/table/esm2022/table.component.mjs +206 -19
- package/components/data/table/fesm2022/index.mjs +229 -21
- package/components/data/table/fesm2022/index.mjs.map +1 -1
- package/components/data/table/table.component.d.ts +16 -1
- package/core/bundles/index.umd.js +7 -1
- package/core/esm2022/utils/dom.mjs +4 -2
- package/core/esm2022/utils/utils.mjs +5 -1
- package/core/fesm2022/index.mjs +7 -1
- package/core/fesm2022/index.mjs.map +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/runtime/base/bundles/index.umd.js +45 -12
- package/runtime/base/components/app-component/app.component.d.ts +1 -1
- package/runtime/base/esm2022/components/app-component/app.component.mjs +23 -12
- package/runtime/base/esm2022/guards/role.guard.mjs +2 -2
- package/runtime/base/esm2022/services/app.manager.service.mjs +23 -1
- package/runtime/base/fesm2022/index.mjs +45 -12
- package/runtime/base/fesm2022/index.mjs.map +1 -1
- package/runtime/base/services/app.manager.service.d.ts +5 -0
- package/scripts/datatable/datatable.js +282 -44
- package/transpiler/bundles/index.umd.js +3 -0
- package/transpiler/esm2022/build.mjs +4 -1
- package/transpiler/fesm2022/index.mjs +3 -0
- package/transpiler/fesm2022/index.mjs.map +1 -1
|
@@ -91,6 +91,11 @@ export declare class AppManagerService implements OnDestroy {
|
|
|
91
91
|
getAppLocale(): any;
|
|
92
92
|
getSelectedLocale(): string;
|
|
93
93
|
notifyApp(template: any, type: any, title?: any): void;
|
|
94
|
+
/**
|
|
95
|
+
* Notifies access denied for a page (e.g. RoleGuard) and invokes App.onServiceError
|
|
96
|
+
* with a 403-shaped response.
|
|
97
|
+
*/
|
|
98
|
+
notifyAccessDenied(pageName?: string, message?: string): void;
|
|
94
99
|
/**
|
|
95
100
|
* Triggers the onBeforeService method defined in app.js of the app
|
|
96
101
|
* @param requestParams
|
|
@@ -736,6 +736,10 @@ $.widget('wm.datatable', {
|
|
|
736
736
|
colExpression = colDef.customExpression,
|
|
737
737
|
styles = "text-align: " + colDef.textAlignment + ";position: relative;"
|
|
738
738
|
|
|
739
|
+
if (!_.isUndefined(colDef.show) && !colDef.show) {
|
|
740
|
+
styles += "display: none;";
|
|
741
|
+
}
|
|
742
|
+
|
|
739
743
|
$htm = $('<td class="' + classes + '" data-col-id="' + colId + '" role="cell" tabindex="0"></td>');
|
|
740
744
|
this._setStyles($htm, styles);
|
|
741
745
|
|
|
@@ -1131,6 +1135,144 @@ $.widget('wm.datatable', {
|
|
|
1131
1135
|
this._setGridEditMode(false);
|
|
1132
1136
|
this.toggleNewRowActions(false);
|
|
1133
1137
|
},
|
|
1138
|
+
/*
|
|
1139
|
+
* Updates internal state (options.data, preparedData, custom expressions,
|
|
1140
|
+
* conditional class watchers, and summary row) without a full DOM re-render.
|
|
1141
|
+
* Used during quickedit inline save for model variables to avoid focus loss.
|
|
1142
|
+
*/
|
|
1143
|
+
softRefreshData: function (newData) {
|
|
1144
|
+
// With pagination, navigator / selection can emit the same page twice in one
|
|
1145
|
+
// save cycle. Full refresh skipped duplicate data via isEqual on option set;
|
|
1146
|
+
// soft refresh must do the same or onDataRender (datarender) fires twice.
|
|
1147
|
+
if (this.options.data && newData && _.isEqual(this.options.data, newData)) {
|
|
1148
|
+
return;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
var self = this,
|
|
1152
|
+
isScrollOrOnDemand = this.options.isNavTypeScrollOrOndemand(),
|
|
1153
|
+
pageStartIndex = this.getPageStartIndex(),
|
|
1154
|
+
startRowIndex = this.options.startRowIndex || 0,
|
|
1155
|
+
selectedMap = {},
|
|
1156
|
+
preparedData;
|
|
1157
|
+
|
|
1158
|
+
// Preserve _selected state before _prepareData rebuilds preparedData
|
|
1159
|
+
this.preparedData.forEach(function (data, i) {
|
|
1160
|
+
if (data._selected) {
|
|
1161
|
+
selectedMap[i] = true;
|
|
1162
|
+
}
|
|
1163
|
+
});
|
|
1164
|
+
|
|
1165
|
+
this.options.data = newData;
|
|
1166
|
+
this._prepareData();
|
|
1167
|
+
|
|
1168
|
+
// Restore _selected state on new preparedData
|
|
1169
|
+
Object.keys(selectedMap).forEach(function (i) {
|
|
1170
|
+
if (self.preparedData[i]) {
|
|
1171
|
+
self.preparedData[i]._selected = true;
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
|
|
1175
|
+
if (isScrollOrOnDemand) {
|
|
1176
|
+
preparedData = this.preparedData.slice(pageStartIndex);
|
|
1177
|
+
} else {
|
|
1178
|
+
preparedData = this.preparedData;
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
// Update existing custom expression view contexts in-place
|
|
1182
|
+
// so Angular change detection picks up new data without DOM manipulation.
|
|
1183
|
+
if (_.isFunction(this.options.updateCustomExpressionContexts)) {
|
|
1184
|
+
this.options.updateCustomExpressionContexts(preparedData);
|
|
1185
|
+
}
|
|
1186
|
+
|
|
1187
|
+
// Update plain text cells with fresh data from preparedData.
|
|
1188
|
+
// hideRowEditMode runs before softRefreshData and may restore cells
|
|
1189
|
+
// before preparedData is updated, leaving them with stale values.
|
|
1190
|
+
self.gridElement.find('tr.' + self.options.cssClassNames.tableRow + ':not(.always-new-row)').each(function () {
|
|
1191
|
+
var $row = $(this),
|
|
1192
|
+
rowId = +$row.attr('data-row-id'),
|
|
1193
|
+
rowData = self.preparedData[rowId];
|
|
1194
|
+
if (!rowData) return;
|
|
1195
|
+
|
|
1196
|
+
$row.find('td.' + self.options.cssClassNames.tableCell + ':not(.cell-editing)').each(function () {
|
|
1197
|
+
var $cell = $(this),
|
|
1198
|
+
colId = +$cell.attr('data-col-id'),
|
|
1199
|
+
colDef = self.preparedHeaderData[colId],
|
|
1200
|
+
value;
|
|
1201
|
+
|
|
1202
|
+
if (colDef && !colDef.customExpression && colDef.type !== 'custom') {
|
|
1203
|
+
value = _.get(rowData, colDef.field);
|
|
1204
|
+
var newText;
|
|
1205
|
+
if (self.Utils.isDefined(value) && value !== null) {
|
|
1206
|
+
newText = '' + value;
|
|
1207
|
+
} else if (self.options.filterNullRecords && value === null) {
|
|
1208
|
+
newText = 'null';
|
|
1209
|
+
} else {
|
|
1210
|
+
newText = '';
|
|
1211
|
+
}
|
|
1212
|
+
if ($cell.text() !== newText) {
|
|
1213
|
+
$cell.text(newText);
|
|
1214
|
+
$cell.attr('title', newText);
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
});
|
|
1218
|
+
});
|
|
1219
|
+
|
|
1220
|
+
// Re-register conditional class watchers with fresh row clones
|
|
1221
|
+
_.forEach(preparedData, function (row, index) {
|
|
1222
|
+
var _row = _.clone(row),
|
|
1223
|
+
rowIndex = isScrollOrOnDemand ? startRowIndex + index - 1 : index;
|
|
1224
|
+
_row.$index = rowIndex + 1;
|
|
1225
|
+
|
|
1226
|
+
self.options.registerRowNgClassWatcher(_row, rowIndex);
|
|
1227
|
+
|
|
1228
|
+
self.preparedHeaderData.forEach(function (colDef, colId) {
|
|
1229
|
+
self.options.registerColNgClassWatcher(_row, colDef, rowIndex, colId);
|
|
1230
|
+
});
|
|
1231
|
+
});
|
|
1232
|
+
|
|
1233
|
+
// Reset action state flags (mirrors _getGridTemplate cleanup)
|
|
1234
|
+
if (!this.options.isdynamictable) {
|
|
1235
|
+
this.options.setLastActionPerformed(this.options.ACTIONS.DEFAULT);
|
|
1236
|
+
this.options.setIsDataUpdatedByUser(false);
|
|
1237
|
+
this.options.clearActionRowIndex();
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
// Refresh row action buttons and expansion buttons with updated row data.
|
|
1241
|
+
// Scope to data rows only — exclude always-new-row which has no backing data entry.
|
|
1242
|
+
var $dataRows = self.gridElement.find('tr.' + self.options.cssClassNames.tableRow + ':not(.always-new-row)');
|
|
1243
|
+
this.options.clearRowActions();
|
|
1244
|
+
this._appendRowExpansionButtons($dataRows);
|
|
1245
|
+
this._appendRowActions($dataRows);
|
|
1246
|
+
// Regenerated action / expansion DOM — re-bind handlers (attachEventHandlers only runs on full render).
|
|
1247
|
+
this._bindRowActionsAndExpansionClickHandlers($dataRows);
|
|
1248
|
+
|
|
1249
|
+
// Re-render summary row if present
|
|
1250
|
+
if (this.options.summaryRow) {
|
|
1251
|
+
var $summaryRowHtm = $(this._getSummaryRowTemplate());
|
|
1252
|
+
this.tableContainer.find('tfoot').remove();
|
|
1253
|
+
if (this.options.data.length) {
|
|
1254
|
+
this.tableContainer.append($summaryRowHtm);
|
|
1255
|
+
}
|
|
1256
|
+
this.gridFooter = this.tableContainer.find('tfoot');
|
|
1257
|
+
}
|
|
1258
|
+
|
|
1259
|
+
// Invalidate row detail (expansion) cache so collapse+re-expand
|
|
1260
|
+
// creates fresh views with updated data.
|
|
1261
|
+
if (_.isFunction(this.options.invalidateRowDetailCache)) {
|
|
1262
|
+
this.options.invalidateRowDetailCache(preparedData);
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// Refresh this.items with fresh data references from the updated dataset
|
|
1266
|
+
// so that selecteditem / currentItem reflect the new values.
|
|
1267
|
+
if (_.isFunction(this.options.refreshSelectedItems)) {
|
|
1268
|
+
this.options.refreshSelectedItems();
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
// Fire datarender event callback
|
|
1272
|
+
if (_.isFunction(this.options.onDataRender)) {
|
|
1273
|
+
this.options.onDataRender();
|
|
1274
|
+
}
|
|
1275
|
+
},
|
|
1134
1276
|
//Populate row data with default data
|
|
1135
1277
|
setDefaultRowData: function (rowData) {
|
|
1136
1278
|
_.forEach(this.preparedHeaderData, function (colDef) {
|
|
@@ -1551,8 +1693,24 @@ $.widget('wm.datatable', {
|
|
|
1551
1693
|
|
|
1552
1694
|
/* Sets the options for the grid. */
|
|
1553
1695
|
_setOption: function (key, value) {
|
|
1696
|
+
const isSortEnabled = v => v !== false && v !== 'false';
|
|
1697
|
+
let prev;
|
|
1698
|
+
|
|
1699
|
+
if (key === 'enableSort') {
|
|
1700
|
+
prev = isSortEnabled(this.options.enableSort);
|
|
1701
|
+
}
|
|
1554
1702
|
this._super(key, value);
|
|
1555
1703
|
switch (key) {
|
|
1704
|
+
case 'enableSort':
|
|
1705
|
+
if (this.tableContainer?.length) {
|
|
1706
|
+
this.refreshSortHeader(); // Refresh the table header and update column widths when sort is enabled/disabled
|
|
1707
|
+
}
|
|
1708
|
+
break;
|
|
1709
|
+
case 'enableColumnSelection':
|
|
1710
|
+
if (this.tableContainer?.length) {
|
|
1711
|
+
this.refreshSortHeader(); // Refresh the table header and update column widths when column selection is enabled/disabled
|
|
1712
|
+
}
|
|
1713
|
+
break;
|
|
1556
1714
|
case 'showHeader':
|
|
1557
1715
|
this._toggleHeader();
|
|
1558
1716
|
this._toggleSearch();
|
|
@@ -1635,6 +1793,17 @@ $.widget('wm.datatable', {
|
|
|
1635
1793
|
return this.options;
|
|
1636
1794
|
},
|
|
1637
1795
|
|
|
1796
|
+
/** function to rebuild table header and update column widths. */
|
|
1797
|
+
refreshSortHeader: function () {
|
|
1798
|
+
this._prepareHeaderData();
|
|
1799
|
+
if (this.options.showHeader) {
|
|
1800
|
+
this._renderHeader();
|
|
1801
|
+
this._attachHeaderEventHandlers();
|
|
1802
|
+
}
|
|
1803
|
+
this.setColGroupWidths();
|
|
1804
|
+
this.addOrRemoveScroll();
|
|
1805
|
+
},
|
|
1806
|
+
|
|
1638
1807
|
/* Toggles the table header visibility. */
|
|
1639
1808
|
_toggleHeader: function () {
|
|
1640
1809
|
if (this.gridHeaderElement) {
|
|
@@ -1647,6 +1816,7 @@ $.widget('wm.datatable', {
|
|
|
1647
1816
|
this.setDefaultColsData();
|
|
1648
1817
|
if (this.options.showHeader) {
|
|
1649
1818
|
this._renderHeader();
|
|
1819
|
+
this._attachHeaderEventHandlers(); // Attach all event handlers specifically for the table header
|
|
1650
1820
|
}
|
|
1651
1821
|
},
|
|
1652
1822
|
|
|
@@ -1729,11 +1899,14 @@ $.widget('wm.datatable', {
|
|
|
1729
1899
|
if (this.options.showRadioColumn) {
|
|
1730
1900
|
$radio = $row.find('td input[rowSelectInput]:radio:not(:disabled)');
|
|
1731
1901
|
$radio.prop('checked', selected);
|
|
1902
|
+
$radio.attr('checked', selected ? 'checked' : null); //
|
|
1732
1903
|
this.preparedData[rowId]._checked = selected;
|
|
1733
1904
|
}
|
|
1734
1905
|
if (this.options.multiselect) {
|
|
1735
1906
|
$checkbox = $row.find('td input[name="gridMultiSelect"]:checkbox:not(:disabled)');
|
|
1736
1907
|
$checkbox.prop('checked', selected);
|
|
1908
|
+
$checkbox.attr('checked', selected ? 'checked' : null);
|
|
1909
|
+
$checkbox.closest('label').toggleClass('unchecked', !selected);
|
|
1737
1910
|
$checkbox.siblings('span.sr-only').text(selected ? 'Row Selected' : 'Row Deselected');
|
|
1738
1911
|
this.preparedData[rowId]._checked = selected;
|
|
1739
1912
|
// if we check header checkbox(select/unselect all the records) then updating selectAll checkbox state is not required.
|
|
@@ -1767,6 +1940,7 @@ $.widget('wm.datatable', {
|
|
|
1767
1940
|
$headerCheckbox.prop('checked', false);
|
|
1768
1941
|
}
|
|
1769
1942
|
},
|
|
1943
|
+
|
|
1770
1944
|
// triggered on capture phase of click listener.
|
|
1771
1945
|
// sets the selected rowdata on click.
|
|
1772
1946
|
rowClickHandlerOnCapture: function (e, $row, options) {
|
|
@@ -2155,6 +2329,10 @@ $.widget('wm.datatable', {
|
|
|
2155
2329
|
var rowId = parseInt($row.attr('data-row-id'), 10);
|
|
2156
2330
|
return rowId >= this.preparedData.length || $row.hasClass('always-new-row');
|
|
2157
2331
|
},
|
|
2332
|
+
_getWmVariableRowLocator: function (rowId) {
|
|
2333
|
+
var liveRow = this.options.data[parseInt(rowId, 10)];
|
|
2334
|
+
return (liveRow && liveRow.$$wmSourceListIndex != null) ? liveRow.$$wmSourceListIndex : (liveRow || parseInt(rowId, 10));
|
|
2335
|
+
},
|
|
2158
2336
|
/* Toggles the edit state of a row. */
|
|
2159
2337
|
toggleEditRow: function (e, options) {
|
|
2160
2338
|
if(e?.target && $(e.target).closest('.app-menu').length) {
|
|
@@ -2360,8 +2538,9 @@ $.widget('wm.datatable', {
|
|
|
2360
2538
|
return;
|
|
2361
2539
|
}
|
|
2362
2540
|
}
|
|
2363
|
-
|
|
2364
|
-
|
|
2541
|
+
var ds = this.options.getDataSource && this.options.getDataSource();
|
|
2542
|
+
if (ds && ds.category === 'wm.Variable') {
|
|
2543
|
+
editOptions.rowindex = self._getWmVariableRowLocator(rowindex);
|
|
2365
2544
|
}
|
|
2366
2545
|
this.options.afterRowUpdate(rowData, e, onSaveSuccess, editOptions);
|
|
2367
2546
|
}
|
|
@@ -2514,6 +2693,10 @@ $.widget('wm.datatable', {
|
|
|
2514
2693
|
return;
|
|
2515
2694
|
}
|
|
2516
2695
|
}
|
|
2696
|
+
var deleteDs = this.options.getDataSource && this.options.getDataSource();
|
|
2697
|
+
if (deleteDs && deleteDs.category === 'wm.Variable') {
|
|
2698
|
+
options.rowindex = this._getWmVariableRowLocator(rowId);
|
|
2699
|
+
}
|
|
2517
2700
|
if (_.isFunction(this.options.onRowDelete)) {
|
|
2518
2701
|
className = this.options.cssClassNames.deleteRow;
|
|
2519
2702
|
isActiveRow = $row.attr('class').indexOf('active') !== -1;
|
|
@@ -2626,8 +2809,10 @@ $.widget('wm.datatable', {
|
|
|
2626
2809
|
/* Handles table sorting. */
|
|
2627
2810
|
sortHandler: function (e) {
|
|
2628
2811
|
e.stopImmediatePropagation();
|
|
2629
|
-
// If header span is clicked and column selection is enabled, call header click
|
|
2812
|
+
// If header span is clicked and column selection is enabled, call header click hand
|
|
2813
|
+
//Calling the column selection handler so that column selection works even when the bind exp changes later from false to true.
|
|
2630
2814
|
if ($(e.target).hasClass('header-data') && this.options.enableColumnSelection) {
|
|
2815
|
+
this.columnSelectionHandler(e);
|
|
2631
2816
|
this.headerClickHandler(e);
|
|
2632
2817
|
}
|
|
2633
2818
|
var $e = $(e.target),
|
|
@@ -2892,10 +3077,31 @@ $.widget('wm.datatable', {
|
|
|
2892
3077
|
this.sortHandler(event);
|
|
2893
3078
|
}
|
|
2894
3079
|
},
|
|
3080
|
+
/**
|
|
3081
|
+
* Binds jQuery handlers on save/cancel row-action buttons and row-expansion controls.
|
|
3082
|
+
* Must run after DOM for those controls is replaced (e.g. softRefreshData).
|
|
3083
|
+
*/
|
|
3084
|
+
_bindRowActionsAndExpansionClickHandlers: function ($scope) {
|
|
3085
|
+
var self = this;
|
|
3086
|
+
if (this.options.rowActions.length) {
|
|
3087
|
+
$scope.find('.cancel-edit-row-button').off('click');
|
|
3088
|
+
$scope.find('.save-edit-row-button').off('click');
|
|
3089
|
+
$scope.find('.cancel-edit-row-button').on('click', {action: 'cancel'}, this.toggleEditRow.bind(this));
|
|
3090
|
+
$scope.find('.save-edit-row-button').on('click', {action: 'save'}, this.toggleEditRow.bind(this));
|
|
3091
|
+
}
|
|
3092
|
+
$scope.find('[data-identifier="rowExpansionButtons"]').off('click');
|
|
3093
|
+
$scope.find('[data-identifier="rowExpansionButtons"]').on('click', function (e) {
|
|
3094
|
+
var $row = $(e.target).closest('tr.app-datagrid-row');
|
|
3095
|
+
if ($(this).find('.app-button').attr('disabled')) {
|
|
3096
|
+
return;
|
|
3097
|
+
}
|
|
3098
|
+
self.toggleExpandRow(+$row.attr('data-row-id'), undefined, e);
|
|
3099
|
+
});
|
|
3100
|
+
},
|
|
3101
|
+
|
|
2895
3102
|
/* Attaches all event handlers for the table. */
|
|
2896
3103
|
attachEventHandlers: function ($htm) {
|
|
2897
|
-
var
|
|
2898
|
-
self = this;
|
|
3104
|
+
var self = this;
|
|
2899
3105
|
|
|
2900
3106
|
if (this.options.enableRowSelection) {
|
|
2901
3107
|
$htm[0].removeEventListener('click', this.rowClickHandlerOnCapture.bind(this));
|
|
@@ -2917,40 +3123,15 @@ $.widget('wm.datatable', {
|
|
|
2917
3123
|
$htm.on('keydown', this.onKeyDown.bind(this));
|
|
2918
3124
|
}
|
|
2919
3125
|
|
|
2920
|
-
|
|
2921
|
-
if (this.options.enableColumnSelection) {
|
|
2922
|
-
$header.find('th[data-col-selectable]').off('click', this.columnSelectionHandler.bind(this));
|
|
2923
|
-
$header.find('th[data-col-selectable]').on('click', this.columnSelectionHandler.bind(this));
|
|
2924
|
-
} else {
|
|
2925
|
-
$header.find('th[data-col-selectable]').off('click');
|
|
2926
|
-
}
|
|
3126
|
+
this._attachHeaderEventHandlers();
|
|
2927
3127
|
|
|
2928
|
-
if (this.options.enableSort) {
|
|
2929
|
-
if (this.options.enableColumnSelection) {
|
|
2930
|
-
$header.find('th[data-col-sortable] .header-data').off('click', this.sortHandler.bind(this));
|
|
2931
|
-
$header.find('th[data-col-sortable] .header-data').on('click', this.sortHandler.bind(this));
|
|
2932
|
-
$header.find('th[data-col-sortable]').off('keydown', this.keydownHandler.bind(this));
|
|
2933
|
-
$header.find('th[data-col-sortable]').on('keydown', this.keydownHandler.bind(this));
|
|
2934
|
-
} else {
|
|
2935
|
-
$header.find('th[data-col-sortable]').off('click', this.sortHandler.bind(this));
|
|
2936
|
-
$header.find('th[data-col-sortable]').on('click', this.sortHandler.bind(this));
|
|
2937
|
-
$header.find('th[data-col-sortable]').off('keydown', this.keydownHandler.bind(this));
|
|
2938
|
-
$header.find('th[data-col-sortable]').on('keydown', this.keydownHandler.bind(this));
|
|
2939
|
-
}
|
|
2940
|
-
} else {
|
|
2941
|
-
if (this.options.enableColumnSelection) {
|
|
2942
|
-
$header.find('th[data-col-sortable] .header-data').off('click');
|
|
2943
|
-
} else {
|
|
2944
|
-
$header.find('th[data-col-sortable]').off('click');
|
|
2945
|
-
}
|
|
2946
|
-
}
|
|
2947
|
-
}
|
|
2948
3128
|
if (this.options.rowActions.length) {
|
|
2949
3129
|
$htm.find('.cancel-edit-row-button').off('click');
|
|
2950
3130
|
$htm.find('.save-edit-row-button').off('click');
|
|
2951
3131
|
$htm.find('.cancel-edit-row-button').on('click', {action: 'cancel'}, this.toggleEditRow.bind(this));
|
|
2952
3132
|
$htm.find('.save-edit-row-button').on('click', {action: 'save'}, this.toggleEditRow.bind(this));
|
|
2953
3133
|
}
|
|
3134
|
+
this._bindRowActionsAndExpansionClickHandlers($htm);
|
|
2954
3135
|
if (self.options.editmode === self.CONSTANTS.QUICK_EDIT) {
|
|
2955
3136
|
$htm.on('focus', 'tr.app-datagrid-row', function (e) {
|
|
2956
3137
|
var $row = $(e.currentTarget);
|
|
@@ -2971,13 +3152,23 @@ $.widget('wm.datatable', {
|
|
|
2971
3152
|
isRelatedTargetRowAction = $relatedTarget.closest('span.actions-column').length>0,
|
|
2972
3153
|
isTargetGridAction = $relatedTarget.closest('div.app-datagrid-actions').length>0,
|
|
2973
3154
|
isRelatedTargetGridAction = $relatedTarget.closest('div.app-datagrid-actions').length>0,
|
|
3155
|
+
currentGridId = $($target.closest('.app-grid'))?.attr('widget-id'),
|
|
3156
|
+
relatedGrid = $relatedTarget.closest('.app-grid')[0],
|
|
3157
|
+
relatedGridId = relatedGrid ? $(relatedGrid).attr('widget-id') : null,
|
|
3158
|
+
isRelatedGridDifferent = relatedGrid && relatedGridId !== currentGridId,
|
|
2974
3159
|
invalidTargets = '.row-editing:not(".always-new-row"), .row-action-button, .app-datagrid-cell, .caption, button.btn-time, button.btn-date';
|
|
2975
3160
|
|
|
2976
3161
|
//Check if the focus out element is outside the grid or some special elements
|
|
2977
3162
|
function isInvalidTarget() {
|
|
2978
|
-
|
|
3163
|
+
// If relatedTarget is not in any grid, it's invalid (outside all tables)
|
|
3164
|
+
if (!relatedGrid) {
|
|
2979
3165
|
return true;
|
|
2980
3166
|
}
|
|
3167
|
+
// If relatedTarget is in a different grid, allow save (return false)
|
|
3168
|
+
if (isRelatedGridDifferent) {
|
|
3169
|
+
return false; // NOT invalid - we should save the grid
|
|
3170
|
+
}
|
|
3171
|
+
// If relatedTarget is in SAME grid, check if it's an invalid target within this grid
|
|
2981
3172
|
return $relatedTarget.is(invalidTargets);
|
|
2982
3173
|
}
|
|
2983
3174
|
|
|
@@ -2994,8 +3185,9 @@ $.widget('wm.datatable', {
|
|
|
2994
3185
|
}
|
|
2995
3186
|
// Save the Row if any button from Grid action is clicked / AddRow action is
|
|
2996
3187
|
// triggered from the Row Actions
|
|
2997
|
-
if (!isTargetGridAction && !isTargetRowAction) {
|
|
2998
|
-
//
|
|
3188
|
+
if (!isTargetGridAction && !isTargetRowAction && !isRelatedGridDifferent) {
|
|
3189
|
+
// If focus moved to a DIFFERENT grid, allow save (skip isLastColumn check)
|
|
3190
|
+
// Otherwise Save the row on last column of the data table. Do not save the row if focus is out of input file.
|
|
2999
3191
|
if (!isLastColumn || (isLastColumn && (e.relatedTarget === null || $(e.target).is('tr.app-datagrid-row'))) || $target.hasClass("file-upload")) {
|
|
3000
3192
|
return;
|
|
3001
3193
|
}
|
|
@@ -3005,7 +3197,9 @@ $.widget('wm.datatable', {
|
|
|
3005
3197
|
'action': 'save',
|
|
3006
3198
|
'noMsg': true,
|
|
3007
3199
|
'success': function (skipFocus, error, isNewRow) {
|
|
3008
|
-
if
|
|
3200
|
+
// Only navigate to next row if staying in SAME grid
|
|
3201
|
+
// If switching to DIFFERENT grid, let that grid's click handler take over
|
|
3202
|
+
if (!isNewRow && !isRelatedGridDifferent) {
|
|
3009
3203
|
self.editSuccessHandler(skipFocus, error, e, $row,false);
|
|
3010
3204
|
}
|
|
3011
3205
|
}
|
|
@@ -3024,6 +3218,42 @@ $.widget('wm.datatable', {
|
|
|
3024
3218
|
self.toggleExpandRow(+$row.attr('data-row-id'), undefined, e);
|
|
3025
3219
|
});
|
|
3026
3220
|
},
|
|
3221
|
+
/**
|
|
3222
|
+
* Function which attaches all event handlers specifically for the table header.
|
|
3223
|
+
* Needed when table header is rebuilt (e.g. showHeader toggle) without a full _renderGrid
|
|
3224
|
+
*/
|
|
3225
|
+
_attachHeaderEventHandlers: function () {
|
|
3226
|
+
var $header = this.gridHeaderElement;
|
|
3227
|
+
if (!$header || !$header.length) {
|
|
3228
|
+
return;
|
|
3229
|
+
}
|
|
3230
|
+
if (this.options.enableColumnSelection) {
|
|
3231
|
+
$header.find('th[data-col-selectable]').off('click', this.columnSelectionHandler.bind(this));
|
|
3232
|
+
$header.find('th[data-col-selectable]').on('click', this.columnSelectionHandler.bind(this));
|
|
3233
|
+
} else {
|
|
3234
|
+
$header.find('th[data-col-selectable]').off('click');
|
|
3235
|
+
}
|
|
3236
|
+
|
|
3237
|
+
if (!(this.options.enableSort === false || this.options.enableSort === 'false')) {
|
|
3238
|
+
if (this.options.enableColumnSelection) {
|
|
3239
|
+
$header.find('th[data-col-sortable] .header-data').off('click', this.sortHandler.bind(this));
|
|
3240
|
+
$header.find('th[data-col-sortable] .header-data').on('click', this.sortHandler.bind(this));
|
|
3241
|
+
$header.find('th[data-col-sortable]').off('keydown', this.keydownHandler.bind(this));
|
|
3242
|
+
$header.find('th[data-col-sortable]').on('keydown', this.keydownHandler.bind(this));
|
|
3243
|
+
} else {
|
|
3244
|
+
$header.find('th[data-col-sortable]').off('click', this.sortHandler.bind(this));
|
|
3245
|
+
$header.find('th[data-col-sortable]').on('click', this.sortHandler.bind(this));
|
|
3246
|
+
$header.find('th[data-col-sortable]').off('keydown', this.keydownHandler.bind(this));
|
|
3247
|
+
$header.find('th[data-col-sortable]').on('keydown', this.keydownHandler.bind(this));
|
|
3248
|
+
}
|
|
3249
|
+
} else {
|
|
3250
|
+
if (this.options.enableColumnSelection) {
|
|
3251
|
+
$header.find('th[data-col-sortable] .header-data').off('click');
|
|
3252
|
+
} else {
|
|
3253
|
+
$header.find('th[data-col-sortable]').off('click');
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
},
|
|
3027
3257
|
expandRow: function(rowId) {
|
|
3028
3258
|
this.toggleExpandRow(rowId, true)
|
|
3029
3259
|
},
|
|
@@ -3209,11 +3439,19 @@ $.widget('wm.datatable', {
|
|
|
3209
3439
|
self.gridHeaderElement.parent().prop('scrollLeft', this.scrollLeft);
|
|
3210
3440
|
});
|
|
3211
3441
|
if (!this.options.showHeader) {
|
|
3442
|
+
this.tableContainer.find('colgroup').remove(); // Remove the colgroup from the table container when showHeader is false
|
|
3212
3443
|
this.tableContainer.append($colgroup);
|
|
3213
3444
|
this.gridHeaderElement.hide();
|
|
3214
3445
|
//this.gridElement.prepend($colgroup.clone());
|
|
3215
3446
|
return;
|
|
3216
3447
|
} else {
|
|
3448
|
+
/* _toggleHeader() removes thead from the DOM when toggling showHeader; gridHeaderElement
|
|
3449
|
+
* still references the detached thead. Re-insert it before the tbody so the header
|
|
3450
|
+
* is visible when bind changes from false to true. */
|
|
3451
|
+
if (this.gridHeaderElement.length && this.tableContainer?.length &&
|
|
3452
|
+
!this.tableContainer[0].contains(this.gridHeaderElement[0])) {
|
|
3453
|
+
this.tableContainer.prepend(this.gridHeaderElement); // Re-insert the table header before the tbody when showHeader is true
|
|
3454
|
+
}
|
|
3217
3455
|
this.gridHeaderElement.show();
|
|
3218
3456
|
}
|
|
3219
3457
|
$header = headerTemplate.header;
|
|
@@ -3262,7 +3500,7 @@ $.widget('wm.datatable', {
|
|
|
3262
3500
|
$headerCol.hide();
|
|
3263
3501
|
}
|
|
3264
3502
|
});
|
|
3265
|
-
|
|
3503
|
+
this.tableContainer.find('colgroup').remove(); // Remove the colgroup from the table container when showHeader is false
|
|
3266
3504
|
/*For mobile view, append header to the main table only*/
|
|
3267
3505
|
if (this.options.isMobile) {
|
|
3268
3506
|
this.tableContainer.append($colgroup);
|
|
@@ -3546,8 +3784,8 @@ $.widget('wm.datatable', {
|
|
|
3546
3784
|
this.dataStatusContainer.hide();
|
|
3547
3785
|
} else {
|
|
3548
3786
|
// [WMS-23839] always show load more btn if show view less btn is true
|
|
3549
|
-
if (this.options.isNavTypeScrollOrOndemand() &&
|
|
3550
|
-
(state === 'nodata' ||
|
|
3787
|
+
if (this.options.isNavTypeScrollOrOndemand() &&
|
|
3788
|
+
(state === 'nodata' ||
|
|
3551
3789
|
(this.options.getCurrentPage && typeof this.options.getCurrentPage === 'function' &&
|
|
3552
3790
|
this.options.getPageCount && typeof this.options.getPageCount === 'function' &&
|
|
3553
3791
|
(this.options.getCurrentPage() == this.options.getPageCount()) && !this.options.showviewlessbutton))) {
|
|
@@ -3560,7 +3798,7 @@ $.widget('wm.datatable', {
|
|
|
3560
3798
|
if (state === 'nodata') {
|
|
3561
3799
|
this.dataStatusContainer.css('height', 'auto');
|
|
3562
3800
|
this.dataStatus.contentHeight = 0;
|
|
3563
|
-
} else if (this.options.isNavTypeScrollOrOndemand() &&
|
|
3801
|
+
} else if (this.options.isNavTypeScrollOrOndemand() &&
|
|
3564
3802
|
this.options.getCurrentPage && typeof this.options.getCurrentPage === 'function' &&
|
|
3565
3803
|
this.options.getCurrentPage() > 1){
|
|
3566
3804
|
// showing the loading icon only for the first page
|
|
@@ -3572,7 +3810,7 @@ $.widget('wm.datatable', {
|
|
|
3572
3810
|
this.dataStatusContainer.css('height', this.dataStatus.height > this.dataStatus.contentHeight ? 'auto' : this.dataStatus.contentHeight);
|
|
3573
3811
|
}
|
|
3574
3812
|
}
|
|
3575
|
-
if (!isScrollOrOndemand || (isScrollOrOndemand &&
|
|
3813
|
+
if (!isScrollOrOndemand || (isScrollOrOndemand &&
|
|
3576
3814
|
this.options.getCurrentPage && typeof this.options.getCurrentPage === 'function' &&
|
|
3577
3815
|
this.options.getCurrentPage() === 1)) {
|
|
3578
3816
|
this.gridContainer.addClass("show-msg");
|
|
@@ -3698,7 +3936,7 @@ $.widget('wm.datatable', {
|
|
|
3698
3936
|
// this.gridElement[0].removeEventListener('click', this.boundRowClickHandlerOnCapture, true);
|
|
3699
3937
|
// this.boundRowClickHandlerOnCapture = null;
|
|
3700
3938
|
// }
|
|
3701
|
-
|
|
3939
|
+
|
|
3702
3940
|
// MEMORY LEAK FIX: Remove all jQuery event handlers
|
|
3703
3941
|
if (this.gridHeaderElement) {
|
|
3704
3942
|
this.gridHeaderElement.off();
|
|
@@ -3715,12 +3953,12 @@ $.widget('wm.datatable', {
|
|
|
3715
3953
|
if (this.gridContainer) {
|
|
3716
3954
|
this.gridContainer.off();
|
|
3717
3955
|
}
|
|
3718
|
-
|
|
3956
|
+
|
|
3719
3957
|
// MEMORY LEAK FIX: Clear all internal structures
|
|
3720
3958
|
this.preparedData = [];
|
|
3721
3959
|
this.preparedHeaderData = [];
|
|
3722
3960
|
this.compiledCellTemplates = {};
|
|
3723
|
-
|
|
3961
|
+
|
|
3724
3962
|
this.element.text('');
|
|
3725
3963
|
window.clearTimeout(this.refreshGridTimeout);
|
|
3726
3964
|
}
|
|
@@ -405,6 +405,9 @@
|
|
|
405
405
|
if (parts[0] === 'Variables' || parts[0] === 'Widgets') {
|
|
406
406
|
return `${parts[0]}.${parts[1]}`;
|
|
407
407
|
}
|
|
408
|
+
if (parts[0] === 'App' && parts[1] === 'activePage' && parts[2] === 'Variables' && parts[3]) {
|
|
409
|
+
return `App.activePage.Variables.${parts[3]}`;
|
|
410
|
+
}
|
|
408
411
|
};
|
|
409
412
|
const widgetChildAttrs = (() => {
|
|
410
413
|
const childAttrs = new Map();
|