diff --git a/src/frontend/components/button/lib/submit-field-button.ts b/src/frontend/components/button/lib/submit-field-button.ts index a511f272d..644ea20b1 100644 --- a/src/frontend/components/button/lib/submit-field-button.ts +++ b/src/frontend/components/button/lib/submit-field-button.ts @@ -1,6 +1,8 @@ +/* eslint-disable */ import "jstree"; import "datatables.net"; import "@lol768/jquery-querybuilder-no-eval" +import { validateQueryBuilder } from "validation"; declare global { interface Window { @@ -27,6 +29,7 @@ export default class SubmitFieldButton { */ constructor(element:JQuery) { element.on('click', (ev) => { + const $form = $(ev.currentTarget).closest('form') as JQuery; const $jstreeContainer = $('#field_type_tree'); const $jstreeEl = $('#tree-config .tree-widget-container'); @@ -70,7 +73,9 @@ export default class SubmitFieldButton { bUpdateFilter = true; } - if (res && $displayConditionsField.length) { + if(!validateQueryBuilder($displayConditionsBuilderEl)) { + ev.preventDefault(); + } else if (res && $displayConditionsField.length) { bUpdateDisplayConditions = true; } @@ -105,7 +110,7 @@ export default class SubmitFieldButton { window.UpdatePeopleFilter(peopleConditionsFieldEl, ev); } - if (bUpdateDisplayConditions) { + if (bUpdateDisplayConditions && res) { $displayConditionsField.val(JSON.stringify(res, null, 2)); } @@ -115,7 +120,6 @@ export default class SubmitFieldButton { * and appends them to the form manually */ const $inputs = $permissionTable.DataTable().$('input,select,textarea'); $inputs.hide(); // Stop them appearing to the user in a strange format - const $form = $(ev.currentTarget).closest('form'); $permissionTable.remove(); $form.append($inputs); }); diff --git a/src/frontend/components/form-group/display-conditions/lib/component.js b/src/frontend/components/form-group/display-conditions/lib/component.js index 8decad367..188c2b999 100644 --- a/src/frontend/components/form-group/display-conditions/lib/component.js +++ b/src/frontend/components/form-group/display-conditions/lib/component.js @@ -25,13 +25,11 @@ class DisplayConditionsComponent extends Component { { type: 'contains', accept_values: true, apply_to: ['string'] }, { type: 'not_equal', accept_values: true, apply_to: ['string'] }, { type: 'not_contains', accept_values: true, apply_to: ['string'] } - ] - }) - - if (builderData.filterBase) { - const data = JSON.parse(atob(builderData.filterBase)) - this.el.queryBuilder('setRules', data) - } + ], + allow_empty: true + }).queryBuilder('setRules', builderData.filterBase + ? JSON.parse(atob(builderData.filterBase)) + : {rules:[]}); } } diff --git a/src/frontend/js/lib/validation.js b/src/frontend/js/lib/validation.js index 0c23eb84b..18b111391 100644 --- a/src/frontend/js/lib/validation.js +++ b/src/frontend/js/lib/validation.js @@ -1,3 +1,5 @@ +import { DangerAlert } from "components/alert/lib/dangerAlert"; + // Bind events to a field to trigger validation const initValidationOnField = (field) => { // Input @@ -299,6 +301,20 @@ const validateTree = (field) => { } } +const validateQueryBuilder = (field) => { + if(!(field && field.length)) return; + const result = field.queryBuilder('validate'); + if(!result) { + if($('.display-conditions-error').length) return false; + const danger = new DangerAlert('There are errors in the conditions you have set, please fix these before submitting the form'); + const banner = danger.render(); + banner.classList.add('mb-3', 'mt-0', 'display-conditions-error'); + field.closest('.card__content').prepend(banner); + return false; + } + return true; +} + // Expand the card with a certain field and scroll it into view const expandCardValidate = (field) => { const $collapse = $(field).closest('.card--expandable').find('.collapse') @@ -321,4 +337,4 @@ const expandCardValidate = (field) => { } } -export { initValidationOnField, validateTree, validateRadioGroup, validateCheckboxGroup, validateRequiredFields }; +export { initValidationOnField, validateTree, validateRadioGroup, validateCheckboxGroup, validateRequiredFields, validateQueryBuilder };