diff --git a/docs/building-a-form/available-form-features-and-usage-guidelines.md b/docs/building-a-form/available-form-features-and-usage-guidelines.md
index e714e8d..45249de 100644
--- a/docs/building-a-form/available-form-features-and-usage-guidelines.md
+++ b/docs/building-a-form/available-form-features-and-usage-guidelines.md
@@ -419,7 +419,17 @@ For the code implementation, see the [`review` folder](../../src/js/review).
### Required checkbox before form submission
-Use this feature to require a user to indicate they have read terms and conditions, a privacy policy, or any other text before submitting your form. This includes a checkbox and short-form text that can include relevant links to more verbose text on separate pages on your site.
+Use this feature to require a user to indicate they have read terms and conditions, a privacy policy, or any other text before submitting your form. It includes a checkbox and short-form text that can include relevant links to more verbose information on separate pages on your site. To configure this feature, place a `preSubmitInfo` object in the `formConfig`:
+
+```js
+preSubmitInfo: {
+ notice: '
Note: According to federal law, there are criminal penalties, including a fine and/or imprisonment for up to 5 years, for withholding information or for providing incorrect information. (See 18 U.S.C. 1001)
',
+ required: true, // when false, the notice is shown without a checkbox
+ field: 'privacyAgreementAccepted', // name of the field in submitted data
+ label: 'I have read and accept the privacy policy.',
+ error: 'You must accept the privacy policy before continuing',
+}
+```
![Required checkbox before form submission](https://raw.githubusercontent.com/wiki/usds/us-forms-system/images/Required-Checkbox.jpg)
diff --git a/lib/js/actions.js b/lib/js/actions.js
index d6f6dde..0e6ef56 100644
--- a/lib/js/actions.js
+++ b/lib/js/actions.js
@@ -3,13 +3,13 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
-exports.CLOSE_REVIEW_CHAPTER = exports.OPEN_REVIEW_CHAPTER = exports.SET_SUBMITTED = exports.SET_SUBMISSION = exports.SET_PRIVACY_AGREEMENT = exports.SET_VIEWED_PAGES = exports.SET_DATA = exports.SET_EDIT_MODE = undefined;
+exports.CLOSE_REVIEW_CHAPTER = exports.OPEN_REVIEW_CHAPTER = exports.SET_SUBMITTED = exports.SET_SUBMISSION = exports.SET_PRE_SUBMIT = exports.SET_VIEWED_PAGES = exports.SET_DATA = exports.SET_EDIT_MODE = undefined;
exports.closeReviewChapter = closeReviewChapter;
exports.openReviewChapter = openReviewChapter;
exports.setData = setData;
exports.setEditMode = setEditMode;
exports.setSubmission = setSubmission;
-exports.setPrivacyAgreement = setPrivacyAgreement;
+exports.setPreSubmit = setPreSubmit;
exports.setSubmitted = setSubmitted;
exports.setViewedPages = setViewedPages;
exports.submitForm = submitForm;
@@ -36,7 +36,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
var SET_EDIT_MODE = exports.SET_EDIT_MODE = 'SET_EDIT_MODE';
var SET_DATA = exports.SET_DATA = 'SET_DATA';
var SET_VIEWED_PAGES = exports.SET_VIEWED_PAGES = 'SET_VIEWED_PAGES';
-var SET_PRIVACY_AGREEMENT = exports.SET_PRIVACY_AGREEMENT = 'SET_PRIVACY_AGREEMENT';
+var SET_PRE_SUBMIT = exports.SET_PRE_SUBMIT = 'SET_PRE_SUBMIT';
var SET_SUBMISSION = exports.SET_SUBMISSION = 'SET_SUBMISSION';
var SET_SUBMITTED = exports.SET_SUBMITTED = 'SET_SUBMITTED';
var OPEN_REVIEW_CHAPTER = exports.OPEN_REVIEW_CHAPTER = 'OPEN_REVIEW_CHAPTER';
@@ -90,10 +90,11 @@ function setSubmission(field, value) {
};
}
-function setPrivacyAgreement(privacyAgreementAccepted) {
+function setPreSubmit(preSubmitField, preSubmitAccepted) {
return {
- type: SET_PRIVACY_AGREEMENT,
- privacyAgreementAccepted: privacyAgreementAccepted
+ type: SET_PRE_SUBMIT,
+ preSubmitField: preSubmitField,
+ preSubmitAccepted: preSubmitAccepted
};
}
diff --git a/lib/js/actions.js.map b/lib/js/actions.js.map
index d68b655..a672268 100644
--- a/lib/js/actions.js.map
+++ b/lib/js/actions.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../../src/js/actions.js"],"names":["closeReviewChapter","openReviewChapter","setData","setEditMode","setSubmission","setPrivacyAgreement","setSubmitted","setViewedPages","submitForm","uploadFile","SET_EDIT_MODE","SET_DATA","SET_VIEWED_PAGES","SET_PRIVACY_AGREEMENT","SET_SUBMISSION","SET_SUBMITTED","OPEN_REVIEW_CHAPTER","CLOSE_REVIEW_CHAPTER","closedChapter","pageKeys","type","openedChapter","data","page","edit","index","field","value","extra","privacyAgreementAccepted","response","submitToUrl","body","submitUrl","trackingPrefix","Promise","resolve","reject","req","XMLHttpRequest","open","addEventListener","status","event","responseBody","responseText","results","JSON","parse","error","Error","statusText","parseInt","getResponseHeader","setRequestHeader","userToken","_","get","window","send","formConfig","form","captureError","errorType","Raven","captureException","fingerprint","message","startsWith","dispatch","promise","submit","transformForSubmit","then","resp","catch","errorReceived","errorMessage","String","file","uiOptions","onProgress","onChange","onError","getState","size","maxSize","name","minSize","fileTypes","some","toLowerCase","endsWith","fileType","uploading","payload","createPayload","formId","fileUploadUrl","fileData","parseResponse","moment","unix","captureMessage","upload","evt","lengthComputable","loaded","total"],"mappings":"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","file":"actions.js","sourcesContent":["import Raven from 'raven-js';\nimport moment from 'moment';\nimport _ from './utilities/data';\nimport { transformForSubmit, recordEvent } from './helpers';\nimport { timeFromNow } from './utilities/date';\n\nexport const SET_EDIT_MODE = 'SET_EDIT_MODE';\nexport const SET_DATA = 'SET_DATA';\nexport const SET_VIEWED_PAGES = 'SET_VIEWED_PAGES';\nexport const SET_PRIVACY_AGREEMENT = 'SET_PRIVACY_AGREEMENT';\nexport const SET_SUBMISSION = 'SET_SUBMISSION';\nexport const SET_SUBMITTED = 'SET_SUBMITTED';\nexport const OPEN_REVIEW_CHAPTER = 'OPEN_REVIEW_CHAPTER';\nexport const CLOSE_REVIEW_CHAPTER = 'CLOSE_REVIEW_CHAPTER';\n\nexport function closeReviewChapter(closedChapter, pageKeys = []) {\n return {\n type: CLOSE_REVIEW_CHAPTER,\n closedChapter,\n pageKeys\n };\n}\n\nexport function openReviewChapter(openedChapter) {\n return {\n type: OPEN_REVIEW_CHAPTER,\n openedChapter\n };\n}\n\nexport function setData(data) {\n return {\n type: SET_DATA,\n data\n };\n}\n\nexport function setEditMode(page, edit, index = null) {\n return {\n type: SET_EDIT_MODE,\n edit,\n page,\n index\n };\n}\n\n// extra is used to pass other information (from a submission error or anything else)\n// into the submission state object\nexport function setSubmission(field, value, extra = null) {\n return {\n type: SET_SUBMISSION,\n field,\n value,\n extra\n };\n}\n\nexport function setPrivacyAgreement(privacyAgreementAccepted) {\n return {\n type: SET_PRIVACY_AGREEMENT,\n privacyAgreementAccepted\n };\n}\n\nexport function setSubmitted(response) {\n return {\n type: SET_SUBMITTED,\n response: typeof response.data !== 'undefined' ? response.data : response\n };\n}\n\n\nexport function setViewedPages(pageKeys) {\n return {\n type: SET_VIEWED_PAGES,\n pageKeys\n };\n}\n\nfunction submitToUrl(body, submitUrl, trackingPrefix) {\n return new Promise((resolve, reject) => {\n const req = new XMLHttpRequest();\n req.open('POST', submitUrl);\n req.addEventListener('load', () => {\n if (req.status >= 200 && req.status < 300) {\n recordEvent({\n event: `${trackingPrefix}-submission-successful`,\n });\n // got this from the fetch polyfill, keeping it to be safe\n const responseBody = 'response' in req ? req.response : req.responseText;\n const results = JSON.parse(responseBody);\n resolve(results);\n } else {\n let error;\n if (req.status === 429) {\n error = new Error(`vets_throttled_error: ${req.statusText}`);\n error.extra = parseInt(req.getResponseHeader('x-ratelimit-reset'), 10);\n } else {\n error = new Error(`vets_server_error: ${req.statusText}`);\n }\n error.statusText = req.statusText;\n reject(error);\n }\n });\n\n req.addEventListener('error', () => {\n const error = new Error('vets_client_error: Network request failed');\n error.statusText = req.statusText;\n reject(error);\n });\n\n req.addEventListener('abort', () => {\n const error = new Error('vets_client_error: Request aborted');\n error.statusText = req.statusText;\n reject(error);\n });\n\n req.addEventListener('timeout', () => {\n const error = new Error('vets_client_error: Request timed out');\n error.statusText = req.statusText;\n reject(error);\n });\n\n req.setRequestHeader('X-Key-Inflection', 'camel');\n req.setRequestHeader('Content-Type', 'application/json');\n\n const userToken = _.get('sessionStorage.userToken', window);\n if (userToken) {\n req.setRequestHeader('Authorization', `Token token=${userToken}`);\n }\n\n req.send(body);\n });\n}\n\nexport function submitForm(formConfig, form) {\n const captureError = (error, errorType) => {\n Raven.captureException(error, {\n fingerprint: [formConfig.trackingPrefix, error.message],\n extra: {\n errorType,\n statusText: error.statusText\n }\n });\n recordEvent({\n event: `${formConfig.trackingPrefix}-submission-failed${errorType.startsWith('client') ? '-client' : ''}`,\n });\n };\n\n return dispatch => {\n dispatch(setSubmission('status', 'submitPending'));\n recordEvent({\n event: `${formConfig.trackingPrefix}-submission`,\n });\n\n let promise;\n if (formConfig.submit) {\n promise = formConfig.submit(form, formConfig);\n } else {\n const body = formConfig.transformForSubmit\n ? formConfig.transformForSubmit(formConfig, form)\n : transformForSubmit(formConfig, form);\n\n promise = submitToUrl(body, formConfig.submitUrl, formConfig.trackingPrefix);\n }\n\n return promise\n .then(resp => dispatch(setSubmitted(resp)))\n .catch(errorReceived => {\n // overly cautious\n const error = errorReceived instanceof Error ? errorReceived : new Error(errorReceived);\n const errorMessage = String(error.message);\n let errorType = 'clientError';\n if (errorMessage.startsWith('vets_throttled_error')) {\n errorType = 'throttledError';\n } else if (errorMessage.startsWith('vets_server_error')) {\n errorType = 'serverError';\n }\n captureError(error, errorType);\n dispatch(setSubmission('status', errorType, error.extra));\n });\n };\n}\n\nexport function uploadFile(file, uiOptions, onProgress, onChange, onError) {\n return (dispatch, getState) => {\n if (file.size > uiOptions.maxSize) {\n onChange({\n name: file.name,\n errorMessage: 'File is too large to be uploaded'\n });\n\n onError();\n return null;\n }\n\n if (file.size < uiOptions.minSize) {\n onChange({\n name: file.name,\n errorMessage: 'File is too small to be uploaded'\n });\n\n onError();\n return null;\n }\n\n // we limit file types, but it’s not respected on mobile and desktop\n // users can bypass it without much effort\n if (!uiOptions.fileTypes.some(fileType => file.name.toLowerCase().endsWith(fileType.toLowerCase()))) {\n onChange({\n name: file.name,\n errorMessage: 'File is not one of the allowed types'\n });\n\n onError();\n return null;\n }\n\n onChange({\n name: file.name,\n uploading: true\n });\n\n const payload = uiOptions.createPayload(file, getState().form.formId);\n\n const req = new XMLHttpRequest();\n\n req.open('POST', uiOptions.fileUploadUrl);\n req.addEventListener('load', () => {\n if (req.status >= 200 && req.status < 300) {\n const body = 'response' in req ? req.response : req.responseText;\n const fileData = uiOptions.parseResponse(JSON.parse(body), file);\n onChange(fileData);\n } else {\n let errorMessage = req.statusText;\n if (req.status === 429) {\n errorMessage = `You’ve reached the limit for the number of submissions we can accept at this time. Please try again in ${timeFromNow(moment.unix(parseInt(req.getResponseHeader('x-ratelimit-reset'), 10)))}.`;\n }\n\n onChange({\n name: file.name,\n errorMessage\n });\n Raven.captureMessage(`vets_upload_error: ${req.statusText}`);\n onError();\n }\n });\n\n req.addEventListener('error', () => {\n const errorMessage = 'Network request failed';\n onChange({\n name: file.name,\n errorMessage\n });\n Raven.captureMessage(`vets_upload_error: ${errorMessage}`, {\n extra: {\n statusText: req.statusText\n }\n });\n onError();\n });\n\n req.upload.addEventListener('progress', (evt) => {\n if (evt.lengthComputable && onProgress) {\n // setting this at 80, because there's some time after we get to 100%\n // where the backend is uploading to s3\n onProgress((evt.loaded / evt.total) * 80);\n }\n });\n\n req.setRequestHeader('X-Key-Inflection', 'camel');\n req.send(payload);\n\n return req;\n };\n}\n"]}
\ No newline at end of file
+{"version":3,"sources":["../../src/js/actions.js"],"names":["closeReviewChapter","openReviewChapter","setData","setEditMode","setSubmission","setPreSubmit","setSubmitted","setViewedPages","submitForm","uploadFile","SET_EDIT_MODE","SET_DATA","SET_VIEWED_PAGES","SET_PRE_SUBMIT","SET_SUBMISSION","SET_SUBMITTED","OPEN_REVIEW_CHAPTER","CLOSE_REVIEW_CHAPTER","closedChapter","pageKeys","type","openedChapter","data","page","edit","index","field","value","extra","preSubmitField","preSubmitAccepted","response","submitToUrl","body","submitUrl","trackingPrefix","Promise","resolve","reject","req","XMLHttpRequest","open","addEventListener","status","event","responseBody","responseText","results","JSON","parse","error","Error","statusText","parseInt","getResponseHeader","setRequestHeader","userToken","_","get","window","send","formConfig","form","captureError","errorType","Raven","captureException","fingerprint","message","startsWith","dispatch","promise","submit","transformForSubmit","then","resp","catch","errorReceived","errorMessage","String","file","uiOptions","onProgress","onChange","onError","getState","size","maxSize","name","minSize","fileTypes","some","toLowerCase","endsWith","fileType","uploading","payload","createPayload","formId","fileUploadUrl","fileData","parseResponse","moment","unix","captureMessage","upload","evt","lengthComputable","loaded","total"],"mappings":"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","file":"actions.js","sourcesContent":["import Raven from 'raven-js';\nimport moment from 'moment';\nimport _ from './utilities/data';\nimport { transformForSubmit, recordEvent } from './helpers';\nimport { timeFromNow } from './utilities/date';\n\nexport const SET_EDIT_MODE = 'SET_EDIT_MODE';\nexport const SET_DATA = 'SET_DATA';\nexport const SET_VIEWED_PAGES = 'SET_VIEWED_PAGES';\nexport const SET_PRE_SUBMIT = 'SET_PRE_SUBMIT';\nexport const SET_SUBMISSION = 'SET_SUBMISSION';\nexport const SET_SUBMITTED = 'SET_SUBMITTED';\nexport const OPEN_REVIEW_CHAPTER = 'OPEN_REVIEW_CHAPTER';\nexport const CLOSE_REVIEW_CHAPTER = 'CLOSE_REVIEW_CHAPTER';\n\nexport function closeReviewChapter(closedChapter, pageKeys = []) {\n return {\n type: CLOSE_REVIEW_CHAPTER,\n closedChapter,\n pageKeys\n };\n}\n\nexport function openReviewChapter(openedChapter) {\n return {\n type: OPEN_REVIEW_CHAPTER,\n openedChapter\n };\n}\n\nexport function setData(data) {\n return {\n type: SET_DATA,\n data\n };\n}\n\nexport function setEditMode(page, edit, index = null) {\n return {\n type: SET_EDIT_MODE,\n edit,\n page,\n index\n };\n}\n\n// extra is used to pass other information (from a submission error or anything else)\n// into the submission state object\nexport function setSubmission(field, value, extra = null) {\n return {\n type: SET_SUBMISSION,\n field,\n value,\n extra\n };\n}\n\nexport function setPreSubmit(preSubmitField, preSubmitAccepted) {\n return {\n type: SET_PRE_SUBMIT,\n preSubmitField,\n preSubmitAccepted\n };\n}\n\nexport function setSubmitted(response) {\n return {\n type: SET_SUBMITTED,\n response: typeof response.data !== 'undefined' ? response.data : response\n };\n}\n\n\nexport function setViewedPages(pageKeys) {\n return {\n type: SET_VIEWED_PAGES,\n pageKeys\n };\n}\n\nfunction submitToUrl(body, submitUrl, trackingPrefix) {\n return new Promise((resolve, reject) => {\n const req = new XMLHttpRequest();\n req.open('POST', submitUrl);\n req.addEventListener('load', () => {\n if (req.status >= 200 && req.status < 300) {\n recordEvent({\n event: `${trackingPrefix}-submission-successful`,\n });\n // got this from the fetch polyfill, keeping it to be safe\n const responseBody = 'response' in req ? req.response : req.responseText;\n const results = JSON.parse(responseBody);\n resolve(results);\n } else {\n let error;\n if (req.status === 429) {\n error = new Error(`vets_throttled_error: ${req.statusText}`);\n error.extra = parseInt(req.getResponseHeader('x-ratelimit-reset'), 10);\n } else {\n error = new Error(`vets_server_error: ${req.statusText}`);\n }\n error.statusText = req.statusText;\n reject(error);\n }\n });\n\n req.addEventListener('error', () => {\n const error = new Error('vets_client_error: Network request failed');\n error.statusText = req.statusText;\n reject(error);\n });\n\n req.addEventListener('abort', () => {\n const error = new Error('vets_client_error: Request aborted');\n error.statusText = req.statusText;\n reject(error);\n });\n\n req.addEventListener('timeout', () => {\n const error = new Error('vets_client_error: Request timed out');\n error.statusText = req.statusText;\n reject(error);\n });\n\n req.setRequestHeader('X-Key-Inflection', 'camel');\n req.setRequestHeader('Content-Type', 'application/json');\n\n const userToken = _.get('sessionStorage.userToken', window);\n if (userToken) {\n req.setRequestHeader('Authorization', `Token token=${userToken}`);\n }\n\n req.send(body);\n });\n}\n\nexport function submitForm(formConfig, form) {\n const captureError = (error, errorType) => {\n Raven.captureException(error, {\n fingerprint: [formConfig.trackingPrefix, error.message],\n extra: {\n errorType,\n statusText: error.statusText\n }\n });\n recordEvent({\n event: `${formConfig.trackingPrefix}-submission-failed${errorType.startsWith('client') ? '-client' : ''}`,\n });\n };\n\n return dispatch => {\n dispatch(setSubmission('status', 'submitPending'));\n recordEvent({\n event: `${formConfig.trackingPrefix}-submission`,\n });\n\n let promise;\n if (formConfig.submit) {\n promise = formConfig.submit(form, formConfig);\n } else {\n const body = formConfig.transformForSubmit\n ? formConfig.transformForSubmit(formConfig, form)\n : transformForSubmit(formConfig, form);\n\n promise = submitToUrl(body, formConfig.submitUrl, formConfig.trackingPrefix);\n }\n\n return promise\n .then(resp => dispatch(setSubmitted(resp)))\n .catch(errorReceived => {\n // overly cautious\n const error = errorReceived instanceof Error ? errorReceived : new Error(errorReceived);\n const errorMessage = String(error.message);\n let errorType = 'clientError';\n if (errorMessage.startsWith('vets_throttled_error')) {\n errorType = 'throttledError';\n } else if (errorMessage.startsWith('vets_server_error')) {\n errorType = 'serverError';\n }\n captureError(error, errorType);\n dispatch(setSubmission('status', errorType, error.extra));\n });\n };\n}\n\nexport function uploadFile(file, uiOptions, onProgress, onChange, onError) {\n return (dispatch, getState) => {\n if (file.size > uiOptions.maxSize) {\n onChange({\n name: file.name,\n errorMessage: 'File is too large to be uploaded'\n });\n\n onError();\n return null;\n }\n\n if (file.size < uiOptions.minSize) {\n onChange({\n name: file.name,\n errorMessage: 'File is too small to be uploaded'\n });\n\n onError();\n return null;\n }\n\n // we limit file types, but it’s not respected on mobile and desktop\n // users can bypass it without much effort\n if (!uiOptions.fileTypes.some(fileType => file.name.toLowerCase().endsWith(fileType.toLowerCase()))) {\n onChange({\n name: file.name,\n errorMessage: 'File is not one of the allowed types'\n });\n\n onError();\n return null;\n }\n\n onChange({\n name: file.name,\n uploading: true\n });\n\n const payload = uiOptions.createPayload(file, getState().form.formId);\n\n const req = new XMLHttpRequest();\n\n req.open('POST', uiOptions.fileUploadUrl);\n req.addEventListener('load', () => {\n if (req.status >= 200 && req.status < 300) {\n const body = 'response' in req ? req.response : req.responseText;\n const fileData = uiOptions.parseResponse(JSON.parse(body), file);\n onChange(fileData);\n } else {\n let errorMessage = req.statusText;\n if (req.status === 429) {\n errorMessage = `You’ve reached the limit for the number of submissions we can accept at this time. Please try again in ${timeFromNow(moment.unix(parseInt(req.getResponseHeader('x-ratelimit-reset'), 10)))}.`;\n }\n\n onChange({\n name: file.name,\n errorMessage\n });\n Raven.captureMessage(`vets_upload_error: ${req.statusText}`);\n onError();\n }\n });\n\n req.addEventListener('error', () => {\n const errorMessage = 'Network request failed';\n onChange({\n name: file.name,\n errorMessage\n });\n Raven.captureMessage(`vets_upload_error: ${errorMessage}`, {\n extra: {\n statusText: req.statusText\n }\n });\n onError();\n });\n\n req.upload.addEventListener('progress', (evt) => {\n if (evt.lengthComputable && onProgress) {\n // setting this at 80, because there's some time after we get to 100%\n // where the backend is uploading to s3\n onProgress((evt.loaded / evt.total) * 80);\n }\n });\n\n req.setRequestHeader('X-Key-Inflection', 'camel');\n req.send(payload);\n\n return req;\n };\n}\n"]}
\ No newline at end of file
diff --git a/lib/js/components/PreSubmitSection.js b/lib/js/components/PreSubmitSection.js
new file mode 100644
index 0000000..28abf51
--- /dev/null
+++ b/lib/js/components/PreSubmitSection.js
@@ -0,0 +1,50 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.PreSubmitSection = PreSubmitSection;
+
+var _propTypes = require('prop-types');
+
+var _propTypes2 = _interopRequireDefault(_propTypes);
+
+var _react = require('react');
+
+var _react2 = _interopRequireDefault(_react);
+
+var _ErrorableCheckbox = require('./ErrorableCheckbox');
+
+var _ErrorableCheckbox2 = _interopRequireDefault(_ErrorableCheckbox);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function PreSubmitSection(_ref) {
+ var onChange = _ref.onChange,
+ showError = _ref.showError,
+ preSubmitInfo = _ref.preSubmitInfo,
+ form = _ref.form;
+
+ var info = preSubmitInfo || {};
+ var field = info.field || 'AGREED';
+
+ return _react2.default.createElement(
+ 'div',
+ null,
+ info.notice,
+ info.required && _react2.default.createElement(_ErrorableCheckbox2.default, { required: true,
+ checked: form.data[field],
+ onValueChange: onChange,
+ name: field,
+ errorMessage: showError && !form.data[field] ? info.error || 'Please agree before continuing' : undefined,
+ label: info.label })
+ );
+}
+
+PreSubmitSection.propTypes = {
+ form: _propTypes2.default.object.isRequired,
+ onChange: _propTypes2.default.func.isRequired,
+ preSubmitInfo: _propTypes2.default.object,
+ showError: _propTypes2.default.bool
+};
+//# sourceMappingURL=PreSubmitSection.js.map
\ No newline at end of file
diff --git a/lib/js/components/PreSubmitSection.js.map b/lib/js/components/PreSubmitSection.js.map
new file mode 100644
index 0000000..fe521ea
--- /dev/null
+++ b/lib/js/components/PreSubmitSection.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["../../../src/js/components/PreSubmitSection.jsx"],"names":["PreSubmitSection","onChange","showError","preSubmitInfo","form","info","field","notice","required","data","error","undefined","label","propTypes","PropTypes","object","isRequired","func","bool"],"mappings":";;;;;QAIgBA,gB,GAAAA,gB;;AAJhB;;;;AACA;;;;AACA;;;;;;AAEO,SAASA,gBAAT,OAAwE;AAAA,MAA5CC,QAA4C,QAA5CA,QAA4C;AAAA,MAAlCC,SAAkC,QAAlCA,SAAkC;AAAA,MAAvBC,aAAuB,QAAvBA,aAAuB;AAAA,MAARC,IAAQ,QAARA,IAAQ;;AAC7E,MAAMC,OAAOF,iBAAiB,EAA9B;AACA,MAAMG,QAAQD,KAAKC,KAAL,IAAc,QAA5B;;AAEA,SACE;AAAA;AAAA;AACGD,SAAKE,MADR;AAEGF,SAAKG,QAAL,IACC,8BAAC,2BAAD,IAAmB,cAAnB;AACE,eAASJ,KAAKK,IAAL,CAAUH,KAAV,CADX;AAEE,qBAAeL,QAFjB;AAGE,YAAMK,KAHR;AAIE,oBAAcJ,aAAa,CAACE,KAAKK,IAAL,CAAUH,KAAV,CAAd,GAAkCD,KAAKK,KAAL,IAAc,gCAAhD,GAAoFC,SAJpG;AAKE,aAAON,KAAKO,KALd;AAHJ,GADF;AAaD;;AAEDZ,iBAAiBa,SAAjB,GAA6B;AAC3BT,QAAMU,oBAAUC,MAAV,CAAiBC,UADI;AAE3Bf,YAAUa,oBAAUG,IAAV,CAAeD,UAFE;AAG3Bb,iBAAeW,oBAAUC,MAHE;AAI3Bb,aAAWY,oBAAUI;AAJM,CAA7B","file":"PreSubmitSection.js","sourcesContent":["import PropTypes from 'prop-types';\nimport React from 'react';\nimport ErrorableCheckbox from './ErrorableCheckbox';\n\nexport function PreSubmitSection({ onChange, showError, preSubmitInfo, form }) {\n const info = preSubmitInfo || {};\n const field = info.field || 'AGREED';\n\n return (\n \n {info.notice}\n {info.required &&\n \n }\n
\n );\n}\n\nPreSubmitSection.propTypes = {\n form: PropTypes.object.isRequired,\n onChange: PropTypes.func.isRequired,\n preSubmitInfo: PropTypes.object,\n showError: PropTypes.bool\n};\n"]}
\ No newline at end of file
diff --git a/lib/js/components/PrivacyAgreement.js b/lib/js/components/PrivacyAgreement.js
deleted file mode 100644
index ffa0f45..0000000
--- a/lib/js/components/PrivacyAgreement.js
+++ /dev/null
@@ -1,52 +0,0 @@
-'use strict';
-
-Object.defineProperty(exports, "__esModule", {
- value: true
-});
-exports.default = PrivacyAgreement;
-
-var _propTypes = require('prop-types');
-
-var _propTypes2 = _interopRequireDefault(_propTypes);
-
-var _react = require('react');
-
-var _react2 = _interopRequireDefault(_react);
-
-var _ErrorableCheckbox = require('./ErrorableCheckbox');
-
-var _ErrorableCheckbox2 = _interopRequireDefault(_ErrorableCheckbox);
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
-
-function PrivacyAgreement(_ref) {
- var onChange = _ref.onChange,
- checked = _ref.checked,
- showError = _ref.showError;
-
- return _react2.default.createElement(
- 'div',
- null,
- _react2.default.createElement(_ErrorableCheckbox2.default, { required: true,
- checked: checked,
- onValueChange: onChange,
- name: 'privacyAgreement',
- errorMessage: showError && !checked ? 'You must accept the privacy policy before continuing' : undefined,
- label: _react2.default.createElement(
- 'span',
- null,
- 'I have read and accept the ',
- _react2.default.createElement(
- 'a',
- { target: '_blank', href: '/privacy/' },
- 'privacy policy'
- )
- ) })
- );
-}
-
-PrivacyAgreement.propTypes = {
- onChange: _propTypes2.default.func.isRequired,
- checked: _propTypes2.default.bool.isRequired
-};
-//# sourceMappingURL=PrivacyAgreement.js.map
\ No newline at end of file
diff --git a/lib/js/components/PrivacyAgreement.js.map b/lib/js/components/PrivacyAgreement.js.map
deleted file mode 100644
index ea64a2d..0000000
--- a/lib/js/components/PrivacyAgreement.js.map
+++ /dev/null
@@ -1 +0,0 @@
-{"version":3,"sources":["../../../src/js/components/PrivacyAgreement.jsx"],"names":["PrivacyAgreement","onChange","checked","showError","undefined","propTypes","PropTypes","func","isRequired","bool"],"mappings":";;;;;kBAIwBA,gB;;AAJxB;;;;AACA;;;;AACA;;;;;;AAEe,SAASA,gBAAT,OAA4D;AAAA,MAAhCC,QAAgC,QAAhCA,QAAgC;AAAA,MAAtBC,OAAsB,QAAtBA,OAAsB;AAAA,MAAbC,SAAa,QAAbA,SAAa;;AACzE,SACE;AAAA;AAAA;AACE,kCAAC,2BAAD,IAAmB,cAAnB;AACE,eAASD,OADX;AAEE,qBAAeD,QAFjB;AAGE,YAAK,kBAHP;AAIE,oBAAcE,aAAa,CAACD,OAAd,GAAwB,sDAAxB,GAAiFE,SAJjG;AAKE,aAAO;AAAA;AAAA;AAAA;AAAiC;AAAA;AAAA,YAAG,QAAO,QAAV,EAAmB,MAAK,WAAxB;AAAA;AAAA;AAAjC,OALT;AADF,GADF;AAUD;;AAEDJ,iBAAiBK,SAAjB,GAA6B;AAC3BJ,YAAUK,oBAAUC,IAAV,CAAeC,UADE;AAE3BN,WAASI,oBAAUG,IAAV,CAAeD;AAFG,CAA7B","file":"PrivacyAgreement.js","sourcesContent":["import PropTypes from 'prop-types';\nimport React from 'react';\nimport ErrorableCheckbox from './ErrorableCheckbox';\n\nexport default function PrivacyAgreement({ onChange, checked, showError }) {\n return (\n \n );\n}\n\nPrivacyAgreement.propTypes = {\n onChange: PropTypes.func.isRequired,\n checked: PropTypes.bool.isRequired\n};\n"]}
\ No newline at end of file
diff --git a/lib/js/review/SubmitController.js b/lib/js/review/SubmitController.js
index 6c09fa5..c8bbdef 100644
--- a/lib/js/review/SubmitController.js
+++ b/lib/js/review/SubmitController.js
@@ -27,9 +27,7 @@ var _SubmitButtons = require('./SubmitButtons');
var _SubmitButtons2 = _interopRequireDefault(_SubmitButtons);
-var _PrivacyAgreement = require('../components/PrivacyAgreement');
-
-var _PrivacyAgreement2 = _interopRequireDefault(_PrivacyAgreement);
+var _PreSubmitSection = require('../components/PreSubmitSection');
var _validation = require('../validation');
@@ -75,19 +73,29 @@ var SubmitController = function (_React$Component) {
form = _this$props2.form,
formConfig = _this$props2.formConfig,
pagesByChapter = _this$props2.pagesByChapter,
- privacyAgreementAccepted = _this$props2.privacyAgreementAccepted,
trackingPrefix = _this$props2.trackingPrefix;
- var _isValidForm = (0, _validation.isValidForm)(form, pagesByChapter),
- isValid = _isValidForm.isValid,
- errors = _isValidForm.errors;
+
+ var isValid = void 0;
+ var errors = void 0;
+
+ // If a pre-submit agreement was specified, it has to be accepted first
+ var preSubmitField = formConfig.preSubmitInfo && formConfig.preSubmitInfo.required && (formConfig.preSubmitInfo.field || 'AGREED');
+ if (preSubmitField && !form.data[preSubmitField]) {
+ isValid = false;
+ } else {
+ var _isValidForm = (0, _validation.isValidForm)(form, pagesByChapter);
+
+ isValid = _isValidForm.isValid;
+ errors = _isValidForm.errors;
+ }
if (isValid) {
_this.props.submitForm(formConfig, form);
} else {
// validation errors in this situation are not visible, so we’d
// like to know if they’re common
- if (privacyAgreementAccepted) {
+ if (preSubmitField && form.data[preSubmitField]) {
(0, _helpers.recordEvent)({
event: trackingPrefix + '-validation-failed'
});
@@ -117,30 +125,26 @@ var SubmitController = function (_React$Component) {
}, {
key: 'render',
value: function render() {
+ var _this2 = this;
+
var _props = this.props,
- privacyAgreementAccepted = _props.privacyAgreementAccepted,
+ form = _props.form,
+ formConfig = _props.formConfig,
+ showPreSubmitError = _props.showPreSubmitError,
renderErrorMessage = _props.renderErrorMessage,
- showPrivacyAgreementError = _props.showPrivacyAgreementError,
submission = _props.submission;
return _react2.default.createElement(
'div',
null,
- _react2.default.createElement(
- 'p',
- null,
- _react2.default.createElement(
- 'strong',
- null,
- 'Note:'
- ),
- ' According to federal law, there are criminal penalties, including a fine and/or imprisonment for up to 5 years, for withholding information or for providing incorrect information. (See 18 U.S.C. 1001)'
- ),
- _react2.default.createElement(_PrivacyAgreement2.default, {
+ this.preSubmitInfo && _react2.default.createElement(_PreSubmitSection.PreSubmitSection, {
required: true,
- onChange: this.props.setPrivacyAgreement,
- checked: privacyAgreementAccepted,
- showError: showPrivacyAgreementError }),
+ preSubmitInfo: formConfig.preSubmitInfo,
+ onChange: function onChange() {
+ return _this2.props.setPreSubmit(formConfig.preSubmitInfo.field, _this2.value);
+ },
+ form: form,
+ showError: showPreSubmitError }),
_react2.default.createElement(_SubmitButtons2.default, {
onBack: this.goBack,
onSubmit: this.handleSubmit,
@@ -164,25 +168,23 @@ function mapStateToProps(state, ownProps) {
var pagesByChapter = (0, _helpers.createPageListByChapter)(formConfig);
var trackingPrefix = formConfig.trackingPrefix;
var submission = form.submission;
- var showPrivacyAgreementError = submission.hasAttemptedSubmit;
- var privacyAgreementAccepted = form.data.privacyAgreementAccepted;
+ var showPreSubmitError = submission.hasAttemptedSubmit;
return {
form: form,
formConfig: formConfig,
pagesByChapter: pagesByChapter,
pageList: pageList,
- privacyAgreementAccepted: privacyAgreementAccepted,
renderErrorMessage: renderErrorMessage,
router: router,
submission: submission,
- showPrivacyAgreementError: showPrivacyAgreementError,
+ showPreSubmitError: showPreSubmitError,
trackingPrefix: trackingPrefix
};
}
var mapDispatchToProps = {
- setPrivacyAgreement: _actions.setPrivacyAgreement,
+ setPreSubmit: _actions.setPreSubmit,
setSubmission: _actions.setSubmission,
submitForm: _actions.submitForm
};
@@ -192,10 +194,9 @@ SubmitController.propTypes = {
formConfig: _propTypes2.default.object.isRequired,
pagesByChapter: _propTypes2.default.object.isRequired,
pageList: _propTypes2.default.array.isRequired,
- privacyAgreementAccepted: _propTypes2.default.bool.isRequired,
renderErrorMessage: _propTypes2.default.func,
router: _propTypes2.default.object.isRequired,
- setPrivacyAgreement: _propTypes2.default.func.isRequired,
+ setPreSubmit: _propTypes2.default.func.isRequired,
setSubmission: _propTypes2.default.func.isRequired,
submitForm: _propTypes2.default.func.isRequired,
submission: _propTypes2.default.object.isRequired,
diff --git a/lib/js/review/SubmitController.js.map b/lib/js/review/SubmitController.js.map
index 00cf0c5..d01f44f 100644
--- a/lib/js/review/SubmitController.js.map
+++ b/lib/js/review/SubmitController.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../../../src/js/review/SubmitController.jsx"],"names":["SubmitController","goBack","props","form","pageList","router","eligiblePageList","data","expandedPageList","push","length","path","handleSubmit","formConfig","pagesByChapter","privacyAgreementAccepted","trackingPrefix","isValid","errors","submitForm","event","Raven","captureMessage","extra","prefix","setSubmission","nextProps","nextStatus","submission","status","previousStatus","newRoute","urlPrefix","renderErrorMessage","showPrivacyAgreementError","setPrivacyAgreement","React","Component","mapStateToProps","state","ownProps","hasAttemptedSubmit","mapDispatchToProps","propTypes","PropTypes","object","isRequired","array","bool","func","string"],"mappings":"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","file":"SubmitController.js","sourcesContent":["import React from 'react';\nimport Raven from 'raven-js';\nimport PropTypes from 'prop-types';\nimport { connect } from 'react-redux';\nimport { withRouter } from 'react-router';\n\nimport SubmitButtons from './SubmitButtons';\nimport PrivacyAgreement from '../components/PrivacyAgreement';\nimport { isValidForm } from '../validation';\nimport {\n createPageListByChapter,\n expandArrayPages,\n getActivePages,\n recordEvent\n} from '../helpers';\nimport {\n setPrivacyAgreement,\n setSubmission,\n submitForm\n} from '../actions';\n\nclass SubmitController extends React.Component {\n\n componentWillReceiveProps(nextProps) {\n const nextStatus = nextProps.form.submission.status;\n const previousStatus = this.props.form.submission.status;\n if (nextStatus !== previousStatus && nextStatus === 'applicationSubmitted') {\n const newRoute = `${nextProps.formConfig.urlPrefix}confirmation`;\n this.props.router.push(newRoute);\n }\n }\n\n goBack = () => {\n const {\n form,\n pageList,\n router\n } = this.props;\n\n const eligiblePageList = getActivePages(pageList, form.data);\n const expandedPageList = expandArrayPages(eligiblePageList, this.props.form.data);\n\n router.push(expandedPageList[expandedPageList.length - 2].path);\n }\n\n handleSubmit = () => {\n const {\n form,\n formConfig,\n pagesByChapter,\n privacyAgreementAccepted,\n trackingPrefix\n } = this.props;\n\n const {\n isValid,\n errors\n } = isValidForm(form, pagesByChapter);\n\n if (isValid) {\n this.props.submitForm(formConfig, form);\n } else {\n // validation errors in this situation are not visible, so we’d\n // like to know if they’re common\n if (privacyAgreementAccepted) {\n recordEvent({\n event: `${trackingPrefix}-validation-failed`,\n });\n Raven.captureMessage('Validation issue not displayed', {\n extra: {\n errors,\n prefix: trackingPrefix\n }\n });\n this.props.setSubmission('status', 'validationError');\n }\n this.props.setSubmission('hasAttemptedSubmit', true);\n }\n }\n\n render() {\n const {\n privacyAgreementAccepted,\n renderErrorMessage,\n showPrivacyAgreementError,\n submission\n } = this.props;\n return (\n \n
Note: According to federal law, there are criminal penalties, including a fine and/or imprisonment for up to 5 years, for withholding information or for providing incorrect information. (See 18 U.S.C. 1001)
\n
\n \n \n );\n }\n}\n\nfunction mapStateToProps(state, ownProps) {\n const {\n formConfig,\n pageList,\n renderErrorMessage\n } = ownProps;\n const router = ownProps.router;\n\n const form = state.form;\n const pagesByChapter = createPageListByChapter(formConfig);\n const trackingPrefix = formConfig.trackingPrefix;\n const submission = form.submission;\n const showPrivacyAgreementError = submission.hasAttemptedSubmit;\n const privacyAgreementAccepted = form.data.privacyAgreementAccepted;\n\n return {\n form,\n formConfig,\n pagesByChapter,\n pageList,\n privacyAgreementAccepted,\n renderErrorMessage,\n router,\n submission,\n showPrivacyAgreementError,\n trackingPrefix\n };\n}\n\nconst mapDispatchToProps = {\n setPrivacyAgreement,\n setSubmission,\n submitForm\n};\n\nSubmitController.propTypes = {\n form: PropTypes.object.isRequired,\n formConfig: PropTypes.object.isRequired,\n pagesByChapter: PropTypes.object.isRequired,\n pageList: PropTypes.array.isRequired,\n privacyAgreementAccepted: PropTypes.bool.isRequired,\n renderErrorMessage: PropTypes.func,\n router: PropTypes.object.isRequired,\n setPrivacyAgreement: PropTypes.func.isRequired,\n setSubmission: PropTypes.func.isRequired,\n submitForm: PropTypes.func.isRequired,\n submission: PropTypes.object.isRequired,\n trackingPrefix: PropTypes.string.isRequired\n};\n\nexport default withRouter(connect(mapStateToProps, mapDispatchToProps)(SubmitController));\n\n// for tests\nexport { SubmitController };\n"]}
\ No newline at end of file
+{"version":3,"sources":["../../../src/js/review/SubmitController.jsx"],"names":["SubmitController","goBack","props","form","pageList","router","eligiblePageList","data","expandedPageList","push","length","path","handleSubmit","formConfig","pagesByChapter","trackingPrefix","isValid","errors","preSubmitField","preSubmitInfo","required","field","submitForm","event","Raven","captureMessage","extra","prefix","setSubmission","nextProps","nextStatus","submission","status","previousStatus","newRoute","urlPrefix","showPreSubmitError","renderErrorMessage","setPreSubmit","value","React","Component","mapStateToProps","state","ownProps","hasAttemptedSubmit","mapDispatchToProps","propTypes","PropTypes","object","isRequired","array","func","string"],"mappings":"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","file":"SubmitController.js","sourcesContent":["import React from 'react';\nimport Raven from 'raven-js';\nimport PropTypes from 'prop-types';\nimport { connect } from 'react-redux';\nimport { withRouter } from 'react-router';\n\nimport SubmitButtons from './SubmitButtons';\nimport { PreSubmitSection } from '../components/PreSubmitSection';\nimport { isValidForm } from '../validation';\nimport {\n createPageListByChapter,\n expandArrayPages,\n getActivePages,\n recordEvent\n} from '../helpers';\nimport {\n setPreSubmit,\n setSubmission,\n submitForm\n} from '../actions';\n\nclass SubmitController extends React.Component {\n\n componentWillReceiveProps(nextProps) {\n const nextStatus = nextProps.form.submission.status;\n const previousStatus = this.props.form.submission.status;\n if (nextStatus !== previousStatus && nextStatus === 'applicationSubmitted') {\n const newRoute = `${nextProps.formConfig.urlPrefix}confirmation`;\n this.props.router.push(newRoute);\n }\n }\n\n goBack = () => {\n const {\n form,\n pageList,\n router\n } = this.props;\n\n const eligiblePageList = getActivePages(pageList, form.data);\n const expandedPageList = expandArrayPages(eligiblePageList, this.props.form.data);\n\n router.push(expandedPageList[expandedPageList.length - 2].path);\n }\n\n handleSubmit = () => {\n const {\n form,\n formConfig,\n pagesByChapter,\n trackingPrefix\n } = this.props;\n\n let isValid;\n let errors;\n\n // If a pre-submit agreement was specified, it has to be accepted first\n const preSubmitField = formConfig.preSubmitInfo &&\n formConfig.preSubmitInfo.required && (formConfig.preSubmitInfo.field || 'AGREED');\n if (preSubmitField && !form.data[preSubmitField]) {\n isValid = false;\n } else {\n ({ isValid, errors } = isValidForm(form, pagesByChapter));\n }\n\n if (isValid) {\n this.props.submitForm(formConfig, form);\n } else {\n // validation errors in this situation are not visible, so we’d\n // like to know if they’re common\n if (preSubmitField && form.data[preSubmitField]) {\n recordEvent({\n event: `${trackingPrefix}-validation-failed`,\n });\n Raven.captureMessage('Validation issue not displayed', {\n extra: {\n errors,\n prefix: trackingPrefix\n }\n });\n this.props.setSubmission('status', 'validationError');\n }\n this.props.setSubmission('hasAttemptedSubmit', true);\n }\n }\n\n render() {\n const {\n form,\n formConfig,\n showPreSubmitError,\n renderErrorMessage,\n submission\n } = this.props;\n return (\n \n { this.preSubmitInfo &&
this.props.setPreSubmit(formConfig.preSubmitInfo.field, this.value)}\n form={form}\n showError={showPreSubmitError}/> }\n \n \n );\n }\n}\n\nfunction mapStateToProps(state, ownProps) {\n const {\n formConfig,\n pageList,\n renderErrorMessage\n } = ownProps;\n const router = ownProps.router;\n\n const form = state.form;\n const pagesByChapter = createPageListByChapter(formConfig);\n const trackingPrefix = formConfig.trackingPrefix;\n const submission = form.submission;\n const showPreSubmitError = submission.hasAttemptedSubmit;\n\n return {\n form,\n formConfig,\n pagesByChapter,\n pageList,\n renderErrorMessage,\n router,\n submission,\n showPreSubmitError,\n trackingPrefix\n };\n}\n\nconst mapDispatchToProps = {\n setPreSubmit,\n setSubmission,\n submitForm\n};\n\nSubmitController.propTypes = {\n form: PropTypes.object.isRequired,\n formConfig: PropTypes.object.isRequired,\n pagesByChapter: PropTypes.object.isRequired,\n pageList: PropTypes.array.isRequired,\n renderErrorMessage: PropTypes.func,\n router: PropTypes.object.isRequired,\n setPreSubmit: PropTypes.func.isRequired,\n setSubmission: PropTypes.func.isRequired,\n submitForm: PropTypes.func.isRequired,\n submission: PropTypes.object.isRequired,\n trackingPrefix: PropTypes.string.isRequired\n};\n\nexport default withRouter(connect(mapStateToProps, mapDispatchToProps)(SubmitController));\n\n// for tests\nexport { SubmitController };\n"]}
\ No newline at end of file
diff --git a/lib/js/state/helpers.js b/lib/js/state/helpers.js
index b0e98da..ed45c40 100644
--- a/lib/js/state/helpers.js
+++ b/lib/js/state/helpers.js
@@ -559,12 +559,16 @@ function createInitialState(formConfig) {
return state;
}, {
- data: {
- privacyAgreementAccepted: false
- },
+ data: {},
pages: {}
});
+ // Initialize the preSubmit flag if one was specified
+ var preSubmitInfo = formConfig.preSubmitInfo;
+ if (preSubmitInfo && preSubmitInfo.field) {
+ pageAndDataState.data[preSubmitInfo.field] = false;
+ }
+
initialState = (0, _assign3.default)(initialState, pageAndDataState);
// Take another pass and recalculate the schema and data based on the default data
// We do this to avoid passing undefined for the whole form state when the form first renders
diff --git a/lib/js/state/helpers.js.map b/lib/js/state/helpers.js.map
index 37bd64f..65e66eb 100644
--- a/lib/js/state/helpers.js.map
+++ b/lib/js/state/helpers.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../../../src/js/state/helpers.js"],"names":["updateRequiredFields","isContentExpanded","setHiddenFields","removeHiddenData","updateSchemaFromUiSchema","replaceRefSchemas","updateItemsSchema","updateSchemaAndData","recalculateSchemaAndData","createInitialState","isHiddenField","schema","get","path","data","reduce","current","next","uiSchema","formData","index","type","newRequired","Object","keys","properties","requiredArray","nextProp","field","isRequired","arrayHasField","some","prop","filter","concat","required","newSchema","currentSchema","nextSchema","length","newItemSchemas","items","map","item","idx","newItem","matcher","containingObject","slice","updatedSchema","hideIf","expandUnder","expandUnderCondition","newProperties","undefined","nextData","newItems","updateSchema","newSchemaProps","definitions","Error","$ref","refPath","replace","split","definition","fieldData","Array","isArray","additionalItems","fillIn","fill","updatedItems","newData","initialState","pages","state","pageKey","page","newState","showPagePerItem","arrayData","arrayPath","editMode","formConfig","submission","status","errorMessage","id","timestamp","hasAttemptedSubmit","formId","loadedData","metadata","reviewPageView","openChapters","viewedPages","Set","trackingPrefix","pageAndDataState","defaultDefinitions","isArrayPage","initialData","itemFilter","privacyAgreementAccepted"],"mappings":"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","file":"helpers.js","sourcesContent":["import _ from 'lodash/fp';\nimport { getDefaultFormState } from '@department-of-veterans-affairs/react-jsonschema-form/lib/utils';\n\nimport {\n checkValidSchema,\n createFormPageList\n} from '../helpers';\n\nfunction isHiddenField(schema) {\n return !!schema['ui:collapsed'] || !!schema['ui:hidden'];\n}\n\nfunction get(path, data) {\n return path.reduce((current, next) => {\n return typeof current === 'undefined' ? current : current[next];\n }, data);\n}\n\n/*\n * This function goes through a schema/uiSchema and updates the required array\n * based on any ui:required field properties in the uiSchema.\n *\n * If no required fields are changing, it makes sure to not mutate the existing schema,\n * so we can still take advantage of any shouldComponentUpdate optimizations\n */\nexport function updateRequiredFields(schema, uiSchema, formData, index = null) {\n if (!uiSchema) {\n return schema;\n }\n\n if (schema.type === 'object') {\n const newRequired = Object.keys(schema.properties).reduce((requiredArray, nextProp) => {\n const field = uiSchema[nextProp];\n if (field && field['ui:required']) {\n const isRequired = field['ui:required'](formData, index);\n const arrayHasField = requiredArray.some(prop => prop === nextProp);\n\n if (arrayHasField && !isRequired) {\n return requiredArray.filter(prop => prop !== nextProp);\n } else if (!arrayHasField && isRequired) {\n return requiredArray.concat(nextProp);\n }\n\n return requiredArray;\n }\n\n return requiredArray;\n }, schema.required || []);\n\n const newSchema = Object.keys(schema.properties).reduce((currentSchema, nextProp) => {\n if (uiSchema) {\n const nextSchema = updateRequiredFields(currentSchema.properties[nextProp], uiSchema[nextProp], formData, index);\n if (nextSchema !== currentSchema.properties[nextProp]) {\n return _.set(['properties', nextProp], nextSchema, currentSchema);\n }\n }\n\n return currentSchema;\n }, schema);\n\n if (newSchema.required !== newRequired && (newSchema.required || newRequired.length > 0)) {\n return _.set('required', newRequired, newSchema);\n }\n\n return newSchema;\n }\n\n if (schema.type === 'array') {\n // each item has its own schema, so we need to update the required fields on those schemas\n // and then check for differences\n const newItemSchemas = schema.items.map((item, idx) => updateRequiredFields(item, uiSchema.items, formData, idx));\n if (newItemSchemas.some((newItem, idx) => newItem !== schema.items[idx])) {\n return _.set('items', newItemSchemas, schema);\n }\n }\n\n return schema;\n}\n\nexport function isContentExpanded(data, matcher) {\n if (typeof matcher === 'undefined') {\n return !!data;\n } else if (typeof matcher === 'function') {\n return matcher(data);\n }\n\n return data === matcher;\n}\n\n/*\n * This steps through a schema and sets any fields to hidden, based on a\n * hideIf function from uiSchema and the current page data. Sets 'ui:hidden'\n * which is a non-standard JSON Schema property\n *\n * The path parameter will contain the path, relative to formData, to the\n * form data corresponding to the current schema object\n */\nexport function setHiddenFields(schema, uiSchema, formData, path = []) {\n if (!uiSchema) {\n return schema;\n }\n\n // expandUnder fields are relative to the parent object of the current\n // field, so get that object using path here\n const containingObject = get(path.slice(0, -1), formData) || formData;\n\n let updatedSchema = schema;\n const hideIf = get(['ui:options', 'hideIf'], uiSchema);\n const index = path.reduce((current, next) => {\n return typeof next === 'number' ? next : current;\n }, null);\n\n if (hideIf && hideIf(formData, index)) {\n if (!updatedSchema['ui:hidden']) {\n updatedSchema = _.set('ui:hidden', true, updatedSchema);\n }\n } else if (updatedSchema['ui:hidden']) {\n updatedSchema = _.unset('ui:hidden', updatedSchema);\n }\n\n const expandUnder = get(['ui:options', 'expandUnder'], uiSchema);\n const expandUnderCondition = get(['ui:options', 'expandUnderCondition'], uiSchema);\n if (expandUnder && !isContentExpanded(containingObject[expandUnder], expandUnderCondition)) {\n if (!updatedSchema['ui:collapsed']) {\n updatedSchema = _.set('ui:collapsed', true, updatedSchema);\n }\n } else if (updatedSchema['ui:collapsed']) {\n updatedSchema = _.unset('ui:collapsed', updatedSchema);\n }\n\n if (updatedSchema.type === 'object') {\n const newProperties = Object.keys(updatedSchema.properties).reduce((current, next) => {\n const newSchema = setHiddenFields(updatedSchema.properties[next], uiSchema[next], formData, path.concat(next));\n\n if (newSchema !== updatedSchema.properties[next]) {\n return _.set(next, newSchema, current);\n }\n\n return current;\n }, updatedSchema.properties);\n\n if (newProperties !== updatedSchema.properties) {\n return _.set('properties', newProperties, updatedSchema);\n }\n }\n\n if (updatedSchema.type === 'array') {\n // each item has its own schema, so we need to update the required fields on those schemas\n // and then check for differences\n const newItemSchemas = updatedSchema.items.map((item, idx) =>\n setHiddenFields(item, uiSchema.items, formData, path.concat(idx))\n );\n\n if (newItemSchemas.some((newItem, idx) => newItem !== updatedSchema.items[idx])) {\n return _.set('items', newItemSchemas, updatedSchema);\n }\n }\n\n return updatedSchema;\n}\n\n/*\n * Steps through data and removes any fields that are marked as hidden\n * This is done so that hidden fields don’t cause validation errors that\n * a user can’t see.\n */\nexport function removeHiddenData(schema, data) {\n // null is necessary here because Rails 4 will convert empty arrays to null\n // In the forms, there's no difference between an empty array and null or undefined\n if (isHiddenField(schema) || typeof data === 'undefined' || data === null) {\n return undefined;\n }\n\n if (schema.type === 'object') {\n return Object.keys(data).reduce((current, next) => {\n if (typeof data[next] !== 'undefined' && schema.properties[next]) {\n const nextData = removeHiddenData(schema.properties[next], data[next]);\n\n // if the data was removed, then just unset it\n if (typeof nextData === 'undefined') {\n return _.unset(next, current);\n }\n\n // if data was updated (like a nested prop was removed), update it\n if (nextData !== data[next]) {\n return _.set(next, nextData, current);\n }\n }\n\n return current;\n }, data);\n }\n\n if (schema.type === 'array') {\n const newItems = data.map((item, index) => {\n return removeHiddenData(schema.items[index], item);\n });\n\n if (newItems.some((newItem, idx) => newItem !== data[idx])) {\n return newItems;\n }\n\n return data;\n }\n\n return data;\n}\n\n/*\n * This is similar to the hidden fields schema function above, except more general.\n * It will step through a schema and replace parts of it based on an updateSchema\n * function in uiSchema. This means the schema can be re-calculated based on data\n * a user has entered.\n */\nexport function updateSchemaFromUiSchema(schema, uiSchema, formData, index = null, path = []) {\n if (!uiSchema) {\n return schema;\n }\n\n let currentSchema = schema;\n\n if (currentSchema.type === 'object') {\n const newSchema = Object.keys(currentSchema.properties).reduce((current, next) => {\n const nextProp = updateSchemaFromUiSchema(current.properties[next], uiSchema[next], formData, index, path.concat(next));\n\n if (current.properties[next] !== nextProp) {\n return _.set(['properties', next], nextProp, current);\n }\n\n return current;\n }, currentSchema);\n\n if (newSchema !== schema) {\n currentSchema = newSchema;\n }\n }\n\n if (currentSchema.type === 'array') {\n // each item has its own schema, so we need to update the required fields on those schemas\n // and then check for differences\n const newItemSchemas = currentSchema.items.map((item, idx) =>\n updateSchemaFromUiSchema(item, uiSchema.items, formData, idx, path.concat(idx))\n );\n\n if (newItemSchemas.some((newItem, idx) => newItem !== currentSchema.items[idx])) {\n currentSchema = _.set('items', newItemSchemas, currentSchema);\n }\n }\n\n const updateSchema = get(['ui:options', 'updateSchema'], uiSchema);\n\n if (updateSchema) {\n const newSchemaProps = updateSchema(formData, currentSchema, uiSchema, index, path);\n\n const newSchema = Object.keys(newSchemaProps).reduce((current, next) => {\n if (newSchemaProps[next] !== schema[next]) {\n return _.set(next, newSchemaProps[next], current);\n }\n\n return current;\n }, currentSchema);\n\n if (newSchema !== currentSchema) {\n return newSchema;\n }\n }\n\n return currentSchema;\n}\n\nexport function replaceRefSchemas(schema, definitions, path = '') {\n // this can happen if you import a field that doesn’t exist from a schema\n if (!schema) {\n throw new Error(`Schema is undefined at ${path}`);\n }\n if (schema.$ref) {\n // There’s a whole spec for JSON pointers, but we don’t use anything more complicated\n // than this so far\n const refPath = schema.$ref.replace('#/definitions/', '').split('/');\n const definition = get(refPath, definitions);\n if (!definition) {\n throw new Error(`Missing definition for ${schema.$ref} at ${path}. You probably need to add it to defaultDefinitions`);\n }\n\n return replaceRefSchemas(definition, definitions, path);\n }\n\n if (schema.type === 'object') {\n const newSchema = Object.keys(schema.properties).reduce((current, next) => {\n const nextProp = replaceRefSchemas(schema.properties[next], definitions, `${path}.${next}`);\n\n if (current.properties[next] !== nextProp) {\n return _.set(['properties', next], nextProp, current);\n }\n\n return current;\n }, schema);\n\n return newSchema;\n }\n\n if (schema.type === 'array') {\n const newItems = replaceRefSchemas(schema.items, definitions, `${path}.items`);\n\n if (newItems !== schema.items) {\n return _.set('items', newItems, schema);\n }\n }\n\n return schema;\n}\n\n/**\n * This function updates an array schema to use the array of\n * item schema format and keeps that array in sync with the\n * data in that array in the form data.\n *\n * This allows us to have conditional fields for each array item,\n * because our conditional field implementation depends on modifying\n * schemas\n *\n * @param {Object} schema The current JSON Schema object\n * @param {any} fieldData The data associated with the current schema\n */\nexport function updateItemsSchema(schema, fieldData = null) {\n if (schema.type === 'array') {\n let newSchema = schema;\n\n // This happens the first time this function is called when\n // generating the form\n if (!Array.isArray(schema.items)) {\n newSchema = _.assign(schema, {\n items: [],\n additionalItems: schema.items\n });\n }\n\n if (!fieldData) {\n // If there’s no data, the list of schemas should be empty\n newSchema = _.set('items', [], newSchema);\n } else if (fieldData.length > newSchema.items.length) {\n // Here we’re filling in the items array to make it the same\n // length as the array of form data. This happens when you add\n // another record on the form, mainly.\n const fillIn = Array(fieldData.length - newSchema.items.length)\n .fill(newSchema.additionalItems);\n newSchema = _.set('items', newSchema.items.concat(fillIn), newSchema);\n } else if (fieldData.length < newSchema.items.length) {\n // If someone removed a record we’re removing the last schema item\n // This may not be the actual removed schema, but the schemas will\n // always be updated in the next step\n newSchema = _.set('items', _.dropRight(1, newSchema.items), newSchema);\n }\n\n const updatedItems = newSchema.items.map(\n (item, index) => updateItemsSchema(item, fieldData[index])\n );\n if (newSchema.items.some((item, index) => item !== updatedItems[index])) {\n return _.set('items', updatedItems, newSchema);\n }\n\n return newSchema;\n }\n\n if (schema.type === 'object') {\n const newSchema = Object.keys(schema.properties).reduce((current, next) => {\n const nextProp = updateItemsSchema(schema.properties[next], fieldData ? fieldData[next] : null);\n\n if (current.properties[next] !== nextProp) {\n return _.set(['properties', next], nextProp, current);\n }\n\n return current;\n }, schema);\n\n return newSchema;\n }\n\n return schema;\n}\n\n/**\n * This is the main sequence of updates that happens when data is changed\n * on a form. Most updates are applied to the schema, except that the data\n * is updated to remove newly hidden data\n *\n * @param {Object} schema The current JSON Schema\n * @param {Object} uiSchema The current UI Schema (does not change)\n * @param {Object} formData Flattened data for the entire form\n */\nexport function updateSchemaAndData(schema, uiSchema, formData) {\n let newSchema = updateItemsSchema(schema, formData);\n newSchema = updateRequiredFields(newSchema, uiSchema, formData);\n\n // Update the schema with any fields that are now hidden because of the data change\n newSchema = setHiddenFields(newSchema, uiSchema, formData);\n\n // Update the schema with any general updates based on the new data\n newSchema = updateSchemaFromUiSchema(newSchema, uiSchema, formData);\n\n // Remove any data that’s now hidden in the schema\n const newData = removeHiddenData(newSchema, formData);\n\n // We need to do this again because array data might have been removed\n newSchema = updateItemsSchema(newSchema, newData);\n\n checkValidSchema(newSchema);\n\n return {\n data: newData,\n schema: newSchema\n };\n}\n\nexport function recalculateSchemaAndData(initialState) {\n return Object.keys(initialState.pages)\n .reduce((state, pageKey) => {\n // on each data change, we need to do the following steps\n // Recalculate any required fields, based on the new data\n const page = state.pages[pageKey];\n const formData = initialState.data;\n\n const { data, schema } = updateSchemaAndData(page.schema, page.uiSchema, formData);\n\n let newState = state;\n\n if (formData !== data) {\n newState = _.set('data', data, state);\n }\n\n if (page.schema !== schema) {\n newState = _.set(['pages', pageKey, 'schema'], schema, newState);\n }\n\n if (page.showPagePerItem) {\n const arrayData = _.get(page.arrayPath, newState.data) || [];\n // If an item was added or removed for the data used by a showPagePerItem page,\n // we have to reset everything because we can’t match the edit states to rows directly\n // This will rarely ever be noticeable\n if (page.editMode.length !== arrayData.length) {\n newState = _.set(['pages', pageKey, 'editMode'], arrayData.map(() => false), newState);\n }\n }\n\n return newState;\n }, initialState);\n}\n\nexport function createInitialState(formConfig) {\n let initialState = {\n submission: {\n status: false,\n errorMessage: false,\n id: false,\n timestamp: false,\n hasAttemptedSubmit: false\n },\n formId: formConfig.formId,\n loadedData: {\n formData: {},\n metadata: {}\n },\n reviewPageView: {\n openChapters: [],\n viewedPages: new Set()\n },\n trackingPrefix: formConfig.trackingPrefix\n };\n\n const pageAndDataState = createFormPageList(formConfig)\n .reduce((state, page) => {\n const definitions = _.assign(formConfig.defaultDefinitions || {}, page.schema.definitions);\n let schema = replaceRefSchemas(page.schema, definitions, page.pageKey);\n // Throw an error if the new schema is invalid\n checkValidSchema(schema);\n schema = updateItemsSchema(schema);\n const isArrayPage = page.showPagePerItem;\n const data = getDefaultFormState(schema, page.initialData, schema.definitions);\n\n /* eslint-disable no-param-reassign */\n state.pages[page.pageKey] = {\n uiSchema: page.uiSchema,\n schema,\n editMode: isArrayPage ? [] : false,\n showPagePerItem: page.showPagePerItem,\n arrayPath: page.arrayPath,\n itemFilter: page.itemFilter\n };\n\n state.data = _.merge(state.data, data);\n /* eslint-enable no-param-reassign */\n\n return state;\n }, {\n data: {\n privacyAgreementAccepted: false,\n },\n pages: {},\n });\n\n initialState = _.assign(initialState, pageAndDataState);\n // Take another pass and recalculate the schema and data based on the default data\n // We do this to avoid passing undefined for the whole form state when the form first renders\n initialState = recalculateSchemaAndData(initialState);\n\n return initialState;\n}\n\n"]}
\ No newline at end of file
+{"version":3,"sources":["../../../src/js/state/helpers.js"],"names":["updateRequiredFields","isContentExpanded","setHiddenFields","removeHiddenData","updateSchemaFromUiSchema","replaceRefSchemas","updateItemsSchema","updateSchemaAndData","recalculateSchemaAndData","createInitialState","isHiddenField","schema","get","path","data","reduce","current","next","uiSchema","formData","index","type","newRequired","Object","keys","properties","requiredArray","nextProp","field","isRequired","arrayHasField","some","prop","filter","concat","required","newSchema","currentSchema","nextSchema","length","newItemSchemas","items","map","item","idx","newItem","matcher","containingObject","slice","updatedSchema","hideIf","expandUnder","expandUnderCondition","newProperties","undefined","nextData","newItems","updateSchema","newSchemaProps","definitions","Error","$ref","refPath","replace","split","definition","fieldData","Array","isArray","additionalItems","fillIn","fill","updatedItems","newData","initialState","pages","state","pageKey","page","newState","showPagePerItem","arrayData","arrayPath","editMode","formConfig","submission","status","errorMessage","id","timestamp","hasAttemptedSubmit","formId","loadedData","metadata","reviewPageView","openChapters","viewedPages","Set","trackingPrefix","pageAndDataState","defaultDefinitions","isArrayPage","initialData","itemFilter","preSubmitInfo"],"mappings":"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","file":"helpers.js","sourcesContent":["import _ from 'lodash/fp';\nimport { getDefaultFormState } from '@department-of-veterans-affairs/react-jsonschema-form/lib/utils';\n\nimport {\n checkValidSchema,\n createFormPageList\n} from '../helpers';\n\nfunction isHiddenField(schema) {\n return !!schema['ui:collapsed'] || !!schema['ui:hidden'];\n}\n\nfunction get(path, data) {\n return path.reduce((current, next) => {\n return typeof current === 'undefined' ? current : current[next];\n }, data);\n}\n\n/*\n * This function goes through a schema/uiSchema and updates the required array\n * based on any ui:required field properties in the uiSchema.\n *\n * If no required fields are changing, it makes sure to not mutate the existing schema,\n * so we can still take advantage of any shouldComponentUpdate optimizations\n */\nexport function updateRequiredFields(schema, uiSchema, formData, index = null) {\n if (!uiSchema) {\n return schema;\n }\n\n if (schema.type === 'object') {\n const newRequired = Object.keys(schema.properties).reduce((requiredArray, nextProp) => {\n const field = uiSchema[nextProp];\n if (field && field['ui:required']) {\n const isRequired = field['ui:required'](formData, index);\n const arrayHasField = requiredArray.some(prop => prop === nextProp);\n\n if (arrayHasField && !isRequired) {\n return requiredArray.filter(prop => prop !== nextProp);\n } else if (!arrayHasField && isRequired) {\n return requiredArray.concat(nextProp);\n }\n\n return requiredArray;\n }\n\n return requiredArray;\n }, schema.required || []);\n\n const newSchema = Object.keys(schema.properties).reduce((currentSchema, nextProp) => {\n if (uiSchema) {\n const nextSchema = updateRequiredFields(currentSchema.properties[nextProp], uiSchema[nextProp], formData, index);\n if (nextSchema !== currentSchema.properties[nextProp]) {\n return _.set(['properties', nextProp], nextSchema, currentSchema);\n }\n }\n\n return currentSchema;\n }, schema);\n\n if (newSchema.required !== newRequired && (newSchema.required || newRequired.length > 0)) {\n return _.set('required', newRequired, newSchema);\n }\n\n return newSchema;\n }\n\n if (schema.type === 'array') {\n // each item has its own schema, so we need to update the required fields on those schemas\n // and then check for differences\n const newItemSchemas = schema.items.map((item, idx) => updateRequiredFields(item, uiSchema.items, formData, idx));\n if (newItemSchemas.some((newItem, idx) => newItem !== schema.items[idx])) {\n return _.set('items', newItemSchemas, schema);\n }\n }\n\n return schema;\n}\n\nexport function isContentExpanded(data, matcher) {\n if (typeof matcher === 'undefined') {\n return !!data;\n } else if (typeof matcher === 'function') {\n return matcher(data);\n }\n\n return data === matcher;\n}\n\n/*\n * This steps through a schema and sets any fields to hidden, based on a\n * hideIf function from uiSchema and the current page data. Sets 'ui:hidden'\n * which is a non-standard JSON Schema property\n *\n * The path parameter will contain the path, relative to formData, to the\n * form data corresponding to the current schema object\n */\nexport function setHiddenFields(schema, uiSchema, formData, path = []) {\n if (!uiSchema) {\n return schema;\n }\n\n // expandUnder fields are relative to the parent object of the current\n // field, so get that object using path here\n const containingObject = get(path.slice(0, -1), formData) || formData;\n\n let updatedSchema = schema;\n const hideIf = get(['ui:options', 'hideIf'], uiSchema);\n const index = path.reduce((current, next) => {\n return typeof next === 'number' ? next : current;\n }, null);\n\n if (hideIf && hideIf(formData, index)) {\n if (!updatedSchema['ui:hidden']) {\n updatedSchema = _.set('ui:hidden', true, updatedSchema);\n }\n } else if (updatedSchema['ui:hidden']) {\n updatedSchema = _.unset('ui:hidden', updatedSchema);\n }\n\n const expandUnder = get(['ui:options', 'expandUnder'], uiSchema);\n const expandUnderCondition = get(['ui:options', 'expandUnderCondition'], uiSchema);\n if (expandUnder && !isContentExpanded(containingObject[expandUnder], expandUnderCondition)) {\n if (!updatedSchema['ui:collapsed']) {\n updatedSchema = _.set('ui:collapsed', true, updatedSchema);\n }\n } else if (updatedSchema['ui:collapsed']) {\n updatedSchema = _.unset('ui:collapsed', updatedSchema);\n }\n\n if (updatedSchema.type === 'object') {\n const newProperties = Object.keys(updatedSchema.properties).reduce((current, next) => {\n const newSchema = setHiddenFields(updatedSchema.properties[next], uiSchema[next], formData, path.concat(next));\n\n if (newSchema !== updatedSchema.properties[next]) {\n return _.set(next, newSchema, current);\n }\n\n return current;\n }, updatedSchema.properties);\n\n if (newProperties !== updatedSchema.properties) {\n return _.set('properties', newProperties, updatedSchema);\n }\n }\n\n if (updatedSchema.type === 'array') {\n // each item has its own schema, so we need to update the required fields on those schemas\n // and then check for differences\n const newItemSchemas = updatedSchema.items.map((item, idx) =>\n setHiddenFields(item, uiSchema.items, formData, path.concat(idx))\n );\n\n if (newItemSchemas.some((newItem, idx) => newItem !== updatedSchema.items[idx])) {\n return _.set('items', newItemSchemas, updatedSchema);\n }\n }\n\n return updatedSchema;\n}\n\n/*\n * Steps through data and removes any fields that are marked as hidden\n * This is done so that hidden fields don’t cause validation errors that\n * a user can’t see.\n */\nexport function removeHiddenData(schema, data) {\n // null is necessary here because Rails 4 will convert empty arrays to null\n // In the forms, there's no difference between an empty array and null or undefined\n if (isHiddenField(schema) || typeof data === 'undefined' || data === null) {\n return undefined;\n }\n\n if (schema.type === 'object') {\n return Object.keys(data).reduce((current, next) => {\n if (typeof data[next] !== 'undefined' && schema.properties[next]) {\n const nextData = removeHiddenData(schema.properties[next], data[next]);\n\n // if the data was removed, then just unset it\n if (typeof nextData === 'undefined') {\n return _.unset(next, current);\n }\n\n // if data was updated (like a nested prop was removed), update it\n if (nextData !== data[next]) {\n return _.set(next, nextData, current);\n }\n }\n\n return current;\n }, data);\n }\n\n if (schema.type === 'array') {\n const newItems = data.map((item, index) => {\n return removeHiddenData(schema.items[index], item);\n });\n\n if (newItems.some((newItem, idx) => newItem !== data[idx])) {\n return newItems;\n }\n\n return data;\n }\n\n return data;\n}\n\n/*\n * This is similar to the hidden fields schema function above, except more general.\n * It will step through a schema and replace parts of it based on an updateSchema\n * function in uiSchema. This means the schema can be re-calculated based on data\n * a user has entered.\n */\nexport function updateSchemaFromUiSchema(schema, uiSchema, formData, index = null, path = []) {\n if (!uiSchema) {\n return schema;\n }\n\n let currentSchema = schema;\n\n if (currentSchema.type === 'object') {\n const newSchema = Object.keys(currentSchema.properties).reduce((current, next) => {\n const nextProp = updateSchemaFromUiSchema(current.properties[next], uiSchema[next], formData, index, path.concat(next));\n\n if (current.properties[next] !== nextProp) {\n return _.set(['properties', next], nextProp, current);\n }\n\n return current;\n }, currentSchema);\n\n if (newSchema !== schema) {\n currentSchema = newSchema;\n }\n }\n\n if (currentSchema.type === 'array') {\n // each item has its own schema, so we need to update the required fields on those schemas\n // and then check for differences\n const newItemSchemas = currentSchema.items.map((item, idx) =>\n updateSchemaFromUiSchema(item, uiSchema.items, formData, idx, path.concat(idx))\n );\n\n if (newItemSchemas.some((newItem, idx) => newItem !== currentSchema.items[idx])) {\n currentSchema = _.set('items', newItemSchemas, currentSchema);\n }\n }\n\n const updateSchema = get(['ui:options', 'updateSchema'], uiSchema);\n\n if (updateSchema) {\n const newSchemaProps = updateSchema(formData, currentSchema, uiSchema, index, path);\n\n const newSchema = Object.keys(newSchemaProps).reduce((current, next) => {\n if (newSchemaProps[next] !== schema[next]) {\n return _.set(next, newSchemaProps[next], current);\n }\n\n return current;\n }, currentSchema);\n\n if (newSchema !== currentSchema) {\n return newSchema;\n }\n }\n\n return currentSchema;\n}\n\nexport function replaceRefSchemas(schema, definitions, path = '') {\n // this can happen if you import a field that doesn’t exist from a schema\n if (!schema) {\n throw new Error(`Schema is undefined at ${path}`);\n }\n if (schema.$ref) {\n // There’s a whole spec for JSON pointers, but we don’t use anything more complicated\n // than this so far\n const refPath = schema.$ref.replace('#/definitions/', '').split('/');\n const definition = get(refPath, definitions);\n if (!definition) {\n throw new Error(`Missing definition for ${schema.$ref} at ${path}. You probably need to add it to defaultDefinitions`);\n }\n\n return replaceRefSchemas(definition, definitions, path);\n }\n\n if (schema.type === 'object') {\n const newSchema = Object.keys(schema.properties).reduce((current, next) => {\n const nextProp = replaceRefSchemas(schema.properties[next], definitions, `${path}.${next}`);\n\n if (current.properties[next] !== nextProp) {\n return _.set(['properties', next], nextProp, current);\n }\n\n return current;\n }, schema);\n\n return newSchema;\n }\n\n if (schema.type === 'array') {\n const newItems = replaceRefSchemas(schema.items, definitions, `${path}.items`);\n\n if (newItems !== schema.items) {\n return _.set('items', newItems, schema);\n }\n }\n\n return schema;\n}\n\n/**\n * This function updates an array schema to use the array of\n * item schema format and keeps that array in sync with the\n * data in that array in the form data.\n *\n * This allows us to have conditional fields for each array item,\n * because our conditional field implementation depends on modifying\n * schemas\n *\n * @param {Object} schema The current JSON Schema object\n * @param {any} fieldData The data associated with the current schema\n */\nexport function updateItemsSchema(schema, fieldData = null) {\n if (schema.type === 'array') {\n let newSchema = schema;\n\n // This happens the first time this function is called when\n // generating the form\n if (!Array.isArray(schema.items)) {\n newSchema = _.assign(schema, {\n items: [],\n additionalItems: schema.items\n });\n }\n\n if (!fieldData) {\n // If there’s no data, the list of schemas should be empty\n newSchema = _.set('items', [], newSchema);\n } else if (fieldData.length > newSchema.items.length) {\n // Here we’re filling in the items array to make it the same\n // length as the array of form data. This happens when you add\n // another record on the form, mainly.\n const fillIn = Array(fieldData.length - newSchema.items.length)\n .fill(newSchema.additionalItems);\n newSchema = _.set('items', newSchema.items.concat(fillIn), newSchema);\n } else if (fieldData.length < newSchema.items.length) {\n // If someone removed a record we’re removing the last schema item\n // This may not be the actual removed schema, but the schemas will\n // always be updated in the next step\n newSchema = _.set('items', _.dropRight(1, newSchema.items), newSchema);\n }\n\n const updatedItems = newSchema.items.map(\n (item, index) => updateItemsSchema(item, fieldData[index])\n );\n if (newSchema.items.some((item, index) => item !== updatedItems[index])) {\n return _.set('items', updatedItems, newSchema);\n }\n\n return newSchema;\n }\n\n if (schema.type === 'object') {\n const newSchema = Object.keys(schema.properties).reduce((current, next) => {\n const nextProp = updateItemsSchema(schema.properties[next], fieldData ? fieldData[next] : null);\n\n if (current.properties[next] !== nextProp) {\n return _.set(['properties', next], nextProp, current);\n }\n\n return current;\n }, schema);\n\n return newSchema;\n }\n\n return schema;\n}\n\n/**\n * This is the main sequence of updates that happens when data is changed\n * on a form. Most updates are applied to the schema, except that the data\n * is updated to remove newly hidden data\n *\n * @param {Object} schema The current JSON Schema\n * @param {Object} uiSchema The current UI Schema (does not change)\n * @param {Object} formData Flattened data for the entire form\n */\nexport function updateSchemaAndData(schema, uiSchema, formData) {\n let newSchema = updateItemsSchema(schema, formData);\n newSchema = updateRequiredFields(newSchema, uiSchema, formData);\n\n // Update the schema with any fields that are now hidden because of the data change\n newSchema = setHiddenFields(newSchema, uiSchema, formData);\n\n // Update the schema with any general updates based on the new data\n newSchema = updateSchemaFromUiSchema(newSchema, uiSchema, formData);\n\n // Remove any data that’s now hidden in the schema\n const newData = removeHiddenData(newSchema, formData);\n\n // We need to do this again because array data might have been removed\n newSchema = updateItemsSchema(newSchema, newData);\n\n checkValidSchema(newSchema);\n\n return {\n data: newData,\n schema: newSchema\n };\n}\n\nexport function recalculateSchemaAndData(initialState) {\n return Object.keys(initialState.pages)\n .reduce((state, pageKey) => {\n // on each data change, we need to do the following steps\n // Recalculate any required fields, based on the new data\n const page = state.pages[pageKey];\n const formData = initialState.data;\n\n const { data, schema } = updateSchemaAndData(page.schema, page.uiSchema, formData);\n\n let newState = state;\n\n if (formData !== data) {\n newState = _.set('data', data, state);\n }\n\n if (page.schema !== schema) {\n newState = _.set(['pages', pageKey, 'schema'], schema, newState);\n }\n\n if (page.showPagePerItem) {\n const arrayData = _.get(page.arrayPath, newState.data) || [];\n // If an item was added or removed for the data used by a showPagePerItem page,\n // we have to reset everything because we can’t match the edit states to rows directly\n // This will rarely ever be noticeable\n if (page.editMode.length !== arrayData.length) {\n newState = _.set(['pages', pageKey, 'editMode'], arrayData.map(() => false), newState);\n }\n }\n\n return newState;\n }, initialState);\n}\n\nexport function createInitialState(formConfig) {\n let initialState = {\n submission: {\n status: false,\n errorMessage: false,\n id: false,\n timestamp: false,\n hasAttemptedSubmit: false\n },\n formId: formConfig.formId,\n loadedData: {\n formData: {},\n metadata: {}\n },\n reviewPageView: {\n openChapters: [],\n viewedPages: new Set()\n },\n trackingPrefix: formConfig.trackingPrefix\n };\n\n const pageAndDataState = createFormPageList(formConfig)\n .reduce((state, page) => {\n const definitions = _.assign(formConfig.defaultDefinitions || {}, page.schema.definitions);\n let schema = replaceRefSchemas(page.schema, definitions, page.pageKey);\n // Throw an error if the new schema is invalid\n checkValidSchema(schema);\n schema = updateItemsSchema(schema);\n const isArrayPage = page.showPagePerItem;\n const data = getDefaultFormState(schema, page.initialData, schema.definitions);\n\n /* eslint-disable no-param-reassign */\n state.pages[page.pageKey] = {\n uiSchema: page.uiSchema,\n schema,\n editMode: isArrayPage ? [] : false,\n showPagePerItem: page.showPagePerItem,\n arrayPath: page.arrayPath,\n itemFilter: page.itemFilter\n };\n\n state.data = _.merge(state.data, data);\n /* eslint-enable no-param-reassign */\n\n return state;\n }, {\n data: {},\n pages: {},\n });\n\n // Initialize the preSubmit flag if one was specified\n const preSubmitInfo = formConfig.preSubmitInfo;\n if (preSubmitInfo && preSubmitInfo.field) {\n pageAndDataState.data[preSubmitInfo.field] = false;\n }\n\n initialState = _.assign(initialState, pageAndDataState);\n // Take another pass and recalculate the schema and data based on the default data\n // We do this to avoid passing undefined for the whole form state when the form first renders\n initialState = recalculateSchemaAndData(initialState);\n\n return initialState;\n}\n"]}
\ No newline at end of file
diff --git a/lib/js/state/reducers.js b/lib/js/state/reducers.js
index ca39c3b..fa2a778 100644
--- a/lib/js/state/reducers.js
+++ b/lib/js/state/reducers.js
@@ -14,6 +14,8 @@ var _set3 = _interopRequireDefault(_set2);
var _OPEN_REVIEW_CHAPTER$;
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
var _actions = require('../actions');
var _helpers = require('../state/helpers');
@@ -51,8 +53,8 @@ exports.default = (_OPEN_REVIEW_CHAPTER$ = {}, _defineProperty(_OPEN_REVIEW_CHAP
return (0, _set3.default)(['pages', action.page, 'editMode', action.index], action.edit, state);
}
return (0, _set3.default)(['pages', action.page, 'editMode'], action.edit, state);
-}), _defineProperty(_OPEN_REVIEW_CHAPTER$, _actions.SET_PRIVACY_AGREEMENT, function (state, action) {
- return (0, _set3.default)('data.privacyAgreementAccepted', action.privacyAgreementAccepted, state);
+}), _defineProperty(_OPEN_REVIEW_CHAPTER$, _actions.SET_PRE_SUBMIT, function (state, action) {
+ return _extends({}, state, { data: _extends({}, state.data, _defineProperty({}, action.preSubmitField, action.preSubmitAccepted)) });
}), _defineProperty(_OPEN_REVIEW_CHAPTER$, _actions.SET_SUBMISSION, function (state, action) {
var newState = (0, _set3.default)(['submission', action.field], action.value, state);
if (action.extra) {
diff --git a/lib/js/state/reducers.js.map b/lib/js/state/reducers.js.map
index 639d9a2..244791e 100644
--- a/lib/js/state/reducers.js.map
+++ b/lib/js/state/reducers.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../../../src/js/state/reducers.js"],"names":["OPEN_REVIEW_CHAPTER","state","action","openChapters","reviewPageView","openedChapter","CLOSE_REVIEW_CHAPTER","filter","value","closedChapter","newState","viewedPages","Set","pageKeys","forEach","add","pageKey","SET_DATA","data","SET_EDIT_MODE","pages","page","showPagePerItem","index","edit","SET_PRIVACY_AGREEMENT","privacyAgreementAccepted","SET_SUBMISSION","field","extra","submission","SET_SUBMITTED","response","status","SET_VIEWED_PAGES"],"mappings":";;;;;;;;;;;;;;;;AAEA;;AAWA;;;;;;;;sFAKGA,4B,EAAsB,UAACC,KAAD,EAAQC,MAAR,EAAmB;AACxC,MAAMC,4CACDF,MAAMG,cAAN,CAAqBD,YADpB,IAEJD,OAAOG,aAFH,EAAN;;AAKA,SAAO,mBAAM,6BAAN,EAAqCF,YAArC,EAAmDF,KAAnD,CAAP;AACD,C,0CACAK,6B,EAAuB,UAACL,KAAD,EAAQC,MAAR,EAAmB;AACzC,MAAMC,eAAeF,MAClBG,cADkB,CAElBD,YAFkB,CAGlBI,MAHkB,CAGX;AAAA,WAASC,UAAUN,OAAOO,aAA1B;AAAA,GAHW,CAArB;;AAKA,MAAMC,WAAW,mBAAM,6BAAN,EAAqCP,YAArC,EAAmDF,KAAnD,CAAjB;;AAEA,MAAMU,cAAc,IAAIC,GAAJ,CAAQX,MACzBG,cADyB,CAEzBO,WAFiB,CAApB;;AAIAT,SAAOW,QAAP,CAAgBC,OAAhB,CAAwB;AAAA,WAAWH,YAAYI,GAAZ,CAAgBC,OAAhB,CAAX;AAAA,GAAxB;;AAEA,SAAO,mBAAM,4BAAN,EAAoCL,WAApC,EAAiDD,QAAjD,CAAP;AACD,C,0CACAO,iB,EAAW,UAAChB,KAAD,EAAQC,MAAR,EAAmB;AAC7B,MAAMQ,WAAW,mBAAM,MAAN,EAAcR,OAAOgB,IAArB,EAA2BjB,KAA3B,CAAjB;;AAEA,SAAO,uCAAyBS,QAAzB,CAAP;AACD,C,0CACAS,sB,EAAgB,UAAClB,KAAD,EAAQC,MAAR,EAAmB;AAClC,MAAID,MAAMmB,KAAN,CAAYlB,OAAOmB,IAAnB,EAAyBC,eAA7B,EAA8C;AAC5C,WAAO,mBAAM,CAAC,OAAD,EAAUpB,OAAOmB,IAAjB,EAAuB,UAAvB,EAAmCnB,OAAOqB,KAA1C,CAAN,EAAwDrB,OAAOsB,IAA/D,EAAqEvB,KAArE,CAAP;AACD;AACD,SAAO,mBAAM,CAAC,OAAD,EAAUC,OAAOmB,IAAjB,EAAuB,UAAvB,CAAN,EAA0CnB,OAAOsB,IAAjD,EAAuDvB,KAAvD,CAAP;AACD,C,0CACAwB,8B,EAAwB,UAACxB,KAAD,EAAQC,MAAR,EAAmB;AAC1C,SAAO,mBAAM,+BAAN,EAAuCA,OAAOwB,wBAA9C,EAAwEzB,KAAxE,CAAP;AACD,C,0CACA0B,uB,EAAiB,UAAC1B,KAAD,EAAQC,MAAR,EAAmB;AACnC,MAAMQ,WAAW,mBAAM,CAAC,YAAD,EAAeR,OAAO0B,KAAtB,CAAN,EAAoC1B,OAAOM,KAA3C,EAAkDP,KAAlD,CAAjB;AACA,MAAIC,OAAO2B,KAAX,EAAkB;AAChBnB,aAASoB,UAAT,CAAoBD,KAApB,GAA4B3B,OAAO2B,KAAnC;AACD;;AAED,SAAOnB,QAAP;AACD,C,0CACAqB,sB,EAAgB,UAAC9B,KAAD,EAAQC,MAAR,EAAmB;AAClC,MAAM4B,aAAa,sBAAS7B,MAAM6B,UAAf,EAA2B;AAC5CE,cAAU9B,OAAO8B,QAD2B;AAE5CC,YAAQ;AAFoC,GAA3B,CAAnB;;AAKA,SAAO,mBAAM,YAAN,EAAoBH,UAApB,EAAgC7B,KAAhC,CAAP;AACD,C,0CACAiC,yB,EAAmB,UAACjC,KAAD,EAAQC,MAAR,EAAmB;AACrC,MAAMS,cAAc,IAAIC,GAAJ,CAAQX,MACzBG,cADyB,CAEzBO,WAFiB,CAApB;;AAIAT,SAAOW,QAAP,CAAgBC,OAAhB,CAAwB;AAAA,WAAWH,YAAYI,GAAZ,CAAgBC,OAAhB,CAAX;AAAA,GAAxB;;AAEA,SAAO,mBAAM,4BAAN,EAAoCL,WAApC,EAAiDV,KAAjD,CAAP;AACD,C","file":"reducers.js","sourcesContent":["import _ from 'lodash/fp';\n\nimport {\n CLOSE_REVIEW_CHAPTER,\n OPEN_REVIEW_CHAPTER,\n SET_DATA,\n SET_EDIT_MODE,\n SET_PRIVACY_AGREEMENT,\n SET_SUBMISSION,\n SET_SUBMITTED,\n SET_VIEWED_PAGES\n} from '../actions';\n\nimport {\n recalculateSchemaAndData\n} from '../state/helpers';\n\nexport default {\n [OPEN_REVIEW_CHAPTER]: (state, action) => {\n const openChapters = [\n ...state.reviewPageView.openChapters,\n action.openedChapter\n ];\n\n return _.set('reviewPageView.openChapters', openChapters, state);\n },\n [CLOSE_REVIEW_CHAPTER]: (state, action) => {\n const openChapters = state\n .reviewPageView\n .openChapters\n .filter(value => value !== action.closedChapter);\n\n const newState = _.set('reviewPageView.openChapters', openChapters, state);\n\n const viewedPages = new Set(state\n .reviewPageView\n .viewedPages);\n\n action.pageKeys.forEach(pageKey => viewedPages.add(pageKey));\n\n return _.set('reviewPageView.viewedPages', viewedPages, newState);\n },\n [SET_DATA]: (state, action) => {\n const newState = _.set('data', action.data, state);\n\n return recalculateSchemaAndData(newState);\n },\n [SET_EDIT_MODE]: (state, action) => {\n if (state.pages[action.page].showPagePerItem) {\n return _.set(['pages', action.page, 'editMode', action.index], action.edit, state);\n }\n return _.set(['pages', action.page, 'editMode'], action.edit, state);\n },\n [SET_PRIVACY_AGREEMENT]: (state, action) => {\n return _.set('data.privacyAgreementAccepted', action.privacyAgreementAccepted, state);\n },\n [SET_SUBMISSION]: (state, action) => {\n const newState = _.set(['submission', action.field], action.value, state);\n if (action.extra) {\n newState.submission.extra = action.extra;\n }\n\n return newState;\n },\n [SET_SUBMITTED]: (state, action) => {\n const submission = _.assign(state.submission, {\n response: action.response,\n status: 'applicationSubmitted'\n });\n\n return _.set('submission', submission, state);\n },\n [SET_VIEWED_PAGES]: (state, action) => {\n const viewedPages = new Set(state\n .reviewPageView\n .viewedPages);\n\n action.pageKeys.forEach(pageKey => viewedPages.add(pageKey));\n\n return _.set('reviewPageView.viewedPages', viewedPages, state);\n }\n};\n"]}
\ No newline at end of file
+{"version":3,"sources":["../../../src/js/state/reducers.js"],"names":["OPEN_REVIEW_CHAPTER","state","action","openChapters","reviewPageView","openedChapter","CLOSE_REVIEW_CHAPTER","filter","value","closedChapter","newState","viewedPages","Set","pageKeys","forEach","add","pageKey","SET_DATA","data","SET_EDIT_MODE","pages","page","showPagePerItem","index","edit","SET_PRE_SUBMIT","preSubmitField","preSubmitAccepted","SET_SUBMISSION","field","extra","submission","SET_SUBMITTED","response","status","SET_VIEWED_PAGES"],"mappings":"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","file":"reducers.js","sourcesContent":["import _ from 'lodash/fp';\n\nimport {\n CLOSE_REVIEW_CHAPTER,\n OPEN_REVIEW_CHAPTER,\n SET_DATA,\n SET_EDIT_MODE,\n SET_PRE_SUBMIT,\n SET_SUBMISSION,\n SET_SUBMITTED,\n SET_VIEWED_PAGES\n} from '../actions';\n\nimport {\n recalculateSchemaAndData\n} from '../state/helpers';\n\nexport default {\n [OPEN_REVIEW_CHAPTER]: (state, action) => {\n const openChapters = [\n ...state.reviewPageView.openChapters,\n action.openedChapter\n ];\n\n return _.set('reviewPageView.openChapters', openChapters, state);\n },\n [CLOSE_REVIEW_CHAPTER]: (state, action) => {\n const openChapters = state\n .reviewPageView\n .openChapters\n .filter(value => value !== action.closedChapter);\n\n const newState = _.set('reviewPageView.openChapters', openChapters, state);\n\n const viewedPages = new Set(state\n .reviewPageView\n .viewedPages);\n\n action.pageKeys.forEach(pageKey => viewedPages.add(pageKey));\n\n return _.set('reviewPageView.viewedPages', viewedPages, newState);\n },\n [SET_DATA]: (state, action) => {\n const newState = _.set('data', action.data, state);\n\n return recalculateSchemaAndData(newState);\n },\n [SET_EDIT_MODE]: (state, action) => {\n if (state.pages[action.page].showPagePerItem) {\n return _.set(['pages', action.page, 'editMode', action.index], action.edit, state);\n }\n return _.set(['pages', action.page, 'editMode'], action.edit, state);\n },\n [SET_PRE_SUBMIT]: (state, action) => {\n return { ...state, data: { ...state.data, [action.preSubmitField]: action.preSubmitAccepted } };\n },\n [SET_SUBMISSION]: (state, action) => {\n const newState = _.set(['submission', action.field], action.value, state);\n if (action.extra) {\n newState.submission.extra = action.extra;\n }\n\n return newState;\n },\n [SET_SUBMITTED]: (state, action) => {\n const submission = _.assign(state.submission, {\n response: action.response,\n status: 'applicationSubmitted'\n });\n\n return _.set('submission', submission, state);\n },\n [SET_VIEWED_PAGES]: (state, action) => {\n const viewedPages = new Set(state\n .reviewPageView\n .viewedPages);\n\n action.pageKeys.forEach(pageKey => viewedPages.add(pageKey));\n\n return _.set('reviewPageView.viewedPages', viewedPages, state);\n }\n};\n"]}
\ No newline at end of file
diff --git a/lib/js/validation.js b/lib/js/validation.js
index 6177ed6..d780278 100644
--- a/lib/js/validation.js
+++ b/lib/js/validation.js
@@ -240,10 +240,6 @@ function isValidForm(form, pageListByChapters) {
var v = new _jsonschema.Validator();
- if (!form.data.privacyAgreementAccepted) {
- return { isValid: false };
- }
-
return validPages.reduce(function (_ref, page) {
var isValid = _ref.isValid,
errors = _ref.errors;
diff --git a/lib/js/validation.js.map b/lib/js/validation.js.map
index 7399c0f..3ca81c7 100644
--- a/lib/js/validation.js.map
+++ b/lib/js/validation.js.map
@@ -1 +1 @@
-{"version":3,"sources":["../../src/js/validation.js"],"names":["transformErrors","uiSchemaValidate","errorSchemaIsValid","isValidForm","validateSSN","validateDate","validateMonthYear","validateCurrentOrPastDate","validateCurrentOrPastMonthYear","validateFutureDateIfExpectedGrad","validateCurrentOrPastYear","validateMatch","convertToDateField","validateDateRange","getFileError","validateFileField","validateBooleanGroup","validateAutosuggestOption","defaultMessages","required","maxLength","max","minLength","min","format","type","getMessage","path","name","uiSchema","errorArgument","pathSpecificMessage","cleanPath","replace","errors","newErrors","map","error","property","argument","message","newMessage","schema","formData","currentIndex","currentData","items","forEach","item","index","newPath","currentSchema","length","additionalItems","currentErrors","__errors","addError","push","Object","keys","filter","prop","startsWith","nextPath","properties","validations","pathErrors","validation","validator","options","errorSchema","every","form","pageListByChapters","pageConfigs","validPages","pages","pageKey","data","v","Validator","privacyAgreementAccepted","isValid","reduce","page","showPagePerItem","itemFilter","arrayPath","arrayData","result","validate","valid","customErrors","concat","ssn","dateString","day","month","year","errorMessages","futureDate","highSchool","status","field1","field2","dateStr","date","dateField","part","datePart","value","dateRange","fromDate","from","toDate","to","pattern","file","errorMessage","uploading","confirmationCode","fileList","msg","userGroup","atLeastOne","group","widget","id","label"],"mappings":"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","file":"validation.js","sourcesContent":["import _ from 'lodash/fp';\nimport { Validator } from 'jsonschema';\n\nimport { isActivePage, parseISODate } from './helpers';\nimport {\n isValidSSN,\n isValidPartialDate,\n isValidCurrentOrPastDate,\n isValidCurrentOrPastYear,\n isValidCurrentOrFutureMonthYear,\n isValidDateRange,\n isValidPartialMonthYear,\n isValidPartialMonthYearInPast\n} from './utilities/validations';\n\n/*\n * This contains the code for supporting our own custom validations and messages\n */\n\n/*\n * Override the default messages for these json schema error types\n */\nconst defaultMessages = {\n required: 'Please provide a response',\n 'enum': 'Please select a valid option',\n maxLength: (max) => `This field should be less than ${max} characters`,\n minLength: (min) => `This field should be at least ${min} character(s)`,\n format: (type) => {\n if (type === 'email') {\n return 'Please enter a valid email address';\n }\n\n return 'Please enter a valid value';\n }\n};\n\nfunction getMessage(path, name, uiSchema, errorArgument) {\n let pathSpecificMessage;\n if (path === 'instance') {\n pathSpecificMessage = _.get(['ui:errorMessages', name], uiSchema);\n } else {\n const cleanPath = path.replace('instance.', '').replace(/\\[\\d+\\]/g, '.items');\n pathSpecificMessage = _.get(`${cleanPath}['ui:errorMessages'].${name}`, uiSchema);\n }\n\n if (pathSpecificMessage) {\n return pathSpecificMessage;\n }\n\n return typeof defaultMessages[name] === 'function'\n ? defaultMessages[name](errorArgument)\n : defaultMessages[name];\n}\n\n/*\n * This takes the list of errors outputted by the json schema node library\n * and moves the required errors to the missing field, rather than the containing\n * object.\n *\n * It also replaces the error messages with any form specific messages.\n */\nexport function transformErrors(errors, uiSchema) {\n const newErrors = errors.map(error => {\n if (error.name === 'required') {\n const path = `${error.property}.${error.argument}`;\n return _.assign(error, {\n property: path,\n message: getMessage(path, error.name, uiSchema, error.argument)\n });\n }\n\n const newMessage = getMessage(error.property, error.name, uiSchema, error.argument);\n if (newMessage) {\n return _.set('message', newMessage, error);\n }\n\n return error;\n });\n\n return newErrors;\n}\n\n/**\n * This pulls custom validations specified in the uiSchema and validates the formData\n * against them.\n *\n * Expects validations that look like:\n *\n * someField: {\n * \"ui:validations\": [\n * someValidation\n * ]\n * }\n *\n * Each item in the ui:validations array can be a function OR an object:\n * - Functions are called with (in order)\n * pathErrors: Errors object for the field\n * currentData: Data for the field\n * formData: Current form data\n * schema: Current JSON Schema for the field\n * uiSchema['ui:errorMessages']: Error messsage object (if available) for the field\n * currentIndex: Used to select the correct field data to validate against\n * - Objects should have two properties, 'options' and 'validator'\n * options: Object (or anything, really) that will be passed to your validation function.\n * You can use this to allow your validation function to be configurable for\n * different fields on the form.\n * validator: Same signature as function above, but with extra 'options' object as the\n * second-to-last argument (...options, currentIndex)\n * Both versions of custom validators should call `addError()` to actually add any errors to the\n * errors object\n *\n * @param {Object} errors Errors object from rjsf, which includes an addError method\n * @param {Object} uiSchema The uiSchema for the current field\n * @param {Object} schema The schema for the current field\n * @param {Object} formData The (flattened) data for the entire form\n * @param {string} [path] The path to the current field relative to the root of the page.\n * @param {number} [currentIndex] Used to select the correct field data to validate against\n */\n\nexport function uiSchemaValidate(errors, uiSchema, schema, formData, path = '', currentIndex = null) {\n if (uiSchema && schema) {\n const currentData = path !== '' ? _.get(path, formData) : formData;\n if (uiSchema.items && currentData) {\n currentData.forEach((item, index) => {\n const newPath = `${path}[${index}]`;\n const currentSchema = index < schema.items.length\n ? schema.items[index]\n : schema.additionalItems;\n if (!_.get(newPath, errors)) {\n const currentErrors = path ? _.get(path, errors) : errors;\n currentErrors[index] = {\n __errors: [],\n addError(error) {\n this.__errors.push(error);\n }\n };\n }\n uiSchemaValidate(errors, uiSchema.items, currentSchema, formData, newPath, index);\n });\n } else if (!uiSchema.items) {\n Object.keys(uiSchema)\n .filter(prop => !prop.startsWith('ui:'))\n .forEach((item) => {\n const nextPath = path !== '' ? `${path}.${item}` : item;\n if (!_.get(nextPath, errors)) {\n const currentErrors = path === ''\n ? errors\n : _.get(path, errors);\n\n currentErrors[item] = {\n __errors: [],\n addError(error) {\n this.__errors.push(error);\n }\n };\n }\n uiSchemaValidate(errors, uiSchema[item], schema.properties[item], formData, nextPath, currentIndex);\n });\n }\n\n const validations = uiSchema['ui:validations'];\n if (validations && currentData) {\n validations.forEach(validation => {\n const pathErrors = path ? _.get(path, errors) : errors;\n if (typeof validation === 'function') {\n validation(pathErrors, currentData, formData, schema, uiSchema['ui:errorMessages'], currentIndex);\n } else {\n validation.validator(pathErrors, currentData, formData, schema, uiSchema['ui:errorMessages'], validation.options, currentIndex);\n }\n });\n }\n }\n return errors;\n}\n\nexport function errorSchemaIsValid(errorSchema) {\n if (errorSchema && errorSchema.__errors && errorSchema.__errors.length) {\n return false;\n }\n\n return _.values(_.omit('__errors', errorSchema)).every(errorSchemaIsValid);\n}\n\nexport function isValidForm(form, pageListByChapters) {\n const pageConfigs = _.flatten(_.values(pageListByChapters));\n const validPages = Object.keys(form.pages)\n .filter(pageKey => isActivePage(_.find({ pageKey }, pageConfigs), form.data));\n\n const v = new Validator();\n\n if (!form.data.privacyAgreementAccepted) {\n return { isValid: false };\n }\n\n return validPages.reduce(({ isValid, errors }, page) => {\n const { uiSchema, schema, showPagePerItem, itemFilter, arrayPath } = form.pages[page];\n let formData = form.data;\n\n if (showPagePerItem) {\n const arrayData = formData[arrayPath];\n if (arrayData) {\n formData = _.set(arrayPath, itemFilter ? arrayData.filter(itemFilter) : arrayData, formData);\n } else {\n formData = _.unset(arrayPath, formData);\n }\n }\n\n const result = v.validate(\n formData,\n schema\n );\n\n if (result.valid) {\n const customErrors = {};\n uiSchemaValidate(customErrors, uiSchema, schema, formData);\n\n return {\n isValid: isValid && errorSchemaIsValid(customErrors),\n errors: errors.concat(customErrors)\n };\n }\n\n return {\n isValid: false,\n // removes PII\n errors: errors.concat(result.errors.map(_.unset('instance')))\n };\n }, { isValid: true, errors: [] });\n}\n\n\nexport function validateSSN(errors, ssn) {\n if (ssn && !isValidSSN(ssn)) {\n errors.addError('Please enter a valid 9 digit SSN (dashes allowed)');\n }\n}\n\nexport function validateDate(errors, dateString) {\n const { day, month, year } = parseISODate(dateString);\n if (!isValidPartialDate(day, month, year)) {\n errors.addError('Please provide a valid date');\n }\n}\n\nexport function validateMonthYear(errors, dateString) {\n const { month, year } = parseISODate(dateString);\n if (!isValidPartialMonthYear(month, year)) {\n errors.addError('Please provide a valid date');\n }\n}\n\n/**\n * Adds an error message to errors if a date is an invalid date or in the future.\n *\n * The message it adds can be customized in uiSchema.errorMessages.futureDate\n */\nexport function validateCurrentOrPastDate(errors, dateString, formData, schema, errorMessages = {}) {\n const { futureDate = 'Please provide a valid current or past date' } = errorMessages;\n validateDate(errors, dateString);\n const { day, month, year } = parseISODate(dateString);\n if (!isValidCurrentOrPastDate(day, month, year)) {\n errors.addError(futureDate);\n }\n}\n\nexport function validateCurrentOrPastMonthYear(errors, dateString, formData, schema, errorMessages = {}) {\n const { futureDate = 'Please provide a valid current or past date' } = errorMessages;\n validateMonthYear(errors, dateString);\n const { month, year } = parseISODate(dateString);\n if (!isValidPartialMonthYearInPast(month, year)) {\n errors.addError(futureDate);\n }\n}\n\n/**\n * Adds an error message to errors if a date is an invalid date or in the past.\n */\nexport function validateFutureDateIfExpectedGrad(errors, dateString, formData) {\n validateDate(errors, dateString);\n const { month, year } = parseISODate(dateString);\n if (formData.highSchool.status === 'graduationExpected' && !isValidCurrentOrFutureMonthYear(month, year)) {\n errors.addError('Please provide a valid future date');\n }\n}\n\n/**\n * Adds an error message to errors if an integer year value is not between 1900 and the current year.\n */\nexport function validateCurrentOrPastYear(errors, year) {\n if (!isValidCurrentOrPastYear(year)) {\n errors.addError('Please provide a valid year');\n }\n}\n\nexport function validateMatch(field1, field2) {\n return (errors, formData) => {\n if (formData[field1] !== formData[field2]) {\n errors[field2].addError('Please ensure your entries match');\n }\n };\n}\n\nexport function convertToDateField(dateStr) {\n const date = parseISODate(dateStr);\n return Object.keys(date).reduce((dateField, part) => {\n const datePart = {};\n datePart[part] = {\n value: date[part]\n };\n return _.assign(dateField, datePart);\n }, date);\n}\n\nexport function validateDateRange(errors, dateRange, formData, schema, errorMessages) {\n const fromDate = convertToDateField(dateRange.from);\n const toDate = convertToDateField(dateRange.to);\n\n if (!isValidDateRange(fromDate, toDate)) {\n errors.to.addError(errorMessages.pattern || 'To date must be after from date');\n }\n}\n\nexport function getFileError(file) {\n if (file.errorMessage) {\n return file.errorMessage;\n } else if (file.uploading) {\n return 'Uploading file...';\n } else if (!file.confirmationCode) {\n return 'Something went wrong...';\n }\n\n return null;\n}\n\nexport function validateFileField(errors, fileList) {\n fileList.forEach((file, index) => {\n const error = getFileError(file);\n\n if (error && !errors[index]) {\n /* eslint-disable no-param-reassign */\n errors[index] = {\n __errors: [],\n addError(msg) {\n this.__errors.push(msg);\n }\n };\n /* eslint-enable no-param-reassign */\n }\n\n if (error) {\n errors[index].addError(error);\n }\n });\n}\n\nexport function validateBooleanGroup(errors, userGroup, form, schema, errorMessages = {}) {\n const { atLeastOne = 'Please choose at least one option' } = errorMessages;\n const group = userGroup || {};\n if (!Object.keys(group).filter(item => group[item] === true).length) {\n errors.addError(atLeastOne);\n }\n}\n\nexport function validateAutosuggestOption(errors, formData) {\n if (formData &&\n formData.widget === 'autosuggest' &&\n !formData.id &&\n formData.label) {\n errors.addError('Please select an option from the suggestions');\n }\n}\n"]}
\ No newline at end of file
+{"version":3,"sources":["../../src/js/validation.js"],"names":["transformErrors","uiSchemaValidate","errorSchemaIsValid","isValidForm","validateSSN","validateDate","validateMonthYear","validateCurrentOrPastDate","validateCurrentOrPastMonthYear","validateFutureDateIfExpectedGrad","validateCurrentOrPastYear","validateMatch","convertToDateField","validateDateRange","getFileError","validateFileField","validateBooleanGroup","validateAutosuggestOption","defaultMessages","required","maxLength","max","minLength","min","format","type","getMessage","path","name","uiSchema","errorArgument","pathSpecificMessage","cleanPath","replace","errors","newErrors","map","error","property","argument","message","newMessage","schema","formData","currentIndex","currentData","items","forEach","item","index","newPath","currentSchema","length","additionalItems","currentErrors","__errors","addError","push","Object","keys","filter","prop","startsWith","nextPath","properties","validations","pathErrors","validation","validator","options","errorSchema","every","form","pageListByChapters","pageConfigs","validPages","pages","pageKey","data","v","Validator","reduce","page","isValid","showPagePerItem","itemFilter","arrayPath","arrayData","result","validate","valid","customErrors","concat","ssn","dateString","day","month","year","errorMessages","futureDate","highSchool","status","field1","field2","dateStr","date","dateField","part","datePart","value","dateRange","fromDate","from","toDate","to","pattern","file","errorMessage","uploading","confirmationCode","fileList","msg","userGroup","atLeastOne","group","widget","id","label"],"mappings":"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","file":"validation.js","sourcesContent":["import _ from 'lodash/fp';\nimport { Validator } from 'jsonschema';\n\nimport { isActivePage, parseISODate } from './helpers';\nimport {\n isValidSSN,\n isValidPartialDate,\n isValidCurrentOrPastDate,\n isValidCurrentOrPastYear,\n isValidCurrentOrFutureMonthYear,\n isValidDateRange,\n isValidPartialMonthYear,\n isValidPartialMonthYearInPast\n} from './utilities/validations';\n\n/*\n * This contains the code for supporting our own custom validations and messages\n */\n\n/*\n * Override the default messages for these json schema error types\n */\nconst defaultMessages = {\n required: 'Please provide a response',\n 'enum': 'Please select a valid option',\n maxLength: (max) => `This field should be less than ${max} characters`,\n minLength: (min) => `This field should be at least ${min} character(s)`,\n format: (type) => {\n if (type === 'email') {\n return 'Please enter a valid email address';\n }\n\n return 'Please enter a valid value';\n }\n};\n\nfunction getMessage(path, name, uiSchema, errorArgument) {\n let pathSpecificMessage;\n if (path === 'instance') {\n pathSpecificMessage = _.get(['ui:errorMessages', name], uiSchema);\n } else {\n const cleanPath = path.replace('instance.', '').replace(/\\[\\d+\\]/g, '.items');\n pathSpecificMessage = _.get(`${cleanPath}['ui:errorMessages'].${name}`, uiSchema);\n }\n\n if (pathSpecificMessage) {\n return pathSpecificMessage;\n }\n\n return typeof defaultMessages[name] === 'function'\n ? defaultMessages[name](errorArgument)\n : defaultMessages[name];\n}\n\n/*\n * This takes the list of errors outputted by the json schema node library\n * and moves the required errors to the missing field, rather than the containing\n * object.\n *\n * It also replaces the error messages with any form specific messages.\n */\nexport function transformErrors(errors, uiSchema) {\n const newErrors = errors.map(error => {\n if (error.name === 'required') {\n const path = `${error.property}.${error.argument}`;\n return _.assign(error, {\n property: path,\n message: getMessage(path, error.name, uiSchema, error.argument)\n });\n }\n\n const newMessage = getMessage(error.property, error.name, uiSchema, error.argument);\n if (newMessage) {\n return _.set('message', newMessage, error);\n }\n\n return error;\n });\n\n return newErrors;\n}\n\n/**\n * This pulls custom validations specified in the uiSchema and validates the formData\n * against them.\n *\n * Expects validations that look like:\n *\n * someField: {\n * \"ui:validations\": [\n * someValidation\n * ]\n * }\n *\n * Each item in the ui:validations array can be a function OR an object:\n * - Functions are called with (in order)\n * pathErrors: Errors object for the field\n * currentData: Data for the field\n * formData: Current form data\n * schema: Current JSON Schema for the field\n * uiSchema['ui:errorMessages']: Error messsage object (if available) for the field\n * currentIndex: Used to select the correct field data to validate against\n * - Objects should have two properties, 'options' and 'validator'\n * options: Object (or anything, really) that will be passed to your validation function.\n * You can use this to allow your validation function to be configurable for\n * different fields on the form.\n * validator: Same signature as function above, but with extra 'options' object as the\n * second-to-last argument (...options, currentIndex)\n * Both versions of custom validators should call `addError()` to actually add any errors to the\n * errors object\n *\n * @param {Object} errors Errors object from rjsf, which includes an addError method\n * @param {Object} uiSchema The uiSchema for the current field\n * @param {Object} schema The schema for the current field\n * @param {Object} formData The (flattened) data for the entire form\n * @param {string} [path] The path to the current field relative to the root of the page.\n * @param {number} [currentIndex] Used to select the correct field data to validate against\n */\n\nexport function uiSchemaValidate(errors, uiSchema, schema, formData, path = '', currentIndex = null) {\n if (uiSchema && schema) {\n const currentData = path !== '' ? _.get(path, formData) : formData;\n if (uiSchema.items && currentData) {\n currentData.forEach((item, index) => {\n const newPath = `${path}[${index}]`;\n const currentSchema = index < schema.items.length\n ? schema.items[index]\n : schema.additionalItems;\n if (!_.get(newPath, errors)) {\n const currentErrors = path ? _.get(path, errors) : errors;\n currentErrors[index] = {\n __errors: [],\n addError(error) {\n this.__errors.push(error);\n }\n };\n }\n uiSchemaValidate(errors, uiSchema.items, currentSchema, formData, newPath, index);\n });\n } else if (!uiSchema.items) {\n Object.keys(uiSchema)\n .filter(prop => !prop.startsWith('ui:'))\n .forEach((item) => {\n const nextPath = path !== '' ? `${path}.${item}` : item;\n if (!_.get(nextPath, errors)) {\n const currentErrors = path === ''\n ? errors\n : _.get(path, errors);\n\n currentErrors[item] = {\n __errors: [],\n addError(error) {\n this.__errors.push(error);\n }\n };\n }\n uiSchemaValidate(errors, uiSchema[item], schema.properties[item], formData, nextPath, currentIndex);\n });\n }\n\n const validations = uiSchema['ui:validations'];\n if (validations && currentData) {\n validations.forEach(validation => {\n const pathErrors = path ? _.get(path, errors) : errors;\n if (typeof validation === 'function') {\n validation(pathErrors, currentData, formData, schema, uiSchema['ui:errorMessages'], currentIndex);\n } else {\n validation.validator(pathErrors, currentData, formData, schema, uiSchema['ui:errorMessages'], validation.options, currentIndex);\n }\n });\n }\n }\n return errors;\n}\n\nexport function errorSchemaIsValid(errorSchema) {\n if (errorSchema && errorSchema.__errors && errorSchema.__errors.length) {\n return false;\n }\n\n return _.values(_.omit('__errors', errorSchema)).every(errorSchemaIsValid);\n}\n\nexport function isValidForm(form, pageListByChapters) {\n const pageConfigs = _.flatten(_.values(pageListByChapters));\n const validPages = Object.keys(form.pages)\n .filter(pageKey => isActivePage(_.find({ pageKey }, pageConfigs), form.data));\n\n const v = new Validator();\n\n return validPages.reduce(({ isValid, errors }, page) => {\n const { uiSchema, schema, showPagePerItem, itemFilter, arrayPath } = form.pages[page];\n let formData = form.data;\n\n if (showPagePerItem) {\n const arrayData = formData[arrayPath];\n if (arrayData) {\n formData = _.set(arrayPath, itemFilter ? arrayData.filter(itemFilter) : arrayData, formData);\n } else {\n formData = _.unset(arrayPath, formData);\n }\n }\n\n const result = v.validate(\n formData,\n schema\n );\n\n if (result.valid) {\n const customErrors = {};\n uiSchemaValidate(customErrors, uiSchema, schema, formData);\n\n return {\n isValid: isValid && errorSchemaIsValid(customErrors),\n errors: errors.concat(customErrors)\n };\n }\n\n return {\n isValid: false,\n // removes PII\n errors: errors.concat(result.errors.map(_.unset('instance')))\n };\n }, { isValid: true, errors: [] });\n}\n\n\nexport function validateSSN(errors, ssn) {\n if (ssn && !isValidSSN(ssn)) {\n errors.addError('Please enter a valid 9 digit SSN (dashes allowed)');\n }\n}\n\nexport function validateDate(errors, dateString) {\n const { day, month, year } = parseISODate(dateString);\n if (!isValidPartialDate(day, month, year)) {\n errors.addError('Please provide a valid date');\n }\n}\n\nexport function validateMonthYear(errors, dateString) {\n const { month, year } = parseISODate(dateString);\n if (!isValidPartialMonthYear(month, year)) {\n errors.addError('Please provide a valid date');\n }\n}\n\n/**\n * Adds an error message to errors if a date is an invalid date or in the future.\n *\n * The message it adds can be customized in uiSchema.errorMessages.futureDate\n */\nexport function validateCurrentOrPastDate(errors, dateString, formData, schema, errorMessages = {}) {\n const { futureDate = 'Please provide a valid current or past date' } = errorMessages;\n validateDate(errors, dateString);\n const { day, month, year } = parseISODate(dateString);\n if (!isValidCurrentOrPastDate(day, month, year)) {\n errors.addError(futureDate);\n }\n}\n\nexport function validateCurrentOrPastMonthYear(errors, dateString, formData, schema, errorMessages = {}) {\n const { futureDate = 'Please provide a valid current or past date' } = errorMessages;\n validateMonthYear(errors, dateString);\n const { month, year } = parseISODate(dateString);\n if (!isValidPartialMonthYearInPast(month, year)) {\n errors.addError(futureDate);\n }\n}\n\n/**\n * Adds an error message to errors if a date is an invalid date or in the past.\n */\nexport function validateFutureDateIfExpectedGrad(errors, dateString, formData) {\n validateDate(errors, dateString);\n const { month, year } = parseISODate(dateString);\n if (formData.highSchool.status === 'graduationExpected' && !isValidCurrentOrFutureMonthYear(month, year)) {\n errors.addError('Please provide a valid future date');\n }\n}\n\n/**\n * Adds an error message to errors if an integer year value is not between 1900 and the current year.\n */\nexport function validateCurrentOrPastYear(errors, year) {\n if (!isValidCurrentOrPastYear(year)) {\n errors.addError('Please provide a valid year');\n }\n}\n\nexport function validateMatch(field1, field2) {\n return (errors, formData) => {\n if (formData[field1] !== formData[field2]) {\n errors[field2].addError('Please ensure your entries match');\n }\n };\n}\n\nexport function convertToDateField(dateStr) {\n const date = parseISODate(dateStr);\n return Object.keys(date).reduce((dateField, part) => {\n const datePart = {};\n datePart[part] = {\n value: date[part]\n };\n return _.assign(dateField, datePart);\n }, date);\n}\n\nexport function validateDateRange(errors, dateRange, formData, schema, errorMessages) {\n const fromDate = convertToDateField(dateRange.from);\n const toDate = convertToDateField(dateRange.to);\n\n if (!isValidDateRange(fromDate, toDate)) {\n errors.to.addError(errorMessages.pattern || 'To date must be after from date');\n }\n}\n\nexport function getFileError(file) {\n if (file.errorMessage) {\n return file.errorMessage;\n } else if (file.uploading) {\n return 'Uploading file...';\n } else if (!file.confirmationCode) {\n return 'Something went wrong...';\n }\n\n return null;\n}\n\nexport function validateFileField(errors, fileList) {\n fileList.forEach((file, index) => {\n const error = getFileError(file);\n\n if (error && !errors[index]) {\n /* eslint-disable no-param-reassign */\n errors[index] = {\n __errors: [],\n addError(msg) {\n this.__errors.push(msg);\n }\n };\n /* eslint-enable no-param-reassign */\n }\n\n if (error) {\n errors[index].addError(error);\n }\n });\n}\n\nexport function validateBooleanGroup(errors, userGroup, form, schema, errorMessages = {}) {\n const { atLeastOne = 'Please choose at least one option' } = errorMessages;\n const group = userGroup || {};\n if (!Object.keys(group).filter(item => group[item] === true).length) {\n errors.addError(atLeastOne);\n }\n}\n\nexport function validateAutosuggestOption(errors, formData) {\n if (formData &&\n formData.widget === 'autosuggest' &&\n !formData.id &&\n formData.label) {\n errors.addError('Please select an option from the suggestions');\n }\n}\n"]}
\ No newline at end of file
diff --git a/src/js/actions.js b/src/js/actions.js
index 1089cae..4471e8a 100644
--- a/src/js/actions.js
+++ b/src/js/actions.js
@@ -7,7 +7,7 @@ import { timeFromNow } from './utilities/date';
export const SET_EDIT_MODE = 'SET_EDIT_MODE';
export const SET_DATA = 'SET_DATA';
export const SET_VIEWED_PAGES = 'SET_VIEWED_PAGES';
-export const SET_PRIVACY_AGREEMENT = 'SET_PRIVACY_AGREEMENT';
+export const SET_PRE_SUBMIT = 'SET_PRE_SUBMIT';
export const SET_SUBMISSION = 'SET_SUBMISSION';
export const SET_SUBMITTED = 'SET_SUBMITTED';
export const OPEN_REVIEW_CHAPTER = 'OPEN_REVIEW_CHAPTER';
@@ -55,10 +55,11 @@ export function setSubmission(field, value, extra = null) {
};
}
-export function setPrivacyAgreement(privacyAgreementAccepted) {
+export function setPreSubmit(preSubmitField, preSubmitAccepted) {
return {
- type: SET_PRIVACY_AGREEMENT,
- privacyAgreementAccepted
+ type: SET_PRE_SUBMIT,
+ preSubmitField,
+ preSubmitAccepted
};
}
diff --git a/src/js/components/PreSubmitSection.jsx b/src/js/components/PreSubmitSection.jsx
new file mode 100644
index 0000000..639c1e5
--- /dev/null
+++ b/src/js/components/PreSubmitSection.jsx
@@ -0,0 +1,29 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+import ErrorableCheckbox from './ErrorableCheckbox';
+
+export function PreSubmitSection({ onChange, showError, preSubmitInfo, form }) {
+ const info = preSubmitInfo || {};
+ const field = info.field || 'AGREED';
+
+ return (
+
+ {info.notice}
+ {info.required &&
+
+ }
+
+ );
+}
+
+PreSubmitSection.propTypes = {
+ form: PropTypes.object.isRequired,
+ onChange: PropTypes.func.isRequired,
+ preSubmitInfo: PropTypes.object,
+ showError: PropTypes.bool
+};
diff --git a/src/js/components/PrivacyAgreement.jsx b/src/js/components/PrivacyAgreement.jsx
deleted file mode 100644
index 1f4e8ca..0000000
--- a/src/js/components/PrivacyAgreement.jsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import PropTypes from 'prop-types';
-import React from 'react';
-import ErrorableCheckbox from './ErrorableCheckbox';
-
-export default function PrivacyAgreement({ onChange, checked, showError }) {
- return (
-
- );
-}
-
-PrivacyAgreement.propTypes = {
- onChange: PropTypes.func.isRequired,
- checked: PropTypes.bool.isRequired
-};
diff --git a/src/js/review/SubmitController.jsx b/src/js/review/SubmitController.jsx
index e7ed4af..88664fd 100644
--- a/src/js/review/SubmitController.jsx
+++ b/src/js/review/SubmitController.jsx
@@ -5,7 +5,7 @@ import { connect } from 'react-redux';
import { withRouter } from 'react-router';
import SubmitButtons from './SubmitButtons';
-import PrivacyAgreement from '../components/PrivacyAgreement';
+import { PreSubmitSection } from '../components/PreSubmitSection';
import { isValidForm } from '../validation';
import {
createPageListByChapter,
@@ -14,7 +14,7 @@ import {
recordEvent
} from '../helpers';
import {
- setPrivacyAgreement,
+ setPreSubmit,
setSubmission,
submitForm
} from '../actions';
@@ -48,21 +48,27 @@ class SubmitController extends React.Component {
form,
formConfig,
pagesByChapter,
- privacyAgreementAccepted,
trackingPrefix
} = this.props;
- const {
- isValid,
- errors
- } = isValidForm(form, pagesByChapter);
+ let isValid;
+ let errors;
+
+ // If a pre-submit agreement was specified, it has to be accepted first
+ const preSubmitField = formConfig.preSubmitInfo &&
+ formConfig.preSubmitInfo.required && (formConfig.preSubmitInfo.field || 'AGREED');
+ if (preSubmitField && !form.data[preSubmitField]) {
+ isValid = false;
+ } else {
+ ({ isValid, errors } = isValidForm(form, pagesByChapter));
+ }
if (isValid) {
this.props.submitForm(formConfig, form);
} else {
// validation errors in this situation are not visible, so we’d
// like to know if they’re common
- if (privacyAgreementAccepted) {
+ if (preSubmitField && form.data[preSubmitField]) {
recordEvent({
event: `${trackingPrefix}-validation-failed`,
});
@@ -80,19 +86,20 @@ class SubmitController extends React.Component {
render() {
const {
- privacyAgreementAccepted,
+ form,
+ formConfig,
+ showPreSubmitError,
renderErrorMessage,
- showPrivacyAgreementError,
submission
} = this.props;
return (
-
Note: According to federal law, there are criminal penalties, including a fine and/or imprisonment for up to 5 years, for withholding information or for providing incorrect information. (See 18 U.S.C. 1001)
-
+ preSubmitInfo={formConfig.preSubmitInfo}
+ onChange={() => this.props.setPreSubmit(formConfig.preSubmitInfo.field, this.value)}
+ form={form}
+ showError={showPreSubmitError}/> }
{
- return _.set('data.privacyAgreementAccepted', action.privacyAgreementAccepted, state);
+ [SET_PRE_SUBMIT]: (state, action) => {
+ return { ...state, data: { ...state.data, [action.preSubmitField]: action.preSubmitAccepted } };
},
[SET_SUBMISSION]: (state, action) => {
const newState = _.set(['submission', action.field], action.value, state);
diff --git a/src/js/validation.js b/src/js/validation.js
index d3d17f8..21543ba 100644
--- a/src/js/validation.js
+++ b/src/js/validation.js
@@ -188,10 +188,6 @@ export function isValidForm(form, pageListByChapters) {
const v = new Validator();
- if (!form.data.privacyAgreementAccepted) {
- return { isValid: false };
- }
-
return validPages.reduce(({ isValid, errors }, page) => {
const { uiSchema, schema, showPagePerItem, itemFilter, arrayPath } = form.pages[page];
let formData = form.data;
diff --git a/test/js/actions.unit.spec.js b/test/js/actions.unit.spec.js
index a2d3e6e..f06edeb 100644
--- a/test/js/actions.unit.spec.js
+++ b/test/js/actions.unit.spec.js
@@ -8,8 +8,8 @@ import {
SET_EDIT_MODE,
setSubmission,
SET_SUBMISSION,
- setPrivacyAgreement,
- SET_PRIVACY_AGREEMENT,
+ setPreSubmit,
+ SET_PRE_SUBMIT,
setSubmitted,
SET_SUBMITTED,
submitForm,
@@ -48,13 +48,13 @@ describe('Schemaform actions:', () => {
expect(action.type).to.equal(SET_SUBMISSION);
});
});
- describe('setPrivacyAgreement', () => {
+ describe('setPreSubmit', () => {
it('should return action', () => {
const accepted = false;
- const action = setPrivacyAgreement(accepted);
+ const action = setPreSubmit('preSubmitAccepted', accepted);
- expect(action.privacyAgreementAccepted).to.equal(accepted);
- expect(action.type).to.equal(SET_PRIVACY_AGREEMENT);
+ expect(action.preSubmitAccepted).to.equal(accepted);
+ expect(action.type).to.equal(SET_PRE_SUBMIT);
});
});
describe('setSubmitted', () => {
diff --git a/test/js/review/ReviewPage.unit.spec.jsx b/test/js/review/ReviewPage.unit.spec.jsx
index 080993b..6eaf169 100644
--- a/test/js/review/ReviewPage.unit.spec.jsx
+++ b/test/js/review/ReviewPage.unit.spec.jsx
@@ -11,6 +11,13 @@ describe('Schemaform review: ReviewPage', () => {
it('should render chapters', () => {
const formConfig = {
+ preSubmitInfo: {
+ required: true,
+ field: 'privacyAgreementAccepted',
+ notice: 'Notice',
+ label: 'I accept the privacy agreement',
+ error: 'You must accept the privacy agreement'
+ },
chapters: {
chapter1: {
pages: {
@@ -53,7 +60,7 @@ describe('Schemaform review: ReviewPage', () => {
openChapters={[]}
route={{ formConfig, pageList }}
setEditMode={f => f}
- setPrivacyAgreement={f => f}
+ setPreSubmit={f => f}
location={location}/>
);
diff --git a/test/js/review/SubmitController.unit.spec.jsx b/test/js/review/SubmitController.unit.spec.jsx
index c460bd4..8a30f96 100644
--- a/test/js/review/SubmitController.unit.spec.jsx
+++ b/test/js/review/SubmitController.unit.spec.jsx
@@ -6,9 +6,18 @@ import sinon from 'sinon';
import { SubmitController } from '../../../src/js/review/SubmitController';
+const preSubmitInfo = {
+ required: true,
+ field: 'privacyAgreementAccepted',
+ notice: 'Notice
',
+ label: 'I accept the privacy agreement',
+ error: 'You must accept the privacy agreement'
+};
+
describe('Schemaform review: SubmitController', () => {
it('should route to confirmation page after submit', () => {
const formConfig = {
+ preSubmitInfo,
chapters: {
chapter1: {
pages: {
@@ -52,13 +61,17 @@ describe('Schemaform review: SubmitController', () => {
const tree = SkinDeep.shallowRender(
);
tree.getMountedInstance().componentWillReceiveProps({
route: {
- formConfig: {}
+ },
+ formConfig: {
+ urlPrefix: '/',
+ preSubmitInfo
},
form: {
submission: {
@@ -67,13 +80,10 @@ describe('Schemaform review: SubmitController', () => {
data: {
privacyAgreementAccepted: false
}
- },
- formConfig: {
- urlPrefix: '/'
}
});
- expect(router.push.calledWith('confirmation'));
+ expect(router.push.calledWith('/confirmation')).to.be.true;
});
it('should not submit when privacy agreement not accepted', () => {
const form = {
@@ -99,7 +109,9 @@ describe('Schemaform review: SubmitController', () => {
pageKey: 'page2'
}]
};
-
+ const formConfig = {
+ preSubmitInfo
+ };
const submitForm = sinon.spy();
const setSubmission = sinon.spy();
@@ -107,6 +119,7 @@ describe('Schemaform review: SubmitController', () => {
@@ -119,6 +132,7 @@ describe('Schemaform review: SubmitController', () => {
});
it('should not submit when invalid', () => {
const formConfig = {
+ preSubmitInfo,
chapters: {
chapter1: {
pages: {
@@ -182,6 +196,7 @@ describe('Schemaform review: SubmitController', () => {
setSubmission={setSubmission}
submitForm={submitForm}
form={form}
+ formConfig={formConfig}
pagesByChapter={pagesByChapter}
pageList={pageList}
route={{ formConfig, pageList }}/>
@@ -194,6 +209,7 @@ describe('Schemaform review: SubmitController', () => {
});
it('should submit when valid', () => {
const formConfig = {
+ preSubmitInfo,
chapters: {
chapter1: {
pages: {
@@ -257,6 +273,81 @@ describe('Schemaform review: SubmitController', () => {
const tree = SkinDeep.shallowRender(
+ );
+
+ tree.getMountedInstance().handleSubmit();
+
+ expect(submitForm.called).to.be.true;
+ });
+ it('should submit when valid and no preSubmit specified', () => {
+ const formConfig = {
+ chapters: {
+ chapter1: {
+ pages: {
+ page1: {
+ schema: {}
+ }
+ }
+ },
+ chapter2: {
+ pages: {
+ page2: {
+ }
+ }
+ }
+ }
+ };
+
+ const pagesByChapter = {
+ chapter1: [{
+ chapterKey: 'chapter1',
+ pageKey: 'page1'
+ }],
+ chapter2: [{
+ chapterKey: 'chapter2',
+ pageKey: 'page2'
+ }]
+ };
+
+ const form = {
+ submission: {
+ hasAttemptedSubmit: false
+ },
+ pages: {
+ page1: {
+ schema: {},
+ },
+ page2: {
+ schema: {},
+ },
+ },
+ data: {}
+ };
+
+ const pageList = [
+ {
+ path: 'previous-page'
+ },
+ {
+ path: 'testing',
+ pageKey: 'testPage'
+ },
+ {
+ path: 'next-page'
+ }
+ ];
+
+ const submitForm = sinon.spy();
+
+ const tree = SkinDeep.shallowRender(
+ {
push: sinon.spy()
};
const formConfig = {
+ preSubmitInfo,
chapters: {
chapter1: {
pages: {
@@ -306,14 +398,14 @@ describe('Schemaform review: SubmitController', () => {
const tree = mount(
).instance();
tree.goBack();
- expect(router.push.calledWith('previous-page'));
+ expect(router.push.called).to.be.true;
});
});
diff --git a/test/js/state/index.unit.spec.js b/test/js/state/index.unit.spec.js
index e6a23a0..f1d8654 100644
--- a/test/js/state/index.unit.spec.js
+++ b/test/js/state/index.unit.spec.js
@@ -5,7 +5,7 @@ import {
OPEN_REVIEW_CHAPTER,
SET_DATA,
SET_EDIT_MODE,
- SET_PRIVACY_AGREEMENT,
+ SET_PRE_SUBMIT,
SET_SUBMISSION,
SET_SUBMITTED
} from '../../../src/js/actions';
@@ -15,6 +15,13 @@ import createSchemaFormReducer from '../../../src/js/state';
describe('schemaform createSchemaFormReducer', () => {
it('creates a reducer with initial state for each page', () => {
const formConfig = {
+ preSubmitInfo: {
+ required: true,
+ field: 'privacyAgreementAccepted',
+ notice: 'Notice',
+ label: 'I accept the privacy agreement',
+ error: 'You must accept the privacy agreement'
+ },
disableSave: true,
chapters: {
test: {
@@ -181,8 +188,9 @@ describe('schemaform createSchemaFormReducer', () => {
privacyAgreementAccepted: false
}
}, {
- type: SET_PRIVACY_AGREEMENT,
- privacyAgreementAccepted: true
+ type: SET_PRE_SUBMIT,
+ preSubmitField: 'privacyAgreementAccepted',
+ preSubmitAccepted: true
});
expect(state.data.privacyAgreementAccepted).to.be.true;