kopia lustrzana https://github.com/wagtail/wagtail
Add drag and drop support to InlinePanel
rodzic
1c3f84f9c2
commit
fe9409f99c
|
@ -1,4 +1,5 @@
|
|||
import $ from 'jquery';
|
||||
import Sortable from 'sortablejs';
|
||||
import { initCollapsiblePanels } from '../../includes/panels';
|
||||
import { ExpandingFormset } from '../ExpandingFormset';
|
||||
|
||||
|
@ -19,6 +20,14 @@ export class InlinePanel extends ExpandingFormset {
|
|||
super(opts.formsetPrefix, opts);
|
||||
this.formsElt = $('#' + opts.formsetPrefix + '-FORMS');
|
||||
|
||||
if (this.opts.canOrder) {
|
||||
this.sortable = Sortable.create(this.formsElt.get(0), {
|
||||
handle: '[data-inline-panel-child-drag]',
|
||||
animation: 200,
|
||||
onEnd: this.handleDragEnd.bind(this),
|
||||
});
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.formCount; i += 1) {
|
||||
const childPrefix = this.opts.emptyChildFormPrefix.replace(
|
||||
/__prefix__/g,
|
||||
|
@ -315,4 +324,24 @@ export class InlinePanel extends ExpandingFormset {
|
|||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update fields based on the current DOM order.
|
||||
*/
|
||||
updateOrderValues() {
|
||||
const forms = this.formsElt.children(':not(.deleted)');
|
||||
forms.each((index, form) => {
|
||||
const prefix = form.id.replace('inline_child_', '');
|
||||
const orderInput = $(form).find(`[name="${prefix}-ORDER"]`);
|
||||
orderInput.val(index + 1);
|
||||
});
|
||||
}
|
||||
|
||||
handleDragEnd(e) {
|
||||
const { oldIndex, newIndex } = e;
|
||||
if (oldIndex !== newIndex) {
|
||||
this.updateOrderValues();
|
||||
this.updateControlStates();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ describe('InlinePanel', () => {
|
|||
<p>Form for inline child</p>
|
||||
<button type="button" data-inline-panel-child-move-up>Move up</button>
|
||||
<button type="button" data-inline-panel-child-move-down>Move down</button>
|
||||
<button type="button" data-inline-panel-child-drag>Drag</button>
|
||||
<button type="button" id="id_${childPrefix}-DELETE-button">Delete</button>
|
||||
<input type="hidden" name="${childPrefix}-ORDER" id="id_${childPrefix}-ORDER">
|
||||
<input type="hidden" name="${childPrefix}-DELETE" id="id_${childPrefix}-DELETE">
|
||||
|
@ -116,4 +117,29 @@ describe('InlinePanel', () => {
|
|||
|
||||
expect(handleRemovedEvent).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('updates order values after drag-and-drop', () => {
|
||||
const addBtn = document.getElementById('id_person_cafe_relationship-ADD');
|
||||
addBtn.click();
|
||||
addBtn.click();
|
||||
|
||||
// Simulate drag-and-drop by manually moving an element.
|
||||
const forms = document.querySelectorAll(
|
||||
'[data-inline-panel-child]:not(.deleted)',
|
||||
);
|
||||
forms[0].parentElement.insertBefore(forms[0], forms[2]);
|
||||
panel.handleDragEnd({ oldIndex: 0, newIndex: 2 });
|
||||
|
||||
expect(
|
||||
Array.from(
|
||||
document.querySelectorAll(
|
||||
'[data-inline-panel-child]:not(.deleted) [name$="-ORDER"]',
|
||||
),
|
||||
).map((field) => [field.name, field.value]),
|
||||
).toEqual([
|
||||
['person_cafe_relationship-2-ORDER', '1'],
|
||||
['person_cafe_relationship-1-ORDER', '2'],
|
||||
['person_cafe_relationship-3-ORDER', '3'],
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
{% if can_order %}
|
||||
<button type="button" class="button button--icon text-replace white" data-inline-panel-child-move-up title="{% trans 'Move up' %}">{% icon name="arrow-up" %}</button>
|
||||
<button type="button" class="button button--icon text-replace white" data-inline-panel-child-move-down title="{% trans 'Move down' %}">{% icon name="arrow-down" %}</button>
|
||||
<button type="button" class="button button--icon text-replace white" data-inline-panel-child-drag title="{% trans 'Drag' %}">{% icon name="grip" %}</button>
|
||||
{% endif %}
|
||||
<button type="button" class="button button--icon text-replace white" id="{{ child.form.DELETE.id_for_label }}-button" title="{% trans 'Delete' %}">{% icon name="bin" %}</button>
|
||||
{% endfragment %}
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
{% fragment as header_controls %}
|
||||
<button type="button" class="button button--icon text-replace" data-inline-panel-child-move-up>{% icon name="arrow-up" %}{% trans "Move up" %}</button>
|
||||
<button type="button" class="button button--icon text-replace" data-inline-panel-child-move-down>{% icon name="arrow-down" %}{% trans "Move down" %}</button>
|
||||
<button type="button" class="button button--icon text-replace" data-inline-panel-child-drag>{% icon name="grip" %}{% trans "Drag" %}</button>
|
||||
<button type="button" class="button button--icon text-replace" id="{{ form.DELETE.id_for_label }}-button">{% icon name="bin" %}{% trans "Delete" %}</button>
|
||||
{% endfragment %}
|
||||
|
||||
|
|
Ładowanie…
Reference in New Issue