/**
* @file
* tabledrag.js overrides and functionality extensions.
*/
(($, Drupal) => {
/**
* Extends core's Tabledrag functionality.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.claroTableDrag = {
attach(context, settings) {
/**
* Refactors the table row markup to improve item label text wrapping.
*
* This addresses an issue specific to item labels that are long enough
* to be wrapped to a new line. Without this fix, a new line may start
* at the beginning of the table row, instead of the expected behavior of
* starting at the x axis of the first line.
*
* Addressing this issue requires changing the structure of a tabledrag
* cell's first row.
* @example
*
*
*
* @param {number} index
* The index in the loop, as provided by `jQuery.each`.
* @param {HTMLElement} row
* A draggable table row.
*
* @todo this may be removable as part of https://drupal.org/node/3083044
*/
const createItemWrapBoundaries = (row) => {
const $row = $(row);
const $firstCell = $row
.find('td:first-of-type')
.eq(0)
.wrapInner(Drupal.theme('tableDragCellContentWrapper'))
.wrapInner(
$(Drupal.theme('tableDragCellItemsWrapper')).addClass(
'js-tabledrag-cell-content',
),
);
const $targetElem = $firstCell.find('.js-tabledrag-cell-content');
// Move handle into the '.js-tabledrag-cell-content' target.
$targetElem
.eq(0)
.find(
'> .tabledrag-cell-content__item > .js-tabledrag-handle, > .tabledrag-cell-content__item > .js-indentation',
)
.prependTo($targetElem);
};
// Find each row in a draggable table and process it with
// createItemWrapBoundaries().
Object.keys(settings.tableDrag || {}).forEach((base) => {
once(
'claroTabledrag',
$(context)
.find(`#${base}`)
.find('> tr.draggable, > tbody > tr.draggable'),
).forEach(createItemWrapBoundaries);
});
},
};
$.extend(Drupal.tableDrag.prototype.row.prototype, {
/**
* Add an asterisk or other marker to the changed row.
*
* @todo this may be removable as part of https://drupal.org/node/3084910
*/
markChanged() {
const marker = $(Drupal.theme('tableDragChangedMarker')).addClass(
'js-tabledrag-changed-marker',
);
const cell = $(this.element).find('td:first-of-type');
if (cell.find('.js-tabledrag-changed-marker').length === 0) {
cell.find('.js-tabledrag-handle').after(marker);
}
Drupal.tableDrag[this.table.id].changedRowIds.add(this.element.id);
},
/**
* Moves added indents into Claro's wrapper element.
*
* For indents to work properly, they must be inside the wrapper
* created by createItemWrapBoundaries(). When an indent is added via
* dragging, core's tabledrag functionality does not add it inside the
* wrapper. This function fires immediately after an indent is added, which
* moves the indent into that wrapper.
*
* @see Drupal.tableDrag.prototype.row.prototype.indent
*
* @todo this may be removable as part of https://drupal.org/node/3083044
*/
onIndent() {
$(this.table)
.find('.tabledrag-cell > .js-indentation')
.each((index, indentToMove) => {
const $indentToMove = $(indentToMove);
const $cellContent = $indentToMove.siblings(
'.tabledrag-cell-content',
);
$indentToMove.prependTo($cellContent);
});
},
});
$.extend(
Drupal.theme,
/** @lends Drupal.theme */ {
/**
* Constructs the table drag changed marker.
*
* @return {string}
* Markup for the indentation.
*/
tableDragIndentation() {
return '';
},
/**
* Constructs the table drag changed warning.
*
* @return {string}
* Markup for the warning.
*/
tableDragChangedWarning() {
return `
${Drupal.theme(
'tableDragChangedMarker',
)} ${Drupal.t('You have unsaved changes.')}
`;
},
/**
* Constructs the table drag handle.
*
* @return {string}
* A string representing a DOM fragment.
*/
tableDragHandle: () =>
``,
/**
* The button for toggling table row weight visibility.
*
* @return {string}
* HTML markup for the weight toggle button and its container.
*/
tableDragToggle: () =>
`
`,
/**
* Constructs contents of the toggle weight button.
*
* @param {boolean} show
* If the table weights are currently displayed.
*
* @return {string}
* HTML markup for the weight toggle button content.
*/
toggleButtonContent: (show) => {
const classes = [
'action-link',
'action-link--extrasmall',
'tabledrag-toggle-weight',
];
let text = '';
if (show) {
classes.push('action-link--icon-hide');
text = Drupal.t('Hide row weights');
} else {
classes.push('action-link--icon-show');
text = Drupal.t('Show row weights');
}
return `${text}`;
},
/**
* Constructs the wrapper for the initial content of the drag cell.
*
* @return {string}
* A string representing a DOM fragment.
*/
tableDragCellContentWrapper() {
return '';
},
/**
* Constructs the wrapper for the whole table drag cell.
*
* @return {string}
* A string representing a DOM fragment.
*/
tableDragCellItemsWrapper() {
return '';
},
},
);
})(jQuery, Drupal);