array drag handle

This commit is contained in:
Yuri Kuznetsov
2025-08-01 11:18:30 +03:00
parent 6e487345ec
commit c2261feeec
5 changed files with 174 additions and 36 deletions
@@ -30,6 +30,8 @@ import OptionsView from 'views/admin/field-manager/fields/options';
export default class extends OptionsView {
noDragHandle = true
setup() {
super.setup();
+24 -2
View File
@@ -121,6 +121,13 @@ class ArrayFieldView extends BaseFieldView {
*/
translatedOptions = null
/**
* @protected
* @type {boolean}
* @since 9.2.0
*/
noDragHandle = false
// noinspection JSCheckFunctionSignatures
/** @inheritDoc */
@@ -434,6 +441,7 @@ class ArrayFieldView extends BaseFieldView {
distance: 5,
cancel: 'input,textarea,button,select,option,a[role="button"]',
cursor: 'grabbing',
handle: !this.noDragHandle ? '.drag-handle' : undefined,
});
}
@@ -658,7 +666,7 @@ class ArrayFieldView extends BaseFieldView {
value;
const div = document.createElement('div');
div.classList.add('list-group-item');
div.className = 'list-group-item';
div.dataset.value = value;
div.style.cursor = 'default';
@@ -672,7 +680,7 @@ class ArrayFieldView extends BaseFieldView {
a.append(
(() => {
const span = document.createElement('span');
span.classList.add('fas', 'fa-times');
span.className = 'fas fa-times'
return span;
})(),
@@ -682,6 +690,20 @@ class ArrayFieldView extends BaseFieldView {
}
div.append(
(() => {
const span = document.createElement('span');
span.className = 'drag-handle';
span.append(
(() => {
const span = document.createElement('span');
span.className = 'fas fa-grip fa-sm';
return span;
})(),
);
return span;
})(),
(() => {
const span = document.createElement('span');
span.classList.add('text');
@@ -55,10 +55,26 @@ export default class extends ArrayFieldView {
return $('<div>')
.addClass('list-group-item link-with-role form-inline')
.attr('data-value', value)
.append(
(() => {
const span = document.createElement('span');
span.className = 'drag-handle pull-left';
span.append(
(() => {
const span = document.createElement('span');
span.className = 'fas fa-grip fa-sm';
return span;
})(),
);
return span;
})(),
)
.append(
$('<div>')
.addClass('pull-left')
.css('width', '92%')
.css('width', 'calc(100% - var(--36px))')
.css('display', 'inline-block')
.append(
$('<input>')
@@ -67,12 +83,12 @@ export default class extends ArrayFieldView {
.attr('data-value', value)
.addClass('role form-control input-sm')
.attr('value', translatedValue)
.css('width', '65%')
.css('width', 'calc(100% - var(--4px))')
)
)
.append(
$('<div>')
.css('width', '8%')
.css('width', 'var(--18px)')
.css('display', 'inline-block')
.css('vertical-align', 'top')
.append(
@@ -87,9 +103,6 @@ export default class extends ArrayFieldView {
)
)
)
.append(
$('<br>').css('clear', 'both')
)
.get(0).outerHTML;
}
+92 -23
View File
@@ -46,11 +46,9 @@ class TabListFieldView extends ArrayFieldView {
}
});
this.events['click [data-action="editGroup"]'] = e => {
const id = $(e.currentTarget).parent().data('value').toString();
this.editGroup(id);
};
this.addActionHandler('editGroup', (e, target) => {
this.editGroup(target.dataset.value);
})
}
generateItemId() {
@@ -132,39 +130,110 @@ class TabListFieldView extends ArrayFieldView {
return super.getItemHtml(value);
}
/**
*
* @param {{id: string, text?: string|null, type: string}} item
* @return {string | jQuery}
*/
getGroupItemHtml(item) {
const label = item.text || '';
const labelElement = document.createElement('span');
labelElement.textContent = item.text ?? '';
const $label = $('<span>').text(label);
let $icon = null;
let icon;
if (item.type === 'group') {
$icon = $('<span>')
.addClass('far fa-list-alt')
.addClass('text-muted')
icon = document.createElement('span');
icon.className = 'far fa-list-alt text-muted';
}
if (item.type === 'url') {
$icon = $('<span>')
.addClass('fas fa-link fa-sm')
.addClass('text-muted')
icon = document.createElement('span');
icon.className = 'fas fa-link fa-sm text-muted';
}
if (item.type === 'divider') {
$label.addClass('text-soft')
.addClass('text-italic');
labelElement.classList.add('text-soft', 'text-italic');
}
const $item = $('<span>').append($label);
const itemElement = document.createElement('span');
itemElement.append(labelElement);
itemElement.className = 'text';
if ($icon) {
$item.prepend(
$icon,
' '
)
if (icon) {
icon.style.marginRight = 'var(--4px)';
itemElement.prepend(icon);
}
const div = document.createElement('div');
div.className = 'list-group-item';
div.dataset.value = item.id;
div.style.cursor = 'default';
div.append(
(() => {
const span = document.createElement('span');
span.className = 'drag-handle';
span.append(
(() => {
const span = document.createElement('span');
span.className = 'fas fa-grip fa-sm';
return span;
})(),
);
return span;
})(),
(() => {
const span = document.createElement('span');
span.className = 'item-button'
span.append(
(() => {
const a = document.createElement('a');
a.role = 'button';
a.tabIndex = 0;
a.dataset.value = item.id;
a.dataset.action = 'editGroup';
a.append(
(() => {
const span = document.createElement('span');
span.className = 'fas fa-pencil-alt fa-sm';
return span;
})(),
);
return a;
})(),
)
return span;
})(),
itemElement,
(() => {
const a = document.createElement('a');
a.role = 'button';
a.tabIndex = 0;
a.classList.add('pull-right');
a.dataset.value = item.id;
a.dataset.action = 'removeValue';
a.append(
(() => {
const span = document.createElement('span');
span.className = 'fas fa-times'
return span;
})(),
);
return a;
})(),
);
return div.outerHTML;
return $('<div>')
.addClass('list-group-item')
.attr('data-value', item.id)
+37 -5
View File
@@ -827,6 +827,43 @@ input.global-search-input {
width: calc(100% - var(--18px));
display: inline-block;
}
> span.drag-handle {
display: inline-block;
width: var(--18px);
color: var(--text-muted-color);
cursor: grab;
vertical-align: top;
}
> span.item-button {
display: inline-block;
width: var(--18px);
vertical-align: top;
}
&:has(> .item-button) {
> span.text {
width: calc(100% - var(--36px));
}
}
&:has(> .drag-handle) {
> span.text {
width: calc(100% - var(--36px));
}
}
&:has(> .item-button):has(> .drag-handle) {
> span.text {
width: calc(100% - var(--36px) - var(--18px));
}
}
> a[role="button"] {
margin-top: var(--1px);
margin-left: var(--2px);
}
}
.link-group-item-with-columns {
@@ -947,11 +984,6 @@ input.global-search-input {
margin-left: var(--2px);
}
.field .link-container .list-group-item a[role="button"] {
margin-top: var(--1px);
margin-left: var(--2px);
}
.field .link-container > .list-group-item.link-with-role > a[role="button"],
.field .link-container > .list-group-item.link-with-role > div > a[role="button"] {
margin-top: var(--7px);