Skip to content

Commit

Permalink
feat: support maxItems & minItems in Vue array renderer
Browse files Browse the repository at this point in the history
Disable add and remove buttons in Vue array renderer according to 'maxItems' and
'minItems' when the 'restrict' UI Schema option is set.

Also all array buttons are now disabled if the overall control is disabled.
  • Loading branch information
Droxx authored Jul 11, 2023
1 parent f74e9ed commit 369370a
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 2 deletions.
3 changes: 3 additions & 0 deletions packages/examples/src/examples/arrays-with-detail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ export const schema = {
occupation: { type: 'string' },
comments: {
type: 'array',
minItems: 2,
maxItems: 8,
items: {
type: 'object',
properties: {
Expand All @@ -58,6 +60,7 @@ export const uischema = {
scope: '#/properties/comments',
options: {
showSortButtons: true,
restrict: true,
detail: {
type: 'VerticalLayout',
elements: [
Expand Down
4 changes: 4 additions & 0 deletions packages/examples/src/examples/arrays-with-sorting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ export const schema = {
properties: {
comments: {
type: 'array',
minItems: 2,
maxItems: 8,
items: {
type: 'object',
properties: {
Expand Down Expand Up @@ -64,6 +66,7 @@ export const uischema = {
scope: '#/properties/comments',
options: {
showSortButtons: true,
restrict: true,
},
},
],
Expand All @@ -81,6 +84,7 @@ export const uischemaWithSorting = {
scope: '#/properties/comments',
options: {
showSortButtons: true,
restrict: true,
},
},
],
Expand Down
6 changes: 6 additions & 0 deletions packages/vue/vue-vanilla/src/array/ArrayListElement.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
</button>
<button
:disabled="!deleteEnabled"
:class="styles.arrayList.itemDelete"
type="button"
@click="deleteClicked"
Expand Down Expand Up @@ -69,6 +70,11 @@ const listItem = defineComponent({
type: Function,
default: undefined,
},
deleteEnabled: {
required: false,
type: Boolean,
default: true,
},
delete: {
required: false,
type: Function,
Expand Down
33 changes: 31 additions & 2 deletions packages/vue/vue-vanilla/src/array/ArrayListRenderer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
<button
:class="styles.arrayList.addButton"
type="button"
:disabled="
!control.enabled || (appliedOptions.restrict && maxItemsReached)
"
@click="addButtonClick"
>
+
Expand All @@ -19,9 +22,10 @@
>
<array-list-element
:move-up="moveUp(control.path, index)"
:move-up-enabled="index > 0"
:move-up-enabled="control.enabled && index > 0"
:move-down="moveDown(control.path, index)"
:move-down-enabled="index < control.data.length - 1"
:move-down-enabled="control.enabled && index < control.data.length - 1"
:delete-enabled="control.enabled && !minItemsReached"
:delete="removeItems(control.path, [index])"
:label="childLabelForIndex(index)"
:styles="styles"
Expand Down Expand Up @@ -50,6 +54,8 @@ import {
rankWith,
ControlElement,
schemaTypeIs,
Resolve,
JsonSchema,
} from '@jsonforms/core';
import { defineComponent } from 'vue';
import {
Expand Down Expand Up @@ -77,6 +83,29 @@ const controlRenderer = defineComponent({
noData(): boolean {
return !this.control.data || this.control.data.length === 0;
},
arraySchema(): JsonSchema | undefined {
return Resolve.schema(
this.schema,
this.control.uischema.scope,
this.control.rootSchema
);
},
maxItemsReached(): boolean | undefined {
return (
this.arraySchema !== undefined &&
this.arraySchema.maxItems !== undefined &&
this.control.data !== undefined &&
this.control.data.length >= this.arraySchema.maxItems
);
},
minItemsReached(): boolean | undefined {
return (
this.arraySchema !== undefined &&
this.arraySchema.minItems !== undefined &&
this.control.data !== undefined &&
this.control.data.length <= this.arraySchema.minItems
);
},
},
methods: {
composePaths,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import { mountJsonForms } from '../util';
const schema = {
type: 'array',
title: 'My Array',
maxItems: 3,
minItems: 1,
items: {
type: 'string',
},
};
const uischema = {
type: 'Control',
scope: '#',
options: {
restrict: true,
},
};

describe('ArrayListRenderer.vue', () => {
Expand All @@ -37,13 +42,30 @@ describe('ArrayListRenderer.vue', () => {
expect(wrapper.vm.data).to.deep.equal(['a', 'b', '']);
});

it('add button disabled if maxItems is reached', async () => {
const wrapper = mountJsonForms(['a', 'b'], schema, uischema);
const addButton = wrapper.find('.array-list-add');
expect(addButton.attributes().disabled).to.not.exist;
await addButton.trigger('click');
expect(addButton.attributes().disabled).to.exist;
});

it('remove element from array', async () => {
const wrapper = mountJsonForms(['a', 'b', 'c'], schema, uischema);
const deleteButtons = wrapper.findAll('.array-list-item-delete');
await deleteButtons[1].trigger('click');
expect(wrapper.vm.data).to.deep.equal(['a', 'c']);
});

it('remove button disabled if minItems is reached', async () => {
const wrapper = mountJsonForms(['a', 'b'], schema, uischema);
const deleteButtons = wrapper.findAll('.array-list-item-delete');
expect(deleteButtons[0].attributes().disabled).to.not.exist;
expect(deleteButtons[1].attributes().disabled).to.not.exist;
await deleteButtons[0].trigger('click');
expect(deleteButtons[0].attributes().disabled).to.exist;
});

it('move element up', async () => {
const wrapper = mountJsonForms(['a', 'b', 'c'], schema, uischema);
const moveUpButtons = wrapper.findAll('.array-list-item-move-up');
Expand Down

0 comments on commit 369370a

Please sign in to comment.