diff --git a/mocks/mocks/data/formio-api/select-boxes.json b/mocks/mocks/data/formio-api/select-boxes.json new file mode 100644 index 000000000..e5c1f6429 --- /dev/null +++ b/mocks/mocks/data/formio-api/select-boxes.json @@ -0,0 +1,463 @@ +{ + "_id": "666ff7af1301140a4a5a4775", + "title": "Select boxes test", + "name": "selectBoxesTest", + "path": "selectboxestest", + "type": "form", + "display": "wizard", + "tags": ["nav-skjema", ""], + "access": [ + { + "type": "read_all", + "roles": ["000000000000000000000000"] + }, + { + "type": "update_all", + "roles": ["628ca77305690db58c974d04", "628ca77305690db58c974d09"] + } + ], + "owner": "64cc9fc4739f245ce96bb79a", + "components": [ + { + "isAttachmentPanel": false, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "customConditional": "", + "title": "Selectboxes", + "key": "veiledning", + "type": "panel", + "input": false, + "components": [ + { + "validate": { + "required": true, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false + }, + "label": "Select boxes", + "key": "selectBoxes", + "values": [ + { + "label": "Choice 1", + "value": "choice1" + }, + { + "value": "choice2", + "label": "Choice 2" + }, + { + "value": "choice3", + "label": "Choice 3" + } + ], + "input": true, + "tableView": false, + "validateOn": "blur", + "type": "selectboxes", + "inputType": "checkbox", + "navId": "eyqfjt", + "id": "eynwysp", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "dataSrc": "values", + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "data": { + "url": "" + }, + "fieldSet": false, + "inline": false, + "isNavCheckboxPanel": true + }, + { + "description": "", + "additionalDescriptionText": "", + "validate": { + "required": true, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false + }, + "errors": "", + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "customConditional": "", + "label": "Select boxes with defaultValue", + "additionalDescriptionLabel": "", + "key": "selectBoxesWithDefaultValue", + "values": [ + { + "label": "Choice 1", + "value": "choice1" + }, + { + "value": "choice2", + "label": "Choice 2" + }, + { + "value": "choice3", + "label": "Choice 3" + } + ], + "input": true, + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "tableView": false, + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "blur", + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "dataSrc": "values", + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "type": "selectboxes", + "inputType": "radio", + "data": { + "url": "" + }, + "fieldSet": false, + "inline": false, + "isNavCheckboxPanel": true, + "navId": "e7fyvys", + "id": "e2jx6dw", + "defaultValue": { + "choice1": true, + "choice2": true, + "choice3": false + } + }, + { + "description": "

Normal description

", + "additionalDescriptionText": "

Extended description text

", + "validate": { + "required": true, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false, + "onlyAvailableItems": false + }, + "errors": "", + "conditional": { + "show": null, + "when": null, + "eq": "" + }, + "customConditional": "", + "label": "Select boxes with description", + "additionalDescriptionLabel": "Extended description", + "key": "selectBoxesWithDescription", + "values": [ + { + "label": "Choice 1", + "value": "choice1", + "description": "Description 1" + }, + { + "value": "choice2", + "label": "Choice 2", + "description": "Description 2" + }, + { + "value": "choice3", + "label": "Choice 3", + "description": "Description 3" + }, + { + "value": "choice4", + "label": "Choice 4", + "description": "Description 4" + }, + { + "value": "choice5", + "label": "Choice 5" + } + ], + "defaultValue": { + "choice1": false, + "choice2": false, + "choice3": false, + "choice4": false, + "choice5": false + }, + "input": true, + "tableView": false, + "validateOn": "blur", + "type": "selectboxes", + "inputType": "checkbox", + "navId": "ei4858", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "protected": false, + "unique": false, + "persistent": true, + "hidden": false, + "clearOnHide": true, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "dataSrc": "values", + "authenticate": false, + "ignoreCache": false, + "template": "{{ item.label }}", + "data": { + "url": "" + }, + "fieldSet": false, + "inline": false, + "isNavCheckboxPanel": true, + "id": "ed550ae" + } + ], + "tableView": false, + "label": "Panel", + "navId": "ez1onmr", + "placeholder": "", + "prefix": "", + "customClass": "", + "suffix": "", + "multiple": false, + "defaultValue": null, + "protected": false, + "unique": false, + "persistent": false, + "hidden": false, + "clearOnHide": false, + "refreshOn": "", + "redrawOn": "", + "modalEdit": false, + "dataGridLabel": false, + "labelPosition": "top", + "description": "", + "errorLabel": "", + "tooltip": "", + "hideLabel": false, + "tabindex": "", + "disabled": false, + "autofocus": false, + "dbIndex": false, + "customDefaultValue": "", + "calculateValue": "", + "calculateServer": false, + "widget": null, + "attributes": {}, + "validateOn": "change", + "validate": { + "required": false, + "custom": "", + "customPrivate": false, + "strictDateValidation": false, + "multiple": false, + "unique": false + }, + "overlay": { + "style": "", + "left": "", + "top": "", + "width": "", + "height": "" + }, + "allowCalculateOverride": false, + "encrypted": false, + "showCharCount": false, + "showWordCount": false, + "properties": {}, + "allowMultipleMasks": false, + "addons": [], + "tree": false, + "lazyLoad": false, + "theme": "default", + "breadcrumb": "default", + "id": "elp5mf8" + }, + { + "title": "Vedlegg", + "type": "panel", + "key": "vedlegg", + "input": false, + "theme": "default", + "isAttachmentPanel": true, + "components": [ + { + "label": "Annen dokumentasjon", + "description": "Har du noen annen dokumentasjon du ønsker å legge ved?", + "type": "attachment", + "key": "annenDokumentasjon", + "validate": { + "required": true + }, + "attachmentType": "other", + "properties": { + "vedleggstittel": "Annet", + "vedleggskode": "N6" + }, + "attachmentValues": { + "leggerVedNaa": { + "enabled": true + }, + "ettersender": { + "enabled": true + }, + "nei": { + "enabled": true + } + }, + "navId": "e30kk7e" + } + ], + "navId": "e06hdc7" + } + ], + "properties": { + "skjemanummer": "select-boxes-test", + "tema": "AGR", + "innsending": "PAPIR_OG_DIGITAL", + "ettersending": "PAPIR_OG_DIGITAL", + "signatures": [ + { + "label": "", + "description": "", + "key": "90aab859-e711-4852-bd61-5390228f0978" + } + ], + "ettersendelsesfrist": "14", + "modified": "2024-06-17T10:46:53.427Z" + }, + "project": "628ca77305690db58c974cfd", + "revisions": "", + "submissionRevisions": "", + "_vid": 0, + "submissionAccess": [], + "created": "2024-06-17T08:45:35.356Z", + "modified": "2024-06-17T10:46:53.897Z", + "machineName": "jvcemxwcpghcqjn:selectBoxesTest" +} diff --git a/mocks/mocks/data/innsending-api/select-boxes/mellomlagring-select-boxes.json b/mocks/mocks/data/innsending-api/select-boxes/mellomlagring-select-boxes.json new file mode 100644 index 000000000..13b495ebb --- /dev/null +++ b/mocks/mocks/data/innsending-api/select-boxes/mellomlagring-select-boxes.json @@ -0,0 +1,66 @@ +{ + "brukerId": "19876898104", + "skjemanr": "select-boxes-test", + "tittel": "Select boxes test", + "tema": "AGR", + "spraak": "nb", + "hoveddokument": { + "vedleggsnr": "select-boxes-test", + "tittel": "Select boxes test", + "label": "Select boxes test", + "pakrevd": true, + "mimetype": "application/pdf" + }, + "hoveddokumentVariant": { + "vedleggsnr": "select-boxes-test", + "tittel": "Select boxes test", + "label": "Select boxes test", + "pakrevd": false, + "mimetype": "application/json", + "document": { + "language": "nb-NO", + "data": { + "data": { + "selectBoxesWithDefaultValue": { + "choice1": true, + "choice2": true, + "choice3": false + }, + "selectBoxesWithDescription": { + "choice1": true, + "choice2": false, + "choice3": false, + "choice4": false, + "choice5": false + }, + "selectBoxes": { + "choice1": true, + "choice2": false, + "choice3": false + } + }, + "metadata": { + "timezone": "Europe/Oslo", + "offset": 120, + "origin": "http://localhost:3001", + "referrer": "http://localhost:3001/fyllut/selectboxestest", + "browserName": "Netscape", + "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36", + "pathName": "/fyllut/selectboxestest/veiledning", + "onLine": true + }, + "state": "submitted", + "_vnote": "" + } + } + }, + "innsendingsId": "e5a341ee-810d-4138-9550-b96d5c307cb6", + "status": "Opprettet", + "vedleggsListe": [], + "kanLasteOppAnnet": true, + "fristForEttersendelse": 14, + "endretDato": "2024-06-17T13:21:09.17675+02:00", + "skalSlettesDato": "2024-07-15T11:21:09.166405Z", + "skjemaPath": "selectboxestest", + "visningsType": "fyllUt" +} diff --git a/mocks/mocks/routes/formio-api.js b/mocks/mocks/routes/formio-api.js index 43d57df15..40cc16eb9 100644 --- a/mocks/mocks/routes/formio-api.js +++ b/mocks/mocks/routes/formio-api.js @@ -31,6 +31,7 @@ const formAccordion = require('../data/formio-api/accordion.json'); const checkboxForm = require('../data/formio-api/custom-components-checkbox.json'); const hiddenConditionalForm = require('../data/formio-api/hidden-conditional.json'); const radioForm = require('../data/formio-api/radio.json'); +const selectBoxesForm = require('../data/formio-api/select-boxes.json'); const allForms = [ { form: formCypress101, translations: translationsCypress101 }, @@ -59,6 +60,7 @@ const allForms = [ { form: checkboxForm, translations: undefined }, { form: hiddenConditionalForm, translations: undefined }, { form: radioForm, translations: undefined }, + { form: selectBoxesForm, translations: undefined }, ]; const findTestdata = (formPath) => allForms.find((testdata) => testdata.form.path === formPath); diff --git a/mocks/mocks/routes/innsending-api.js b/mocks/mocks/routes/innsending-api.js index 82750def1..95bfbeb51 100644 --- a/mocks/mocks/routes/innsending-api.js +++ b/mocks/mocks/routes/innsending-api.js @@ -22,6 +22,7 @@ const mellomlagringDrivingListNoDates = require('../data/innsending-api/driving- const mellomlagringCheckbox = require('../data/innsending-api/checkbox/mellomlagring-checkbox.json'); const activitesFuture = require('../data/innsending-api/activities/activities-future.json'); const prefillData = require('../data/innsending-api/prefill-data/prefill-data.json'); +const mellomlagringSelectBoxes = require('../data/innsending-api/select-boxes/mellomlagring-select-boxes.json'); const objectToByteArray = (obj) => Array.from(new TextEncoder().encode(JSON.stringify(obj))); @@ -208,6 +209,14 @@ module.exports = [ body: convertToInnsendingApiResponse(mellomlagringCheckbox), }, }, + { + id: 'success-select-boxes', + type: 'json', + options: { + status: 200, + body: convertToInnsendingApiResponse(mellomlagringSelectBoxes), + }, + }, { id: 'container123-complete', type: 'json', diff --git a/packages/bygger/cypress/e2e/form-builder.spec.cy.ts b/packages/bygger/cypress/e2e/form-builder.spec.cy.ts index cac0fecda..2838103e9 100644 --- a/packages/bygger/cypress/e2e/form-builder.spec.cy.ts +++ b/packages/bygger/cypress/e2e/form-builder.spec.cy.ts @@ -153,7 +153,7 @@ describe('Form Builder', () => { cy.get('div').contains('"label": "Flervalg"').click({ force: true }); cy.focused().type('{end}{leftArrow}{leftArrow} (endret)', { force: true }); cy.get('[data-testid="editorSaveButton"]').click(); - cy.get('label').contains('Flervalg (endret)'); + cy.findByRole('group', { name: 'Flervalg (endret)' }).should('exist'); }); // TODO: Add test for radio group when it gets the new data values. diff --git a/packages/fyllut/cypress/e2e/components/select-boxes.cy.ts b/packages/fyllut/cypress/e2e/components/select-boxes.cy.ts new file mode 100644 index 000000000..0455d11b8 --- /dev/null +++ b/packages/fyllut/cypress/e2e/components/select-boxes.cy.ts @@ -0,0 +1,148 @@ +/* + * Tests that the select boxes component (react) renders and functions correctly + */ + +import { TEXTS } from '@navikt/skjemadigitalisering-shared-domain'; +import { expect } from 'chai'; + +describe('Select boxes', () => { + before(() => { + cy.configMocksServer(); + }); + + after(() => { + cy.mocksRestoreRouteVariants(); + }); + + describe('Paper', () => { + beforeEach(() => { + cy.defaultIntercepts(); + cy.visit('/fyllut/selectboxestest/selectBoxes?sub=paper'); + cy.defaultWaits(); + }); + + it('should check 2 select boxes and show correct values in summary', () => { + cy.findByRole('group', { name: 'Select boxes' }).within(() => { + cy.findByRole('checkbox', { name: 'Choice 1' }).check(); + }); + + cy.findByRole('group', { name: 'Select boxes with description' }).within(() => { + cy.findByRole('checkbox', { name: 'Choice 2 Description 2' }).check(); + }); + + cy.clickNextStep(); + + cy.findByRole('radio', { name: 'Jeg legger det ved dette skjemaet' }).check(); + + cy.clickNextStep(); + + // Summary + cy.get('dl') + .first() + .within(() => { + // Select boxes + cy.get('li').eq(0).should('contain.text', 'Choice 1'); + + // Select boxes with defaultValue + cy.get('li').eq(1).should('contain.text', 'Choice 1'); + cy.get('li').eq(2).should('contain.text', 'Choice 2'); + + // Select boxes with description + cy.get('li').eq(3).should('contain.text', 'Choice 2'); + }); + }); + + it('should show error for required select boxes', () => { + cy.clickNextStep(); + + // Error summary + cy.findByRole('region', { name: TEXTS.validering.error }) + .should('exist') + .within(() => { + cy.findByRole('link', { name: 'Du må fylle ut: Select boxes' }).should('exist'); + }); + + // Component error + cy.findAllByText('Du må fylle ut: Select boxes').should('have.length', 2); + }); + + it('should show description', () => { + cy.findByText('Normal description').should('exist'); + cy.findByRole('button', { name: 'Extended description' }).should('exist'); + cy.findByRole('button', { name: 'Extended description' }).click(); + cy.findByText('Extended description text').should('exist'); + }); + }); + + describe('Digital', () => { + it('should have correct submission values', () => { + cy.defaultIntercepts(); + cy.visit('/fyllut/selectboxestest/selectBoxes?sub=digital'); + cy.defaultWaits(); + + cy.findByRole('group', { name: 'Select boxes' }).within(() => { + cy.findByRole('checkbox', { name: 'Choice 3' }).check(); + }); + + cy.findByRole('group', { name: 'Select boxes with description' }).within(() => { + cy.findByRole('checkbox', { name: 'Choice 4 Description 4' }).check(); + }); + + cy.clickSaveAndContinue(); + + cy.submitMellomlagring((req) => { + const { + submission: { data }, + } = req.body; + + // Select boxes + expect(data.selectBoxes.choice1).to.equal(false); + expect(data.selectBoxes.choice2).to.equal(false); + expect(data.selectBoxes.choice3).to.equal(true); + + // Select boxes with defaultValue + expect(data.selectBoxesWithDefaultValue.choice1).to.equal(true); + expect(data.selectBoxesWithDefaultValue.choice2).to.equal(true); + expect(data.selectBoxesWithDefaultValue.choice3).to.equal(false); + + // Select boxes with description + expect(data.selectBoxesWithDescription.choice1).to.equal(false); + expect(data.selectBoxesWithDescription.choice2).to.equal(false); + expect(data.selectBoxesWithDescription.choice3).to.equal(false); + expect(data.selectBoxesWithDescription.choice4).to.equal(true); + expect(data.selectBoxesWithDescription.choice5).to.equal(false); + }); + + cy.clickSaveAndContinue(); + cy.wait('@submitMellomlagring'); + }); + + it('should load mellomlagring', () => { + cy.mocksUseRouteVariant('get-soknad:success-select-boxes'); + + cy.defaultIntercepts(); + cy.visit('/fyllut/selectboxestest/selectBoxes?sub=digital&innsendingsId=e5a341ee-810d-4138-9550-b96d5c307cb6'); + cy.defaultWaits(); + + cy.findByRole('group', { name: 'Select boxes' }).within(() => { + cy.findByRole('checkbox', { name: 'Choice 1' }).should('be.checked'); + cy.findByRole('checkbox', { name: 'Choice 2' }).should('not.be.checked'); + cy.findByRole('checkbox', { name: 'Choice 3' }).should('not.be.checked'); + }); + + cy.findByRole('group', { name: 'Select boxes with defaultValue' }).within(() => { + cy.findByRole('checkbox', { name: 'Choice 1' }).should('be.checked'); + cy.findByRole('checkbox', { name: 'Choice 2' }).should('be.checked'); + cy.findByRole('checkbox', { name: 'Choice 3' }).should('not.be.checked'); + }); + + cy.findByRole('group', { name: 'Select boxes with description' }).within(() => { + cy.findByRole('checkbox', { name: 'Choice 1 Description 1' }).should('be.checked'); + cy.findByRole('checkbox', { name: 'Choice 2 Description 2' }).should('not.be.checked'); + cy.findByRole('checkbox', { name: 'Choice 3 Description 3' }).should('not.be.checked'); + cy.findByRole('checkbox', { name: 'Choice 4 Description 4' }).should('not.be.checked'); + cy.findByRole('checkbox', { name: 'Choice 5' }).should('not.be.checked'); + }); + }); + }); +}); diff --git a/packages/shared-components/src/formio/components/base/editForm/data/editFormValues.ts b/packages/shared-components/src/formio/components/base/editForm/data/editFormValues.ts index ebb96c817..f136083f0 100644 --- a/packages/shared-components/src/formio/components/base/editForm/data/editFormValues.ts +++ b/packages/shared-components/src/formio/components/base/editForm/data/editFormValues.ts @@ -3,10 +3,11 @@ import editFormValuesGrid from '../shared/editFormValuesGrid'; interface Options { withDescription?: boolean; + minLength?: number; } -const editFormValues = (options: Options = { withDescription: false }): Component => ({ - ...editFormValuesGrid({ withDescription: options.withDescription }), +const editFormValues = (options: Options = { withDescription: false, minLength: 1 }): Component => ({ + ...editFormValuesGrid({ withDescription: options.withDescription, minLength: options.minLength }), key: 'values', }); diff --git a/packages/shared-components/src/formio/components/base/editForm/shared/editFormValuesGrid.ts b/packages/shared-components/src/formio/components/base/editForm/shared/editFormValuesGrid.ts index 7e9fa0972..2966b6f73 100644 --- a/packages/shared-components/src/formio/components/base/editForm/shared/editFormValuesGrid.ts +++ b/packages/shared-components/src/formio/components/base/editForm/shared/editFormValuesGrid.ts @@ -1,10 +1,13 @@ import { Component } from '@navikt/skjemadigitalisering-shared-domain'; +// withDescription: Adds description textfield to the datagrid +// minLength: Minimum number of rows in the datagrid (will hide delete button until this number of rows is reached) interface Options { withDescription?: boolean; + minLength?: number; } -const editFormValuesGrid = (options: Options = { withDescription: false }): Component => { +const editFormValuesGrid = (options: Options = { withDescription: false, minLength: 1 }): Component => { const description = { label: 'Beskrivelse', key: 'description', @@ -20,6 +23,9 @@ const editFormValuesGrid = (options: Options = { withDescription: false }): Comp type: 'datagrid', label: 'Dataverdier', reorder: true, + validate: { + minLength: options.minLength, + }, components: [ { label: 'Ledetekst', diff --git a/packages/shared-components/src/formio/components/base/index.d.ts b/packages/shared-components/src/formio/components/base/index.d.ts index 36aab7d5d..4711854f3 100644 --- a/packages/shared-components/src/formio/components/base/index.d.ts +++ b/packages/shared-components/src/formio/components/base/index.d.ts @@ -70,6 +70,7 @@ interface ReactComponentType { addFocusBlurEvents(element): void; labelIsHidden(): boolean; setCustomValidity(messages: string | string[], dirty?: boolean, external?: boolean): void; + isEmpty(value?: any): boolean; // Element id?: any; emit(event: string, data: Object): void; diff --git a/packages/shared-components/src/formio/components/core/select-boxes/SelectBoxes.form.ts b/packages/shared-components/src/formio/components/core/select-boxes/SelectBoxes.form.ts index 3db15ec79..6bd3269df 100644 --- a/packages/shared-components/src/formio/components/core/select-boxes/SelectBoxes.form.ts +++ b/packages/shared-components/src/formio/components/core/select-boxes/SelectBoxes.form.ts @@ -16,7 +16,7 @@ const selectBoxesForm = (componentType: string) => { editFormDisplay.additionalDescription(), ]), data([ - editFormData.values(), + editFormData.values({withDescription: true, minLength: 2}), editFormData.defaultValue(componentType), ]), validation([ diff --git a/packages/shared-components/src/formio/components/core/select-boxes/SelectBoxes.ts b/packages/shared-components/src/formio/components/core/select-boxes/SelectBoxes.ts deleted file mode 100644 index 3e6ed8820..000000000 --- a/packages/shared-components/src/formio/components/core/select-boxes/SelectBoxes.ts +++ /dev/null @@ -1,75 +0,0 @@ -import FormioSelectBoxes from 'formiojs/components/selectboxes/SelectBoxes'; -import selectBoxesBuilder from './SelectBoxes.builder'; -import selectBoxesForm from './SelectBoxes.form'; - -class SelectBoxes extends FormioSelectBoxes { - static schema() { - return FormioSelectBoxes.schema({ - label: 'Flervalg', - type: 'selectboxes', - key: 'selectboxes', - fieldSize: 'input--xxl', - isNavCheckboxPanel: true, - }); - } - - static editForm() { - return selectBoxesForm(SelectBoxes.schema().type); - } - - static get builderInfo() { - return selectBoxesBuilder(); - } - - toggleChecked(event) { - if (event.target.checked) { - event.target.setAttribute('checked', 'checked'); - } else { - event.target.removeAttribute('checked'); - } - event.target.setAttribute('aria-checked', event.target.checked); - } - - onFocusedInput() { - // @ts-ignore - this.refs.wrapper.forEach((wrapper) => { - if (wrapper.contains(document.activeElement)) { - wrapper.classList.add('inputPanel--focused'); - } - }); - } - - onBlurredInput() { - // @ts-ignore - this.refs.wrapper.forEach((wrapper) => { - if (!wrapper.contains(document.activeElement)) { - wrapper.classList.remove('inputPanel--focused'); - } - }); - } - - attach(element) { - super.attach(element); - // @ts-ignore - this.refs.input.forEach((input) => { - input.addEventListener('change', this.toggleChecked); - input.addEventListener('focus', () => this.onFocusedInput()); - input.addEventListener('blur', () => this.onBlurredInput()); - }); - } - - detach(element) { - // @ts-ignore - if (element && this.refs.input) { - // @ts-ignore - this.refs.input.forEach((input) => { - input.removeEventListener('change', this.toggleChecked); - input.removeEventListener('focus', () => this.onFocusedInput()); - input.removeEventListener('blur', () => this.onBlurredInput()); - }); - } - super.detach(element); - } -} - -export default SelectBoxes; diff --git a/packages/shared-components/src/formio/components/core/select-boxes/SelectBoxes.tsx b/packages/shared-components/src/formio/components/core/select-boxes/SelectBoxes.tsx new file mode 100644 index 000000000..b32d3c7ee --- /dev/null +++ b/packages/shared-components/src/formio/components/core/select-boxes/SelectBoxes.tsx @@ -0,0 +1,76 @@ +import { Checkbox, CheckboxGroup } from '@navikt/ds-react'; +import FormioSelectBoxes from 'formiojs/components/selectboxes/SelectBoxes'; +import BaseComponent from '../../base/BaseComponent'; +import selectBoxesBuilder from './SelectBoxes.builder'; +import selectBoxesForm from './SelectBoxes.form'; + +class SelectBoxes extends BaseComponent { + static schema() { + return FormioSelectBoxes.schema({ + label: 'Flervalg', + type: 'selectboxes', + key: 'selectboxes', + }); + } + + static editForm() { + return selectBoxesForm(SelectBoxes.schema().type); + } + + static get builderInfo() { + return selectBoxesBuilder(); + } + + // Submission value is an object + convertToObject(values: string[]): Record { + const componentValues = this.component?.values ?? []; + return componentValues.reduce((acc, { value }) => ({ ...acc, [value]: values.includes(value) }), {}); + } + + // Aksel component value is an array + convertToArray(values: Record): string[] { + if (!values) return []; + return Object.entries(values) + .filter(([, value]) => value === true) + .map(([key]) => key); + } + + changeHandler(values: string[]) { + super.handleChange(this.convertToObject(values)); + this.rerender(); + } + + // Only empty if the values are all false + override isEmpty(value = this.dataValue) { + if (!value) return true; + return !Object.values(value).some(Boolean); + } + + renderReact(element) { + const values = this.component!.values ?? []; + + const componentValue = this.convertToArray(this.getValue()); + + return element.render( + this.changeHandler(value)} + ref={(ref) => this.setReactInstance(ref)} + className={this.getClassName()} + readOnly={this.getReadOnly()} + error={this.getError()} + tabIndex={-1} + > + {values.map((obj, index, arr) => ( + + {this.translate(obj.label)} + + ))} + , + ); + } +} + +export default SelectBoxes; diff --git a/packages/shared-components/src/formio/template/templates/navdesign/field/form.ejs b/packages/shared-components/src/formio/template/templates/navdesign/field/form.ejs index 927743515..4c3e5f623 100644 --- a/packages/shared-components/src/formio/template/templates/navdesign/field/form.ejs +++ b/packages/shared-components/src/formio/template/templates/navdesign/field/form.ejs @@ -1,15 +1,15 @@ -{% if (ctx.component.type === "textfield" || ctx.component.type === "textarea" || ctx.component.type === "orgNr" || ctx.component.type === "bankAccount" || ctx.component.type === "htmlelement" || ctx.component.type === "radiopanel" || ctx.component.type === "attachment" || ctx.component.type === "email" || ctx.component.type === "activities" || ctx.component.type === "accordion" || ctx.component.type === "navDatepicker" || ctx.component.type === "navCheckbox" || ctx.component.type === "number" || ctx.component.type === "currency" || ctx.component.type === "phoneNumber") { %} +{% if (ctx.component.type === "textfield" || ctx.component.type === "textarea" || ctx.component.type === "orgNr" || ctx.component.type === "bankAccount" || ctx.component.type === "htmlelement" || ctx.component.type === "radiopanel" || ctx.component.type === "attachment" || ctx.component.type === "email" || ctx.component.type === "activities" || ctx.component.type === "accordion" || ctx.component.type === "navDatepicker" || ctx.component.type === "navCheckbox" || ctx.component.type === "number" || ctx.component.type === "currency" || ctx.component.type === "phoneNumber" || ctx.component.type === "selectboxes") { %} {{ctx.element}} {% } else { %} {% if (ctx.component.description && ctx.component.type !== "datagrid" && ctx.component.descriptionPosition === "above") { %}
{{ctx.t(ctx.component.description, { _userInput: true })}}
{% } %} - {% if (ctx.component.label && ((ctx.builder || !ctx.component.hideLabel) && ctx.component.type !== "radio" && ctx.component.type !== "container" && ctx.component.type !== "alertstripe" && ctx.component.type !== "selectboxes" && ctx.component.type !== "navCheckbox" && ctx.component.type !== "datagrid" && ctx.component.type !== "navSkjemagruppe" && !ctx.component.isNavCheckboxPanel)) { %} + {% if (ctx.component.label && ((ctx.builder || !ctx.component.hideLabel) && ctx.component.type !== "radio" && ctx.component.type !== "container" && ctx.component.type !== "alertstripe" && ctx.component.type !== "selectboxes" && ctx.component.type !== "navCheckbox" && ctx.component.type !== "datagrid" && ctx.component.type !== "navSkjemagruppe" )) { %} {{ ctx.labelMarkup }} {% } %} - {% if (ctx.component.description && ctx.component.type !== "radio" && ctx.component.type !== "selectboxes" && ctx.component.type !== "datagrid" && !ctx.component.isNavCheckboxPanel && ctx.component.descriptionPosition !== "above" && (ctx.component.type !== "navCheckbox" || !ctx.component.descriptionPosition)) { %} + {% if (ctx.component.description && ctx.component.type !== "radio" && ctx.component.type !== "selectboxes" && ctx.component.type !== "datagrid" && ctx.component.descriptionPosition !== "above" && (ctx.component.type !== "navCheckbox" || !ctx.component.descriptionPosition)) { %}
{{ctx.t(ctx.component.description, { _userInput: true })}}
{% } %} diff --git a/packages/shared-domain/src/form/index.ts b/packages/shared-domain/src/form/index.ts index 85a2a47b5..37bf0a2d4 100644 --- a/packages/shared-domain/src/form/index.ts +++ b/packages/shared-domain/src/form/index.ts @@ -218,6 +218,7 @@ export interface ComponentValidate { patternMessage?: string; min?: number; max?: number; + minLength?: number; maxLength?: number; }