Skip to content

Commit

Permalink
Merge pull request #5664 from formio/FIO-7478-fixed-datagrid-reordering
Browse files Browse the repository at this point in the history
FIO-7478: fixed and isse where dataGrod reordering does not work in 5.x and fixed reordering with select component
  • Loading branch information
brendanbond authored and lane-formio committed Jul 24, 2024
1 parent 2b83377 commit b9542c3
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 40 deletions.
94 changes: 55 additions & 39 deletions src/components/datagrid/DataGrid.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import _ from 'lodash';
import NestedArrayComponent from '../_classes/nestedarray/NestedArrayComponent';
import { fastCloneDeep, getFocusableElements } from '../../utils/utils';
import { Components } from '../Components';
import dragula from 'dragula';

export default class DataGridComponent extends NestedArrayComponent {
static schema(...extend) {
Expand Down Expand Up @@ -332,43 +333,41 @@ export default class DataGridComponent extends NestedArrayComponent {
row.dragInfo = { index };
});

if (this.root.dragulaLib) {
this.dragula = this.root.dragulaLib([this.refs[`${this.datagridKey}-tbody`]], {
moves: (_draggedElement, _oldParent, clickedElement) => {
const clickedElementKey = clickedElement.getAttribute('data-key');
const oldParentKey = _oldParent.getAttribute('data-key');
this.dragula = dragula([this.refs[`${this.datagridKey}-tbody`]], {
moves: (_draggedElement, _oldParent, clickedElement) => {
const clickedElementKey = clickedElement.getAttribute('data-key');
const oldParentKey = _oldParent.getAttribute('data-key');

//Check if the clicked button belongs to that container, if false, it belongs to the nested container
if (oldParentKey === clickedElementKey) {
return clickedElement.classList.contains('formio-drag-button');
}
//Check if the clicked button belongs to that container, if false, it belongs to the nested container
if (oldParentKey === clickedElementKey) {
return clickedElement.classList.contains('formio-drag-button');
}
}).on('drop', this.onReorder.bind(this));
}
}).on('drop', this.onReorder.bind(this));

this.dragula.on('cloned', (el, original) => {
if (el && el.children && original && original.children) {
_.each(original.children, (child, index) => {
const styles = getComputedStyle(child, null);
this.dragula.on('cloned', (el, original) => {
if (el && el.children && original && original.children) {
_.each(original.children, (child, index) => {
const styles = getComputedStyle(child, null);

if (styles.cssText !== '') {
el.children[index].style.cssText = styles.cssText;
}
else {
const cssText = Object.values(styles).reduce(
(css, propertyName) => {
return `${css}${propertyName}:${styles.getPropertyValue(
propertyName
)};`;
},
''
);

el.children[index].style.cssText = cssText;
}
});
}
});
}
if (styles.cssText !== '') {
el.children[index].style.cssText = styles.cssText;
}
else {
const cssText = Object.values(styles).reduce(
(css, propertyName) => {
return `${css}${propertyName}:${styles.getPropertyValue(
propertyName
)};`;
},
''
);

el.children[index].style.cssText = cssText;
}
});
}
});
}

this.refs[`${this.datagridKey}-addRow`].forEach((addButton) => {
Expand Down Expand Up @@ -406,6 +405,26 @@ export default class DataGridComponent extends NestedArrayComponent {
return this.component.components;
}

/**
* Reorder values in array based on the old and new position
* @param {any} valuesArr - An array of values.
* @param {number} oldPosition - The index of the value in array before reordering.
* @param {number} newPosition - The index of the value in array after reordering.
* @param {boolean|any} movedBelow - Whether or not the value is moved below.
* @returns {void}
*/
reorderValues(valuesArr, oldPosition, newPosition, movedBelow) {
if (!_.isArray(valuesArr) || _.isEmpty(valuesArr)) {
return;
}

const draggedRowData = valuesArr[oldPosition];
//insert element at new position
valuesArr.splice(newPosition, 0, draggedRowData);
//remove element from old position (if was moved above, after insertion it's at +1 index)
valuesArr.splice(movedBelow ? oldPosition : oldPosition + 1, 1);
}

onReorder(element, _target, _source, sibling) {
if (!element.dragInfo || (sibling && !sibling.dragInfo)) {
console.warn('There is no Drag Info available for either dragged or sibling element');
Expand All @@ -417,12 +436,9 @@ export default class DataGridComponent extends NestedArrayComponent {
const newPosition = sibling ? sibling.dragInfo.index : this.dataValue.length;
const movedBelow = newPosition > oldPosition;
const dataValue = fastCloneDeep(this.dataValue);
const draggedRowData = dataValue[oldPosition];

//insert element at new position
dataValue.splice(newPosition, 0, draggedRowData);
//remove element from old position (if was moved above, after insertion it's at +1 index)
dataValue.splice(movedBelow ? oldPosition : oldPosition + 1, 1);
this.reorderValues(dataValue, oldPosition, newPosition, movedBelow);
//reorder select data
this.reorderValues(_.get(this.root, `submission.metadata.selectData.${this.path}`, []), oldPosition, newPosition, movedBelow);

//need to re-build rows to re-calculate indexes and other indexed fields for component instance (like rows for ex.)
this.setValue(dataValue, { isReordered: true });
Expand Down
51 changes: 51 additions & 0 deletions src/components/datagrid/DataGrid.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
withCollapsibleRowGroups,
withAllowCalculateOverride,
twoWithAllowCalculatedOverride, withCheckboxes,
withReorder
} from './fixtures';

describe('DataGrid Component', () => {
Expand Down Expand Up @@ -733,3 +734,53 @@ describe('DataGrid calculated values', () => {
.catch(done);
});
});

describe('DataGrid Reorder', () => {
it('Should display select components labels correctly on rows reorder', (done) => {
Formio.createForm(document.createElement('div'), withReorder.form)
.then((form) => {
form.setSubmission(withReorder.submission)
.then(() => {
const values = [
{ value: '11', label: 1 },
{ value: '22', label: 2 },
{ value: '33', label: 3 },
{ value: '44', label: 4 },
{ value: '55', label: 5 },
];

const dataGrid = form.getComponent('dataGrid');
_.each(dataGrid.components, (selectComp, ind) => {
const expectedValue = values[ind];
assert.equal(ind, selectComp.rowIndex);
assert.equal(selectComp.dataValue, expectedValue.value);
assert.equal(selectComp.templateData[expectedValue.value].data.number, expectedValue.label);
});

dataGrid.onReorder({ dragInfo: { index: 4 } }, null, null, { dragInfo: { index: 0 } });
dataGrid.onReorder({ dragInfo: { index: 4 } }, null, null, { dragInfo: { index: 1 } });
dataGrid.onReorder({ dragInfo: { index: 2 } }, null, null, { dragInfo: { index: 4 } });

setTimeout(() => {
const values = [
{ value: '55', label: 5 },
{ value: '44', label: 4 },
{ value: '22', label: 2 },
{ value: '11', label: 1 },
{ value: '33', label: 3 },
];

_.each(dataGrid.components, (selectComp, ind) => {
const expectedValue = values[ind];
assert.equal(ind, selectComp.rowIndex, 'Component index after reorder');
assert.equal(selectComp.dataValue, expectedValue.value, 'Component value after reorder');
assert.equal(selectComp.templateData[expectedValue.value].data.number, expectedValue.label, 'Component label value after reorder');
});

done();
}, 600);
});
})
.catch(done);
});
});
139 changes: 139 additions & 0 deletions src/components/datagrid/fixtures/comp-with-reorder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
const form = {
_id: '66742f4146717b98a9fa280f',
title: 'test reorder',
name: 'testReorder',
path: 'testreorder',
type: 'form',
display: 'form',
components: [
{
label: 'Data Grid',
reorder: true,
addAnotherPosition: 'bottom',
layoutFixed: false,
enableRowGroups: false,
initEmpty: false,
tableView: false,
defaultValue: [
{
select: '',
},
],
key: 'dataGrid',
type: 'datagrid',
input: true,
components: [
{
label: 'Select',
widget: 'choicesjs',
tableView: true,
dataSrc: 'resource',
data: {
resource: '66742ee946717b98a9fa1b0b',
},
dataType: 'string',
valueProperty: 'data.textField',
template: '<span>{{ item.data.number }}</span>',
validate: {
select: false,
},
key: 'select',
type: 'select',
searchField: 'data.textField__regex',
limit: 10,
noRefreshOnScroll: false,
addResource: false,
reference: false,
input: true,
},
],
},
{
type: 'button',
label: 'Submit',
key: 'submit',
disableOnInvalid: true,
input: true,
tableView: false,
},
],
created: '2024-06-20T13:31:45.177Z',
modified: '2024-06-25T10:32:46.577Z',
machineName: 'tifwklexhyrgxbr:testReorder',
};

const submission = {
form: '66742f4146717b98a9fa280f',
metadata: {
selectData: {
dataGrid: [
{
select: {
data: {
number: 1,
},
},
},
{
select: {
data: {
number: 2,
},
},
},
{
select: {
data: {
number: 3,
},
},
},
{
select: {
data: {
number: 4,
},
},
},
{
select: {
data: {
number: 5,
},
},
},
],
},
},
data: {
dataGrid: [
{
select: '11',
},
{
select: '22',
},
{
select: '33',
},
{
select: '44',
},
{
select: '55',
},
],
dataTable: [],
submit: true,
},
_id: '667ab5ee6a69739703d30def',
project: '65df46bc93bcfaa231f3db1c',
state: 'submitted',
created: '2024-06-25T12:19:58.626Z',
modified: '2024-06-25T12:19:58.627Z',
};

export default {
form,
submission,
};
3 changes: 2 additions & 1 deletion src/components/datagrid/fixtures/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,5 @@ import withCollapsibleRowGroups from './comp-with-collapsible-groups';
import withAllowCalculateOverride from './comp-with-allow-calculate-override';
import twoWithAllowCalculatedOverride from './two-comp-with-allow-calculate-override';
import withCheckboxes from './comp-with-checkboxes';
export { comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9, withCollapsibleRowGroups, withConditionalFieldsAndValidations, withDefValue, withLogic, withRowGroupsAndDefValue, modalWithRequiredFields, withAllowCalculateOverride, twoWithAllowCalculatedOverride, withCheckboxes };
import withReorder from './comp-with-reorder';
export { comp1, comp2, comp3, comp4, comp5, comp6, comp7, comp8, comp9, withCollapsibleRowGroups, withConditionalFieldsAndValidations, withDefValue, withLogic, withRowGroupsAndDefValue, modalWithRequiredFields, withAllowCalculateOverride, twoWithAllowCalculatedOverride, withCheckboxes, withReorder };

0 comments on commit b9542c3

Please sign in to comment.