{"version":3,"file":"js/keenform-renderer-bundle-849e11e7a1363509ba56.js","mappings":"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","sources":["webpack://keenforms/./app/javascript/bundles/KeenformRenderer/utils/FormAttributeStateManager.js","webpack://keenforms/./app/javascript/bundles/KeenformRenderer/utils/FormRuleResponder.js","webpack://keenforms/./app/javascript/bundles/KeenformRenderer/utils/KeenformStateManager.js","webpack://keenforms/./app/javascript/bundles/shared/constants/standard_form_rule_responses.js","webpack://keenforms/./app/javascript/bundles/KeenformRenderer/components/formelements/ReadOnlyFreeFormAttribute/ReadOnlyFreeFormAttribute.jsx","webpack://keenforms/./app/javascript/bundles/KeenformRenderer/components/formelements/RatingScaleFormAttribute/RatingScaleFormAttribute.jsx","webpack://keenforms/./app/javascript/bundles/KeenformRenderer/KeenformViewManager.jsx","webpack://keenforms/./app/javascript/bundles/KeenformPostSubmit/KeenformPostSubmit.jsx","webpack://keenforms/./app/javascript/packs/keenform-renderer-bundle.js","webpack://keenforms/./app/javascript/bundles/KeenformRenderer/KeenformPreviewManager.jsx"],"sourcesContent":["import {isValidInteger, isValidFloat, isStringValidEmailAddress} from \"../../shared/form_attribute_utils\";\nimport \n APP_CONSTANTS,\n { PLACEHOLDER_OPTION, KF_FA_CONTAINER_CLASS }\nfrom '../../shared/constants/app_constants';\n\n//this object will contain data about the attribute\n//it will return an object that can be used for setting the state in the configurator\n\nexport default class FormAttributeStateManager{\n /*\n * constructor accepts hash of attributes for Form Attribute, sets attributes based on values in hash\n * params {object} attrHash - an JSON representation of this config attribute\n */\n constructor(attrHash) {\n // TODO maybe we change this, set attributes, key or no key, but dont provide state if there is no key\n if ( attrHash.hasOwnProperty(\"name\") && attrHash.hasOwnProperty(\"display_type\")){\n //required attributes\n this._key = attrHash.name, //*required, unique identifier\n this._name = attrHash.name,\n this._uuid = attrHash.uuid,\n this._label = attrHash.label,\n this._form_attribute_type = attrHash.form_attribute_type || APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.FREEFORM, //fix this\n this._value_type = attrHash.value_type || APP_CONSTANTS.VALUE_TYPES.TEXT,\n this._display_type = attrHash.display_type || APP_CONSTANTS.DISPLAY_TYPES_HTML.TEXT,\n this._is_inialized = false,\n this._position = attrHash.position,\n this._value,\n\n // optional attributes\n this._required = attrHash.required || false,\n this._hidden = attrHash.hidden || false,\n this._read_only = attrHash.read_only || false,\n this._locked = false, //TODO do we add this to api?\n this._placeholder = attrHash.placeholder, //TODO: do we set this just for freeform?\n this._hide_label_flag = attrHash.hide_label_flag || false,\n this._default_value = attrHash.default_value,\n this._metadata_types = attrHash.metadata_types || null,\n this._use_blank_placeholder_option = attrHash.use_blank_placeholder_option || false,\n this._description = attrHash.description,\n this._display_options = attrHash.display_options, // DEPRECATED\n this._settings = attrHash.settings;\n\n this._touched = false;\n this._locked = false; // TODO: virtual attribute changed by form rules\n\n this._float_precision = undefined;\n if (this._form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.FREEFORM \n && this._value_type === APP_CONSTANTS.VALUE_TYPES.FLOAT\n && !!attrHash.float_precision ){\n this._float_precision = attrHash.float_precision;\n }\n\n //3 types of inputs - freeform (), single select ()\n switch (this._form_attribute_type){\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.FREEFORM:\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.NON_INPUT:\n // TODO: any other special attributes for text/textarea?\n if (this._display_type === APP_CONSTANTS.DISPLAY_TYPES_HTML.STATIC_HTML) {\n this._register_click_events_on_html = attrHash.register_click_events_on_html;\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT:\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n // TODO: need options map or array - for now its an array\n let optionsAvailable = attrHash.options;\n if (attrHash.settings && attrHash.settings['randomize_options'] && attrHash.settings['randomize_options'] === true) {\n let shuffledArray = this.shuffleArray(optionsAvailable);\n optionsAvailable = shuffledArray;\n }\n this._options = optionsAvailable.map(option => {\n return {\n ...option,\n hidden: false\n };\n }) || [];\n break;\n // ADD DATEPICKER HERE\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.DATEPICKER:\n // do nothing?\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.INLINE_STYLE:\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SYSTEM:\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.NON_DISPLAY:\n break;\n default:\n console.error(\"there may be an invalid form attribute type\");\n console.log(this);\n break;\n }\n } else {\n //TODO - is this the right thing to do? How do we handle trying to create this type of object that is invalid\n console.error(\"name and input_rype are required fields - You cannot make this an object -> attrHash:\", attrHash);\n console.log(this);\n //this.isValid = false;\n return ({isValid: false, errorMessage: 'missing required fields for AttributeStateManager'});\n }\n }\n\n /**\n * response needs to be standard message object for value setting\n * @param {*} floatValue \n */\n getResponseForValidFloatValue = (floatValue) => {\n let responseMessage = {\n value: floatValue,\n isValid: true\n }\n\n if (this._float_precision){\n const floatSplit = floatValue.toString().split(\".\");\n if (floatSplit.length === 2) {\n const afterDecimalValue = floatSplit[1];\n if (afterDecimalValue.length > this._float_precision){\n responseMessage.value = `${floatSplit[0]}.${floatSplit[1].slice(0, this._float_precision)}`;\n responseMessage.notificationMessage = `this value only allows for ${this._float_precision} digits after decimal point`;\n }\n }\n }\n\n const {number_input_min, number_input_max} = this._settings;\n\n if (typeof number_input_min === 'number' && floatValue < number_input_min) {\n responseMessage.isValid = false;\n responseMessage.errorMessage = `the minimum number for this input is ${number_input_min}`;\n } else if (typeof number_input_max === 'number' && floatValue > number_input_max) {\n responseMessage.isValid = false;\n responseMessage.errorMessage = `the maximum number for this input is ${number_input_max}`;\n }\n \n return responseMessage;\n }\n\n // deprecated\n getKey(){\n return this._key || undefined;\n }\n\n getName() {\n return this._name;\n }\n\n getLabel(){\n return this._label;\n }\n\n /*\n * getStateForUI will return an object with the necessary attributes to be passed to Form Element\n */\n getStateForUI(){\n const faName = this.getName();\n let stateObj = {\n _key: this._key, // TODO: we need this, but should be decommissioned\n uuid: this._uuid,\n name: faName,\n value: this.getValue(),\n label: this.getLabel(),\n hidden: this._hidden,\n read_only: this._read_only,\n locked: this._locked,\n hide_label_flag: this._hide_label_flag,\n isValid: this._is_valid, // TODO: refactor this, using static attribute seems like a bad idea\n isValidPerValueType: this.isValidPerValueType(),\n touched: this._touched,\n required: this._required,\n form_attribute_type: this._form_attribute_type,\n value_type: this._value_type,\n display_type: this._display_type,\n placeholder: this._placeholder,\n metadata_types: this._metadata_types,\n description: this._description,\n containerDomId: `${KF_FA_CONTAINER_CLASS}-${faName}`,\n display_options: this._display_options, // deprecated\n settings: this._settings\n }\n //non required attributes\n if (!this.isValid()){\n stateObj.errorMessage = this._errorMessage;\n }\n\n if (this._notificationMessage){\n stateObj.notificationMessage = this._notificationMessage;\n }\n\n if (this._form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT || this._form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT){\n stateObj.options = this._options;\n switch (this._form_attribute_type){\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT:\n stateObj.option_selected = this._options.find(option => option.value === stateObj.value);\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n stateObj.options_selected = this._options.filter(option => stateObj.value.includes(option.value));\n break;\n default:\n console.warn('this probably should not happen');\n }\n }\n\n if (!!this._float_precision){\n stateObj.float_precision = this._float_precision;\n }\n\n if (this.hasOwnProperty('_register_click_events_on_html')) {\n stateObj.register_click_events_on_html = this._register_click_events_on_html\n }\n\n return stateObj;\n }\n\n getValue(){\n return this._value;\n }\n\n //TODO: this isnt being used, but will be for character counter or validating input (regex, etc)\n getNotificationMessage(value){\n let notificationMessage = undefined;\n //check for value is null or undefined\n if (value === null || value === undefined){\n return notificationMessage;\n }\n\n return notificationMessage;\n }\n\n //TODO: lets clean this up - either use disabled or readonly not both\n isLocked(){\n return this._read_only === true;\n }\n\n isValid(){\n return this._is_valid;\n }\n\n isValidPerValueType() {\n if (\n this._form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.FREEFORM \n || this._form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT) {\n switch (this._value_type) {\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n return true;\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n return isValidInteger(this._value);\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n return isValidFloat(this._value);\n // add date picker\n case APP_CONSTANTS.VALUE_TYPES.DATE:\n // TODO: add date picker\n console.warn('date picker validation here');\n return true;\n default:\n console.error('an error has occurred in testing value validity');\n return false;\n }\n } else if (this._form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT) {\n // console.log('under construction for validating multiselect');\n return true;\n } else if (\n this._form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.NON_INPUT\n || this._form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.INLINE_STYLE\n || this._form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SYSTEM) {\n // always true, cannot be invalid\n return true;\n } else if (this._form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.DATEPICKER) {\n // TODO: needs more work\n return true;\n } else {\n console.error('unexpected form attribute type', this._form_attribute_type);\n return false;\n }\n }\n\n onBlurOfAttribute(){\n this._touched = true;\n return this.getStateForUI();\n }\n\n setAsHidden(hideThisAttribute){\n this._hidden = hideThisAttribute;\n return this.getStateForUI();\n }\n\n /**\n * accepts a value, returns state of ConfigAttribute\n * @params {value} - a candidate value for this attribute\n * @return {object} - current state of this ConfigAttribute\n */\n setValue(value){\n //TODO: value should not always be set - for certain conditions, like a read only attribute this should fail\n const responseForValue = this.testValueValidityPerType(value);\n if (responseForValue && responseForValue.isValid === true){\n this._value = responseForValue.value,\n this._is_valid = true,\n this._notificationMessage = responseForValue.notificationMessage ? responseForValue.notificationMessage : undefined;\n } else {\n //TODO: set internal state of this object - value, isValid, errorMessage\n if (value === NaN){ //TODO - add other restricted values here\n this._value = value;\n } else if (this._required && responseForValue.value === ''){\n this._value = responseForValue.value; //TODO - this is the source of a problem, an empty string for a required field is being set to null\n } else {\n this._value = value;\n }\n this._is_valid = false,\n this._errorMessage = responseForValue.errorMessage;\n }\n return this.getStateForUI();\n }\n\n testFreeformValueForValidity = (value) => {\n switch (this._value_type){\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n return this.validateTextValue(value);\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n return this.validateIntegerValue(value);\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n return this.validateFloatValue(value);\n case APP_CONSTANTS.VALUE_TYPES.DATE:\n // under construction\n console.log('date picker under construction');\n return true;\n default:\n console.error('an error has occurred in testing value validity');\n return {\n isValid: false,\n errorMessage: \"THERE WAS AN ERROR - INVALID VALUE TYPE\"\n }\n }\n }\n\n testValueValidityPerType = (value) => {\n switch(this._form_attribute_type){\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.FREEFORM:\n //make sure value matches value type\n return this.testFreeformValueForValidity(value);\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT:\n return this.testSingleSelectValueForValidity(value);\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n //make sure this is an array, and each option is an option\n return this.testMultiSelectValueForValiditiy(value);\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.DATEPICKER:\n // TODO:\n return {\n value: value,\n isValid: true\n };\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.NON_INPUT:\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.INLINE_STYLE:\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SYSTEM:\n return {\n value: value,\n isValid: true\n };\n default:\n console.error('invalid form attribute type', this);\n return {\n isValid: false,\n errorMessage: \"THERE WAS AN ERROR - INVALID VALUE TYPE\"\n };\n }\n }\n\n testSingleSelectValueForValidity = (value) => {\n if ((value === undefined || value === PLACEHOLDER_OPTION ) && this.hasOwnProperty('_placeholder') ){\n const isValueValid = this._required === false;\n let responseMessage = {\n value: PLACEHOLDER_OPTION,\n isValid: isValueValid //TODO: do we check if this is required?\n };\n if (!isValueValid){\n responseMessage.errorMessage = \"This attribute is required\";\n }\n return responseMessage;\n } else {\n // make sure value exists is an option\n // NOTE: we're change value to string because people can put weird shit in the option value\n // this is single select so get an exact match for the string\n // TODO: so that conversion to string is why it works when we have a value that is a number\n const selectedOption = this._options.find(opt => opt.value.toString() === value.toString()); //TODO: this could be a problem\n if (!!selectedOption){\n return {\n value: value,\n isValid: true\n };\n } else {\n /**\n * TODO: this option is not available, this might happen because\n * form rule used expression editor with invalid option value\n * or someone hacked the form\n */\n console.warn('Form rule is attempting to set ineligble option value for single select, value: ', value, 'available options: ', this._options);\n return {\n isValid: false,\n errorMessage: \"THERE WAS AN ERROR - INVALID VALUE TYPE\"\n };\n }\n }\n }\n\n testMultiSelectValueForValiditiy = (valueArray) => {\n //TODO: this works but is unstable and requires more testing\n if (Array.isArray(valueArray) === false){\n return {\n isValid: false,\n errorMessage: \"Invalid value type for multiselect - this should be an array\"\n };\n }\n const matchingOptionArr = valueArray.filter((valueItem) => {\n return !!( this._options.find(opt => opt.value === valueItem));\n });\n if (matchingOptionArr.length != valueArray.length){\n return {\n isValid: false,\n errorMessage: \"Invalid value type for multiselect - there are options that are not valid\"\n };\n } else {\n return {\n value: valueArray,\n isValid: true\n };\n }\n }\n\n touchAttribute(){\n this._touched = true;\n }\n\n validateTextValue(value){\n const validDisplayTypes = [\n APP_CONSTANTS.DISPLAY_TYPES_HTML.TEXT, \n APP_CONSTANTS.DISPLAY_TYPES_HTML.TEXTAREA,\n APP_CONSTANTS.DISPLAY_TYPES_HTML.EMAIL\n ];\n\n if ( validDisplayTypes.includes(this._display_type) ) {\n if (this._required && (typeof value === \"undefined\" || value === null || value.trim() === \"\")){\n return {\n value: \"\",\n isValid: false,\n errorMessage: `${this.getLabel()} is a required field`,\n }\n }\n }\n\n let textValueIsValid = true,\n notificationMessage = this.getNotificationMessage(value),\n errorMessage = null;\n\n if (this._display_type === APP_CONSTANTS.DISPLAY_TYPES_HTML.EMAIL && value.length > 0) {\n textValueIsValid = isStringValidEmailAddress(value);\n if (textValueIsValid !== true) {\n errorMessage = \"This is an invalid email address\";\n }\n }\n\n if (!!this._settings) {\n const {text_input_minlength, text_input_maxlength} = this._settings;\n if (typeof text_input_minlength == \"number\" && value.length < text_input_minlength) { \n textValueIsValid = false;\n errorMessage = `this input's value must be at least ${this._settings.text_input_minlength} characters long`;\n }\n \n if (typeof text_input_maxlength == \"number\" && value.length > text_input_maxlength) {\n textValueIsValid = false;\n errorMessage = `this input's value must be no greater than ${text_input_maxlength} characters long`;\n } else if (value.length === this._settings.text_input_maxlength) {\n notificationMessage = `this input is at maximum length of ${text_input_maxlength} characters long`;\n }\n }\n\n const responseMessage = {\n value: value,\n isValid: textValueIsValid,\n notificationMessage: notificationMessage\n };\n if (errorMessage) {\n responseMessage.errorMessage = errorMessage;\n }\n return responseMessage;\n }\n\n /**\n * returns message object with \n * ADD validation for min/max\n */\n validateIntegerValue(value) {\n //TODO: validate this is an integer - check if this is a real integer\n const valueIsValidInteger = isValidInteger(value);\n\n if (valueIsValidInteger) {\n let returnMsg = { \n value: parseInt(value),\n isValid: true\n };\n\n // check for min/max\n if (!!this._settings) {\n const {number_input_min, number_input_max} = this._settings;\n if (typeof number_input_min === 'number' && value < number_input_min) {\n returnMsg.isValid = false;\n returnMsg.errorMessage = `the minimum number for this input is ${number_input_min}`;\n } else if (typeof number_input_max === 'number' && value > number_input_max) {\n returnMsg.isValid = false;\n returnMsg.errorMessage = `the maximum number for this input is ${number_input_max}`;\n }\n }\n return returnMsg;\n } else if (value === undefined || value === \"\"){\n //TODO: resolve if we treat undefined integer as zero?\n const returnMsg = {\n value: undefined,\n isValid: !this._required, //TODO: we're only checking for isValid based on required?\n errorMessage: (this._required ? `${this.getLabel()} is required` : undefined)\n };\n return returnMsg;\n } else {\n console.warn('this is an invalid integer');\n return {\n value: value,\n isValid: false,\n errorMessage: `${value} is an invalid integer`\n };\n }\n\n }\n \n validateFloatValue(value) {\n const valueIsValidFloat = isValidFloat(value);\n if (valueIsValidFloat){\n return this.getResponseForValidFloatValue(value);\n } else if (value === undefined || value === \"\") {\n let returnMsg = {\n value: undefined, // set as undefined because of form rules\n isValid: !this._required,\n errorMessage: (this._required ? `${this.getLabel()} is required` : undefined)\n };\n return returnMsg;\n } else {\n console.error('invalid float value');\n return {\n value: value,\n isValid: false,\n errorMessage: `${value} is an invalid decimal number`\n };\n }\n }\n\n // TODO: this function is still under construction, needs thought -\n // TODO: - what happens when a value IS DEFINED? THIS REQUIRES MORE WORK, 2019.08.04\n initializeFormAttributeVal(value) {\n if (this._is_inialized === false){\n this._is_inialized = true;\n let thisValue = this._default_value;//TODO: we dont have an initial value right now in the database\n switch(this._form_attribute_type){\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT:\n thisValue = this.initializeValueForSingleSelect(value);\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n // console.log('initializeValueForMultiselect');\n thisValue = this.initializeValueForMultiSelect(value);\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.FREEFORM:\n thisValue = this.initializeValueForFreeForm(value);\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.DATEPICKER:\n // TODO: add date picker here FIX ME\n // thisValue = this.initializeValueForDatepicker(value);\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.NON_INPUT : // \"noninput\":\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.INLINE_STYLE: // \"inline_style\":\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SYSTEM:\n // do nothing\n break;\n default:\n console.error('form attribute type not found');\n thisValue = undefined;\n }\n return this.setValue(thisValue);\n } else {\n console.log('value was already initialized, do nothing');\n return;\n }\n }\n\n initializeValueForSingleSelect(value) {\n /**\n * check if this fa has options and value exists for this fa - if so then set it\n * else if it is undefined and has placeholder, set to placeholder\n * else if it is undefined and has options, then set to first value\n * else return undefined\n */\n let retVal, retValOption;\n if (this._options && this._options.length > 0) {\n // using double not triple equals because vars passed as string not number\n retValOption = this._options.find(option => value == option.value);\n if (retValOption === undefined) {\n const defaultRadioOptionToNone = this._use_blank_placeholder_option && this._display_type === APP_CONSTANTS.DISPLAY_TYPES_HTML.RADIO;\n const defaultSelectOptionToNone = this._use_blank_placeholder_option && this._display_type === APP_CONSTANTS.DISPLAY_TYPES_HTML.SELECT;\n if ( defaultSelectOptionToNone || defaultRadioOptionToNone ) {\n retVal = PLACEHOLDER_OPTION;\n } else { // otherwise default to first option available \n retVal = this._options[0].value;\n }\n } else {\n retVal = retValOption.value;\n }\n }\n return retVal;\n }\n\n initializeValueForMultiSelect(value){\n //if value is undefined then set to empty array\n let retVal = [];\n if (value === undefined){\n return [];\n } else {\n if (this._options && this._options.length > 0){\n const valueArr = this._options.filter(option => value === option.value);\n retVal = valueArr.map(option => option.value);\n }\n return retVal;\n }\n }\n\n initializeValueForFreeForm(value){\n switch(this._value_type){\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n return ( isValidInteger(value) ? parseInt(value) : undefined );\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n return ( isValidFloat(value) ? parseFloat(value) : undefined );\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n if (!!value){\n return value;\n } else {\n return \"\";\n }\n default:\n return undefined;\n }\n }\n\n shuffleArray(array) {\n return array\n .map(value => ({ value, sort: Math.random() }))\n .sort((a, b) => a.sort - b.sort)\n .map(({ value }) => value);\n }\n\n}\n","import \n APP_CONSTANTS, { \n LAST_USER_MODIFIED_FA,\n LAST_USER_MODIFIED_FA_OPERATOR_PREFIX,\n PLACEHOLDER_OPTION,\n RULE_TYPES,\n MULTISELECT_SUMTOTAL_ATTRIBUTE,\n METADATA_DISPLAY_TYPES,\n OPERAND2_PRE_TYPES,\n POST_OP_MODIFIERS\n } \n from '../../shared/constants/app_constants';\nimport {\n FORM_RULE_RESPONSE,\n FAILLING_RULE_RESPONSE,\n FAILING_VALUE_SETTING_RULE,\n CONDITIONS_ARE_FALSE_RESPONSE,\n DISPLAY_RULE_SUCCESS_RESPONSE,\n VALUE_SETTING_RULE_SUCCESS_RESPONSE,\n FAILING_VALUE_SETTING_RULE_NUMBER_NAN,\n FAILING_VALUE_SETTING_RULE_NUMBER_INFINITY,\n FAILING_VALUE_SETTING_RULE_NUMBER_UNDEFINED,\n SOURCE_FORM_ATTRIBUTE_NOT_VALID_RESPONSE,\n SKIP_RULE_RESPONSE\n} from '../../shared/constants/standard_form_rule_responses';\nimport CONDITION_OPERATORS, {\n SYSTEM_OPERATORS,\n OPERATOR_STRING_BLANK,\n OPERATOR_STRING_NOT_BLANK,\n OPERATOR_STRING_EQUALS,\n OPERATOR_STRING_NOT_EQUALS,\n OPERATOR_STRING_CONTAINS,\n OPERATOR_STRING_NOT_CONTAINS,\n OPERATOR_STRING_LENGTH_EQUALS,\n OPERATOR_STRING_LENGTH_NOT_EQUALS,\n OPERATOR_STRING_LENGTH_MIN,\n OPERATOR_STRING_LENGTH_MAX,\n\n OPERATOR_NUMBER_BLANK,\n OPERATOR_NUMBER_NOT_BLANK,\n OPERATOR_NUMBER_EQUAL,\n OPERATOR_NUMBER_NOT_EQUAL,\n OPERATOR_NUMBER_GREATER_THAN,\n OPERATOR_NUMBER_NOT_GREATER_THAN,\n OPERATOR_NUMBER_GREATER_OR_EQUAL,\n OPERATOR_NUMBER_NOT_GREATER_OR_EQUAL,\n OPERATOR_NUMBER_LESSER_THAN,\n OPERATOR_NUMBER_NOT_LESSER_THAN,\n OPERATOR_NUMBER_LESSER_OR_EQUAL,\n OPERATOR_NUMBER_NOT_LESSER_OR_EQUAL,\n\n OPERATOR_SINGLESELECT_EQUALS,\n OPERATOR_SINGLESELECT_NOT_EQUALS,\n\n OPERATOR_MULTISELECT_MATCHES_EXACT,\n OPERATOR_MULTISELECT_NOT_MATCHES_EXACT,\n OPERATOR_MULTISELECT_CONTAINS,\n OPERATOR_MULTISELECT_NOT_CONTAINS,\n OPERATOR_MULTISELECT_LENGTH_EQUALS,\n OPERATOR_MULTISELECT_LENGTH_NOT_EQUALS,\n OPERATOR_MULTISELECT_LENGTH_MIN,\n OPERATOR_MULTISELECT_LENGTH_MAX,\n\n OPERATOR_LAST_USER_MODIFIED_FA_EQUALS,\n OPERATOR_LAST_USER_MODIFIED_FA_NOT_EQUALS,\n\n FILTERING_CONDITION_OPERATORS,\n OPERATOR_FILTERING_MULTISELECT_NOT_CONTAINED_IN,\n OPERATOR_FILTERING_MULTISELECT_CONTAINED_IN\n} from '../../shared/constants/operation_constants';\nimport {isValidInteger, isValidFloat} from '../../shared/form_attribute_utils';\n\n\n/**\n * \n * @param {*} formRule: form rule object, defined by API\n * @param {*} formAttributesStates hash of objects, with name as key, and form attribute as value\n *\n * WHAT THIS FUNCTION DOES\n * This function Returns an object that contains information related to the rule\n * it takes the form rule, and generates a response based on the condition, expression and formAttributeState\n * for example a hiding rule should have at least one condition to determine if it is executed\n * and if that condition is true then value should be set to true, and useValue is set to true\n * however if any error occurs useValue should return false, and errorMessage is populated, and success is set to false\n * \n * HOW THIS FUNCTION WORKS\n * #1 - check that all source attributes are present and valid - call getAllSourceFormAttributesAreValid\n * 1.1 - if they are NOT VALID then we can't execute rule\n * * exception - we should treat numbers (integers/floats) where value is undefined as ZERO, so not really 'invalid'\n * 1.1.1 - set FORM_RULE_RESPONSE to indicate as such\n * useValue: false\n * success: false\n * errorMessage: \"form rule has form attributes with invalid values, rule cannot be executed\"\n * 1.1.2 - return responseMessage\n * 1.2 - else if they are all VALID then PROCEED to next step\n * \n * #2 - EVALUATE rule has condition, based on use_condition_flag\n * 2.1 - if use_condition_flag === true, then determine which piece of data to use:\n * 2.1.1 - if use_cocode_expression is true, then use conditionals array\n * use function to evaluate formRule.metadata.nocode_condition (brand new)\n * formRule.conditionals\n * 2.1.2 - otherwise use rule_condition - as of 2020.08 this has been disabled, using all no code conditions\n * 2.1.2.a - get boolean response from either nocode_expression or eval(rule_condition)\n * need try/catch block for eval(rule_condition), if this fails then set FORM_RULE_RESPONSE\n * useValue: false\n * success: false\n * errorMessage: \"form rule condition expression caused error, rule cannot be evaluated\"\n * 2.1.2.b - if response is FALSE then RETURN FORM_RULE_RESPONSE with the following data:\n * useValue: false, - condition is false so dont use anything\n * success: true - rule did exactly as expected, condition evaluated to false\n * 2.1.2.c - else response from nocode_expression or rule_condition is TRUE, proceed to evaluate expression\n * 2.2 - else use_condition_flag is false, PROCEED\n * \n * #3 - EVALUATE rule expression, dependent on form rule type\n * 3.1 if rule_type is either hiding or locking, \n * 3.1.1 set FORM_RULE_RESPONSE as follows:\n * value: true\n * useValue: true\n * success: true\n * 3.1.2 return FORM_RULE_RESPONSE\n * \n * 3.2 else if rule_type is value_setting, validating, or filtering\n * 3.2.1 rule expression should be able to be evaluated based on eval(expression)\n * however it could also fail, so wrap this in try catch loop\n * 3.2.1.1 if catch condition is tripped, set FORM_RULE_RESPONSE values and return\n * useValue: false\n * success: false\n * errorMessage: \"eval statement for form rule failed with the following message: \" + error message\n * 3.2.2 rule expression eval succeeds\n * 3.2.2.1 - test value for validity,\n * 3.2.2.2 if value returned is not valid return error message\n * //TBD\n * 3.2.2.3 else value is value, set FORM_RULE_RESPONSE values and return\n * value: response from eval of rule_expression\n * useValue: true\n * success: true\n * \n * 3.3 else rule_type not valid\n * 3.3.1 set FORM_RULE_RESPONSE as follows:\n * useValue: false\n * success: false\n * errorMessage: \"form rule type not recognized\" \n * \n */\nclass FormRuleResponder{\n //this would be the ONLY PUBLIC FUNCTION\n static getFormRuleResponse(formRule, formAttributesStates) {\n let responseMessage ={...FORM_RULE_RESPONSE};\n\n // #1 - check that all source attributes are present and valid\n const allSourceFormAttributesAreValid = this.getAllSourceFormAttributesAreValid(formRule, formAttributesStates);\n\n // #1.1 - not all valid, return response\n // WAS DISABLED, still figuring this out\n if (!allSourceFormAttributesAreValid){\n // #1.1.2\n return {\n ...SOURCE_FORM_ATTRIBUTE_NOT_VALID_RESPONSE,\n formRule\n };\n }\n\n // #2 - EVALUATE rule has condition, based on use_condition_flag\n let conditionResponseMessage;\n if (formRule.use_nocode_condition ){\n if ( formRule.use_condition_function && formRule.condition_function ) {\n conditionResponseMessage = this.getResponseForConditionRuleFunction(formRule, formAttributesStates);\n } else {\n const nocodeConditionExpressions = formRule.form_rule_conditionals;\n conditionResponseMessage = this.evaluateNocodeConditions(nocodeConditionExpressions, formAttributesStates, formRule.nocode_condition_joiner, formRule);\n if (formRule.invert_condition === true) {\n conditionResponseMessage = !conditionResponseMessage;\n }\n }\n if (conditionResponseMessage === false){ // condition either failed or returned false\n return {\n ...CONDITIONS_ARE_FALSE_RESPONSE,\n formRule\n };\n } else if (conditionResponseMessage === undefined) {\n return {\n ...FAILLING_RULE_RESPONSE,\n formRule,\n errorMessage: 'this rule has a failing condition function response',\n };\n } else {\n // console.log('Condition is TRUE, PROCEED!!!!!');\n }\n } else {\n // console.log(\"use_nocode_condition is false, PROCEED\");\n }\n\n // #3 - EVALUATE rule expression, dependent on form rule type\n switch (formRule.rule_type){\n case RULE_TYPES.HIDING:\n case RULE_TYPES.LOCKING:\n responseMessage = {\n ...DISPLAY_RULE_SUCCESS_RESPONSE,\n formRule\n };\n break;\n case RULE_TYPES.VALUE_SETTING: // TODO: this should match the target attribute type\n responseMessage = this.getResponseForValueSettingRule(formRule, formAttributesStates);\n break;\n case RULE_TYPES.VALIDATING:\n responseMessage = this.getResponseForValidatingRule(formRule, formAttributesStates);\n break;\n case RULE_TYPES.FILTERING:\n responseMessage = this.getResponseForFilteringRule(formRule, formAttributesStates);\n break;\n case RULE_TYPES.WEBHOOK:\n //do nothing\n responseMessage = {\n ...SKIP_RULE_RESPONSE,\n formRule\n };\n break;\n default:\n console.error(\"invalid rule type provided\");\n return \n }\n\n return responseMessage;\n }\n\n /**\n * WHAT this function does - get hash of all the formRule source form attributes\n * determine if each attribute in hash is valid, based on isValid AND undefined for numbers\n * return true/false\n */\n // TODO: this might be an issue with html attribute, unrelated attribute might be invalid\n // does value setting attribute now scan string to set source attributes?\n static getAllSourceFormAttributesAreValid(formRule, formAttributesStates){\n let allSourceFormAttributesAreValid = true; // default to true, first invalid value found set to false\n const sourceFormAttributeKeys = [].concat(formRule.source_attribute_keys);\n\n sourceFormAttributeKeys.forEach( (key) => {\n const thisFormAttribute = formAttributesStates.get(key);\n if (!thisFormAttribute){\n console.error('source form attribute appears to be missing - key: ' + key);\n return false;\n }\n switch(thisFormAttribute.value_type) {\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n if (thisFormAttribute.isValidPerValueType) {\n // everything is fine, proceed\n } else if (thisFormAttribute.value === PLACEHOLDER_OPTION) {\n // TODO: placeholder option selected, need to test this more thoroughly\n } else if (thisFormAttribute.value === undefined || thisFormAttribute.value === null) {\n // TODO: this might require revisting, for now treat undefined as zero, proceed\n } else {\n console.warn('we have an invalid form attribute value', thisFormAttribute);\n allSourceFormAttributesAreValid = false;\n }\n break;\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n if (!thisFormAttribute.isValidPerValueType){\n allSourceFormAttributesAreValid = false;\n } // else { //this is fine }\n break;\n default:\n console.error('this form attribute has invalid value_type', thisFormAttribute);\n return false;\n }\n });\n return allSourceFormAttributesAreValid;\n }\n\n /**\n * iterate over conditionalsArr, return rule response Message object\n * return boolean if conditions are true or not\n */\n static evaluateNocodeConditions(conditionalsArr, formAttributesStates, condition_joiner, form_rule) {\n // TODO: Fix me, need to set the form attribute key in the rule on the back end\n // const valueHash = this.getAttributeHashPerRule() // why wouldnt we use this function? why pluck each value out?\n let conditionalsEvalArr = [];\n conditionalsArr.forEach(conditional => {\n const operand1Key = conditional['operand1_key'], // replace operand1_uuid with fa_name\n operand1_form_attribute = formAttributesStates.get(operand1Key);\n if (!operand1_form_attribute){\n console.error('form attribute cannot be found for conditional for this key:', operand1Key, form_rule); // \n return false;\n }\n \n const operator = conditional['operator'];\n const operatorObj = this.getOperatorObjectPerKey(operator);\n if (operatorObj.value.includes(LAST_USER_MODIFIED_FA_OPERATOR_PREFIX)) {\n // TODO: THIS NEEDS REFACTORING!!!!\n const operand1Val = operand1Key;\n const operand2Obj = formAttributesStates.get(LAST_USER_MODIFIED_FA);\n if (!!operand2Obj) {\n const conditionExressionResponse = this.evaluateSingleNocodeCondition(operatorObj, operand1Val, operand2Obj.value);\n conditionalsEvalArr.push(conditionExressionResponse);\n } else {\n console.error('ERROR - cannot identify last user modified input');\n }\n } else {\n // default operand1Val to value of form attribute\n let operand1Val = operand1_form_attribute.value;\n\n // TECH DEBT: this is a hack, it smells\n if ( operand1_form_attribute.value_type === 'float' \n && operand1_form_attribute.isValid \n && typeof operand1Val !== 'number'\n && operand1Val != undefined ) {\n operand1Val = parseFloat(operand1Val);\n }\n // if operand1_subkey is not equal to value indicates use metadata value, only avail on single/multi select\n if (conditional['operand1_subkey'] && conditional['operand1_subkey'] !== \"value\") {\n switch(operand1_form_attribute.form_attribute_type) {\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT:\n let hasMetadataValue = false;\n // check to verify that option selected is not the placeholder option\n if (operand1_form_attribute.value === PLACEHOLDER_OPTION) {\n // this will not have any metadata, ignore this, perhaps set value to zero or undefined?\n operand1Val = undefined;\n } else { // need to check for everything that could go wrong\n if (operand1_form_attribute.hasOwnProperty('option_selected')\n && operand1_form_attribute.option_selected !== undefined\n && operand1_form_attribute.option_selected.hasOwnProperty('metadata') ) {\n const metadataValues = operand1_form_attribute.option_selected.metadata;\n const metadataKey = conditional['operand1_subkey'];\n if ( metadataValues.hasOwnProperty(metadataKey) ) {\n hasMetadataValue = true;\n operand1Val = metadataValues[metadataKey];\n } else {\n console.debug('cannot find metadata for ', metadataKey);\n }\n } else {\n console.debug('no matching metadata found');\n }\n }\n\n if (hasMetadataValue === false) { // error handling if metadata is blank\n // based on metadata_types of operand1_form_attribute, get value type\n const metadataType = operand1_form_attribute.metadata_types.find(mdt => {\n return mdt.name === conditional['operand1_subkey'];\n });\n if (metadataType) {\n switch(metadataType.value_type) {\n // if metadata value is undefined and is a number then set to zero\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n case APP_CONSTANTS.VALUE_TYPES.CURRENCY:\n operand1Val = 0;\n break;\n // if metadata value is undefined and text value type then set to empty string\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n operand1Val = \"\";\n break;\n default:\n console.error('invalid metadata value type');\n }\n } else { // this should not happen\n console.error('metadata is undefined and is in unaccounted for value type');\n }\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n let metadataValArray = [];\n if ( conditional.hasOwnProperty('operand1_subkey') ) {\n const metadataKey = conditional['operand1_subkey'];\n if (operand1_form_attribute.hasOwnProperty('options_selected') ) {\n operand1_form_attribute.options_selected.forEach(option => {\n const metadataValues = option.metadata;\n if ( metadataValues.hasOwnProperty(metadataKey) ) {\n metadataValArray.push(metadataValues[metadataKey]);\n } else {\n console.warn('option is missing the metadata value');\n }\n });\n } else {\n console.warn('form attribute is missing options_selected attribute');\n }\n operand1Val = metadataValArray;\n } else {\n console.warn('conditional is missing operand1_subkey');\n }\n break;\n default:\n console.warn('form rule responder encountered unaccounted for FA type error when getting metadata values');\n }\n }\n\n let operand2Val; // = (operatorObj.requiresOperand2 ? conditional['operand2_value'] : undefined);\n if (operatorObj.requiresOperand2 === true) {\n switch (conditional.operand2_pre_type){\n case OPERAND2_PRE_TYPES.FIXED_TEXT:\n case OPERAND2_PRE_TYPES.FIXED_FLOAT:\n case OPERAND2_PRE_TYPES.FIXED_INTEGER:\n operand2Val = conditional.operand2_value;\n break;\n case OPERAND2_PRE_TYPES.FORM_ATTRIBUTE_VALUE:\n // TODO: works with metadata BUT should be more resilient for failure, what happens if metadata is missing\n const operand2_form_attribute = formAttributesStates.get(conditional['operand2_key']);\n // TODO: does this work with multiselect? should this even happen for multiselect?\n if ( conditional.hasOwnProperty('operand2_subkey') && conditional.operand2_subkey !== \"value\" ) { // use metadata\n switch (operand2_form_attribute.form_attribute_type) {\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT:\n // there should be attribute \"option_selected\", singular\n const option_selected = operand2_form_attribute.option_selected;\n if (!!option_selected) { // metadataValues\n const metadataValues = option_selected.metadata;\n operand2Val = ( !!metadataValues ? metadataValues[conditional.operand2_subkey] : undefined );\n } else {\n console.warn('missing option selected');\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n // there should be attribute \"options_selected\", plural\n const options_selected = operand2_form_attribute.options_selected;\n if (!!options_selected) {\n // TODO: iterate over options_selected, grab each metadata value and push into array\n let metadataValueArray = [];\n options_selected.forEach(this_option => {\n const metadataValues = this_option.metadata;\n const thisMetadataValue = metadataValues ? metadataValues[conditional.operand2_subkey] : undefined;\n if (!!thisMetadataValue) {\n metadataValueArray.push(thisMetadataValue);\n }\n });\n operand2Val = metadataValueArray;\n } else {\n console.warn('missing options selected');\n }\n break;\n default:\n // this should not happen\n console.warn('inaccounted for form attribute type, this should not happen')\n }\n\n } else { // use value of FA\n operand2Val = operand2_form_attribute.value;\n // TECH DEBT: you should not be converting it here BUT here we are\n if ( operand2_form_attribute.value_type === 'float' \n && operand2_form_attribute.isValid \n && typeof operand2Val !== 'number') {\n operand1Val = parseFloat(operand2Val);\n }\n }\n break;\n case OPERAND2_PRE_TYPES.OPTION_VALUES:\n operand2Val = conditional.operand2_option_values;\n break;\n case OPERAND2_PRE_TYPES.OPTION_VALUE:\n // TODO: does this work?\n operand2Val = conditional.operand2_option_value;\n break;\n default:\n console.error('cannot find operand 2 for conditional');\n }\n } else {\n // console.log('no operand2 required');\n }\n const conditionExressionResponse = this.evaluateSingleNocodeCondition(operatorObj, operand1Val, operand2Val);\n conditionalsEvalArr.push(conditionExressionResponse);\n } \n });\n\n // reduce conditionExpressionsEvalArr, use condition joiner to determine true or false\n let conditionsResponse;\n switch(condition_joiner){\n case \"AND\":\n conditionsResponse = conditionalsEvalArr.reduce((carryover, condition) => {return (carryover && condition)}, true);\n break;\n case \"OR\":\n conditionsResponse = conditionalsEvalArr.reduce((carryover, condition) => {return (carryover || condition)}, false);\n break;\n default: //this should not happen;\n // maybe we should default this to AND?\n conditionsResponse = false;\n console.error(\"invalid or missing condition_expression_block_joiner\");\n }\n\n return conditionsResponse;\n }\n\n static evaluateSingleNocodeCondition(operatorObj, operand1, operand2, options = null){\n switch(operatorObj.value){\n // STRING OPERATORS\n case OPERATOR_STRING_BLANK:\n return (operand1 === '');\n case OPERATOR_STRING_NOT_BLANK:\n return (operand1 !== '');\n case OPERATOR_STRING_EQUALS:\n return (operand1 === operand2);\n case OPERATOR_STRING_NOT_EQUALS:\n return (operand1 !== operand2);\n case OPERATOR_STRING_CONTAINS:\n return (operand1.includes(operand2));\n case OPERATOR_STRING_NOT_CONTAINS:\n return (operand1.includes(operand2) === false);\n case OPERATOR_STRING_LENGTH_EQUALS:\n // operand1 should never be null but an error is occurring\n if (operand1 !== undefined) {\n return (operand1.length === operand2);\n } else {\n return false;\n }\n case OPERATOR_STRING_LENGTH_NOT_EQUALS: // make sure this works?\n // operand1 should never be null but an error is occurring\n if (operand1 !== undefined) {\n return (operand1.length != operand2); // is this != OR !==\n } else {\n return false;\n }\n case OPERATOR_STRING_LENGTH_MIN:\n // operand1 should never be null but an error is occurring\n if (operand1 !== undefined){\n return (operand1.length > operand2);\n } else {\n return false;\n }\n case OPERATOR_STRING_LENGTH_MAX:\n // operand1 should never be null but an error is occurring\n if (operand1 !== undefined){\n return (operand1.length < operand2);\n } else {\n return false;\n }\n\n // NUMBER OPERATORS\n case OPERATOR_NUMBER_BLANK: //$\n //TODO FIX THIS!!! is operand1 null or undefined?\n return (operand1 === null || operand1 === undefined);\n case OPERATOR_NUMBER_NOT_BLANK: //$\n //TODO FIX THIS!!! is operand1 null or undefined?\n return (operand1 !== null && operand1 !== undefined);\n case OPERATOR_NUMBER_EQUAL: //$\n return (operand1 === operand2);\n case OPERATOR_NUMBER_NOT_EQUAL: //$\n return (operand1 !== operand2);\n case OPERATOR_NUMBER_GREATER_THAN: //$\n return (operand1 > operand2);\n case OPERATOR_NUMBER_NOT_GREATER_THAN: //$\n return !(operand1 > operand2);\n case OPERATOR_NUMBER_GREATER_OR_EQUAL:\n return (operand1 >= operand2);\n case OPERATOR_NUMBER_NOT_GREATER_OR_EQUAL:\n return !(operand1 >= operand2);\n case OPERATOR_NUMBER_LESSER_THAN:\n return (operand1 < operand2);\n case OPERATOR_NUMBER_NOT_LESSER_THAN:\n return !(operand1 < operand2);\n case OPERATOR_NUMBER_LESSER_OR_EQUAL: //$\n return (operand1 <= operand2);\n case OPERATOR_NUMBER_NOT_LESSER_OR_EQUAL: //$\n return !(operand1 <= operand2);\n\n // SINGLE SELECT OPERATORS\n case OPERATOR_SINGLESELECT_EQUALS:\n if (Array.isArray(operand2)) { // usually when matching to own fa values\n return (operand2.includes(operand1) );\n } else { // when matching to another form attribute value\n return operand1 === operand2;\n }\n case OPERATOR_SINGLESELECT_NOT_EQUALS:\n if (Array.isArray(operand2)) { // usually when matching to own fa values\n return (operand2.includes(operand1) === false);\n } else { // when matching to another form attribute value\n return operand1 !== operand2;\n }\n\n // TODO: multiselect is tricky - do we separate as each value? We may need to rethink this\n case OPERATOR_MULTISELECT_CONTAINS:\n return (operand1.includes(operand2) === true);\n case OPERATOR_MULTISELECT_NOT_CONTAINS:\n return (operand1.includes(operand2) === false);\n case OPERATOR_MULTISELECT_MATCHES_EXACT:\n if (operand1.length !== operand2.length){\n return false;\n }\n return operand1.every( value => operand2.includes(value) );\n case OPERATOR_MULTISELECT_NOT_MATCHES_EXACT:\n if (operand1.length !== operand2.length){\n return true;\n }\n return !( operand1.every( value => operand2.includes(value) ) );\n // ADD length of multiselect\n case OPERATOR_MULTISELECT_LENGTH_EQUALS:\n return operand1.length === operand2;\n // add not equals\n case OPERATOR_MULTISELECT_LENGTH_NOT_EQUALS:\n return operand1.length != operand2;\n case OPERATOR_MULTISELECT_LENGTH_MIN:\n return operand1.length >= operand2;\n case OPERATOR_MULTISELECT_LENGTH_MAX:\n return operand1.length <= operand2;\n\n case OPERATOR_LAST_USER_MODIFIED_FA_EQUALS:\n return operand1 === operand2;\n case OPERATOR_LAST_USER_MODIFIED_FA_NOT_EQUALS:\n return operand1 !== operand2;\n\n // TODO: rename these consts - same as OPERATOR_MULTISELECT_CONTAINS\n case OPERATOR_FILTERING_MULTISELECT_CONTAINED_IN:\n return (operand2.includes(operand1) === true);\n case OPERATOR_FILTERING_MULTISELECT_NOT_CONTAINED_IN:\n return (operand2.includes(operand1) !== true);\n default:\n console.error('we are missing an operation');\n return false;\n }\n }\n\n /**\n * WHAT THIS DOES: return a hash of form attributes if all values exist\n * otherwise if a value is missing it returns undefined\n * need to set metadata blank value of metadata type number to ZERO, text to empty string\n * @param {object} formRule - object\n * @param {Map} formAttributesStates - map of all attributes\n * @param {boolean} getAllAttributes - ignore form rule source and targets, send everything\n * @param {boolean} formatNumberAsStr - formats numbers based on param value\n * @returns object or hash of form attribute key/value pairs\n */\n static getAttributeHashPerRule(formRule, formAttributesStates, getAllAttributes = true, formatNumberAsStr = false) {\n let attrHash = {},\n formAttributeKeys = [], // .concat(formRule.source_attribute_keys),\n errorDetected = false;\n if (getAllAttributes) {\n formAttributeKeys = [];\n formAttributesStates.forEach((value, key, map) => {\n formAttributeKeys.push(key);\n });\n }\n formAttributeKeys.forEach( (key) => {\n const thisFormAttribute = formAttributesStates.get(key);\n if (!!thisFormAttribute) {\n switch(thisFormAttribute.form_attribute_type) {\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.FREEFORM:\n switch(thisFormAttribute.value_type){\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n attrHash[key] = thisFormAttribute.value;\n break;\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n attrHash[key] = (thisFormAttribute.value === undefined ? 0 : parseInt(thisFormAttribute.value));\n if (formatNumberAsStr && attrHash[key] != null ) { // if for displayed text then add commas\n const formattedValue = attrHash[key].toLocaleString('en-US');\n attrHash[key] = formattedValue;\n }\n break;\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n attrHash[key] = (thisFormAttribute.value === undefined ? 0 : parseFloat(thisFormAttribute.value));\n if (formatNumberAsStr && attrHash[key] != null ) { // if for displayed text then add commas\n const floatOptions = !!thisFormAttribute.float_precision ?\n {minimumFractionDigits: thisFormAttribute.float_precision, maximumFractionDigits: thisFormAttribute.float_precision} : {};\n const formattedValue = attrHash[key].toLocaleString('en-US', floatOptions);\n attrHash[key] = formattedValue;\n }\n break;\n default:\n console.error('invalid value type on form attribute');\n errorDetected = true;\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT:\n // check for placeholder option\n if (thisFormAttribute.value === PLACEHOLDER_OPTION) {\n // set value based on value type, empty string for text, zero for number\n switch(thisFormAttribute.value_type){\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n attrHash[key] = \"\";\n break;\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n attrHash[key] = 0;\n break;\n default:\n console.error('FormRuleResponder.getAttributeHashPerRule, inaccounted for FA with fa type of single select and value type', thisFormAttribute);\n }\n } else {\n attrHash[key] = thisFormAttribute.value;\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n switch(thisFormAttribute.value_type){\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n // create comma separated list of values\n attrHash[key] = thisFormAttribute.value.join(\", \");\n break;\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n // set value as a subtotal of selected values, initialize to zero\n const subtotalKey = `${key}.${MULTISELECT_SUMTOTAL_ATTRIBUTE}`;\n const subtotal = thisFormAttribute.value.reduce((total, val) => total + val, 0);\n attrHash[subtotalKey] = subtotal;\n break;\n default:\n console.error('invalid value type on form attribute');\n errorDetected = true;\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.DATEPICKER:\n // TODO: needs more work\n attrHash[key] = thisFormAttribute.value;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.NON_INPUT:\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SYSTEM:\n attrHash[key] = thisFormAttribute.value;\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.INLINE_STYLE:\n // do nothing\n break;\n default:\n // unaccounted for form attribute type\n console.error('unaccounted for form attribute type', thisFormAttribute);\n }\n\n // METADATA\n if (thisFormAttribute.metadata_types) {\n thisFormAttribute.metadata_types.forEach(metadata_type => {\n const metadataKeyForHash = thisFormAttribute.name + \".\" + metadata_type.name;\n if (thisFormAttribute.form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT ) {\n switch(metadata_type.display_type) {\n case METADATA_DISPLAY_TYPES.NUMBER:\n case METADATA_DISPLAY_TYPES.TEXT:\n case METADATA_DISPLAY_TYPES.SINGLESELECT:\n const selectedOption = thisFormAttribute.options.find(opt => opt.value == thisFormAttribute.value);\n if (!!selectedOption) {\n if ( !!selectedOption.metadata && selectedOption.metadata.hasOwnProperty(metadata_type.name) ) {\n const metadataValue = selectedOption.metadata[metadata_type.name];\n attrHash[metadataKeyForHash] = metadataValue;\n // format numbers for text here if formatNumberAsStr is true\n if (formatNumberAsStr \n && attrHash[metadataKeyForHash] != null\n && metadata_type.abstract_value_type === METADATA_DISPLAY_TYPES.NUMBER) {\n let formatOptions = {};\n if (metadata_type.value_type === APP_CONSTANTS.VALUE_TYPES.INTEGER ) {\n formatOptions = { minimumFractionDigits: 0, maximumFractionDigits: metadata_type.number_precision};\n } else if ( metadata_type.number_precision != null) {\n formatOptions = {\n minimumFractionDigits: metadata_type.number_precision, \n maximumFractionDigits: metadata_type.number_precision\n };\n }\n attrHash[metadataKeyForHash] = metadataValue.toLocaleString('en-US', formatOptions);\n } /* else if (attrHash[metadataKeyForHash] === null){\n // console.log('!!!!this metadata value is null:', metadata_type, metadataKeyForHash, attrHash);\n } */\n } else {\n // this metadata value does not exist\n console.debug('This option has a missing metadata value');\n }\n } else if (thisFormAttribute.value === PLACEHOLDER_OPTION) {\n // THIS IS FOR BLANK VALUES\n switch(metadata_type.value_type) {\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n case APP_CONSTANTS.VALUE_TYPES.CURRENCY:\n // value is blank, set to ZERO\n attrHash[metadataKeyForHash] = parseInt(0, 10);\n break;\n case \"text\":\n // value is blank, set text to empty string\n attrHash[metadataKeyForHash] = '';\n break;\n default:\n console.warn(`placeholder cannot set metadata for ${thisFormAttribute.name}.${metadata_type.name}`);\n }\n } else {\n console.warn('warning, unaccounted for situation - metadata only exist for selectables. Known error happens setting single select input to non existant value', thisFormAttribute, metadata_type);\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n console.warn('THIS IS A BAD IDEA - dont do this feature YET');\n break;\n default:\n console.error('THIS SHOULD NOT HAPPEN - ', metadata_type);\n break;\n }\n } else if (thisFormAttribute.form_attribute_type === APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT ){\n const selectedOptions = thisFormAttribute.options.filter(opt => thisFormAttribute.value.includes(opt.value));\n switch(metadata_type.value_type) {\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n case APP_CONSTANTS.VALUE_TYPES.CURRENCY:\n let subtotal = 0;\n selectedOptions.forEach(opt => {\n const metadataValue = opt.metadata[metadata_type.name];\n if (metadataValue !== undefined && typeof metadataValue === 'number' ) {\n subtotal += metadataValue; // TODO: what if its not undefined BUT value isnt there\n } else {\n // TODO: should we set it to zero?\n console.warn(`metadata ${metadata_type.name} for ${opt.value} seems to be missing OR is not a number, metadataValue: ${metadataValue}`);\n }\n });\n const subtotalKey = `${metadataKeyForHash}.${MULTISELECT_SUMTOTAL_ATTRIBUTE}`; //TODO: is this working\n attrHash[subtotalKey] = subtotal; //replace with subtotalKey\n break;\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n // this does nothing\n break;\n default:\n console.warn('This is multiselect with invalid metadata value type:', metadata_type.value_type, metadata_type);\n }\n }\n });\n }\n } else {\n console.error(`Form rule form ${formRule.name} on keenform id: ${formRule.keenform_id} has a key for non-existent form attribute`);\n errorDetected = true;\n }\n });\n return (errorDetected ? undefined : attrHash);\n }\n\n /**\n * \n * @param {*} value_type \n * @param {*} display_type \n * @param {*} operatorVal \n * @returns \n */\n // TODO this has to be rewritten\n // this is broken because were missing form attribute\n static getConditionOperatorObject(value_type, display_type, operatorVal) { //TODO fix this to handle matching metadata type\n let conditionOperatorSet, conditionOperator;\n switch(display_type) {\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.FREEFORM:\n case \"text\":\n case \"number\":\n switch(value_type) {\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n conditionOperatorSet = CONDITION_OPERATORS.FREEFORM.TEXT;\n break;\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n case \"currency\":\n conditionOperatorSet = CONDITION_OPERATORS.FREEFORM.NUMBER;\n break;\n default:\n console.warn('no matching operator set found for value_type: ', value_type, display_type);\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT:\n case \"select\": // for metadata\n conditionOperatorSet = CONDITION_OPERATORS.SINGLESELECT;\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n conditionOperatorSet = CONDITION_OPERATORS.MULTISELECT;\n break;\n default:\n console.warn('no matching operator set found for ' + formAttributeType);\n }\n if (conditionOperatorSet){\n const validOperators = conditionOperatorSet.concat(SYSTEM_OPERATORS);\n conditionOperator = validOperators.find(condOp => condOp.value === operatorVal);\n }\n if (!conditionOperator){\n console.error('no matching condition operator not found for ' + operatorVal);\n }\n return conditionOperator;\n }\n\n static getOperatorObjectPerKey(key) {\n let conditionOperatorSet = [];\n if ( key.startsWith('STRING') ) {\n conditionOperatorSet = CONDITION_OPERATORS.FREEFORM.TEXT;\n } else if ( key.startsWith('NUMBER') ) {\n conditionOperatorSet = CONDITION_OPERATORS.FREEFORM.NUMBER;\n } else if ( key.startsWith('SINGLESELECT') ) {\n conditionOperatorSet = CONDITION_OPERATORS.SINGLESELECT;\n } else if ( key.startsWith('MULTISELECT') ) {\n conditionOperatorSet = CONDITION_OPERATORS.MULTISELECT;\n } else if ( key.startsWith('LAST_USER_MODIFIED_FA') ) {\n conditionOperatorSet = SYSTEM_OPERATORS;\n } else if ( key.startsWith('FILTERING') ) {\n // TODO: console.warn('under construction');\n conditionOperatorSet = FILTERING_CONDITION_OPERATORS.SINGLESELECT;\n } else {\n console.error('cannot determine proper operator set');\n return undefined;\n }\n const operatorObject = conditionOperatorSet.find(op => op.value === key);\n return operatorObject;\n }\n\n static getResponseForFilteringRule(formRule, formAttributesStates) {\n const targetAttributeKey = formRule.target_attribute_keys[0];\n const targetFormAttribute = formAttributesStates.get(targetAttributeKey);\n if (!formRule.dynamic_filtering && formRule.filtered_options) {\n const optionsArray = targetFormAttribute.options.map(option => {\n if (option.hidden){\n return {...option};\n } else {\n const hideOption = formRule.filtered_options.includes(option.uuid);\n return {\n ...option,\n hidden: hideOption\n }\n }\n });\n return {\n ...FORM_RULE_RESPONSE,\n formRule,\n value: optionsArray,\n useValue: true,\n success: true,\n errorMessage: 'this filtering rule is under constuction'\n }\n } else if (formRule.dynamic_filtering === true) {\n // use filtering conditionals per option\n const optionsArray = targetFormAttribute.options.map(option => {\n if (option.hidden === true) {\n // option is already hidden, leave as is\n return {...option};\n } else {\n const hideOption = this.hideOptionPerFilteringConditionals(option, formRule, formAttributesStates);\n return {\n ...option,\n hidden: hideOption\n }\n }\n });\n return {\n ...FORM_RULE_RESPONSE,\n formRule,\n value: optionsArray,\n useValue: true,\n success: false,\n errorMessage: 'this filtering rule is under constuction'\n }\n } else {\n console.error('something is wrong with this filtering rule ', formRule);\n }\n }\n\n // enhance this function to handle custom function\n static getResponseForValueSettingRule(formRule, formAttributesStates){\n //steps for getting response for value setting rule\n /**\n * 1 - determine if this is a text or number for target attribute\n * 1.1 if Number then do eval of rule_expression, wrapped in try/catch loop\n * 1.1.1 - if no error then pass value to a handler to generate message\n * 1.1.2 - else if error then return message indicating error\n * 1.2 if String/Text then do string interpolation and return message with interpretted string\n */\n let responseMessage;\n\n if (formRule.use_type_function) {\n // TODO: Add validation for setting a value with a custom function\n responseMessage = this.getResponseForValueSettingRuleFunction(formRule, formAttributesStates);\n } else {\n responseMessage = this.getResponseForValueSettingRuleNoCode(formRule, formAttributesStates);\n }\n\n return responseMessage;\n }\n\n static getResponseForValueSettingRuleNoCode(formRule, formAttributesStates) {\n //steps for getting response for value setting rule\n /**\n * 1 - determine if this is a text or number for target attribute\n * 1.1 if Number then do eval of rule_expression, wrapped in try/catch loop\n * 1.1.1 - if no error then pass value to a handler to generate message\n * 1.1.2 - else if error then return message indicating error\n * 1.2 if String/Text then do string interpolation and return message with interpretted string\n */\n const targetAttributeKey = formRule.target_attribute_keys[0];\n const targetFormAttribute = formAttributesStates.get(targetAttributeKey);\n let responseMessage;\n\n switch (targetFormAttribute.form_attribute_type) {\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT:\n if (formRule.use_nocode_expression !== true) {\n const optionUUID = formRule.option_values; // this will be a single value\n const selectedOption = targetFormAttribute.options.find(opt => opt.uuid === optionUUID);\n if (selectedOption) {\n responseMessage = {\n ...VALUE_SETTING_RULE_SUCCESS_RESPONSE,\n formRule,\n value: selectedOption.value\n };\n } else {\n responseMessage = {\n ...FAILLING_RULE_RESPONSE,\n formRule,\n errorMessage: 'this rule is trying to set target attribute to option that cannot be found, could be old option that is no longer available'\n };\n }\n } else if (formRule.nocode_expression) {\n switch(targetFormAttribute.value_type) {\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n responseMessage = this.getResponseForValueSettingRuleForNumber(formRule, formAttributesStates);\n break;\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n const candidateValue = this.interpolateTextFormRule(formRule, formAttributesStates);\n responseMessage = {\n ...FORM_RULE_RESPONSE,\n formRule,\n value: candidateValue,\n useValue: true,\n success: true\n };\n break;\n default:\n console.error('this does not have a proper target value type, ', formRule.rule_type);\n responseMessage = {\n ...FAILLING_RULE_RESPONSE,\n formRule,\n errorMessage: 'this rule does not have a valid target attribute value type'\n };\n }\n } else {\n console.warn('something is wrong - no code expression is present but use nocode expression is true');\n responseMessage = {\n ...FAILLING_RULE_RESPONSE,\n formRule,\n errorMessage: 'no code expression is present but use nocode expression is true',\n }\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n const optionUUIDs = formRule.option_values; // this should be an arrau\n const selectedOptions = targetFormAttribute.options\n .filter(opt => optionUUIDs.includes(opt.uuid))\n .map(opt => opt.value);\n responseMessage = {\n ...VALUE_SETTING_RULE_SUCCESS_RESPONSE,\n formRule,\n value: selectedOptions\n };\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.FREEFORM:\n switch(targetFormAttribute.value_type){\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n responseMessage = this.getResponseForValueSettingRuleForNumber(formRule, formAttributesStates);\n break;\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n const candidateValue = this.interpolateTextFormRule(formRule, formAttributesStates);\n responseMessage = {\n ...FORM_RULE_RESPONSE,\n formRule,\n value: candidateValue,\n useValue: true,\n success: true\n };\n break;\n default: //THIS should not happen\n console.error('this does not have a proper target value type, ', formRule.rule_type);\n responseMessage = {\n ...FAILLING_RULE_RESPONSE,\n formRule,\n errorMessage: 'this rule does not have a valid target attribute value type'\n };\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.NON_INPUT:\n // UNDER CONSTRUCTION\n if (targetFormAttribute.display_type === APP_CONSTANTS.DISPLAY_TYPES_HTML.STATIC_HTML) {\n const candidateValue = this.interpolateTextFormRule(formRule, formAttributesStates, true);\n responseMessage = {\n ...FORM_RULE_RESPONSE,\n formRule,\n value: candidateValue,\n useValue: true,\n success: true\n };\n } else {\n console.warn('this should not happen');\n responseMessage = {\n ...FAILLING_RULE_RESPONSE, // improve this error message\n formRule,\n errorMessage: `invalid target attribute for value setting - ${targetAttribute.name}`\n };\n }\n break;\n default:\n console.warn('invalid form attribute type');\n responseMessage = {\n ...FAILLING_RULE_RESPONSE,\n formRule,\n errorMessage: 'this rule does not have a valid target attribute value type'\n };\n }\n\n return responseMessage;\n }\n\n static getResponseForValueSettingRuleFunction(formRule, formAttributesStates) {\n let responseMessage;\n try {\n const attrHash = this.getAttributeHashPerRule(formRule, formAttributesStates, true);\n const formRuleFunctionValueResponse = formRule.type_function(attrHash);\n // TODO: VALIDATE value response here\n responseMessage = {\n ...FORM_RULE_RESPONSE,\n formRule,\n value: formRuleFunctionValueResponse,\n useValue: true,\n success: true\n };\n } catch (error) {\n console.warn('error ocurred on custom type function', error, formRule);\n responseMessage = {\n ...FAILLING_RULE_RESPONSE,\n formRule,\n errorMessage: 'custom function failed'\n };\n }\n\n return responseMessage;\n }\n\n static getResponseForConditionRuleFunction(formRule, formAttributesStates) {\n let conditionResponse;\n try {\n const attrHash = this.getAttributeHashPerRule(formRule, formAttributesStates, true);\n const conditionFunctionResponse = formRule.condition_function(attrHash);\n if (conditionFunctionResponse === true || conditionFunctionResponse === false){\n conditionResponse = conditionFunctionResponse;\n } else {\n console.warn('this function is not returning an explicit TRUE or FALSE value');\n }\n } catch (error) {\n console.warn('error ocurred on custom condition function', error, formRule);\n }\n\n return conditionResponse;\n }\n\n static getResponseForValidatingRule(formRule, formAttributesStates){\n //TODO: this is stubbed out, doesn't work the way its supposed to yet\n return {\n ...FORM_RULE_RESPONSE,\n formRule,\n useValue: true,\n success: true,\n value: false, //TODO: make this dynamic, but hardcoding this for now\n }\n }\n\n static getResponseForValueSettingRuleForNumber(formRule, formAttributesStates) {\n const targetAttributeKey = formRule.target_attribute_keys[0];\n const targetFormAttribute = formAttributesStates.get(targetAttributeKey);\n const attrHash = this.getAttributeHashPerRule(formRule, formAttributesStates, true); // why is this unused?\n let candidateValue;\n try {\n candidateValue = eval(formRule.rule_expression);\n if (targetFormAttribute.value_type === APP_CONSTANTS.VALUE_TYPES.FLOAT){\n //TODO: this is a hacky solution, might need work\n const floatStr = candidateValue.toString().split(\"e+\")[0];\n candidateValue = parseFloat(floatStr);\n }\n\n // Check for exception conditions\n switch(true) {\n case isNaN(candidateValue):\n console.error('eval statement returned NaN, form rule has failed', formRule);\n return {\n ...FAILING_VALUE_SETTING_RULE_NUMBER_NAN,\n formRule: formRule\n };\n case !isFinite(candidateValue):\n console.error('eval statement returned Infinity, form rule has failed', formRule);\n return {\n ...FAILING_VALUE_SETTING_RULE_NUMBER_INFINITY,\n formRule: formRule\n };\n case (candidateValue === undefined):\n console.error('eval statement returned undefined, form rule has failed', formRule);\n return {\n ...FAILING_VALUE_SETTING_RULE_NUMBER_UNDEFINED,\n formRule: formRule\n };\n }\n\n let isValidNumber = false;\n candidateValue = this.updateNumberPerFormRulePostOpModifier(candidateValue, targetFormAttribute, formRule);\n switch(targetFormAttribute.value_type){\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n isValidNumber = isValidInteger(candidateValue);\n break;\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n isValidNumber = isValidFloat(candidateValue);\n break;\n }\n\n if (!isValidNumber){\n console.error('invalid number generated by eval: ', formRule);\n return {\n ...FAILING_VALUE_SETTING_RULE,\n formRule: formRule\n };\n } else {\n return {\n ...FORM_RULE_RESPONSE,\n formRule,\n value: candidateValue,\n useValue: true,\n success: true\n };\n }\n } catch (error){\n console.error(error);\n return {\n ...FAILING_VALUE_SETTING_RULE,\n formRule: formRule\n };\n };\n }\n\n static hideOptionPerFilteringConditionals(option, formRule, formAttributesStates) {\n const filtering_conditionals = formRule.filtering_conditionals;\n const conditionalsEvalArr = filtering_conditionals.map( conditional => {\n // operand1 should be a value available for option\n let operand1Value = option.value;\n if (conditional.operand1_subkey && conditional.operand1_subkey != \"value\"){\n const metadataValue = option.metadata;\n if (metadataValue.hasOwnProperty(conditional.operand1_subkey) ){\n operand1Value = metadataValue[conditional.operand1_subkey];\n } else {\n console.error('conditional has a subkey for metadata value that does not exist');\n }\n }\n const operatorObj = this.getOperatorObjectPerKey(conditional.operator);\n let operand2Value;\n if (!!operatorObj && operatorObj.requiresOperand2 && !!conditional.operand2_pre_type) {\n switch (conditional.operand2_pre_type) {\n case OPERAND2_PRE_TYPES.FORM_ATTRIBUTE_VALUE:\n const operand2FA = formAttributesStates.get(conditional.operand2_key);\n // default to value\n operand2Value = operand2FA.value;\n // if operand2_subkey and its not value then grab the metadata value\n if (conditional.operand2_subkey && conditional.operand2_subkey !== \"value\") {\n const metadata = operand2FA.metadata;\n if (metadata[operand2_subkey]) {\n operand2Value = metadata[operand2_subkey];\n } else {\n console.warn('metadata[operand2_subkey] is missing in filtering conditional,', conditional, metadata);\n }\n }\n break;\n case OPERAND2_PRE_TYPES.OPTION_VALUES:\n if (conditional.hasOwnProperty('operand2_option_values')) {\n operand2Value = conditional.operand2_option_values;\n } else {\n console.warn('this conditional is missing an operand2_option_values property');\n }\n break;\n case OPERAND2_PRE_TYPES.FIXED_TEXT:\n case OPERAND2_PRE_TYPES.FIXED_INTEGER:\n case OPERAND2_PRE_TYPES.FIXED_FLOAT:\n if (conditional.hasOwnProperty('operand2_value')) {\n operand2Value = conditional.operand2_value;\n } else {\n console.warn('this conditional is missing an operand2_value property');\n }\n break;\n default:\n console.error('in filtering rule, unaccounted for conditional.operand2_pre_type, this should not happen', conditional);\n }\n } else {\n console.warn('missing operand2 for conditional: ', conditional);\n return false;\n }\n return this.evaluateSingleNocodeCondition(operatorObj, operand1Value, operand2Value);\n });\n\n if ( conditionalsEvalArr.length === 1 ) {\n return conditionalsEvalArr[0];\n } else if (conditionalsEvalArr.length > 1) {\n let conditionalsResponse, dynamicFilteringJoiner;\n if (formRule.hasOwnProperty(\"metadata\") && formRule.metadata.hasOwnProperty(\"dynamic_filtering_joiner\") ){\n dynamicFilteringJoiner = formRule.metadata.dynamic_filtering_joiner;\n } else {\n console.warn('form rule is missing metadata.dynamic_filtering_joiner', formRule);\n }\n \n switch(dynamicFilteringJoiner) {\n case \"OR\":\n conditionalsResponse = conditionalsEvalArr.reduce((carryover, condition) => {return (carryover || condition)}, false);\n break;\n case \"AND\":\n conditionalsResponse = conditionalsEvalArr.reduce((carryover, condition) => {return (carryover && condition)}, true);\n break;\n default: // this should not happen;\n conditionalsResponse = false;\n console.error(\"invalid or missing condition_expression_block_joiner\", formRule);\n }\n return conditionalsResponse;\n } else {\n console.error('there should be at least ONE response');\n return false;\n }\n }\n\n /**\n * returns string with each occurence of form attribute replaced with value\n * @param {*} formRule \n * @param {*} formAttributesStates \n */\n static interpolateTextFormRule(formRule, formAttributesStates, getAllAttributes = true) {\n //iterate over source attributes, use string replacement to change '{{attributeKey}}' to 'value'\n const formatNumbers = formRule.format_numbers_for_display === true;\n const attrHash = this.getAttributeHashPerRule(formRule, formAttributesStates, getAllAttributes, formatNumbers);\n let interpolatedStr = formRule?.rule_expression || \"\";\n if (interpolatedStr.length > 0) {\n for (const [faName, faValue] of Object.entries(attrHash)) {\n const attrKeyReplace = `{{${faName}}}`;\n interpolatedStr = interpolatedStr.replace(new RegExp(attrKeyReplace, 'g'), faValue);\n }\n // TODO: should we also do something to clean up double curly braces occurrences, even if there is no match\n } else if (!formRule.rule_expression ) {\n console.warn('interpolated string for this form rule appears to be undefined/null', formRule);\n }\n\n return interpolatedStr;\n }\n\n static updateNumberPerFormRulePostOpModifier(candidateValue, targetAttribute, formRule){\n let returnValue = candidateValue;\n switch(targetAttribute.value_type){\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n if ( returnValue !== parseInt(returnValue) ){\n //reformat candidateValue\n switch(formRule.post_op_modifier){\n case 'round':\n returnValue = Math.round(candidateValue);\n break;\n case 'floor':\n returnValue = Math.floor(candidateValue);\n break;\n case 'ceiling':\n returnValue = Math.ceil(candidateValue);\n break;\n default:\n returnValue = Math.trunc(candidateValue);\n }\n }\n break;\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n if ( !!targetAttribute.float_precision ){\n // check if returnValue has more digits after decimal than float_precision, modify value if true\n const floatSplit = candidateValue.toString().split(\".\");\n if (floatSplit.length === 2 && floatSplit[1].length > targetAttribute.float_precision){\n const divisor = Math.pow(10, targetAttribute.float_precision);\n switch(formRule.post_op_modifier){\n case POST_OP_MODIFIERS.ROUND:\n returnValue = Math.round((candidateValue + Number.EPSILON) * divisor) / divisor;\n break;\n case POST_OP_MODIFIERS.FLOOR:\n returnValue = Math.floor((candidateValue + Number.EPSILON) * divisor) / divisor;\n break;\n case POST_OP_MODIFIERS.CEILING:\n returnValue = Math.ceil((candidateValue + Number.EPSILON) * divisor) / divisor;\n break;\n default:\n const numberAfterDecimal = floatSplit[1].slice(0,targetAttribute.float_precision)\n returnValue = `${floatSplit[0]}.${numberAfterDecimal}`;\n }\n }\n }\n break;\n default:\n console.error('this should not happen');\n }\n return returnValue;\n }\n \n}\n\nexport default FormRuleResponder;","import APP_CONSTANTS, { \n LAST_USER_MODIFIED_FA,\n KEENFORM_SUBMIT_BUTTON_FA,\n PLACEHOLDER_OPTION,\n RULE_TYPES \n } from \"../../shared/constants/app_constants\";\nimport FormRuleResponder from './FormRuleResponder';\nimport FormAttributeStateManager from './FormAttributeStateManager';\nimport { isValidFloat } from \"../../shared/form_attribute_utils\";\n\nclass KeenformStateManager{\n #formAttributesMap;\n #form_rules;\n\n /**\n * \n * @param {*} keenformData - data of keenform, maybe use typescript?\n * @param {*} initialValues - a hash or object with initial values\n */\n constructor(keenformData, initialValues = {}) {\n this.keenform = keenformData;\n // what happens if this form_attributes does not exist\n this.#formAttributesMap = this.#buildFormAttributesMap(keenformData.form_attributes);\n this.#form_rules = this.getFormRulesAsObjects(keenformData.form_rules);\n\n // initialize keenform attribute values IF THEY ARE PASSED - current they are not\n // TODO figure out way to allow users to pass initial values\n this.#formAttributesMap.forEach((formAttributeObj, formAttrKey) => {\n const defaultValue = formAttributeObj._default_value === null ? undefined : formAttributeObj._default_value;\n let onInitializeValue = defaultValue;\n if (initialValues && initialValues[formAttrKey]){\n onInitializeValue = initialValues[formAttrKey]\n }\n //let onInitializeValue = (this.props.initialAttributeValues && this.props.initialAttributeValues[formAttrKey] ? this.props.initialAttributeValues[formAttrKey] : undefined);\n formAttributeObj.initializeFormAttributeVal(onInitializeValue);\n });\n\n this.#regulateAndPublishKeenform();\n }\n\n /**\n * \n * @param {*} form_attributes_array\n * @param {*} initialValues object with values that will map to form attributes\n * @returns Map of FormAttributeStateManagers\n */\n #buildFormAttributesMap(form_attributes_array, initialValues = {}){\n //iterate over keenform_props.form_attributes to validate fa data\n let formAttributesMap = new Map();\n\n // TODO: this could fail if not an array\n form_attributes_array.forEach((thisFormAttributeData) => {\n const thisFormAttrKey = thisFormAttributeData.name,\n formAttributeStateManager = new FormAttributeStateManager(thisFormAttributeData);\n //all checks passed, add this attribute to formAttributesMap\n formAttributesMap.set(thisFormAttrKey, formAttributeStateManager);\n });\n\n // add lastUserModifiedFAState - need to use FormAttributeStateManager, handle exceptions for this\n const lastUserModifiedFAData = {\n name: LAST_USER_MODIFIED_FA,\n uuid: LAST_USER_MODIFIED_FA,\n label: LAST_USER_MODIFIED_FA,\n value: null,\n isValid: true,\n isValidPerValueType: true,\n display_type: APP_CONSTANTS.DISPLAY_TYPES_HTML.NON_DISPLAY,\n form_attribute_type: APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SYSTEM,\n value_type: APP_CONSTANTS.VALUE_TYPES.TEXT,\n hidden: true,\n }\n const lastUserModifiedFAObject = new FormAttributeStateManager(lastUserModifiedFAData);\n formAttributesMap.set(LAST_USER_MODIFIED_FA, lastUserModifiedFAObject);\n\n // ADD new system attribute for SUBMIT button\n const submitButton = {\n name: KEENFORM_SUBMIT_BUTTON_FA,\n uuid: KEENFORM_SUBMIT_BUTTON_FA,\n label: KEENFORM_SUBMIT_BUTTON_FA,\n value: null,\n isValid: true,\n isValidPerValueType: true,\n display_type: APP_CONSTANTS.DISPLAY_TYPES_HTML.NON_DISPLAY,\n form_attribute_type: APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SYSTEM,\n value_type: APP_CONSTANTS.VALUE_TYPES.TEXT,\n hidden: false,\n };\n const submitButtonFAObject = new FormAttributeStateManager(submitButton);\n formAttributesMap.set(KEENFORM_SUBMIT_BUTTON_FA, submitButtonFAObject);\n\n return formAttributesMap;\n }\n\n /**\n * \n * @returns boolean if all form attributes are valid\n */\n getAllAttributesAreValid() {\n let isFormValid = true;\n this.#formAttributesMap.forEach((fa) => {\n if (fa._is_valid === false) {\n isFormValid = false;\n }\n });\n return isFormValid;\n }\n\n /**\n * \n * @param {*} key \n * @returns form attribute object\n */\n #getFormAttribute(key) {\n if (this.#formAttributesMap.has(key)) {\n return this.#formAttributesMap.get(key);\n } else {\n console.warn(`key ${key} does not exist`);\n return null;\n }\n }\n\n /**\n * \n * @returns Map of Form Attribute states\n */\n #getFormAttributesStates(){\n let formAttributesStates = new Map();\n this.#formAttributesMap.forEach( (formAttribute, key) => {\n formAttributesStates.set( key, formAttribute.getStateForUI() );\n });\n return formAttributesStates;\n }\n\n getFormRules(){\n return this.#form_rules;\n }\n\n getFormRulesAsObjects(formRulesArray) {\n return formRulesArray.map((formRule) => {\n let formRuleObject = {\n ...formRule\n };\n // convert functions for type and condition depending on data\n if (formRule.use_type_function && formRule.type_function_for_eval) {\n try {\n const formRuleTypeFunction = eval(formRule.type_function_for_eval);\n formRuleObject.type_function = formRuleTypeFunction;\n } catch (error) {\n console.error('something bad happened with converting form rule type function via eval', error);\n console.log(formRule);\n }\n }\n\n if (formRule.use_condition_function && formRule.condition_function_for_eval) {\n try {\n const formRuleConditionFunction = eval(formRule.condition_function_for_eval);\n formRuleObject.condition_function = formRuleConditionFunction;\n } catch (error) {\n console.error('something bad happened with converting form rule condition function via eval', error);\n console.log(formRule);\n }\n }\n\n return formRuleObject;\n });\n }\n\n getKeenformState() {\n const currentStateOfFormAttributes = this.#getFormAttributesStates();\n const formAttributesMapPostRules = this.#runAllOtherRules(currentStateOfFormAttributes);\n // CLEAR last updated form attrinbute - prevents event based rules using LAST_USER_MODIFIED_FA for touch/blur\n this.#updateValueOfFormAttribute(LAST_USER_MODIFIED_FA, null);\n return formAttributesMapPostRules;\n }\n\n #regulateAndPublishKeenform(){\n this.#runValueSettingRules();\n return this.getKeenformState();\n }\n\n /**\n * @param {*} formAttributesStateMap \n * @returns {*} Map of current form attributes\n */\n #runAllOtherRules(formAttributesStateMap){\n let faStateMap = formAttributesStateMap;\n const allOtherRules = this.#form_rules.filter(rule => rule.rule_type !== \"value_setting\" ); // replace with constant\n allOtherRules.forEach( (rule) => {\n const ruleResponse = FormRuleResponder.getFormRuleResponse(rule, faStateMap);\n if (ruleResponse.useValue){\n //set hidden/locked for this attribute to true\n switch (rule.rule_type){\n case RULE_TYPES.HIDING:\n case RULE_TYPES.LOCKING:\n if (ruleResponse.value === true) { // only set to true if value is true, not false if false\n rule.target_attribute_keys.forEach( (targetAttributeKey) => {\n let targetAttribute = faStateMap.get(targetAttributeKey);\n if (targetAttribute) {\n if (rule.rule_type === RULE_TYPES.HIDING) {\n targetAttribute.hidden = true;\n } else if (rule.rule_type === RULE_TYPES.LOCKING) {\n // TODO: change this to a new attribute, locked\n targetAttribute.read_only = true; // do we change this? does it matter?\n targetAttribute.locked = true;\n }\n } else {\n console.warn(\"targetAttributeKey cannot be found\", targetAttributeKey);\n }\n });\n }\n\n /**\n * hacky way of handling hiding submit button - check if hiding rule metadata has \"target_submit_button\"\n */\n if (rule.metadata?.target_submit_button) {\n let submitButton = faStateMap.get(KEENFORM_SUBMIT_BUTTON_FA);\n submitButton.hidden = true;\n }\n break;\n case RULE_TYPES.FILTERING:\n let targetAttribute = faStateMap.get(rule.target_attribute_keys[0]); // TODO - there should only be one of these, make this less likely to fail\n targetAttribute.options = ruleResponse.value;\n if ( targetAttribute.form_attribute_type === \"singleselect\" ) {\n const targetAttributeValue = targetAttribute.hasOwnProperty('value') ? targetAttribute.value : PLACEHOLDER_OPTION; // this isnt quite right\n const valueAsOption = targetAttribute.options\n .find(option => option.value === targetAttributeValue);\n if (!!valueAsOption && valueAsOption.hidden === true) {\n //set error message\n targetAttribute.isValid = false;\n targetAttribute.errorMessage = \"This option is selected but not available, please make another selection\";\n targetAttribute.touched = true;\n }\n } else if (targetAttribute.form_attribute_type === \"multiselect\"){\n targetAttribute.value.forEach(optionValue => {\n console.log(optionValue);\n const thisOption = targetAttribute.options.find(option => option.value === optionValue);\n if (thisOption.hidden){\n console.warn('this option should not be selected');\n {\n //set error message\n targetAttribute.isValid = false;\n targetAttribute.errorMessage = \"This form attribute has an option selected that is not available, please unselect\";\n targetAttribute.touched = true;\n }\n }\n })\n } else {\n console.error('this should not happen');\n }\n break;\n case RULE_TYPES.VALIDATING:\n //TODO: under construction\n if (ruleResponse.value === false){\n let targetAttribute = faStateMap.get(rule.target_attribute_keys[0]);//TODO - there should only be one of these\n targetAttribute.isValid = false;\n if (ruleResponse.formRule.message_content){\n targetAttribute.errorMessage = ruleResponse.formRule.message_content;\n }\n }\n break;\n }\n } else if (ruleResponse.useValue !== true && ruleResponse.success !== true){\n console.warn('we have a failing rule');\n console.log(ruleResponse);\n } else {\n // console.log(\"rule did not fail but don't do anything\", ruleResponse );\n }\n })\n return faStateMap;\n }\n\n /**\n * Facilitates communication between form attributes and form rule\n * Should stay part of KeenformStateManager\n */\n #runValueSettingRules() {\n var self = this;\n const valueSettingRules = this.#form_rules.filter(rule => rule.rule_type === \"value_setting\"); // make this constant\n let formAttributesStates = this.#getFormAttributesStates();\n\n valueSettingRules.forEach( (rule) => {\n formAttributesStates = this.#getFormAttributesStates();\n const ruleResponse = FormRuleResponder.getFormRuleResponse(rule, formAttributesStates);\n if (ruleResponse.useValue){\n const newValue = ruleResponse.value,\n targetFormAttributeKey = rule.target_attribute_keys[0];\n const valueUpdated = self.#updateValueOfFormAttribute(targetFormAttributeKey, newValue);\n // TODO - what if value has not been properly updated?\n if (!valueUpdated) { // this shouldn't happen\n console.debug('form rule could not update form attribute', rule);\n }\n } else {\n //form rule useValue is false, determine why are we not running this rule\n if (ruleResponse.conditionValue === false){\n //condition was false so this is an anticipated outcome\n } else if (ruleResponse.success === false) {\n //TODO track failing rules here\n console.warn(\"the following rule has failed\", ruleResponse);\n } else {\n console.log('an unanticipated outcome from a rule has occured, rule response: ', ruleResponse);\n }\n }\n });\n }\n\n // need to make distinction between public method of user modify\n /**\n * Public method of changing one form attribute value, as well as lastUserModifiedAttribute\n * and then running all rules, and returning latest state\n * @param {*} formAttrKey \n * @param {*} formAttrValue \n * @returns \n */\n setValueAndGetState(formAttrKey, formAttrValue) {\n this.#updateValueOfFormAttribute(formAttrKey, formAttrValue);\n this.#updateValueOfFormAttribute(LAST_USER_MODIFIED_FA, formAttrKey);\n const updatedPublishableState = this.#regulateAndPublishKeenform();\n return updatedPublishableState;\n }\n\n /**\n * Sets each Form Attribute touched to true\n * @returns Map of Form Attribute States\n */\n touchAllAttributes() {\n this.#formAttributesMap.forEach((formAttributeObj, formAttrKey) => {\n formAttributeObj.touchAttribute();\n });\n const updatedPublishableState = this.#regulateAndPublishKeenform();\n return updatedPublishableState;\n }\n\n /**\n * Sets one Form Attribute touched to true\n * @param {*} formAttrKey string\n * @returns Map of Form Attribute States\n */\n touchAttribute(formAttrKey) {\n const thisFormAttribute = this.#getFormAttribute(formAttrKey);\n // fixes float values that are valid but improperly formatted\n if (thisFormAttribute._value_type === \"float\" && thisFormAttribute._form_attribute_type === \"freeform\" ) {\n // IF this is a valid float value, cast as float\n const isThisValidFloat = isValidFloat(thisFormAttribute._value);\n if (isThisValidFloat) { // this fixes number with leading zeros\n const parsedFloatValue = parseFloat(thisFormAttribute._value);\n thisFormAttribute.setValue(parsedFloatValue);\n }\n }\n thisFormAttribute.touchAttribute();\n const updatedPublishableState = this.#regulateAndPublishKeenform();\n return updatedPublishableState;\n }\n\n /**\n * \n * @param {*} formAttrKey string that is key in fa map\n * @param {*} formAttrValue value to be set\n * return boolean - if successful or not\n */\n #updateValueOfFormAttribute(formAttrKey, formAttrValue) {\n const thisFormAttribute = this.#getFormAttribute(formAttrKey);\n if (thisFormAttribute) {\n thisFormAttribute.setValue(formAttrValue);\n thisFormAttribute.touchAttribute();\n return true;\n } else {\n console.debug(`cannot find form attribute with key of ${formAttrKey}`);\n return false;\n }\n }\n\n}\n\nexport default KeenformStateManager;\n","export const FORM_RULE_RESPONSE = {\n formRule: undefined, //return submitted form rule in response\n value: undefined, //the value returned\n useValue: false, //use value as valid response - rule could be executed without error but condition is false\n success: false, //boolean value, whether the rule ran without error\n errorMessage: undefined, //string for error message\n conditionValue: undefined //communicate that condition failed\n};\n\nexport const SOURCE_FORM_ATTRIBUTE_NOT_VALID_RESPONSE = {\n ...FORM_RULE_RESPONSE,\n useValue: false,\n success: false,\n errorMessage: \"this form rule has form attributes with invalid values, rule cannot be executed\" //TODO: make this constant\n}\n\nexport const FAILLING_RULE_RESPONSE = {\n ...FORM_RULE_RESPONSE,\n useValue: false,\n success: false,\n errorMessage: \"this form rule has failed\"\n}\n\nexport const FAILING_VALUE_SETTING_RULE = {\n ...FAILLING_RULE_RESPONSE,\n errorMessage: 'the eval statement for this value setting rule has generated and error'\n}\n\nexport const FAILING_VALUE_SETTING_RULE_NUMBER_NAN = {\n ...FAILLING_RULE_RESPONSE,\n errorMessage: 'cannot set number to NaN'\n}\n\nexport const FAILING_VALUE_SETTING_RULE_NUMBER_INFINITY = {\n ...FAILLING_RULE_RESPONSE,\n errorMessage: 'cannot set number to Infinity'\n}\n\nexport const FAILING_VALUE_SETTING_RULE_NUMBER_UNDEFINED = {\n ...FORM_RULE_RESPONSE,\n errorMessage: 'cannot set number to undefined'\n}\n\nexport const CONDITIONS_ARE_FALSE_RESPONSE = {\n ...FORM_RULE_RESPONSE,\n useValue: false,\n success: true,\n conditionValue: false\n}\n\nexport const DISPLAY_RULE_SUCCESS_RESPONSE = {\n ...FORM_RULE_RESPONSE,\n value: true,\n useValue: true,\n success: true\n}\n\nexport const VALUE_SETTING_RULE_SUCCESS_RESPONSE = {\n ...FORM_RULE_RESPONSE,\n useValue: true,\n success: true\n}\n\nexport const SKIP_RULE_RESPONSE = {\n ...FAILLING_RULE_RESPONSE,\n success: true,\n errorMessage: 'this rule is being skipped'\n}\n","import React from \"react\";\nimport FormAttributeContainer from \"../FormAttributeContainer/FormAttributeContainer\";\nimport FormAttributeNotificationMessage from '../FormAttributeNotificationMessage';\nimport APP_CONSTANTS, {DEFAULT_LOCALE_FORMAT} from \"../../../../shared/constants/app_constants\";\n/**\n * props;\n * name - unique alphanumeric string\n * value - self explanatory\n * label - text that appears\n * hidden - will set class on container to hide attribute\n * locked - will set disabled=true on input\n * invalid - boolean, defaults to false, should have an errorMessage\n * errorMessage - message indicating value set on input is incorrect\n * onChangeFunctionCall - a function mapped to configurator\n * valueAligned - alignment of text field\n * placeholder - html placeholder value\n * cursorPosition - location of cursor\n */\n// export default class FreeFormFieldAttribute extends React.Component{\n\nexport default function ReadOnlyFreeFormAttribute (props) {\n\n const getPropsForHiddenInput = () => {\n const inputProps = {\n type: 'hidden',\n name: `submission_values[${props.name}]`,\n value: props.value,\n };\n return inputProps;\n }\n\n const formattedValue = () => {\n let formattedValue = props.value;\n if (!!props.value) {\n switch(props.value_type) {\n case APP_CONSTANTS.VALUE_TYPES.TEXT:\n // leave as is\n break;\n case APP_CONSTANTS.VALUE_TYPES.INTEGER:\n formattedValue = props.value.toLocaleString(DEFAULT_LOCALE_FORMAT);\n break;\n case APP_CONSTANTS.VALUE_TYPES.FLOAT:\n let options = {};\n if (props.float_precision) {\n options.maximumFractionDigits = props.float_precision;\n options.minimumFractionDigits = props.float_precision;\n }\n formattedValue = props.value.toLocaleString(DEFAULT_LOCALE_FORMAT, options);\n break;\n default:\n console.warn('unaccounted for data format', props);\n }\n }\n return formattedValue;\n }\n \n let inputPrefixText, inputSuffixText, inputSubscriptText;\n if (props.settings?.input_prefix_text && props.settings?.input_prefix_text.trim().length > 0 ) {\n inputPrefixText = props.settings.input_prefix_text;\n }\n if (props.settings?.input_suffix_text && props.settings?.input_suffix_text.trim().length > 0 ) {\n inputSuffixText = props.settings.input_suffix_text;\n }\n if (props.settings?.input_subscript_text && props.settings?.input_subscript_text.trim().length > 0 ) {\n inputSubscriptText = props.settings.input_subscript_text;\n }\n\n const valueTextAlign = props.settings?.input_alignment === \"right\" ? \"text-end\" : \"\";\n const hiddenInputProps = getPropsForHiddenInput();\n\n return (\n \n
\n
\n { inputPrefixText}{formattedValue()}{inputSuffixText}\n \n
\n
\n \n { inputSubscriptText &&\n
{inputSubscriptText}
\n }\n
\n );\n \n}\n","import React from \"react\";\nimport FormAttributeContainer from \"../FormAttributeContainer/FormAttributeContainer\";\nimport FormAttributeNotificationMessage from '../FormAttributeNotificationMessage';\n// import APP_CONSTANTS, {DEFAULT_LOCALE_FORMAT} from \"../../../../shared/constants/app_constants\";\n\nexport default class RatingScaleFormAttribute extends React.Component{\n getRatingOptions = () => {\n const ratingPointScale = this.props.settings?.rating_point_scale || 5; // default is set to 5\n const ratingScaleStart = this.props.settings?.rating_scale_start || 1;\n const maxValue = ratingPointScale + (ratingScaleStart - 1);\n // TODO: this should be moved to the form attribute state manager\n const optionsArray = Array.from({ length: maxValue - ratingScaleStart + 1 }, (_, i) => ratingScaleStart + i);\n const flexJustifyClass = `justify-content-${this.props.settings.rating_options_justify_content}`;\n return
\n {optionsArray.map((opt, index) => {\n const optionSelected = (opt === this.props.value);\n const ratingOptionContainerClasses = [\"border\", \"d-flex\", \"rating-option-container\", \"selectable-option-container\", \"p-2\"];\n if (optionSelected) {\n ratingOptionContainerClasses.push(\"option-selected\");\n }\n return (\n
{this.setRatingValue(opt)}}\n >\n
\n {console.log('do nothing')}} />\n
\n
\n {opt}\n
\n
\n );\n })}\n
;\n };\n\n setRatingValue = (value) => {\n this.props.onChangeFunctionCall(this.props.name, value);\n };\n\n getRatingsScale = () => {\n let showRatingScale = false,\n ratingScaleContent;\n\n if (this.props.settings?.lowest_rating_text?.length > 0 && this.props.settings?.highest_rating_text?.length > 0) {\n showRatingScale = true;\n const flexJustifyContent = this.props.settings?.rating_scale_superscript_justify_content || \"between\";\n const flexJustifyClass = `justify-content-${flexJustifyContent}`;\n ratingScaleContent =
\n
{this.props.settings.lowest_rating_text}
\n {this.props.settings?.middle_rating_text.length > 0 &&
{this.props.settings?.middle_rating_text}
}\n
{this.props.settings.highest_rating_text}
\n
\n }\n\n if (showRatingScale) {\n return ratingScaleContent;\n } else {\n return undefined;\n }\n \n };\n\n render() {\n let inputSubscriptText;\n if (this.props.settings?.input_subscript_text && this.props.settings?.input_subscript_text.trim().length > 0 ) {\n inputSubscriptText = this.props.settings.input_subscript_text;\n }\n return (\n \n {this.getRatingsScale()}\n
\n {this.getRatingOptions()}\n
\n \n { inputSubscriptText &&\n
{inputSubscriptText}
\n }\n
\n );\n }\n}","import React from \"react\";\nimport FreeFormFieldAttribute from \"./components/formelements/FreeFormFieldAttribute/FreeFormFieldAttribute\";\nimport RadioSingleSelectFieldAttribute from \"./components/formelements/RadioSingleSelectFieldAttribute/RadioSingleSelectFieldAttribute\";\nimport SingleSelectFieldAttribute from \"./components/formelements/SingleSelectFieldAttribute/SingleSelectFieldAttribute\";\nimport MultiSelectFieldAttribute from \"./components/formelements/MultiSelectFieldAttribute/MultiSelectFieldAttribute\";\nimport TextAreaFieldAttribute from \"./components/formelements/TextAreaFieldAttribute/TextAreaFieldAttribute\";\nimport StaticTextFormAttribute from \"./components/formelements/StaticTextFormAttribute/StaticTextFormAttribute\";\nimport DatePickerFieldAttribute from \"./components/formelements/DatePickerFieldAttribute/DatePickerFieldAttribute\";\nimport ReadOnlyFreeFormAttribute from \"./components/formelements/ReadOnlyFreeFormAttribute/ReadOnlyFreeFormAttribute\";\nimport RatingScaleFormAttribute from \"./components/formelements/RatingScaleFormAttribute/RatingScaleFormAttribute\";\nimport APP_CONSTANTS, { \n KEENFORM_SUBMIT_BUTTON_FA,\n POSTMESSAGE_API_EVENT_TYPES\n} from \"../shared/constants/app_constants\";\nimport KeenformStateManager from \"./utils/KeenformStateManager\";\n\nexport default class KeenformViewManager extends React.Component {\n\n constructor(props) {\n super(props);\n this.state = {\n formAttributesStateMap: null,\n cursorStart: null\n };\n this._keenformStateManager = null;\n }\n\n componentDidMount() {\n if (this.props.keenform && this.props.keenform.form_attributes) {\n this._keenformStateManager = new KeenformStateManager(this.props.keenform, this.props.initialAttributeValues);\n } else {\n console.error(\"this is an invalid keenform -> there is no form_attributes in props\");\n return false;\n }\n this.publishKeenformState();\n\n // TODO: verify this setting works\n if (this.props.keenform.settings?.subscribe_to_postmessage_api) {\n this.subcribeToPostmessageApi();\n }\n }\n\n /**\n * this function is called whenever user modifies form attribute ui element\n */\n requestToSetValueOfFormAttributeAndUpdateState = (formAttrKey, formAttrValue, optionalParams) => {\n let formAttributesStateMapUpdated = this._keenformStateManager.setValueAndGetState(formAttrKey, formAttrValue);\n const cursorStart = !!optionalParams && !!optionalParams.cursorStart ? optionalParams.cursorStart : undefined;\n this.setState({\n formAttributesStateMap: formAttributesStateMapUpdated,\n cursorStart: cursorStart\n });\n this.broadcastState(formAttributesStateMapUpdated, \"formAttributeUpdated\");\n }\n\n /**\n * publishes state on component did mount\n */\n publishKeenformState = () => {\n const formAttributesStateMap = this.getFormAttributesStates();\n this.setState({ formAttributesStateMap: formAttributesStateMap });\n this.broadcastState(formAttributesStateMap, \"publish\");\n }\n\n /**\n * return boolean - is form valid\n */\n isKeenformValid = () => {\n let allFormAttributesAreValid = true;\n // iterate over currentFormAttributeStates, if one valid is false\n this.state.formAttributesStateMap.forEach((formAttrState, formAttrKey) => {\n if (formAttrState.isValid === false) {\n allFormAttributesAreValid = false;\n if (formAttrState.hidden) {\n console.error('there is a hidden input is marker as invalid: ', formAttrKey);\n }\n }\n });\n\n return allFormAttributesAreValid;\n }\n\n broadcastState = (faStateMap, actionType) => {\n if (this.props.keenform.settings?.publish_to_postmessage_api) {\n let formAttributeValues = {};\n [...faStateMap].forEach(([key, value]) => {\n formAttributeValues[key] = value.value;\n });\n const messageObj = {\n keenformActionType: actionType,\n keenformMessageType: \"KeenformState\",\n formAttributeValues: formAttributeValues,\n formAttributeStateMap: faStateMap,\n location: JSON.parse(JSON.stringify(window.location))\n };\n const targetOrigin = this.props.keenform.settings?.postmessage_target_origin || \"*\";\n if (targetOrigin.length > 0) {\n window.parent.postMessage(messageObj, targetOrigin);\n }\n }\n }\n\n // TODO: check matching nonce uuid before subscribing\n subcribeToPostmessageApi = () => {\n const self = this;\n window.addEventListener('message', function(event) {\n const message = event.data;\n if (message?.keenformActionType) {\n switch(message.keenformActionType) {\n case POSTMESSAGE_API_EVENT_TYPES.SET_FORM_ATTRIBUTE_VALUE:\n const faName = message?.keenformActionParams?.formAttributeName;\n const faValue = message?.keenformActionParams?.formAttributeValue;\n if (faName && faValue) {\n // TODO: create special function to handle all errors like invalida fa name or value\n self.requestToSetValueOfFormAttributeAndUpdateState(faName, faValue);\n } else {\n console.warn('required parameters for setting form attribute value are missing');\n }\n\n break;\n case POSTMESSAGE_API_EVENT_TYPES.SUBMIT_FORM:\n // TODO: requires more time\n const isValid = self.handleFormSubmit();\n if (isValid) {\n self.autoSubmitForm();\n } else {\n console.log('form cannot be submitted as it has one or more invalid form attribute values');\n }\n break;\n default:\n // this needs more info why this is failing\n console.warn('invalid action type passed, no action taken', message);\n }\n }\n });\n }\n\n autoSubmitForm = () => {\n // TODO should we use a ref instead?\n document.getElementById(\"kf-form-tag\").submit();\n }\n\n getFirstInvalidFormAttribute = () => {\n let firstInvalidFormAttributeState;\n this.state.formAttributesStateMap.forEach((faState) => {\n if (faState.isValid === false && firstInvalidFormAttributeState == undefined){\n firstInvalidFormAttributeState = faState;\n }\n });\n return firstInvalidFormAttributeState;\n }\n\n focusOnFirstInvalidAttribute = () => {\n const firstInvalidFaState = this.getFirstInvalidFormAttribute();\n if (firstInvalidFaState && firstInvalidFaState?.containerDomId ) {\n const firstInvalidFADomElement = document.getElementById(firstInvalidFaState.containerDomId);\n if (firstInvalidFADomElement) {\n firstInvalidFADomElement.scrollIntoView({block: \"start\"});\n }\n } else {\n console.warn('form is invalid but firstInvalidFADomElement is undefined, this should not happen');\n }\n }\n\n handleFormSubmit = (event) => {\n const allFormAttributesAreValid = this.isKeenformValid();\n if (!allFormAttributesAreValid) {\n event.preventDefault();\n alert('cannot save, form has invalid attributes'); //TODO: replace alert with modal\n this.touchAllAttributes();\n // focus on invalid attribute\n this.focusOnFirstInvalidAttribute();\n }\n // broadcast here?\n return allFormAttributesAreValid;\n }\n\n onBlurOfAttribute = (formAttrKey) => {\n const latestState = this._keenformStateManager.touchAttribute(formAttrKey);\n this.setState({\n formAttributesStateMap: latestState\n });\n this.broadcastState(latestState, \"blur\");\n }\n\n /**\n * DEPRECATED, no longer in use, will be removed eventually\n * UI specific\n * @returns array of React elements\n */\n getFormAttributeUIElements = () => {\n let formAttributeUIElementsArr = [];\n if (this.state && this.state.formAttributesStateMap) {\n for (var formAttrKey of this.state.formAttributesStateMap.keys()) {\n let formAttrState = this.state.formAttributesStateMap.get(formAttrKey);\n switch (formAttrState.form_attribute_type) {\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.FREEFORM:\n let freeFormAttribute;\n const showAsReadOnly = (formAttrState.read_only \n && formAttrState.settings?.read_only_display_format === \"formatted_text\");\n if (showAsReadOnly) {\n freeFormAttribute = \n ;\n } else if (formAttrState.display_type === APP_CONSTANTS.DISPLAY_TYPES_HTML.TEXTAREA) {\n freeFormAttribute = ;\n } else {\n freeFormAttribute = ;\n }\n formAttributeUIElementsArr.push(freeFormAttribute);\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SINGLESELECT:\n if (formAttrState.display_type === APP_CONSTANTS.DISPLAY_TYPES_HTML.RADIO) {\n formAttributeUIElementsArr.push();\n } else {\n formAttributeUIElementsArr.push();\n }\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.MULTISELECT:\n formAttributeUIElementsArr.push();\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.DATEPICKER:\n formAttributeUIElementsArr.push();\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.NON_INPUT:\n formAttributeUIElementsArr.push();\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.INLINE_STYLE:\n formAttributeUIElementsArr.push();\n break;\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.SYSTEM:\n case APP_CONSTANTS.FORM_ATTRIBUTE_TYPES.NON_DISPLAY:\n // console.log('SYSTEM ATTRIBUTE, do not render');\n break;\n default:\n console.error(`THIS IS NOT A VALID inputType:`);\n console.log(formAttrState);\n }\n }\n return formAttributeUIElementsArr;\n } else {\n console.log(\"configurator isn't ready\");\n return null;\n }\n }\n\n /**\n * UI Default Simple Layout\n */\n getFormAttributeUIElementsArray = () => {\n let formAttributeUIElementsArr = [];\n if (this.state && this.state.formAttributesStateMap) {\n for (var formAttrKey of this.state.formAttributesStateMap.keys()) {\n let formAttrState = this.state.formAttributesStateMap.get(formAttrKey);\n switch (formAttrState.display_type) {\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.TEXT:\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.NUMBER:\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.EMAIL:\n let freeFormAttribute;\n const showAsReadOnly = (formAttrState.read_only \n && formAttrState.settings?.read_only_display_format === \"formatted_text\");\n if (showAsReadOnly) {\n freeFormAttribute = \n ;\n } else {\n freeFormAttribute = ;\n }\n formAttributeUIElementsArr.push(freeFormAttribute);\n break;\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.TEXTAREA:\n const textareaFA = ;\n formAttributeUIElementsArr.push(textareaFA);\n break;\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.SELECT:\n formAttributeUIElementsArr.push(\n );\n break;\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.RADIO:\n formAttributeUIElementsArr.push();\n break;\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.CHECKBOX:\n formAttributeUIElementsArr.push();\n break;\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.DATEPICKER:\n formAttributeUIElementsArr.push();\n break;\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.INLINE_STYLE:\n formAttributeUIElementsArr.push();\n break;\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.RATING_SCALE:\n // console.warn(\"The rating scale is under construction\");\n formAttributeUIElementsArr.push(\n \n );\n break;\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.STATIC_HTML:\n formAttributeUIElementsArr.push();\n break;\n case APP_CONSTANTS.DISPLAY_TYPES_HTML.NON_DISPLAY:\n // console.info(\"do not display this FA\", formAttrState);\n break;\n default:\n console.error(`THIS IS NOT A VALID inputType:`);\n console.log(formAttrState);\n }\n }\n return formAttributeUIElementsArr;\n } else {\n console.log(\"configurator isn't ready\");\n return null;\n }\n }\n\n /**\n * @returns Map of form attribute states\n */\n getFormAttributesStates = () => {\n if (this._keenformStateManager !== null) {\n const formAttributesStates = this._keenformStateManager.getKeenformState();\n return formAttributesStates;\n } else {\n console.warning('keenform state manager is null, cannot return state');\n return new Map();\n }\n }\n\n getFormPath = () => {\n const formPath = this.props.submissionPath || `/keenforms/${this.props.keenform.uuid}/submit`;\n return formPath;\n }\n\n touchAllAttributes = () => {\n const latestState = this._keenformStateManager.touchAllAttributes();\n this.setState({\n formAttributesStateMap: latestState\n });\n this.broadcastState(latestState, \"touchAllAttributes\");\n }\n\n /**\n * React specific - renders custom header\n * @returns HTML fragment\n */\n renderHeader = () => {\n const keenform = this.props.keenform;\n const useCustomHeader = !!keenform.use_custom_header;\n let headerContent = this.props.keenform.name;\n if (useCustomHeader && !!keenform.custom_header_content) {\n headerContent = this.props.keenform.custom_header_content;\n }\n\n const inlineStyleForm = this.getInlineStyleForMaxWidth();\n\n return (\n
\n
\n
\n
\n {useCustomHeader\n ?
\n :
\n

{headerContent}

\n
\n }\n
\n
\n
\n
\n );\n }\n\n renderSubmitButton = () => {\n let submitButtonMockFA;\n if (this.state.formAttributesStateMap) {\n submitButtonMockFA = this.state.formAttributesStateMap.get(KEENFORM_SUBMIT_BUTTON_FA);\n }\n\n const keenform = this.props.keenform;\n let isFormValid = true;\n if (this._keenformStateManager) {\n isFormValid = this._keenformStateManager.getAllAttributesAreValid();\n }\n const validButtonClass = isFormValid ? 'submit-valid' : 'submit-invalid';\n let submitButtonValue = \"Submit\";\n // FIX ME\n const kf_settings = keenform && keenform.settings ? keenform.settings : {};\n\n if (kf_settings.use_submit_button_custom_text && kf_settings?.submit_button_text) {\n const submitButtonText = kf_settings.submit_button_text;\n if (submitButtonText.trim().length > 0) {\n submitButtonValue = submitButtonText;\n }\n }\n\n let submitButtonStyle = \"default-button-style\";\n let submitButtonParentStyle = \"default\";\n if (kf_settings.submit_button_style) {\n if (kf_settings.submit_button_style === \"full-width\"){\n submitButtonStyle = kf_settings.submit_button_style;\n } else if (kf_settings.submit_button_style === \"align-right\") {\n submitButtonParentStyle = \"align-right\";\n }\n }\n\n if (submitButtonMockFA && submitButtonMockFA.hidden) {\n submitButtonParentStyle += \" d-none\";\n }\n\n return (\n \n \n
\n );\n }\n\n getInlineStyleForMaxWidth = () => {\n const keenform = this.props.keenform;\n let inlineStyles= {};\n if (keenform.settings?.form_max_width_pixels) {\n inlineStyles.maxWidth = keenform.settings.form_max_width_pixels + \"px\";\n }\n return inlineStyles;\n }\n\n render = () => {\n const formPath = this.getFormPath();\n const inlineStyleForm = this.getInlineStyleForMaxWidth();\n\n return (\n \n {this.renderHeader()}\n
\n
\n
\n
\n
\n
\n
\n {this.getFormAttributeUIElementsArray()}\n
\n {this.renderSubmitButton()}\n
\n
\n
\n
\n
\n
\n
\n );\n }\n}\n","// import React from 'react';\nimport { POSTMESSAGE_API_EVENT_TYPES } from '../../bundles/shared/constants/app_constants';\n\nfunction KeenformPostSubmit(props) {\n if (props.keenform.settings?.publish_to_postmessage_api) {\n const formAttributeValues = props.submission.values_submitted;\n const messageObj = {\n keenformActionType: POSTMESSAGE_API_EVENT_TYPES.SUBMISSION_SAVED,\n keenformMessageType: \"KeenformStatePostSubmit\",\n formAttributeValues: formAttributeValues,\n location: JSON.parse(JSON.stringify(window.location)),\n submission: props.submission\n };\n const targetOrigin = props.keenform.settings?.postmessage_target_origin || \"*\";\n if (targetOrigin.length > 0) {\n window.parent.postMessage(messageObj, targetOrigin);\n }\n }\n\n return false;\n}\n\nexport default KeenformPostSubmit;","import \"core-js/stable\";\nimport \"regenerator-runtime/runtime\";\nimport 'react-app-polyfill/ie11';\n/*\nimport 'core-js/features/object/keys';\nimport 'core-js/features/array/find';\nimport 'core-js/features/array/includes';\nimport 'core-js/features/number/is-nan';\nimport 'core-js/features/symbol/iterator';\nimport 'core-js/es/symbol/index';\nimport \"core-js/modules/es.symbol\";\n*/\nimport ReactOnRails from 'react-on-rails';\n\nimport KeenformViewManager from '../bundles/KeenformRenderer/KeenformViewManager';\nimport KeenformPreviewManager from '../bundles/KeenformRenderer/KeenformPreviewManager';\nimport KeenformPostSubmit from '../bundles/KeenformPostSubmit/KeenformPostSubmit';\n\nReactOnRails.register({\n KeenformViewManager,\n KeenformPreviewManager,\n KeenformPostSubmit\n});","// import React from \"react\";\nimport KeenformViewManager from \"./KeenformViewManager\";\n\nexport default class KeenformPreviewManager extends KeenformViewManager {\n\n // getFormPath = () => {\n // if (this.props.version_uuid) {\n // const version_uuid = this.props.version_uuid ? this.props.version_uuid : this.props.keenform.uuid;\n // // get this version uuid\n // const previewSubmissionPath = `/dashboard/preview_submit/${version_uuid}`;\n // return previewSubmissionPath;\n // } else {\n // return super.getFormPath();\n // }\n // }\n\n}\n"],"names":["FormAttributeStateManager","constructor","attrHash","hasOwnProperty","console","error","log","this","isValid","errorMessage","_key","name","_name","_uuid","uuid","_label","label","_form_attribute_type","form_attribute_type","APP_CONSTANTS","FORM_ATTRIBUTE_TYPES","FREEFORM","_value_type","value_type","VALUE_TYPES","TEXT","_display_type","display_type","DISPLAY_TYPES_HTML","_is_inialized","_position","position","_value","_required","required","_hidden","hidden","_read_only","read_only","_locked","_placeholder","placeholder","_hide_label_flag","hide_label_flag","_default_value","default_value","_metadata_types","metadata_types","_use_blank_placeholder_option","use_blank_placeholder_option","_description","description","_display_options","display_options","_settings","settings","_touched","_float_precision","undefined","FLOAT","float_precision","NON_INPUT","STATIC_HTML","_register_click_events_on_html","register_click_events_on_html","SINGLESELECT","MULTISELECT","optionsAvailable","options","shuffleArray","_options","map","option","DATEPICKER","INLINE_STYLE","SYSTEM","NON_DISPLAY","getResponseForValidFloatValue","floatValue","responseMessage","value","floatSplit","toString","split","length","slice","notificationMessage","number_input_min","number_input_max","getKey","getName","getLabel","getStateForUI","faName","stateObj","getValue","locked","_is_valid","isValidPerValueType","touched","containerDomId","KF_FA_CONTAINER_CLASS","_errorMessage","_notificationMessage","option_selected","find","options_selected","filter","includes","warn","getNotificationMessage","isLocked","INTEGER","isValidInteger","isValidFloat","DATE","onBlurOfAttribute","setAsHidden","hideThisAttribute","setValue","responseForValue","testValueValidityPerType","NaN","testFreeformValueForValidity","validateTextValue","validateIntegerValue","validateFloatValue","testSingleSelectValueForValidity","testMultiSelectValueForValiditiy","PLACEHOLDER_OPTION","opt","isValueValid","valueArray","Array","isArray","valueItem","touchAttribute","TEXTAREA","EMAIL","trim","textValueIsValid","isStringValidEmailAddress","text_input_minlength","text_input_maxlength","returnMsg","parseInt","initializeFormAttributeVal","thisValue","initializeValueForSingleSelect","initializeValueForMultiSelect","initializeValueForFreeForm","retVal","retValOption","defaultRadioOptionToNone","RADIO","SELECT","parseFloat","array","sort","Math","random","a","b","_ref","FormRuleResponder","getFormRuleResponse","formRule","formAttributesStates","FORM_RULE_RESPONSE","getAllSourceFormAttributesAreValid","SOURCE_FORM_ATTRIBUTE_NOT_VALID_RESPONSE","conditionResponseMessage","use_nocode_condition","use_condition_function","condition_function","getResponseForConditionRuleFunction","nocodeConditionExpressions","form_rule_conditionals","evaluateNocodeConditions","nocode_condition_joiner","invert_condition","CONDITIONS_ARE_FALSE_RESPONSE","FAILLING_RULE_RESPONSE","rule_type","RULE_TYPES","HIDING","LOCKING","DISPLAY_RULE_SUCCESS_RESPONSE","VALUE_SETTING","getResponseForValueSettingRule","VALIDATING","getResponseForValidatingRule","FILTERING","getResponseForFilteringRule","WEBHOOK","SKIP_RULE_RESPONSE","allSourceFormAttributesAreValid","concat","source_attribute_keys","forEach","key","thisFormAttribute","get","conditionalsArr","condition_joiner","form_rule","conditionsResponse","conditionalsEvalArr","conditional","operand1Key","operand1_form_attribute","operator","operatorObj","getOperatorObjectPerKey","LAST_USER_MODIFIED_FA_OPERATOR_PREFIX","operand1Val","operand2Obj","LAST_USER_MODIFIED_FA","conditionExressionResponse","evaluateSingleNocodeCondition","push","operand2Val","hasMetadataValue","metadataValues","metadata","metadataKey","debug","metadataType","mdt","CURRENCY","metadataValArray","requiresOperand2","operand2_pre_type","OPERAND2_PRE_TYPES","FIXED_TEXT","FIXED_FLOAT","FIXED_INTEGER","operand2_value","FORM_ATTRIBUTE_VALUE","operand2_form_attribute","operand2_subkey","metadataValueArray","this_option","thisMetadataValue","OPTION_VALUES","operand2_option_values","OPTION_VALUE","operand2_option_value","reduce","carryover","condition","operand1","operand2","OPERATOR_STRING_BLANK","OPERATOR_STRING_NOT_BLANK","OPERATOR_STRING_EQUALS","OPERATOR_STRING_NOT_EQUALS","OPERATOR_STRING_CONTAINS","OPERATOR_STRING_NOT_CONTAINS","OPERATOR_STRING_LENGTH_EQUALS","OPERATOR_STRING_LENGTH_NOT_EQUALS","OPERATOR_STRING_LENGTH_MIN","OPERATOR_STRING_LENGTH_MAX","OPERATOR_NUMBER_BLANK","OPERATOR_NUMBER_NOT_BLANK","OPERATOR_NUMBER_EQUAL","OPERATOR_NUMBER_NOT_EQUAL","OPERATOR_NUMBER_GREATER_THAN","OPERATOR_NUMBER_NOT_GREATER_THAN","OPERATOR_NUMBER_GREATER_OR_EQUAL","OPERATOR_NUMBER_NOT_GREATER_OR_EQUAL","OPERATOR_NUMBER_LESSER_THAN","OPERATOR_NUMBER_NOT_LESSER_THAN","OPERATOR_NUMBER_LESSER_OR_EQUAL","OPERATOR_NUMBER_NOT_LESSER_OR_EQUAL","OPERATOR_SINGLESELECT_EQUALS","OPERATOR_SINGLESELECT_NOT_EQUALS","OPERATOR_MULTISELECT_CONTAINS","OPERATOR_MULTISELECT_NOT_CONTAINS","OPERATOR_MULTISELECT_MATCHES_EXACT","every","OPERATOR_MULTISELECT_NOT_MATCHES_EXACT","OPERATOR_MULTISELECT_LENGTH_EQUALS","OPERATOR_MULTISELECT_LENGTH_NOT_EQUALS","OPERATOR_MULTISELECT_LENGTH_MIN","OPERATOR_MULTISELECT_LENGTH_MAX","OPERATOR_LAST_USER_MODIFIED_FA_EQUALS","OPERATOR_LAST_USER_MODIFIED_FA_NOT_EQUALS","OPERATOR_FILTERING_MULTISELECT_CONTAINED_IN","OPERATOR_FILTERING_MULTISELECT_NOT_CONTAINED_IN","getAttributeHashPerRule","formatNumberAsStr","arguments","formAttributeKeys","errorDetected","formattedValue","toLocaleString","floatOptions","minimumFractionDigits","maximumFractionDigits","join","subtotalKey","MULTISELECT_SUMTOTAL_ATTRIBUTE","subtotal","total","val","metadata_type","metadataKeyForHash","METADATA_DISPLAY_TYPES","NUMBER","selectedOption","metadataValue","abstract_value_type","formatOptions","number_precision","selectedOptions","keenform_id","getConditionOperatorObject","operatorVal","conditionOperatorSet","conditionOperator","CONDITION_OPERATORS","formAttributeType","SYSTEM_OPERATORS","condOp","startsWith","FILTERING_CONDITION_OPERATORS","op","targetAttributeKey","target_attribute_keys","targetFormAttribute","dynamic_filtering","filtered_options","optionsArray","hideOption","useValue","success","hideOptionPerFilteringConditionals","use_type_function","getResponseForValueSettingRuleFunction","getResponseForValueSettingRuleNoCode","use_nocode_expression","optionUUID","option_values","VALUE_SETTING_RULE_SUCCESS_RESPONSE","nocode_expression","getResponseForValueSettingRuleForNumber","candidateValue","interpolateTextFormRule","optionUUIDs","targetAttribute","formRuleFunctionValueResponse","type_function","conditionResponse","conditionFunctionResponse","eval","rule_expression","floatStr","isNaN","FAILING_VALUE_SETTING_RULE_NUMBER_NAN","isFinite","FAILING_VALUE_SETTING_RULE_NUMBER_INFINITY","FAILING_VALUE_SETTING_RULE_NUMBER_UNDEFINED","isValidNumber","updateNumberPerFormRulePostOpModifier","FAILING_VALUE_SETTING_RULE","filtering_conditionals","operand1Value","operand1_subkey","operand2Value","operand2FA","operand2_key","conditionalsResponse","dynamicFilteringJoiner","dynamic_filtering_joiner","getAllAttributes","formatNumbers","format_numbers_for_display","interpolatedStr","faValue","Object","entries","attrKeyReplace","replace","RegExp","returnValue","post_op_modifier","round","floor","ceil","trunc","divisor","pow","POST_OP_MODIFIERS","ROUND","Number","EPSILON","FLOOR","CEILING","numberAfterDecimal","KeenformStateManager","keenformData","initialValues","keenform","form_attributes","getFormRulesAsObjects","form_rules","formAttributeObj","formAttrKey","onInitializeValue","form_attributes_array","formAttributesMap","Map","thisFormAttributeData","thisFormAttrKey","formAttributeStateManager","set","lastUserModifiedFAData","lastUserModifiedFAObject","submitButton","KEENFORM_SUBMIT_BUTTON_FA","submitButtonFAObject","getAllAttributesAreValid","isFormValid","fa","has","formAttribute","getFormRules","formRulesArray","formRuleObject","type_function_for_eval","formRuleTypeFunction","condition_function_for_eval","formRuleConditionFunction","getKeenformState","currentStateOfFormAttributes","formAttributesMapPostRules","formAttributesStateMap","faStateMap","rule","ruleResponse","target_submit_button","targetAttributeValue","valueAsOption","optionValue","message_content","self","valueSettingRules","newValue","targetFormAttributeKey","conditionValue","setValueAndGetState","formAttrValue","touchAllAttributes","parsedFloatValue","ReadOnlyFreeFormAttribute","props","inputPrefixText","inputSuffixText","inputSubscriptText","input_prefix_text","input_suffix_text","input_subscript_text","valueTextAlign","input_alignment","hiddenInputProps","type","React","FormAttributeContainer","className","DEFAULT_LOCALE_FORMAT","FormAttributeNotificationMessage","RatingScaleFormAttribute","getRatingOptions","ratingPointScale","rating_point_scale","ratingScaleStart","rating_scale_start","maxValue","from","_","i","flexJustifyClass","rating_options_justify_content","index","optionSelected","ratingOptionContainerClasses","onClick","setRatingValue","checked","onChange","onChangeFunctionCall","getRatingsScale","ratingScaleContent","showRatingScale","lowest_rating_text","highest_rating_text","rating_scale_superscript_justify_content","middle_rating_text","render","KeenformViewManager","super","state","cursorStart","_keenformStateManager","componentDidMount","initialAttributeValues","publishKeenformState","subscribe_to_postmessage_api","subcribeToPostmessageApi","requestToSetValueOfFormAttributeAndUpdateState","optionalParams","formAttributesStateMapUpdated","setState","broadcastState","getFormAttributesStates","isKeenformValid","allFormAttributesAreValid","formAttrState","actionType","publish_to_postmessage_api","formAttributeValues","messageObj","keenformActionType","keenformMessageType","formAttributeStateMap","location","JSON","parse","stringify","window","targetOrigin","postmessage_target_origin","parent","postMessage","addEventListener","event","message","data","POSTMESSAGE_API_EVENT_TYPES","SET_FORM_ATTRIBUTE_VALUE","keenformActionParams","formAttributeName","formAttributeValue","SUBMIT_FORM","handleFormSubmit","autoSubmitForm","document","getElementById","submit","getFirstInvalidFormAttribute","firstInvalidFormAttributeState","faState","focusOnFirstInvalidAttribute","firstInvalidFaState","firstInvalidFADomElement","scrollIntoView","block","preventDefault","alert","latestState","getFormAttributeUIElements","formAttributeUIElementsArr","keys","freeFormAttribute","read_only_display_format","_extends","TextAreaFieldAttribute","lastUserModifiedFormAttribute","autoComplete","autocomplete_allowed","onBlurFunctionCall","bind","FreeFormFieldAttribute","preventSubmitOnReturnKeydown","prevent_submit_on_return_keypress","RadioSingleSelectFieldAttribute","SingleSelectFieldAttribute","MultiSelectFieldAttribute","DatePickerFieldAttribute","StaticTextFormAttribute","getFormAttributeUIElementsArray","textareaFA","CHECKBOX","RATING_SCALE","warning","getFormPath","submissionPath","renderHeader","useCustomHeader","use_custom_header","headerContent","custom_header_content","inlineStyleForm","getInlineStyleForMaxWidth","id","dangerouslySetInnerHTML","__html","style","renderSubmitButton","submitButtonMockFA","validButtonClass","submitButtonValue","kf_settings","use_submit_button_custom_text","submit_button_text","submitButtonText","submitButtonStyle","submitButtonParentStyle","submit_button_style","inlineStyles","form_max_width_pixels","maxWidth","formPath","action","method","submission","values_submitted","SUBMISSION_SAVED","ReactOnRails","KeenformPreviewManager","KeenformPostSubmit"],"sourceRoot":""}