{"version":3,"file":"js/6329-7c4ef1b577ba8d1eef3a.js","mappings":"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","sources":["webpack://client_new/./app/packs/javascript/plugins/choices.js","webpack://client_new/./app/packs/javascript/plugins/dropdown.js","webpack://client_new/./app/packs/javascript/utils/confirm_callback.js","webpack://client_new/./app/packs/javascript/utils/dynamic_toggler.js","webpack://client_new/./app/packs/javascript/utils/masks.js","webpack://client_new/./app/packs/javascript/utils/object_tables.js","webpack://client_new/./app/packs/javascript/utils/randomizer.js","webpack://client_new/./app/packs/javascript/utils/reading_time.js","webpack://client_new/./app/packs/javascript/utils/type_delete_string.js","webpack://client_new/./app/packs/javascript/views/fact_find.js","webpack://client_new/./app/packs/javascript/views/fact_find_validation.js"],"sourcesContent":["import Choices from 'choices.js';\n\nconst bindSelect = (select) => {\n const isDisabled = select.disabled;\n\n // Choices doesn't behave well with disabled attriutes\n // We need to \"enable\" the select and then disable Choices\n if (isDisabled) select.removeAttribute('disabled');\n\n // Add placeholder if there's no selected value already\n if(!select.value.length) {\n const placeholder = document.createElement('option');\n placeholder.setAttribute('value', '')\n placeholder.setAttribute('selected', '')\n placeholder.setAttribute('disabled', '')\n placeholder.setAttribute('placeholder', '')\n placeholder.innerHTML = select.dataset.placeholder;\n select.appendChild(placeholder)\n }\n \n\n const choices = new Choices(select, {\n paste: false,\n searchEnabled: select.children.length >= 7,\n shouldSort: false,\n classNames: {\n containerOuter: `choices ${select.dataset.choicesBorder === 'false' ? 'type-borderless' : ''}`,\n },\n });\n\n // Disable choices if select was disabled\n if (isDisabled) choices.disable();\n\n // Events to control the choices status without making Choices available outside of this scope\n select.addEventListener('enable', () => {\n choices.enable();\n choices.unhighlightAll()\n });\n\n select.addEventListener('disable', () => {\n choices.disable();\n });\n};\n\nconst initChoices = (selectsList) => {\n const selects = selectsList || document.querySelectorAll('select');\n selects.forEach(bindSelect);\n};\n\nexport { initChoices }\n","import { createPopper } from '@popperjs/core';\n\nconst initDropdown = () => {\n\n const items = document.querySelectorAll(\".dropdown\");\n\n items.forEach((item) => {\n const label = item.querySelector(\".dropdown__label\");\n const wrapper = item.querySelector(\".dropdown__wrapper\");\n\n // match width of both elements\n // const labelWidth = label.getBoundingClientRect().width;\n // const wrapperWidth = label.getBoundingClientRect().width;\n // const targetWidth = `${Math.ceil(Math.max(labelWidth, wrapperWidth))}px`;\n // wrapper.style.minWidth = targetWidth;\n // label.style.minWidth = targetWidth;\n\n // use event delegation to avoid applying multiple listeners to click & label\n\n document.body.addEventListener(\"click\", (e) => {\n const path = e.path ? e.path : e.composedPath();\n\n const clickedInLabel = path.includes(label);\n const clickedinWrapper = path.includes(wrapper);\n\n // do nothing if clicking inside the wrapper\n if (clickedinWrapper) return;\n\n // toggle opened when clicking in label\n if (clickedInLabel) {\n wrapper.classList.toggle(\"is-open\")\n label.classList.toggle(\"is-open\")\n return;\n }\n\n // close on any other situation\n if (wrapper.classList.contains(\"is-open\")) {\n wrapper.classList.remove(\"is-open\")\n label.classList.remove(\"is-open\")\n }\n });\n\n createPopper(label, wrapper, {\n // https://popper.js.org/docs/v2/constructors/#options\n placement: \"bottom-start\",\n modifiers: [\n {\n name: \"offset\",\n options: {\n offset: [0, 16] // distance from label\n }\n }\n ]\n });\n });\n}\n\nexport { initDropdown };","/*\n Callback function\n Shows a info-box with a message\n\n params:\n message: MANDATORY;\n duration: time until dismiss, in miliseconds. default: readingTime(). 0 will be infinite;\n targetContainer: ;\n classToAdd: class added to box. default: '';\n dismiss: bolean to see if it's possible to dismiss or not. default: true;\n\n Example:\n confirmCallback(' Agreement saved!', {\n duration: 0,\n targetContainer: document.querySelector('#layout-notifications'),\n classToAdd: 'bg-xs-green-100',\n dismiss: true\n })\n*/\n\nimport randomizer from './randomizer';\nimport readingTime from './reading_time';\n\nconst confirmCallback = (\n message = undefined, {\n duration = undefined,\n targetContainer = document.querySelector('[data-callback-targetContainer]'),\n classToAdd = 'bg-grey-100',\n dismiss = true,\n },\n) => {\n // message is MANDATORY\n if (message !== undefined) {\n // Generate a random ID\n const id = `C${randomizer()}`;\n\n // let timing = duration || readingTime(message);\n // Define timing. (above doesn't work when duration is 0 (zero))\n let timing = duration !== undefined ? duration : readingTime(message).seconds;\n\n // Create element as a DOM element, this way we can use some methods\n const $container = targetContainer;\n const newCallback = document.createElement('div');\n newCallback.className = `notification ${classToAdd}`;\n newCallback.setAttribute('role', 'alert');\n newCallback.dataset.callback = id;\n newCallback.style = 'opacity: 0';\n\n let messageTemplate = `
\n

${message}

\n
`;\n messageTemplate += dismiss ? `
\n \n
` : '';\n // Prevent notifications from appending on to one another\n $container.innerHTML = '';\n // Append element to the page\n targetContainer.insertAdjacentElement('beforeend', newCallback);\n newCallback.insertAdjacentHTML('beforeend', messageTemplate);\n\n // Animation handlers\n newCallback.addEventListener('animationend', () => {\n if (newCallback.classList.contains('fade-in')) {\n newCallback.style = 'opacity: 1';\n newCallback.classList.remove('fade-in');\n }\n\n if (newCallback.classList.contains('fade-out')) {\n newCallback.style = 'opacity: 0';\n newCallback.remove();\n }\n });\n\n newCallback.classList.add('fade-in');\n\n // If timing == 0 then we only remove if the user clicks to remove\n if (timing !== 0) {\n if (timing < 7) timing = 7;\n let isHover = false;\n\n newCallback.addEventListener('mouseenter', () => { isHover = true; });\n newCallback.addEventListener('mouseleave', () => { isHover = false; });\n\n setTimeout(() => {\n if (isHover) {\n newCallback.addEventListener('mouseleave', () => {\n setTimeout(() => {\n newCallback.classList.add('fade-out');\n }, 500);\n });\n } else {\n newCallback.classList.add('fade-out');\n }\n }, timing * 1000);\n }\n\n // if it has the dismiss action, we can click to remove\n if (dismiss) {\n newCallback.querySelector('[data-callback-dismiss]').addEventListener('click', (event) => {\n event.currentTarget.closest('[data-callback]').classList.add('fade-out');\n });\n }\n }\n};\n\nexport default confirmCallback;\nwindow.confirmCallback = confirmCallback;\n","/*\n # USAGE\n\n ## This should be added on the trigger element:\n data-dynamic-target=\"\"\n\n ## This should be added on the target element/wrapper:\n data-dynamic='{\"\": {\"show\": true|false, \"content\": \"\"}, \"\": {\"show\": true|false, \"content\": \"\"}}'\n ## Notes:\n - If you're using a select on the 'data-dynamic' you should use the value for instead;\n - You can add as much as 'data-dynamic' as you want/need to diferent elements as needed;\n - It's possible to add multiple entries to the 'data-dynamic' attribute so that it has multiple changes from diferent sources;\n\n*/\nconst enableEvent = new Event('enable');\nconst disableEvent = new Event('disable');\n// Object with {id: {domObject: ..., action: object }}\nconst targets = {};\n\nconst toggleElements = (elem, bool) => {\n if (bool) {\n elem.classList.remove('hidden-xs');\n elem.setAttribute('aria-hidden', false);\n elem.querySelectorAll('input, select').forEach((field) => {\n field.removeAttribute('disabled');\n field.dispatchEvent(enableEvent);\n });\n } else {\n elem.classList.add('hidden-xs');\n elem.setAttribute('aria-hidden', true);\n elem.querySelectorAll('input, select').forEach((field) => {\n field.setAttribute('disabled', true);\n field.dispatchEvent(disableEvent);\n });\n }\n};\n\nconst dynamicToggler = (trigger) => {\n const togglerID = trigger.dataset.dynamicTarget;\n\n // In the event the toggler is a radio/checkbox inside a group\n // const triggerGroup = document.querySelectorAll(`[name=\"${trigger.getAttribute('name')}\"]`);\n\n const { domObject } = targets[togglerID];\n const { action } = targets[togglerID];\n\n Object.keys(action).forEach((key) => {\n const bool = trigger.tagName === 'SELECT' ? action[key] === trigger.value : action[key];\n\n if (key === 'show') {\n toggleElements(domObject, bool);\n } else if (key === 'content') {\n domObject.innerText = action[key][trigger.value];\n }\n });\n};\n\nconst cacheTargetElements = (domParent) => {\n const targetElements = domParent.querySelectorAll('[data-dynamic]');\n\n targetElements.forEach((elem) => {\n const data = JSON.parse(elem.dataset.dynamic);\n Object.keys(data).forEach((key) => {\n targets[key] = {\n domObject: elem,\n action: data[key],\n };\n });\n });\n};\n\n\nconst initDynamicToggler = (parent) => {\n const domParent = parent || document;\n cacheTargetElements(domParent);\n\n const triggers = domParent.querySelectorAll('[data-dynamic-target]');\n\n triggers.forEach((trigger) => {\n trigger.addEventListener('change', (event) => {\n dynamicToggler(event.currentTarget);\n });\n });\n};\n\n\nexport { initDynamicToggler };\n","import Inputmask from 'inputmask'\n\n/*\n When called, it will be look for in a element:\n\n Money:\n Ex: data-mask-money=\"€\"\n\n Years:\n Ex: data-mask-years=\"years old\"\n\n Percentage:\n Ex: data-mask-percentage\n ^ This needs to be expanded to accept how many decimals you want to display\n\n On a Rails tag you should use it this way:\n :data => {:mask_money => '£'}\n :data => {:mask_percentage => '%'}\n :data => {:mask_years => ''}\n*/\nconst maskTypes = function(elem) {\n return {\n money:{\n alias: 'numeric',\n prefix: elem.dataset.maskMoney,\n groupSeparator: ',',\n autoGroup: true,\n digits: (function(){\n let decimalPlaces = elem.dataset.maskMoneyDecimal;\n if (decimalPlaces == undefined) {\n decimalPlaces = 0\n }\n return decimalPlaces\n })(),\n rightAlign: false,\n placeholder: '',\n clearMaskOnLostFocus: false,\n removeMaskOnSubmit: true,\n showMaskOnHover: false,\n autoUnmask: true\n },\n years:{\n alias: 'numeric',\n suffix: ' ' + elem.dataset.maskYears,\n groupSeparator: ',',\n autoGroup: true,\n digits: 0,\n rightAlign: false,\n clearMaskOnLostFocus: false,\n removeMaskOnSubmit: true,\n showMaskOnHover: false,\n autoUnmask: true\n },\n percentage:{\n alias: 'numeric',\n suffix: '%',\n groupSeparator: ',',\n autoGroup: true,\n digits: 2,\n rightAlign: false,\n placeholder: '',\n removeMaskOnSubmit: true,\n showMaskOnHover: false,\n autoUnmask: true\n }\n }\n}\n\nconst setActive = function(elem) {\n elem.setAttribute(\"data-mask-active\", \"\")\n}\n\nconst isAllowed = function(elem) {\n return !elem.hasAttribute(\"data-mask-active\")\n}\n\nconst createMask = function(type){\n const inputToMask = Array.from(document.querySelectorAll(`[data-mask-${type}]`));\n inputToMask.filter(isAllowed).forEach(function(elem) {\n Inputmask(maskTypes(elem)[type]).mask(elem);\n setActive(elem)\n })\n}\n\nexport default function init() {\n createMask('money')\n createMask('years')\n createMask('percentage')\n}\n\n(function() {\n document.addEventListener('DOMContentLoaded', function () {\n init()\n })\n })();\n\n\n","/*\n Classes used by these functions:\n\n > js-object-table\n\n > js-object-table-row\n - js-object-table-calculatable\n - js-object-table-section-total\n - js-is-calculated\n\n > js-object-table-section-totals\n - js-object-table-section-total\n - js-object-table-total\n\n > js-object-table-remove-line\n > js-object-table-add-line\n*/\n\nimport { initDropdown } from '../plugins/dropdown';\nimport initMasks from './masks';\n\n// Calculate and set the total value using each section total\nconst calculateObjectTableTotals = () => {\n let sectionTotals = 0;\n document.querySelectorAll('.js-object-table-section-totals .js-object-table-section-total').forEach((sectionTotal) => {\n sectionTotals += parseInt(sectionTotal.value, 10);\n });\n if (document.querySelector('.js-object-table-total') !== null) {\n document.querySelector('.js-object-table-total').value = sectionTotals;\n }\n};\n\n// Function to calculate the totals and sub-totals\nconst calculateObjectTableSectionTotals = (sectionTable) => {\n // Sums the annual values on each card\n let totalSum = 0;\n // For each calculatable input in the section, sum the values\n sectionTable.querySelectorAll('.js-object-table-calculatable:not(.js-is-calculated)').forEach((element) => {\n if (element.value !== '') {\n totalSum += parseFloat(element.value) * parseFloat(element.dataset.totalsMultiplier);\n }\n });\n\n // Update this section's totals everywhere\n document.querySelectorAll(`.js-object-table-section-total[data-section-name=\"${sectionTable.dataset.sectionName}\"]`).forEach((element) => {\n element.value = totalSum; // eslint-disable-line no-param-reassign\n });\n\n // Update the table totals\n calculateObjectTableTotals();\n};\n\n// Delete table rows\nconst removeObjectTableLine = (event) => {\n event.preventDefault();\n\n const row = event.target.closest('.js-object-table-row');\n const table = row.closest('.js-object-table');\n if (row.parentNode) {\n row.parentNode.removeChild(row);\n }\n\n calculateObjectTableSectionTotals(table);\n if (window.toggleFactFindSubmitButton) {\n window.toggleFactFindSubmitButton('enable');\n }\n};\n\n/*\n Calculates values for other fields in the same row if necessary\n Only calculates values if the updated field has a totalsMultiplier data attribute\n*/\nconst calculateObjectTableValuesInRow = (event) => {\n const updatedInput = event.target;\n\n if (!updatedInput.dataset.totalsMultiplier) {\n return;\n }\n const listRow = updatedInput.closest('.js-object-table-row');\n\n // For each calculatable input in the row, update the number and define it has having been calculated\n listRow.querySelectorAll(`.js-object-table-calculatable:not(#${updatedInput.id})`)\n .forEach((element) => {\n const otherInput = element;\n // eslint-disable-next-line max-len\n otherInput.value = (updatedInput.value * updatedInput.dataset.totalsMultiplier) / otherInput.dataset.totalsMultiplier;\n otherInput.classList.add('is-calculated', 'js-is-calculated');\n });\n\n updatedInput.classList.remove('is-calculated', 'js-is-calculated');\n};\n\n// Event listener to remove a table object line\nconst initDestroy = () => {\n document.querySelectorAll('.js-object-table-remove-line').forEach((item) => {\n item.addEventListener('click', removeObjectTableLine);\n });\n};\n\nconst addObjectTableLine = (event) => {\n event.preventDefault();\n const clickedLink = event.currentTarget;\n const linkDiv = clickedLink.closest('.js-object-table-add-line');\n const table = clickedLink.closest('.js-object-table');\n const totalsRow = table.querySelector('.js-object-table-totals-row');\n let sectionName = linkDiv.dataset.sectionName.toLowerCase();\n\n if (sectionName !== 'milestones') {\n sectionName = 'expenditures';\n }\n\n let rowTemplate = document.querySelector(linkDiv.dataset.lineTemplate).innerHTML;\n let index = 0;\n let fieldElements = [];\n let fieldName = null;\n\n do {\n fieldName = `fact_find_form[profile_sections][${linkDiv.dataset.cardId}][${sectionName}][${index}]`;\n fieldElements = document.querySelectorAll(`[name^='${fieldName}']`);\n if (fieldElements.length) {\n index += 1;\n }\n } while (fieldElements.length);\n\n rowTemplate = rowTemplate.replace(/\\[0\\]/g, `[${index}]`);\n rowTemplate = rowTemplate.replace(/!section_name!/g, linkDiv.dataset.sectionName);\n\n totalsRow.insertAdjacentHTML('beforebegin', rowTemplate);\n const rowToBind = document.querySelectorAll(`[name^='${fieldName}']`)[0].closest('.row');\n rowToBind.querySelectorAll('.js-object-table .js-object-table-calculatable').forEach((item) => {\n item.addEventListener('input', (inputEvent) => {\n calculateObjectTableValuesInRow(inputEvent);\n calculateObjectTableSectionTotals(inputEvent.target.closest('.js-object-table'));\n });\n });\n\n const addRemoveLineBindElements = table.querySelectorAll('.js-object-table-remove-line');\n addRemoveLineBindElements.forEach((removeButton, i) => {\n if (index === i) {\n removeButton.addEventListener('click', removeObjectTableLine);\n }\n });\n\n window.initChoices();\n initMasks();\n initDropdown();\n initDestroy(); // reload to allow new rows to be removed\n};\n\n// Handler for the focus event\n// If the field is automatically calculated remove the is-calculated class and\n// add it to the sibling that isn't calculated\n// If the field hasn't been calculated just removes the css class and adds it to all siblings\nconst focusObjectTableInput = (event) => {\n event.preventDefault();\n const focusedInput = event.target;\n\n const listRow = focusedInput.closest('.js-object-table-row');\n const siblingFields = listRow.querySelectorAll(`.js-object-table-calculatable:not(#${focusedInput.id})`);\n\n if (focusedInput.classList.contains('js-is-calculated')) {\n // Add focus to this field (remove the style class)\n focusedInput.classList.remove('is-calculated');\n // Add the class to the sibling that has it\n const calculatedSibling = [];\n siblingFields.forEach((element) => {\n if (!element.classList.contains('js-is-calculated')) {\n calculatedSibling.push(element);\n }\n });\n if (calculatedSibling.length === 1) {\n calculatedSibling[0].classList.add('is-calculated');\n }\n } else {\n focusedInput.classList.remove('is-calculated');\n siblingFields.forEach((element) => {\n element.classList.add('is-calculated');\n });\n }\n};\n\n// Handler for the outfocus event\n// If the field is still automatically calculated add the is-calculated class and\n// removes it from the input that has been manually inserted\n// If the field hasn't been calculated, remove the css class\nconst outFocusObjectTableInput = (event) => {\n event.preventDefault();\n const outFocusedInput = event.target;\n\n if (outFocusedInput.classList.contains('js-is-calculated') && !outFocusedInput.classList.contains('is-calculated')) {\n outFocusedInput.classList.add('is-calculated');\n const listRow = outFocusedInput.closest('.js-object-table-row');\n const siblingFields = listRow.querySelectorAll(`.js-object-table-calculatable:not(#${outFocusedInput.id})`);\n const uncalculatedSibling = siblingFields.not('js-is-calculated');\n if (uncalculatedSibling.length === 1) {\n uncalculatedSibling.classList.remove('is-calculated');\n }\n } else {\n outFocusedInput.classList.remove('is-calculated');\n }\n};\n\nconst initObjectTables = () => {\n document.querySelectorAll('.js-object-table .js-object-table-calculatable').forEach((item) => {\n item.addEventListener('input', (event) => {\n calculateObjectTableValuesInRow(event);\n calculateObjectTableSectionTotals(event.target.closest('.js-object-table'));\n });\n });\n\n document.querySelectorAll('.js-object-table-add-line').forEach((item) => {\n item.addEventListener('click', addObjectTableLine);\n });\n\n document.querySelectorAll('.js-object-table-calculatable').forEach((item) => {\n item.addEventListener('focusout', outFocusObjectTableInput);\n item.addEventListener('focus', focusObjectTableInput);\n });\n\n // On document load, existing rows can be deleted\n initDestroy();\n};\n\n/* eslint-disable import/prefer-default-export */\nexport { initObjectTables };\n","const randomizer = () => Math.random().toString(36).substring(7);\n\nexport default randomizer;","/*\n Function to get reading time based on word count\n\n readingTime(\"text string\")\n*/\n\nconst readingTime = (text) => {\n const wpm = 235; // Words Per Minute\n const wordCount = text.trim().split(/\\s+/g).length; // Words in callback\n // const readingTimeThreshold = 7000;\n \n // define words per second based on words per minute (wpm)\n const wordsPerSecond = wpm / 60;\n \n // define total reading time in seconds\n const totalReadingTimeSeconds = wordCount / wordsPerSecond;\n \n // define reading time\n const readingTimeMinutes = Math.ceil(totalReadingTimeSeconds / 60);\n \n return {\n minutes: readingTimeMinutes,\n seconds: totalReadingTimeSeconds\n };\n };\n \n export default readingTime;\n ","/* eslint-disable no-param-reassign */\nlet deleteStringInterval;\n\nconst Delete = (element) => {\n let string = element.innerText;\n string = string.substring(0, string.length - 1);\n element.innerText = string;\n\n if (string === '') {\n element.remove();\n clearInterval(deleteStringInterval);\n }\n};\n\nconst deleteString = (element, interval) => {\n const timing = interval || (75 / element.innerText.length);\n\n deleteStringInterval = setInterval(Delete, timing, element);\n};\n\nexport default deleteString;\n","import Rails from '@rails/ujs';\nimport '../plugins/choices';\nimport { initDynamicToggler } from '../utils/dynamic_toggler';\nimport { initObjectTables } from '../utils/object_tables';\nimport { showInputValidations, toggleFactFindSubmitButton } from './fact_find_validation';\nimport initMasks from '../utils/masks';\nimport { initDropdown } from '../plugins/dropdown';\n\n/*\n Manage card lists\n The js-toggle-inner-cards class must be added to the wrapper (.js-form-group)\n Each input should then have the following data attributes:\n > path - the relative path to the endpoint\n > method - the request method\n\n When an input is selected a request to `path` will be triggered\n*/\n\n// When a card list question is toggled, triggers a call to the defined URLs\nconst innerCardToggler = (event) => {\n const selectedInput = event.target;\n\n var path = selectedInput.dataset.path;\n var method = selectedInput.dataset.method;\n\n Rails.ajax({\n url: path,\n type: method,\n dataType: 'script',\n accept: 'script',\n });\n};\n\n/*\n Toggles the existence of a card from the value of an input elsewhere\n The js-toggle-card class must be added to the control wrapper (.form-group)\n The input should then have the following data attributes:\n > card-type the card type to be toggled\n > add-card-path the path to create the new card\n > show-conditions an array of values that will show the card\n*/\nconst cardToggler = (event) => {\n const changedInput = event.target;\n const valuesToLook = changedInput.dataset.showConditions;\n // Determine the area we're going to act on\n const cardTarget = document.querySelector('[data-cardstarget=\"' + changedInput.dataset.cardType + '\"]');\n\n if (valuesToLook.includes(changedInput.value)) {\n cardTarget.classList.remove('hidden-xs');\n // Check if there is aa hidden card\n if (cardTarget.querySelectorAll('.js-card').length == 0) {\n // Card doesn't exist\n Rails.ajax({\n url: changedInput.dataset.addCardPath,\n type: 'POST',\n dataType: 'script',\n accept: 'script',\n });\n }\n } else {\n cardTarget.classList.add('hidden-xs');\n cardTarget.querySelectorAll('.js-card').forEach((element) => {\n element.remove();\n });\n }\n};\n\n/* *******************************************************\n** Functions called when the Fact Find Section is saved **\n******************************************************** */\n\n/*\n Overrides the submit input to save changes.\n\n Before submitting the changes to the server,\n this will handle any inputs that had to be locally calculated and need\n extra care before being submitted\n*/\nconst bottomNavSaveChanges = (event) => {\n const eventTarget = event.target;\n\n // Move the automatically calculated values to a data attribute (We only want user submitted data)\n document.querySelectorAll('.js-is-calculated').forEach(function (elem, _index) {\n elem.disabled = true;\n });\n\n Rails.fire(eventTarget.closest('form'), 'submit');\n\n // Move the automatically calculated values back to the value attribute\n document.querySelectorAll('.js-is-calculated').forEach(function (elem, _index) {\n elem.disabled = false;\n });\n};\n\n/*\n Whenever an element is changed in the window\n removes the validation messages and enables the submit button\n*/\n\n// Check if there were any changes\nlet formChanged = false;\n\nconst bindChange = (event) => {\n const element = event.target;\n\n if (element === null || !element.matches('.js-fact-find-form input, .js-fact-find-form select, .js-fact-find-form textarea')) {\n return\n }\n\n formChanged = true;\n toggleFactFindSubmitButton('enable');\n const formGroup = event.target.closest('.form-section');\n\n // remove validation-error class\n const errorSpan = formGroup?.querySelector('.text-xs-red-500');\n // remove validation message\n if (errorSpan) {\n errorSpan.remove();\n }\n // else {\n // if (formGroup.querySelectorAll('.radio').length !== 0 && formGroup.closest('.form-control') !== null) {\n // // Radio controls have a slightly more complex structure because there are several inputs\n // const formControlMessage = formGroup.closest('.form-control').querySelector('.validation-message')\n // if (formControlMessage !== null) {\n // formControlMessage.remove();\n // }\n // }\n // }\n};\n\n/**\n * Adds the necessary tools to trigger behaviours in some areas after a field's value is changed\n * elsewhere.\n * The responsibility to determine what changes are supposed to happen falls on the affected area.\n * Nomenclature used is the same as in the Fact-find.\n *\n * The input working as a trigger (the affector) must have the .js-consequence-affector class and\n * a path set as an attribute (data-path).\n * In the Fact-find, the path corresponds to the field's absolute path.\n *\n * The affected area needs to define 2 attributes:\n * - data-affected-by, indicating the path of the field affecting the area\n * - data-consequences, a multidimensional map, indexed by the effect name, with another map\n * inside, indexed by the value which will trigger the new status (defined as the map value)\n * If no value is defined, the function will revert to the behaviour specified in the !default!\n * index. If that isn't defined, nothing will happen.\n *\n * Following effects are implemented:\n * - visibility, toggles the visibility of the affected area. Possible statuses: 'show', 'hide'.\n * - content, replaces the content of the affected area.\n */\nconst triggerConsequence = (event) => {\n const clickedElement = event.target;\n const affector = clickedElement.closest('.js-consequence-affector');\n const hiddenInput = affector.querySelector('input[type=hidden]');\n if (hiddenInput !== null) {\n hiddenInput.remove();\n }\n const affectorPath = affector.dataset.path;\n\n const enableEvent = new Event('enable');\n const disableEvent = new Event('disable');\n // Determine which field was changed, triggering the event\n let affectorField = affector.querySelector('input, select');\n // If the field is a radio array, we must select the checked element\n if (affectorField.type === 'radio') {\n affectorField = affector.querySelector('input:checked');\n }\n var affectorValue = affectorField.value;\n // Determine where we're going to look for affected elements.\n // If there is an js-inner-card close by, use it. If not, use the closest .js-card\n let consequenceArea = null;\n if (clickedElement.closest('.js-inner-card')) {\n consequenceArea = clickedElement.closest('.js-inner-card');\n } else {\n consequenceArea = clickedElement.closest('.js-card');\n }\n // Search for elements that are affected by the change\n const affectedElements = consequenceArea.querySelectorAll(`[data-affected-by*=\"!${affectorPath}!\"]`);\n affectedElements.forEach((affectedElement) => {\n // Each element can be affected in several ways, loop them\n const consequences = JSON.parse(affectedElement.dataset.consequences)[affectorPath];\n // eslint-disable-next-line guard-for-in,no-restricted-syntax\n for (const key in consequences) {\n const options = consequences[key];\n if (key === 'visibility') {\n // Toggle visibility of affectedElement according to the affector's value\n let actionToTake = options[affectorValue];\n // If an option isn't set, check if there is a default behaviour (using the !default! index)\n if (actionToTake === undefined) {\n actionToTake = options['!default!'];\n }\n if (actionToTake === 'show') {\n affectedElement.classList.remove('hidden-xs');\n affectedElement.setAttribute('aria-hidden', false);\n affectedElement.querySelectorAll('input, select').forEach((field) => {\n field.removeAttribute('disabled');\n field.dispatchEvent(enableEvent);\n });\n } else if (actionToTake === 'hide') {\n hide_children(affectedElement);\n affectedElement.classList.add('hidden-xs');\n affectedElement.setAttribute('aria-hidden', true);\n affectedElement.querySelectorAll('input, select').forEach((field) => {\n field.setAttribute('disabled', true);\n field.dispatchEvent(disableEvent);\n });\n }\n } else if (key === 'content') {\n // Change content of div according to the affector's value\n if (options[affectorValue] !== undefined) {\n affectedElement.innerHTML = options[affectorValue];\n }\n }\n }\n });\n};\n\nfunction hide_children(affectedElement){\n // Get div with js-consequence-affector from children\n const affector = affectedElement.querySelector('.js-consequence-affector');\n if(!affector)\n return;\n\n // Get the checked input that are children of a hiding field\n let affectorField = affector.querySelector('input:checked');\n // If the field has a radio button checked, remove the check\n if (affectorField) {\n affectorField.checked = false;\n }\n // Determine where we're going to look for affected elements.\n // If there is an js-inner-card close by, use it. If not, use the closest .js-card\n let consequenceArea = null;\n if (affectedElement.closest('.js-inner-card')) {\n consequenceArea = affectedElement.closest('.js-inner-card');\n } else {\n consequenceArea = affectedElement.closest('.js-card');\n }\n\n // Get path from affector\n const affectorPath = affector.dataset.path;\n // Get all fields affected by the affector\n const affectedElements = consequenceArea.querySelectorAll(`[data-affected-by*=\"!${affectorPath}!\"]`);\n // Hide all children and disable their inputs\n affectedElements.forEach((affectedElement) => {\n affectedElement.classList.add('hidden-xs');\n // Disable elements inside\n affectedElement.querySelectorAll('input,select').forEach((toDisable) => {\n toDisable.disabled = true;\n });\n hide_children(affectedElement);\n });\n}\n\n/*\n Tracks changes in the document\n*/\ndocument.addEventListener('change', bindChange);\ndocument.addEventListener('input', bindChange);\n\n// Init Card togglers\nconst initCardListToggling = () => {\n const cardListToggler = document.querySelectorAll('.js-toggle-inner-cards input');\n cardListToggler.forEach((toggler) => {\n toggler.addEventListener('change', innerCardToggler);\n });\n};\n\nconst initCardToggling = () => {\n const cardTogglers = document.querySelectorAll('.js-toggle-card');\n cardTogglers.forEach((toggler) => {\n const inputToggler = toggler.querySelector('input')\n const selectToggler = toggler.querySelector('select')\n if (inputToggler) {\n inputToggler.addEventListener('change', cardToggler);\n }\n if (selectToggler) {\n selectToggler.addEventListener('change', cardToggler);\n }\n });\n};\n\n/*\n Handles the scrolling behaviour on the toggling between the\n \"write comment\" button and the comment input\n*/\n\nconst commentScroll = (action, buttonHeight) => {\n const layout = document.querySelector('#layout-page');\n if(action === \"down\"){\n layout.scrollTo({\n top:layout.scrollHeight,\n behavior: \"smooth\"\n });\n }\n if(action === \"up\"){\n const commentInput = document.querySelector('.js-comment-input');\n layout.scrollTo({\n top: layout.scrollTop - commentInput.scrollHeight + buttonHeight,\n behavior: \"smooth\"\n });\n }\n}\n\n// Handles the toggling between the \"write comment\" button and the comment input\n\nconst commentInputToggling = () => {\n // If there isn't a comment button, it means that the user doesn't have permission to comment\n // or that the fact-find is locked\n // We can, therefore, cancel the execution of this function\n if (document.querySelector('.js-write-comment') == null) {\n return;\n }\n\n // If is mobile move the modal to be a son of body element\n const isMobile = window.innerWidth < 512;\n if(isMobile) {\n const commentModal = document.getElementById('comment-modal');\n if(commentModal) {\n document.body.insertAdjacentElement('beforeend', commentModal);\n }\n // adding EventListener to the modal \"close\" button\n const closeModal = document.querySelector('.modal-close');\n if(closeModal) {\n closeModal.addEventListener('click', () => {\n commentModal.classList.remove('is-open');\n textareaInput.value = '';\n });\n }\n };\n\n const commentModal = document.getElementById('comment-modal');\n const commentBtn = document.querySelector('.js-write-comment').parentElement;\n const commentInput = document.querySelector('.js-comment-input');\n // if is Mobile target the modal elements\n const textareaInput = document.getElementById(isMobile? 'js-modal-comment-content' : 'js-comment-content');\n const cancelComment = document.querySelector(isMobile? '.js-modal-cancel-comment' : '.js-cancel-comment');\n const submitComment = document.querySelector(isMobile? '.js-modal-submit-comment' :'.js-submit-comment');\n const submitCommentBtn = document.querySelector(isMobile? '.js-modal-submit-comment-btn' : '.js-submit-comment-btn');\n\n const buttonHeight = commentBtn.scrollHeight;\n\n // Handle onClick of 'Write Comment' button\n commentBtn.addEventListener('click', event => {\n event.preventDefault();\n if(isMobile){\n commentModal.classList.add('is-open');\n } else {\n commentInput.classList.remove('hidden-xs');\n commentBtn.classList.add('hidden-xs');\n commentScroll('down');\n }\n textareaInput.focus();\n });\n\n // Handle onClick of 'cancel' button (close input without submiting a comment)\n cancelComment.addEventListener('click', () => {\n if (isMobile) {\n commentModal.classList.remove('is-open');\n } else {\n commentScroll('up', buttonHeight);\n setTimeout(() => {\n commentBtn.classList.remove('hidden-xs');\n commentInput.classList.add('hidden-xs');\n\n }, 130);\n }\n // disable submit comment for next comment\n submitCommentBtn.disabled = true;\n submitCommentBtn.classList.add('is-disabled');\n //reset textarea value\n textareaInput.value = '';\n\n });\n\n // Handle submit comment button is enabled or disabled\n textareaInput.addEventListener('input', () => {\n if(textareaInput.value !== ''){\n submitCommentBtn.disabled = false;\n submitCommentBtn.classList.remove('is-disabled');\n } else {\n submitCommentBtn.disabled = true;\n submitCommentBtn.classList.add('is-disabled');\n }\n });\n\n // Handle submiting a new comment\n submitCommentBtn.addEventListener('click', event => {\n event.preventDefault();\n if(isMobile) {\n commentModal.classList.remove('is-open');\n } else {\n commentBtn.classList.remove('hidden-xs');\n commentInput.classList.add('hidden-xs');\n }\n\n const csrfToken = document.querySelector('meta[name=\"csrf-token\"]').getAttribute('content');\n fetch(submitComment.dataset.submitCommentPath, {\n method: 'POST',\n headers: {\n 'X-Requested-With': 'XMLHttpRequest',\n 'Accept': 'application/json',\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': csrfToken,\n },\n body: JSON.stringify({ content: textareaInput.value })\n })\n .then(response => response.json())\n .then((data) => {\n // get new comment template\n let commentTemplate = document.getElementById('new-comment-template').innerHTML;\n // update values in template\n commentTemplate = commentTemplate.replace(/!comment_author!/, 'You');\n commentTemplate = commentTemplate.replace(/!comment_id!/g, data.id);\n commentTemplate = commentTemplate.replace(/!comment_created_at!/, 'less than a minute ago');\n commentTemplate = commentTemplate.replace(/!comment_content!/, data.content);\n commentTemplate = commentTemplate.replace(/!source_id!/, data.source);\n commentTemplate = commentTemplate.replace(/!source_type!/, 'FactFind::Section');\n // add new comment to the DOM\n let commentHistorySection = document.querySelector('.js-comments-history');\n commentHistorySection.insertAdjacentHTML('beforeend', commentTemplate);\n // clear textare input value\n textareaInput.value = '';\n // scroll down to display the comment that was just added\n commentScroll('down');\n // disable submit comment for next comment\n submitCommentBtn.disabled = true;\n submitCommentBtn.classList.add('is-disabled');\n\n // Hide existing delete links\n let deleteLinks = commentHistorySection.querySelectorAll('.js-delete-comment-link');\n deleteLinks.forEach((deleteLink) => {\n deleteLink.classList.add('hidden-xs');\n });\n // Show last delete link\n if (deleteLinks.length > 0 && data.can_destroy) {\n deleteLinks[deleteLinks.length - 1].classList.remove('hidden-xs');\n }\n });\n });\n}\n\n/*\n Load asynchronously new FF section\n Method called on views/fact_find/show.js.erb\n*/\nconst initConsequences = (element) => {\n const elementToSearch = element || document;\n const cardConsequences = elementToSearch.querySelectorAll('.js-consequence-affector input, .js-consequence-affector select');\n cardConsequences.forEach((card) => {\n card.addEventListener('change', triggerConsequence);\n });\n initMasks();\n}\n\nconst showSection = (currentSection, sectionHTML) => {\n\n document.querySelector('.js-fact-find').outerHTML = sectionHTML;\n const currentURL = window.location.origin;\n window.history.pushState({}, '', `${currentURL}/fact_find/${currentSection}`);\n\n const factFindSection = document.querySelector('.js-fact-find');\n\n window.initChoices();\n initDynamicToggler(factFindSection);\n initCardListToggling();\n initCardToggling();\n commentInputToggling();\n initObjectTables();\n initConsequences();\n initMasks();\n initDropdown();\n\n const saveFactFindButton = document.querySelector('.js-fact-find-save');\n if (saveFactFindButton !== null) {\n saveFactFindButton.addEventListener('click', bottomNavSaveChanges);\n }\n};\n\nconst initFactFind = () => {\n const factFindPage = document.getElementById('layout-fact-find');\n\n if (factFindPage !== null) {\n\n initCardListToggling();\n initCardToggling();\n commentInputToggling();\n initObjectTables();\n initConsequences();\n initDynamicToggler();\n\n window.showSection = showSection;\n window.showInputValidations = showInputValidations;\n window.toggleFactFindSubmitButton = toggleFactFindSubmitButton;\n window.initConsequences = initConsequences;\n window.initChoices();\n\n const saveFactFindButton = document.querySelector('.js-fact-find-save');\n if (saveFactFindButton !== null) {\n saveFactFindButton.addEventListener('click', bottomNavSaveChanges);\n }\n }\n};\n\nconst saveFactFind = (section) => {\n if (formChanged) {\n Rails.ajax({\n url: `/fact_find/${section}/save`,\n type: 'GET',\n dataType: 'script',\n accept: 'script',\n });\n formChanged = false;\n } else {\n Rails.ajax({\n url: `/fact_find/${section}`,\n type: 'GET',\n dataType: 'script',\n accept: 'script',\n });\n }\n}\n\nconst changeFormStatus= () => {\n formChanged = false\n}\n\nexport { initFactFind, saveFactFind, changeFormStatus };\n\n\n// fact_find_save_modal_path(next_section: ff_section.fact_find_section_template.url_name)\n\n","/* eslint-disable no-param-reassign */\nimport confirmCallback from '../utils/confirm_callback';\nimport deleteString from '../utils/type_delete_string';\n\n/* *******************************************************\n ** Functions called when the Fact Find Section is saved **\n ******************************************************** */\nconst cleanInputError = (input) => {\n const formGroup = input.closest('fieldset') || input.parentElement;\n const alertToClean = formGroup.querySelector('[role=\"alert\"]');\n\n if (input.type === 'radio') {\n input.parentElement.querySelector('label').classList.remove('b-xs-red-500', 'text-xs-red-500');\n const inputsToClean = formGroup.querySelectorAll('input.b-xs-red-500');\n // Clean siblings (like yes/no radio buttons)\n inputsToClean.forEach(cleanInputError);\n } else {\n input.classList.remove('b-xs-red-500');\n }\n\n formGroup.classList.remove('has-error');\n // Added the following block to deal with the removal of error messages \n // in the dropdowns, upon selecting a value\n const formGroupParent = formGroup.closest('.has-error');\n if (formGroupParent) {\n formGroupParent.classList.remove('has-error');\n }\n if (alertToClean) {\n deleteString(alertToClean);\n }\n};\n\n// Function to change the submit button status (disabled vs enabled)\nconst toggleFactFindSubmitButton = (status) => {\n const submitButton = document.querySelector('.js-fact-find-save');\n\n if (status === 'disable' || !status) {\n submitButton.classList.add('is-disabled');\n submitButton.disabled = true;\n } else if (status || status === 'enable') {\n submitButton.classList.remove('is-disabled');\n submitButton.disabled = false;\n }\n};\n\n/*\n Whenever an element is changed in the window\n removes the validation messages and enables the submit button\n */\nconst bindChange = (event) => {\n const element = event.target;\n\n if (element && element.matches('.js-fact-find-form input, .js-fact-find-form select, .js-fact-find-form textarea')) {\n toggleFactFindSubmitButton('enable');\n cleanInputError(element);\n }\n};\n\n/*\n Tracks changes in the document\n */\ndocument.addEventListener('change', bindChange);\ndocument.addEventListener('input', bindChange);\n\nlet formSuccess = true; // is the form a success or not?\n\n// function to validate a field\n// adds the class .validation-error to a form-group if the field/input is not valid\n// adds a `validation-message` with an error message\nconst validateField = (element, field, fieldName) => {\n const formGroup = element.closest('.form-group') === null ? element.parentElement.querySelector('.form-group') :\n element.closest('.form-group');\n // in the segmented control fields to display the error message correctly\n // the upper form-group element must be targeted\n const formControl = formGroup.closest('.form-control');\n const target = formControl || formGroup;\n target.classList.add('has-error');\n if (target.querySelector('.text-xs-red-500') === null) {\n let finalMessage = '';\n field[fieldName].forEach((message) => {\n finalMessage += `${message}`;\n });\n target.insertAdjacentHTML('afterend', `${finalMessage}`);\n }\n\n\n formSuccess = false;\n};\n\n/**\n * Adds validation messages to regular cards and card lists\n * @param cardId\n * @param cardObject\n */\nconst validateCard = (cardId, cardObject) => {\n Object.keys(cardObject).forEach((card) => {\n Object.keys(cardObject[card]).forEach((field) => {\n if (cardObject[card]) {\n const fieldElement = document.querySelector(`[data-cardid='${cardId}'] [name*='[${field}]']`);\n\n // will only apply the validation messages if the field is on screen\n if (fieldElement != null) {\n const messages = cardObject[card];\n // Validate if it's a single field\n validateField(fieldElement, messages, field);\n }\n }\n });\n });\n};\n\n/**\n * Adds validation messages to object tables\n * @param cardId\n * @param rows\n */\nconst validateObjectTable = (cardId, rows) => {\n Object.keys(rows).forEach((rowErrorIndex) => {\n Object.keys(rows[rowErrorIndex]).forEach((rowError) => {\n Object.keys(rows[rowErrorIndex][rowError]).forEach((field) => {\n // Get the row number for this error\n const errorIndex = rowError.substring(rowError.indexOf('_err') + 4);\n // Find the actual input by searching in the card for inputs with the same name\n // And get the nth input found\n const element = document.querySelectorAll(`[data-cardid='${cardId}'] [name$='[${field}]']`)[errorIndex];\n validateField(element, rows[rowErrorIndex][rowError], field);\n });\n });\n });\n};\n\n// Called on views/fact_find/update.js.erb\nconst showInputValidations = (formInfo) => {\n // Clean previous errors\n const errorsToClean = document.querySelectorAll('.text-xs-red-500');\n errorsToClean.forEach((element) => {\n element.remove();\n });\n\n if (formInfo !== null) {\n Object.keys(formInfo).forEach((cardId) => {\n const cardObject = formInfo[cardId];\n if (cardObject.length === undefined) {\n validateCard(cardId, cardObject);\n } else {\n // It's an object table (the errors are an array)\n validateObjectTable(cardId, cardObject);\n }\n });\n }\n\n // Show success message\n confirmCallback(`\n \n \n All your changes have been saved${!formSuccess ? ', but you\\'re still missing mandatory fields' : ''}.\n \n `, {\n targetContainer: document.querySelector('#layout-notifications'),\n classToAdd: `bg-xs-${formSuccess ? 'green' : 'yellow'}-100`,\n dismiss: true,\n });\n\n const currentSection = document.querySelector('.vertical-menu-item.is-active');\n if (formSuccess) {\n currentSection.classList.add('is-complete');\n } else {\n currentSection.classList.remove('is-complete');\n // Focus on the first input with error\n const firstError = document.querySelector(\".text-xs-red-500:not([type='hidden'])\");\n firstError.closest('.form-section').querySelector('input').focus();\n // reset form success for next validation\n formSuccess = true;\n }\n\n toggleFactFindSubmitButton('disable');\n};\n\nexport { showInputValidations, toggleFactFindSubmitButton };\n"],"names":["bindSelect","select","isDisabled","disabled","removeAttribute","value","length","placeholder","document","createElement","setAttribute","innerHTML","dataset","appendChild","choices","Choices","paste","searchEnabled","children","shouldSort","classNames","containerOuter","choicesBorder","disable","addEventListener","enable","unhighlightAll","initChoices","selectsList","querySelectorAll","forEach","initDropdown","item","label","querySelector","wrapper","body","e","path","composedPath","clickedInLabel","includes","classList","toggle","contains","remove","createPopper","placement","modifiers","name","options","offset","confirmCallback","message","undefined","duration","targetContainer","classToAdd","dismiss","id","randomizer","timing","readingTime","seconds","$container","newCallback","className","callback","style","messageTemplate","insertAdjacentElement","insertAdjacentHTML","add","isHover","setTimeout","event","currentTarget","closest","window","enableEvent","Event","disableEvent","targets","dynamicToggler","trigger","togglerID","dynamicTarget","domObject","action","Object","keys","key","bool","tagName","elem","field","dispatchEvent","toggleElements","innerText","initDynamicToggler","parent","domParent","data","JSON","parse","dynamic","cacheTargetElements","isAllowed","hasAttribute","createMask","type","Array","from","filter","Inputmask","money","alias","prefix","maskMoney","groupSeparator","autoGroup","digits","decimalPlaces","maskMoneyDecimal","rightAlign","clearMaskOnLostFocus","removeMaskOnSubmit","showMaskOnHover","autoUnmask","years","suffix","maskYears","percentage","maskTypes","mask","setActive","init","calculateObjectTableSectionTotals","sectionTable","sectionTotals","totalSum","element","parseFloat","totalsMultiplier","sectionName","sectionTotal","parseInt","removeObjectTableLine","preventDefault","row","target","table","parentNode","removeChild","toggleFactFindSubmitButton","calculateObjectTableValuesInRow","updatedInput","otherInput","initDestroy","addObjectTableLine","clickedLink","linkDiv","totalsRow","toLowerCase","rowTemplate","lineTemplate","index","fieldElements","fieldName","cardId","replace","inputEvent","removeButton","i","initMasks","focusObjectTableInput","focusedInput","siblingFields","calculatedSibling","push","outFocusObjectTableInput","outFocusedInput","uncalculatedSibling","not","initObjectTables","Math","random","toString","substring","text","totalReadingTimeSeconds","trim","split","wpm","minutes","ceil","deleteStringInterval","Delete","string","clearInterval","interval","setInterval","innerCardToggler","selectedInput","method","Rails","url","dataType","accept","cardToggler","changedInput","valuesToLook","showConditions","cardTarget","cardType","addCardPath","bottomNavSaveChanges","eventTarget","_index","formChanged","bindChange","matches","formGroup","errorSpan","triggerConsequence","clickedElement","affector","hiddenInput","affectorPath","affectorField","affectorValue","affectedElement","consequences","actionToTake","hide_children","checked","consequenceArea","toDisable","initCardListToggling","toggler","initCardToggling","inputToggler","selectToggler","commentScroll","buttonHeight","layout","scrollTo","top","scrollHeight","behavior","commentInput","scrollTop","commentInputToggling","isMobile","innerWidth","commentModal","getElementById","closeModal","textareaInput","commentBtn","parentElement","cancelComment","submitComment","submitCommentBtn","focus","csrfToken","getAttribute","fetch","submitCommentPath","headers","stringify","content","then","response","json","commentTemplate","source","commentHistorySection","deleteLinks","deleteLink","can_destroy","initConsequences","card","showSection","currentSection","sectionHTML","outerHTML","currentURL","location","origin","history","pushState","factFindSection","saveFactFindButton","initFactFind","showInputValidations","saveFactFind","section","changeFormStatus","cleanInputError","input","alertToClean","formGroupParent","deleteString","status","submitButton","formSuccess","validateField","finalMessage","formInfo","cardObject","fieldElement","messages","validateCard","rows","rowErrorIndex","rowError","errorIndex","indexOf","validateObjectTable"],"sourceRoot":""}