@eform/ng-formio-builder
Version:
The Angular.js form builder component.
1,593 lines (1,415 loc) • 1.23 MB
JavaScript
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.formioBuilder = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(_dereq_,module,exports){
(function (global){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var _utils = _dereq_('./utils');
var FormioUtils = _interopRequireWildcard(_utils);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
if ((typeof global === 'undefined' ? 'undefined' : _typeof(global)) === 'object') {
global.FormioUtils = FormioUtils;
}
exports.default = FormioUtils;
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./utils":3}],2:[function(_dereq_,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
// Use only immutable useful functions from Lodash.
// Visit https://lodash.com/docs for more info.
var lodashOperators = exports.lodashOperators = [
// Array
'chunk', 'compact', 'concat', 'difference', 'differenceBy', 'differenceWith', 'drop', 'dropRight', 'dropRightWhile', 'dropWhile', 'findIndex', 'findLastIndex', 'first', 'flatten', 'flattenDeep', 'flattenDepth', 'fromPairs', 'head', 'indexOf', 'initial', 'intersection', 'intersectionBy', 'intersectionWith', 'join', 'last', 'lastIndexOf', 'nth', 'slice', 'sortedIndex', 'sortedIndexBy', 'sortedIndexOf', 'sortedLastIndex', 'sortedLastIndexBy', 'sortedLastIndexOf', 'sortedUniq', 'sortedUniqBy', 'tail', 'take', 'takeRight', 'takeRightWhile', 'takeWhile', 'union', 'unionBy', 'unionWith', 'uniq', 'uniqBy', 'uniqWith', 'unzip', 'unzipWith', 'without', 'xor', 'xorBy', 'xorWith', 'zip', 'zipObject', 'zipObjectDeep', 'zipWith',
// Collection
'countBy', 'every', 'filter', 'find', 'findLast', 'flatMap', 'flatMapDeep', 'flatMapDepth', 'groupBy', 'includes', 'invokeMap', 'keyBy', 'map', 'orderBy', 'partition', 'reduce', 'reduceRight', 'reject', 'sample', 'sampleSize', 'shuffle', 'size', 'some', 'sortBy',
// Date
'now',
// Function
'flip', 'negate', 'overArgs', 'partial', 'partialRight', 'rearg', 'rest', 'spread',
// Lang
'castArray', 'clone', 'cloneDeep', 'cloneDeepWith', 'cloneDeep', 'conformsTo', 'eq', 'gt', 'gte', 'isArguments', 'isArray', 'isArrayBuffer', 'isArrayLike', 'isArrayLikeObject', 'isBoolean', 'isBuffer', 'isDate', 'isElement', 'isEmpty', 'isEqual', 'isEqualWith', 'isError', 'isFinite', 'isFunction', 'isInteger', 'isLength', 'isMap', 'isMatch', 'isMatchWith', 'isNaN', 'isNative', 'isNil', 'isNull', 'isNumber', 'isObject', 'isObjectLike', 'isPlainObject', 'isRegExp', 'isSafeInteger', 'isSet', 'isString', 'isSymbol', 'isTypedArray', 'isUndefined', 'isWeakMap', 'isWeakSet', 'lt', 'lte', 'toArray', 'toFinite', 'toInteger', 'toLength', 'toNumber', 'toPlainObject', 'toSafeInteger', 'toString',
// Math
'add', 'ceil', 'divide', 'floor', 'max', 'maxBy', 'mean', 'meanBy', 'min', 'minBy', 'multiply', 'round', 'subtract', 'sum', 'sumBy',
// Number
'clamp', 'inRange', 'random',
// Object
'at', 'entries', 'entriesIn', 'findKey', 'findLastKey', 'functions', 'functionsIn', 'get', 'has', 'hasIn', 'invert', 'invertBy', 'invoke', 'keys', 'keysIn', 'mapKeys', 'mapValues', 'omit', 'omitBy', 'pick', 'pickBy', 'result', 'toPairs', 'toPairsIn', 'transform', 'values', 'valuesIn',
// String
'camelCase', 'capitalize', 'deburr', 'endsWith', 'escape', 'escapeRegExp', 'kebabCase', 'lowerCase', 'lowerFirst', 'pad', 'padEnd', 'padStart', 'parseInt', 'repeat', 'replace', 'snakeCase', 'split', 'startCase', 'startsWith', 'toLower', 'toUpper', 'trim', 'trimEnd', 'trimStart', 'truncate', 'unescape', 'upperCase', 'upperFirst', 'words',
// Util
'cond', 'conforms', 'constant', 'defaultTo', 'flow', 'flowRight', 'identity', 'iteratee', 'matches', 'matchesProperty', 'method', 'methodOf', 'nthArg', 'over', 'overEvery', 'overSome', 'property', 'propertyOf', 'range', 'rangeRight', 'stubArray', 'stubFalse', 'stubObject', 'stubString', 'stubTrue', 'times', 'toPath', 'uniqueId'];
},{}],3:[function(_dereq_,module,exports){
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.jsonLogic = undefined;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
exports.evaluate = evaluate;
exports.getRandomComponentId = getRandomComponentId;
exports.getPropertyValue = getPropertyValue;
exports.getElementRect = getElementRect;
exports.boolValue = boolValue;
exports.isMongoId = isMongoId;
exports.isLayoutComponent = isLayoutComponent;
exports.eachComponent = eachComponent;
exports.matchComponent = matchComponent;
exports.getComponent = getComponent;
exports.findComponents = findComponents;
exports.flattenComponents = flattenComponents;
exports.hasCondition = hasCondition;
exports.parseFloatExt = parseFloatExt;
exports.formatAsCurrency = formatAsCurrency;
exports.escapeRegExCharacters = escapeRegExCharacters;
exports.checkCalculated = checkCalculated;
exports.checkSimpleConditional = checkSimpleConditional;
exports.checkCustomConditional = checkCustomConditional;
exports.checkJsonConditional = checkJsonConditional;
exports.checkCondition = checkCondition;
exports.checkTrigger = checkTrigger;
exports.setActionProperty = setActionProperty;
exports.getValue = getValue;
exports.interpolate = interpolate;
exports.uniqueName = uniqueName;
exports.guid = guid;
exports.getDateSetting = getDateSetting;
exports.isValidDate = isValidDate;
exports.getLocaleDateFormatInfo = getLocaleDateFormatInfo;
exports.convertFormatToFlatpickr = convertFormatToFlatpickr;
exports.convertFormatToMoment = convertFormatToMoment;
exports.getInputMask = getInputMask;
exports.matchInputMask = matchInputMask;
exports.getNumberSeparators = getNumberSeparators;
exports.getNumberDecimalLimit = getNumberDecimalLimit;
exports.getCurrencyAffixes = getCurrencyAffixes;
exports.fieldData = fieldData;
exports.delay = delay;
var _lodash = _dereq_('lodash');
var _lodash2 = _interopRequireDefault(_lodash);
var _jsonLogicJs = _dereq_('json-logic-js');
var _jsonLogicJs2 = _interopRequireDefault(_jsonLogicJs);
var _moment = _dereq_('moment');
var _moment2 = _interopRequireDefault(_moment);
var _operators = _dereq_('./jsonlogic/operators');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
// Configure JsonLogic
_operators.lodashOperators.forEach(function (name) {
return _jsonLogicJs2.default.add_operation('_' + name, _lodash2.default[name]);
});
// Retrieve Any Date
_jsonLogicJs2.default.add_operation('getDate', function (date) {
return (0, _moment2.default)(date).toISOString();
});
// Set Relative Minimum Date
_jsonLogicJs2.default.add_operation('relativeMinDate', function (relativeMinDate) {
return (0, _moment2.default)().subtract(relativeMinDate, 'days').toISOString();
});
// Set Relative Maximum Date
_jsonLogicJs2.default.add_operation('relativeMaxDate', function (relativeMaxDate) {
return (0, _moment2.default)().add(relativeMaxDate, 'days').toISOString();
});
exports.jsonLogic = _jsonLogicJs2.default;
/**
* Evaluate a method.
*
* @param func
* @param args
* @return {*}
*/
function evaluate(func, args, ret, tokenize) {
var returnVal = null;
var component = args.component ? args.component : { key: 'unknown' };
if (!args.form && args.instance) {
args.form = _lodash2.default.get(args.instance, 'root._form', {});
}
if (typeof func === 'string') {
if (ret) {
func += ';return ' + ret;
}
var params = _lodash2.default.keys(args);
if (tokenize) {
// Replace all {{ }} references with actual data.
func = func.replace(/({{\s+(.*)\s+}})/, function (match, $1, $2) {
if ($2.indexOf('data.') === 0) {
return _lodash2.default.get(args.data, $2.replace('data.', ''));
} else if ($2.indexOf('row.') === 0) {
return _lodash2.default.get(args.row, $2.replace('row.', ''));
}
// Support legacy...
return _lodash2.default.get(args.data, $2);
});
}
try {
func = new (Function.prototype.bind.apply(Function, [null].concat(_toConsumableArray(params), [func])))();
} catch (err) {
console.warn('An error occured within the custom function for ' + component.key, err);
returnVal = null;
func = false;
}
}
if (typeof func === 'function') {
var values = _lodash2.default.values(args);
try {
returnVal = func.apply(undefined, _toConsumableArray(values));
} catch (err) {
returnVal = null;
console.warn('An error occured within custom function for ' + component.key, err);
}
} else if ((typeof func === 'undefined' ? 'undefined' : _typeof(func)) === 'object') {
try {
returnVal = _jsonLogicJs2.default.apply(func, args);
} catch (err) {
returnVal = null;
console.warn('An error occured within custom function for ' + component.key, err);
}
} else if (func) {
console.warn('Unknown function type for ' + component.key);
}
return returnVal;
}
function getRandomComponentId() {
return 'e' + Math.random().toString(36).substring(7);
}
/**
* Get a property value of an element.
*
* @param style
* @param prop
* @return {number}
*/
function getPropertyValue(style, prop) {
var value = style.getPropertyValue(prop);
value = value ? value.replace(/[^0-9.]/g, '') : '0';
return parseFloat(value);
}
/**
* Get an elements bounding rectagle.
*
* @param element
* @return {{x: string, y: string, width: string, height: string}}
*/
function getElementRect(element) {
var style = window.getComputedStyle(element, null);
return {
x: getPropertyValue(style, 'left'),
y: getPropertyValue(style, 'top'),
width: getPropertyValue(style, 'width'),
height: getPropertyValue(style, 'height')
};
}
/**
* Determines the boolean value of a setting.
*
* @param value
* @return {boolean}
*/
function boolValue(value) {
if (_lodash2.default.isBoolean(value)) {
return value;
} else if (_lodash2.default.isString(value)) {
return value.toLowerCase() === 'true';
} else {
return !!value;
}
}
/**
* Check to see if an ID is a mongoID.
* @param text
* @return {Array|{index: number, input: string}|Boolean|*}
*/
function isMongoId(text) {
return text.toString().match(/^[0-9a-fA-F]{24}$/);
}
/**
* Determine if a component is a layout component or not.
*
* @param {Object} component
* The component to check.
*
* @returns {Boolean}
* Whether or not the component is a layout component.
*/
function isLayoutComponent(component) {
return Boolean(component.columns && Array.isArray(component.columns) || component.rows && Array.isArray(component.rows) || component.components && Array.isArray(component.components));
}
/**
* Iterate through each component within a form.
*
* @param {Object} components
* The components to iterate.
* @param {Function} fn
* The iteration function to invoke for each component.
* @param {Boolean} includeAll
* Whether or not to include layout components.
* @param {String} path
* The current data path of the element. Example: data.user.firstName
* @param {Object} parent
* The parent object.
*/
function eachComponent(components, fn, includeAll, path, parent) {
if (!components) return;
path = path || '';
components.forEach(function (component) {
var hasColumns = component.columns && Array.isArray(component.columns);
var hasRows = component.rows && Array.isArray(component.rows);
var hasComps = component.components && Array.isArray(component.components);
var noRecurse = false;
var newPath = component.key ? path ? path + '.' + component.key : component.key : '';
// Keep track of parent references.
if (parent) {
// Ensure we don't create infinite JSON structures.
component.parent = _lodash2.default.clone(parent);
delete component.parent.components;
delete component.parent.componentMap;
delete component.parent.columns;
delete component.parent.rows;
}
if (includeAll || component.tree || !hasColumns && !hasRows && !hasComps) {
noRecurse = fn(component, newPath);
}
var subPath = function subPath() {
if (component.key && !(['panel', 'table', 'well', 'columns', 'fieldset', 'tabs', 'form'].indexOf(component.type) !== -1) && (['datagrid', 'container', 'editgrid'].indexOf(component.type) !== -1 || component.tree)) {
return newPath;
} else if (component.key && component.type === 'form') {
return newPath + '.data';
}
return path;
};
if (!noRecurse) {
if (hasColumns) {
component.columns.forEach(function (column) {
return eachComponent(column.components, fn, includeAll, subPath(), parent ? component : null);
});
} else if (hasRows) {
component.rows.forEach(function (row) {
if (Array.isArray(row)) {
row.forEach(function (column) {
return eachComponent(column.components, fn, includeAll, subPath(), parent ? component : null);
});
}
});
} else if (hasComps) {
eachComponent(component.components, fn, includeAll, subPath(), parent ? component : null);
}
}
});
}
/**
* Matches if a component matches the query.
*
* @param component
* @param query
* @return {boolean}
*/
function matchComponent(component, query) {
if (_lodash2.default.isString(query)) {
return component.key === query;
} else {
var matches = false;
_lodash2.default.forOwn(query, function (value, key) {
matches = _lodash2.default.get(component, key) === value;
if (!matches) {
return false;
}
});
return matches;
}
}
/**
* Get a component by its key
*
* @param {Object} components
* The components to iterate.
* @param {String|Object} key
* The key of the component to get, or a query of the component to search.
*
* @returns {Object}
* The component that matches the given key, or undefined if not found.
*/
function getComponent(components, key, includeAll) {
var result = void 0;
eachComponent(components, function (component, path) {
if (path === key) {
component.path = path;
result = component;
return true;
}
}, includeAll);
return result;
}
/**
* Finds a component provided a query of properties of that component.
*
* @param components
* @param query
* @return {*}
*/
function findComponents(components, query) {
var results = [];
eachComponent(components, function (component, path) {
if (matchComponent(component, query)) {
component.path = path;
results.push(component);
}
}, true);
return results;
}
/**
* Flatten the form components for data manipulation.
*
* @param {Object} components
* The components to iterate.
* @param {Boolean} includeAll
* Whether or not to include layout components.
*
* @returns {Object}
* The flattened components map.
*/
function flattenComponents(components, includeAll) {
var flattened = {};
eachComponent(components, function (component, path) {
flattened[path] = component;
}, includeAll);
return flattened;
}
/**
* Returns if this component has a conditional statement.
*
* @param component - The component JSON schema.
*
* @returns {boolean} - TRUE - This component has a conditional, FALSE - No conditional provided.
*/
function hasCondition(component) {
return Boolean(component.customConditional || component.conditional && component.conditional.when || component.conditional && component.conditional.json);
}
/**
* Extension of standard #parseFloat(value) function, that also clears input string.
*
* @param {any} value
* The value to parse.
*
* @returns {Number}
* Parsed value.
*/
function parseFloatExt(value) {
return parseFloat(_lodash2.default.isString(value) ? value.replace(/[^\de.+-]/gi, '') : value);
}
/**
* Formats provided value in way how Currency component uses it.
*
* @param {any} value
* The value to format.
*
* @returns {String}
* Value formatted for Currency component.
*/
function formatAsCurrency(value) {
var parsedValue = parseFloatExt(value);
if (_lodash2.default.isNaN(parsedValue)) {
return '';
}
var parts = _lodash2.default.round(parsedValue, 2).toString().split('.');
parts[0] = _lodash2.default.chunk(Array.from(parts[0]).reverse(), 3).reverse().map(function (part) {
return part.reverse().join('');
}).join(',');
parts[1] = _lodash2.default.pad(parts[1], 2, '0');
return parts.join('.');
}
/**
* Escapes RegEx characters in provided String value.
*
* @param {String} value
* String for escaping RegEx characters.
* @returns {string}
* String with escaped RegEx characters.
*/
function escapeRegExCharacters(value) {
return value.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
}
/**
* Checks the calculated value for a provided component and data.
*
* @param {Object} component
* The component to check for the calculated value.
* @param {Object} submission
* A submission object.
* @param data
* The full submission data.
*/
function checkCalculated(component, submission, rowData) {
// Process calculated value stuff if present.
if (component.calculateValue) {
_lodash2.default.set(rowData, component.key, evaluate(component.calculateValue, {
value: undefined,
data: submission ? submission.data : rowData,
row: rowData,
util: this,
component: component
}, 'value'));
}
}
/**
* Check if a simple conditional evaluates to true.
*
* @param condition
* @param condition
* @param row
* @param data
* @returns {boolean}
*/
function checkSimpleConditional(component, condition, row, data) {
var value = null;
if (row) {
value = getValue({ data: row }, condition.when);
}
if (data && _lodash2.default.isNil(value)) {
value = getValue({ data: data }, condition.when);
}
// FOR-400 - Fix issue where falsey values were being evaluated as show=true
if (_lodash2.default.isNil(value)) {
value = '';
}
// Special check for selectboxes component.
if (_lodash2.default.isObject(value) && _lodash2.default.has(value, condition.eq)) {
return value[condition.eq].toString() === condition.show.toString();
}
// FOR-179 - Check for multiple values.
if (Array.isArray(value) && value.indexOf(condition.eq) !== -1) {
return condition.show.toString() === 'true';
}
return value.toString() === condition.eq.toString() === (condition.show.toString() === 'true');
}
/**
* Check custom javascript conditional.
*
* @param component
* @param custom
* @param row
* @param data
* @returns {*}
*/
function checkCustomConditional(component, custom, row, data, form, variable, onError, instance) {
if (typeof custom === 'string') {
custom = 'var ' + variable + ' = true; ' + custom + '; return ' + variable + ';';
}
var value = instance && instance.evaluate ? instance.evaluate(custom) : evaluate(custom, { row: row, data: data, form: form });
if (value === null) {
return onError;
}
return value;
}
function checkJsonConditional(component, json, row, data, form, onError) {
try {
return _jsonLogicJs2.default.apply(json, {
data: data,
row: row,
form: form,
_: _lodash2.default
});
} catch (err) {
console.warn('An error occurred in jsonLogic advanced condition for ' + component.key, err);
return onError;
}
}
/**
* Checks the conditions for a provided component and data.
*
* @param component
* The component to check for the condition.
* @param row
* The data within a row
* @param data
* The full submission data.
*
* @returns {boolean}
*/
function checkCondition(component, row, data, form, instance) {
if (component.customConditional) {
return checkCustomConditional(component, component.customConditional, row, data, form, 'show', true, instance);
} else if (component.conditional && component.conditional.when) {
return checkSimpleConditional(component, component.conditional, row, data, true);
} else if (component.conditional && component.conditional.json) {
return checkJsonConditional(component, component.conditional.json, row, data, form, instance);
}
// Default to show.
return true;
}
/**
* Test a trigger on a component.
*
* @param component
* @param action
* @param data
* @param row
* @returns {mixed}
*/
function checkTrigger(component, trigger, row, data, form, instance) {
switch (trigger.type) {
case 'simple':
return checkSimpleConditional(component, trigger.simple, row, data);
case 'javascript':
return checkCustomConditional(component, trigger.javascript, row, data, form, 'result', false, instance);
case 'json':
return checkJsonConditional(component, trigger.json, row, data, form, false);
}
// If none of the types matched, don't fire the trigger.
return false;
}
function setActionProperty(component, action, row, data, result, instance) {
switch (action.property.type) {
case 'boolean':
if (_lodash2.default.get(component, action.property.value, false).toString() !== action.state.toString()) {
_lodash2.default.set(component, action.property.value, action.state.toString() === 'true');
}
break;
case 'string':
{
var evalData = {
data: data,
row: row,
component: component,
result: result
};
var newValue = instance && instance.interpolate ? instance.interpolate(action.text, evalData) : interpolate(action.text, evalData);
if (newValue !== _lodash2.default.get(component, action.property.value, '')) {
_lodash2.default.set(component, action.property.value, newValue);
}
break;
}
}
return component;
}
/**
* Get the value for a component key, in the given submission.
*
* @param {Object} submission
* A submission object to search.
* @param {String} key
* A for components API key to search for.
*/
function getValue(submission, key) {
var search = function search(data) {
if (_lodash2.default.isPlainObject(data)) {
if (_lodash2.default.has(data, key)) {
return data[key];
}
var value = null;
_lodash2.default.forOwn(data, function (prop) {
var result = search(prop);
if (!_lodash2.default.isNil(result)) {
value = result;
return false;
}
});
return value;
} else {
return null;
}
};
return search(submission.data);
}
/**
* Interpolate a string and add data replacements.
*
* @param string
* @param data
* @returns {XML|string|*|void}
*/
function interpolate(string, data) {
var templateSettings = {
evaluate: /\{%(.+?)%\}/g,
interpolate: /\{\{(.+?)\}\}/g,
escape: /\{\{\{(.+?)\}\}\}/g
};
try {
return _lodash2.default.template(string, templateSettings)(data);
} catch (err) {
console.warn('Error interpolating template', err, string, data);
}
}
/**
* Make a filename guaranteed to be unique.
* @param name
* @returns {string}
*/
function uniqueName(name) {
var parts = name.toLowerCase().replace(/[^0-9a-z.]/g, '').split('.');
var fileName = parts[0];
var ext = parts.length > 1 ? '.' + _lodash2.default.last(parts) : '';
return fileName.substr(0, 10) + '-' + guid() + ext;
}
function guid() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0;
var v = c === 'x' ? r : r & 0x3 | 0x8;
return v.toString(16);
});
}
/**
* Return a translated date setting.
*
* @param date
* @return {*}
*/
function getDateSetting(date) {
if (_lodash2.default.isNil(date) || _lodash2.default.isNaN(date) || date === '') {
return null;
}
if (date instanceof Date) {
return date;
} else if (typeof date.toDate === 'function') {
return date.isValid() ? date.toDate() : null;
}
var dateSetting = typeof date !== 'string' || date.indexOf('moment(') === -1 ? (0, _moment2.default)(date) : null;
if (dateSetting && dateSetting.isValid()) {
return dateSetting.toDate();
}
dateSetting = null;
try {
var value = new Function('moment', 'return ' + date + ';')(_moment2.default);
if (typeof value === 'string') {
dateSetting = (0, _moment2.default)(value);
} else if (typeof value.toDate === 'function') {
dateSetting = (0, _moment2.default)(value.toDate().toUTCString());
} else if (value instanceof Date) {
dateSetting = (0, _moment2.default)(value);
}
} catch (e) {
return null;
}
if (!dateSetting) {
return null;
}
// Ensure this is a date.
if (!dateSetting.isValid()) {
return null;
}
return dateSetting.toDate();
}
function isValidDate(date) {
return _lodash2.default.isDate(date) && !_lodash2.default.isNaN(date.getDate());
}
function getLocaleDateFormatInfo(locale) {
var formatInfo = {};
var day = 21;
var exampleDate = new Date(2017, 11, day);
var localDateString = exampleDate.toLocaleDateString(locale);
formatInfo.dayFirst = localDateString.slice(0, 2) === day.toString();
return formatInfo;
}
/**
* Convert the format from the angular-datepicker module to flatpickr format.
* @param format
* @return {string}
*/
function convertFormatToFlatpickr(format) {
return format
// Year conversion.
.replace(/y/g, 'Y').replace('YYYY', 'Y').replace('YY', 'y')
// Month conversion.
.replace('MMMM', 'F').replace(/M/g, 'n').replace('nnn', 'M').replace('nn', 'm')
// Day in month.
.replace(/d/g, 'j').replace('jj', 'd')
// Day in week.
.replace('EEEE', 'l').replace('EEE', 'D')
// Hours, minutes, seconds
.replace('HH', 'H').replace('hh', 'h').replace('mm', 'i').replace('ss', 'S').replace(/a/g, 'K');
}
/**
* Convert the format from the angular-datepicker module to moment format.
* @param format
* @return {string}
*/
function convertFormatToMoment(format) {
return format
// Year conversion.
.replace(/y/g, 'Y')
// Day in month.
.replace(/d/g, 'D')
// Day in week.
.replace(/E/g, 'd')
// AM/PM marker
.replace(/a/g, 'A');
}
/**
* Returns an input mask that is compatible with the input mask library.
* @param {string} mask - The eForm input mask.
* @returns {Array} - The input mask for the mask library.
*/
function getInputMask(mask) {
if (mask instanceof Array) {
return mask;
}
var maskArray = [];
maskArray.numeric = true;
for (var i = 0; i < mask.length; i++) {
switch (mask[i]) {
case '9':
maskArray.push(/\d/);
break;
case 'A':
maskArray.numeric = false;
maskArray.push(/[a-zA-Z]/);
break;
case 'a':
maskArray.numeric = false;
maskArray.push(/[a-z]/);
break;
case '*':
maskArray.numeric = false;
maskArray.push(/[a-zA-Z0-9]/);
break;
default:
maskArray.push(mask[i]);
break;
}
}
return maskArray;
}
function matchInputMask(value, inputMask) {
if (!inputMask) {
return true;
}
for (var i = 0; i < inputMask.length; i++) {
var char = value[i];
var charPart = inputMask[i];
if (!(_lodash2.default.isRegExp(charPart) && charPart.test(char) || charPart === char)) {
return false;
}
}
return true;
}
function getNumberSeparators() {
var lang = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'en';
var formattedNumberString = 12345.6789.toLocaleString(lang);
var delimeters = formattedNumberString.match(/..(.)...(.)../);
if (!delimeters) {
return {
delimiter: ',',
decimalSeparator: '.'
};
}
return {
delimiter: delimeters.length > 1 ? delimeters[1] : ',',
decimalSeparator: delimeters.length > 2 ? delimeters[2] : '.'
};
}
function getNumberDecimalLimit(component) {
// Determine the decimal limit. Defaults to 20 but can be overridden by validate.step or decimalLimit settings.
var decimalLimit = 20;
var step = _lodash2.default.get(component, 'validate.step', 'any');
if (step !== 'any') {
var parts = step.toString().split('.');
if (parts.length > 1) {
decimalLimit = parts[1].length;
}
}
return decimalLimit;
}
function getCurrencyAffixes(_ref) {
var _ref$currency = _ref.currency,
currency = _ref$currency === undefined ? 'USD' : _ref$currency,
decimalLimit = _ref.decimalLimit,
decimalSeparator = _ref.decimalSeparator,
lang = _ref.lang;
// Get the prefix and suffix from the localized string.
var regex = '(.*)?100';
if (decimalLimit) {
regex += (decimalSeparator === '.' ? '\\.' : decimalSeparator) + '0{' + decimalLimit + '}';
}
regex += '(.*)?';
var parts = 100 .toLocaleString(lang, {
style: 'currency',
currency: currency,
useGrouping: true,
maximumFractionDigits: decimalLimit,
minimumFractionDigits: decimalLimit
}).replace('.', decimalSeparator).match(new RegExp(regex));
return {
prefix: parts[1] || '',
suffix: parts[2] || ''
};
}
/**
* Fetch the field data provided a component.
*
* @param data
* @param component
* @return {*}
*/
function fieldData(data, component) {
if (!data) {
return '';
}
if (!component || !component.key) {
return data;
}
if (component.key.indexOf('.') !== -1) {
var value = data;
var parts = component.key.split('.');
var key = '';
for (var i = 0; i < parts.length; i++) {
key = parts[i];
// Handle nested resources
if (value.hasOwnProperty('_id')) {
value = value.data;
}
// Return if the key is not found on the value.
if (!value.hasOwnProperty(key)) {
return;
}
// Convert old single field data in submissions to multiple
if (key === parts[parts.length - 1] && component.multiple && !Array.isArray(value[key])) {
value[key] = [value[key]];
}
// Set the value of this key.
value = value[key];
}
return value;
} else {
// Convert old single field data in submissions to multiple
if (component.multiple && !Array.isArray(data[component.key])) {
data[component.key] = [data[component.key]];
}
return data[component.key];
}
}
/**
* Delays function execution with possibility to execute function synchronously or cancel it.
*
* @param fn Function to delay
* @param delay Delay time
* @return {*}
*/
function delay(fn) {
for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
args[_key - 2] = arguments[_key];
}
var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
var timer = setTimeout.apply(undefined, [fn, delay].concat(args));
function cancel() {
clearTimeout(timer);
}
function earlyCall() {
cancel();
return fn.apply(undefined, args);
}
earlyCall.timer = timer;
earlyCall.cancel = cancel;
return earlyCall;
}
},{"./jsonlogic/operators":2,"json-logic-js":4,"lodash":209,"moment":228}],4:[function(_dereq_,module,exports){
/* globals define,module */
/*
Using a Universal Module Loader that should be browser, require, and AMD friendly
http://ricostacruz.com/cheatsheets/umdjs.html
*/
;(function(root, factory) {
if (typeof define === "function" && define.amd) {
define(factory);
} else if (typeof exports === "object") {
module.exports = factory();
} else {
root.jsonLogic = factory();
}
}(this, function() {
"use strict";
/* globals console:false */
if ( ! Array.isArray) {
Array.isArray = function(arg) {
return Object.prototype.toString.call(arg) === "[object Array]";
};
}
/**
* Return an array that contains no duplicates (original not modified)
* @param {array} array Original reference array
* @return {array} New array with no duplicates
*/
function arrayUnique(array) {
var a = [];
for (var i=0, l=array.length; i<l; i++) {
if (a.indexOf(array[i]) === -1) {
a.push(array[i]);
}
}
return a;
}
var jsonLogic = {};
var operations = {
"==": function(a, b) {
return a == b;
},
"===": function(a, b) {
return a === b;
},
"!=": function(a, b) {
return a != b;
},
"!==": function(a, b) {
return a !== b;
},
">": function(a, b) {
return a > b;
},
">=": function(a, b) {
return a >= b;
},
"<": function(a, b, c) {
return (c === undefined) ? a < b : (a < b) && (b < c);
},
"<=": function(a, b, c) {
return (c === undefined) ? a <= b : (a <= b) && (b <= c);
},
"!!": function(a) {
return jsonLogic.truthy(a);
},
"!": function(a) {
return !jsonLogic.truthy(a);
},
"%": function(a, b) {
return a % b;
},
"log": function(a) {
console.log(a); return a;
},
"in": function(a, b) {
if(!b || typeof b.indexOf === "undefined") return false;
return (b.indexOf(a) !== -1);
},
"cat": function() {
return Array.prototype.join.call(arguments, "");
},
"substr":function(source, start, end) {
if(end < 0){
// JavaScript doesn't support negative end, this emulates PHP behavior
var temp = String(source).substr(start);
return temp.substr(0, temp.length + end);
}
return String(source).substr(start, end);
},
"+": function() {
return Array.prototype.reduce.call(arguments, function(a, b) {
return parseFloat(a, 10) + parseFloat(b, 10);
}, 0);
},
"*": function() {
return Array.prototype.reduce.call(arguments, function(a, b) {
return parseFloat(a, 10) * parseFloat(b, 10);
});
},
"-": function(a, b) {
if(b === undefined) {
return -a;
}else{
return a - b;
}
},
"/": function(a, b) {
return a / b;
},
"min": function() {
return Math.min.apply(this, arguments);
},
"max": function() {
return Math.max.apply(this, arguments);
},
"merge": function() {
return Array.prototype.reduce.call(arguments, function(a, b) {
return a.concat(b);
}, []);
},
"var": function(a, b) {
var not_found = (b === undefined) ? null : b;
var data = this;
if(typeof a === "undefined" || a==="" || a===null) {
return data;
}
var sub_props = String(a).split(".");
for(var i = 0; i < sub_props.length; i++) {
if(data === null) {
return not_found;
}
// Descending into data
data = data[sub_props[i]];
if(data === undefined) {
return not_found;
}
}
return data;
},
"missing": function() {
/*
Missing can receive many keys as many arguments, like {"missing:[1,2]}
Missing can also receive *one* argument that is an array of keys,
which typically happens if it's actually acting on the output of another command
(like 'if' or 'merge')
*/
var missing = [];
var keys = Array.isArray(arguments[0]) ? arguments[0] : arguments;
for(var i = 0; i < keys.length; i++) {
var key = keys[i];
var value = jsonLogic.apply({"var": key}, this);
if(value === null || value === "") {
missing.push(key);
}
}
return missing;
},
"missing_some": function(need_count, options) {
// missing_some takes two arguments, how many (minimum) items must be present, and an array of keys (just like 'missing') to check for presence.
var are_missing = jsonLogic.apply({"missing": options}, this);
if(options.length - are_missing.length >= need_count) {
return [];
}else{
return are_missing;
}
},
"method": function(obj, method, args) {
return obj[method].apply(obj, args);
},
};
jsonLogic.is_logic = function(logic) {
return (
typeof logic === "object" && // An object
logic !== null && // but not null
! Array.isArray(logic) && // and not an array
Object.keys(logic).length === 1 // with exactly one key
);
};
/*
This helper will defer to the JsonLogic spec as a tie-breaker when different language interpreters define different behavior for the truthiness of primitives. E.g., PHP considers empty arrays to be falsy, but Javascript considers them to be truthy. JsonLogic, as an ecosystem, needs one consistent answer.
Spec and rationale here: http://jsonlogic.com/truthy
*/
jsonLogic.truthy = function(value) {
if(Array.isArray(value) && value.length === 0) {
return false;
}
return !! value;
};
jsonLogic.get_operator = function(logic) {
return Object.keys(logic)[0];
};
jsonLogic.get_values = function(logic) {
return logic[jsonLogic.get_operator(logic)];
};
jsonLogic.apply = function(logic, data) {
// Does this array contain logic? Only one way to find out.
if(Array.isArray(logic)) {
return logic.map(function(l) {
return jsonLogic.apply(l, data);
});
}
// You've recursed to a primitive, stop!
if( ! jsonLogic.is_logic(logic) ) {
return logic;
}
data = data || {};
var op = jsonLogic.get_operator(logic);
var values = logic[op];
var i;
var current;
var scopedLogic, scopedData, filtered, initial;
// easy syntax for unary operators, like {"var" : "x"} instead of strict {"var" : ["x"]}
if( ! Array.isArray(values)) {
values = [values];
}
// 'if', 'and', and 'or' violate the normal rule of depth-first calculating consequents, let each manage recursion as needed.
if(op === "if" || op == "?:") {
/* 'if' should be called with a odd number of parameters, 3 or greater
This works on the pattern:
if( 0 ){ 1 }else{ 2 };
if( 0 ){ 1 }else if( 2 ){ 3 }else{ 4 };
if( 0 ){ 1 }else if( 2 ){ 3 }else if( 4 ){ 5 }else{ 6 };
The implementation is:
For pairs of values (0,1 then 2,3 then 4,5 etc)
If the first evaluates truthy, evaluate and return the second
If the first evaluates falsy, jump to the next pair (e.g, 0,1 to 2,3)
given one parameter, evaluate and return it. (it's an Else and all the If/ElseIf were false)
given 0 parameters, return NULL (not great practice, but there was no Else)
*/
for(i = 0; i < values.length - 1; i += 2) {
if( jsonLogic.truthy( jsonLogic.apply(values[i], data) ) ) {
return jsonLogic.apply(values[i+1], data);
}
}
if(values.length === i+1) return jsonLogic.apply(values[i], data);
return null;
}else if(op === "and") { // Return first falsy, or last
for(i=0; i < values.length; i+=1) {
current = jsonLogic.apply(values[i], data);
if( ! jsonLogic.truthy(current)) {
return current;
}
}
return current; // Last
}else if(op === "or") {// Return first truthy, or last
for(i=0; i < values.length; i+=1) {
current = jsonLogic.apply(values[i], data);
if( jsonLogic.truthy(current) ) {
return current;
}
}
return current; // Last
}else if(op === 'filter'){
scopedData = jsonLogic.apply(values[0], data);
scopedLogic = values[1];
if ( ! Array.isArray(scopedData)) {
return [];
}
// Return only the elements from the array in the first argument,
// that return truthy when passed to the logic in the second argument.
// For parity with JavaScript, reindex the returned array
return scopedData.filter(function(datum){
return jsonLogic.truthy( jsonLogic.apply(scopedLogic, datum));
});
}else if(op === 'map'){
scopedData = jsonLogic.apply(values[0], data);
scopedLogic = values[1];
if ( ! Array.isArray(scopedData)) {
return [];
}
return scopedData.map(function(datum){
return jsonLogic.apply(scopedLogic, datum);
});
}else if(op === 'reduce'){
scopedData = jsonLogic.apply(values[0], data);
scopedLogic = values[1];
initial = typeof values[2] !== 'undefined' ? values[2] : null;
if ( ! Array.isArray(scopedData)) {
return initial;
}
return scopedData.reduce(
function(accumulator, current){
return jsonLogic.apply(
scopedLogic,
{'current':current, 'accumulator':accumulator}
);
},
initial
);
}else if(op === "all") {
scopedData = jsonLogic.apply(values[0], data);
scopedLogic = values[1];
// All of an empty set is false. Note, some and none have correct fallback after the for loop
if( ! scopedData.length) {
return false;
}
for(i=0; i < scopedData.length; i+=1) {
if( ! jsonLogic.truthy( jsonLogic.apply(scopedLogic, scopedData[i]) )) {
return false; // First falsy, short circuit
}
}
return true; // All were truthy
}else if(op === "none") {
filtered = jsonLogic.apply({'filter' : values}, data);
return filtered.length === 0;
}else if(op === "some") {
filtered = jsonLogic.apply({'filter' : values}, data);
return filtered.length > 0;
}
// Everyone else gets immediate depth-first recursion
values = values.map(function(val) {
return jsonLogic.apply(val, data);
});
// The operation is called with "data" bound to its "this" and "values" passed as arguments.
// Structured commands like % or > can name formal arguments while flexible commands (like missing or merge) can operate on the pseudo-array arguments
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
if(typeof operations[op] === "function") {
return operations[op].apply(data, values);
}else if(op.indexOf(".") > 0) { // Contains a dot, and not in the 0th position
var sub_ops = String(op).split(".");
var operation = operations;
for(i = 0; i < sub_ops.length; i++) {
// Descending into operations
operation = operation[sub_ops[i]];
if(operation === undefined) {
throw new Error("Unrecognized operation " + op +
" (failed at " + sub_ops.slice(0, i+1).join(".") + ")");
}
}
return operation.apply(data, values);
}
throw new Error("Unrecognized operation " + op );
};
jsonLogic.uses_data = function(logic) {
var collection = [];
if( jsonLogic.is_logic(logic) ) {
var op = jsonLogic.get_operator(logic);
var values = logic[op];
if( ! Array.isArray(values)) {
values = [values];
}
if(op === "var") {
// This doesn't cover the case where the arg to var is itself a rule.
collection.push(values[0]);
}else{
// Recursion!
values.map(function(val) {
collection.push.apply(collection, jsonLogic.uses_data(val) );
});
}
}
return arrayUnique(collection);
};
jsonLogic.add_operation = function(name, code) {
operations[name] = code;
};
jsonLogic.rm_operation = function(name) {
delete operations[name];
};
jsonLogic.rule_like = function(rule, pattern) {
// console.log("Is ". JSON.stringify(rule) . " like " . JSON.stringify(pattern) . "?");
if(pattern === rule) {
return true;
} // TODO : Deep object equivalency?
if(pattern === "@") {
return true;
} // Wildcard!
if(pattern === "number") {
return (typeof rule === "number");
}
if(pattern === "string") {
return (typeof rule === "string");
}
if(pattern === "array") {
// !logic test might be superfluous in JavaScript
return Array.isArray(rule) && ! jsonLogic.is_logic(rule);
}
if(jsonLogic.is_logic(pattern)) {
if(jsonLogic.is_logic(rule)) {
var pattern_op = jsonLogic.get_operator(pattern);
var rule_op = jsonLogic.get_operator(rule);
if(pattern_op === "@" || pattern_op === rule_op) {
// echo "\nOperators match, go deeper\n";
return jsonLogic.rule_like(
jsonLogic.get_values(rule, false),
jsonLogic.get_values(pattern, false)
);
}
}
return false; // pattern is logic, rule isn't, can't be eq
}
if(Array.isArray(pattern)) {
if(Array.isArray(rule)) {
if(pattern.length !== rule.length) {
return false;
}
/*
Note, array order MATTERS, because we're using this array test logic to consider arguments, where order can matter. (e.g., + is commutative, but '-' or 'if' or 'var' are NOT)
*/
for(var i = 0; i < pattern.length; i += 1) {
// If any fail, we fail
if( ! jsonLogic.rule_like(rule[i], pattern[i])) {
return false;
}
}
return true; // If they *all* passed, we pass
}else{
return false; // Pattern is array, rule isn't
}
}
// Not logic, not array, not a === match for rule.
return false;
};
return jsonLogic;
}));
},{}],5:[function(_dereq_,module,exports){
var getNative = _dereq_('./_getNative'),
root = _dereq_('./_root');
/* Built-in method references that are verified to be native. */
var DataView = getNative(root, 'DataView');
module.exports = DataView;
},{"./_getNative":112,"./_root":158}],6:[function(_dereq_,module,exports){
var hashClear = _dereq_('./_hashClear'),
hashDelete = _dereq_('./_hashDelete'),
hashGet = _dereq_('./_hashGet'),
hashHas = _dereq_('./_hashHas'),
hashSet = _dereq_('./_hashSet');
/**
* Creates a hash object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function Hash(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `Hash`.
Hash.prototype.clear = hashClear;
Hash.prototype['delete'] = hashDelete;
Hash.prototype.get = hashGet;
Hash.prototype.has = hashHas;
Hash.prototype.set = hashSet;
module.exports = Hash;
},{"./_hashClear":122,"./_hashDelete":123,"./_hashGet":124,"./_hashHas":125,"./_hashSet":126}],7:[function(_dereq_,module,exports){
var listCacheClear = _dereq_('./_listCacheClear'),
listCacheDelete = _dereq_('./_listCacheDelete'),
listCacheGet = _dereq_('./_listCacheGet'),
listCacheHas = _dereq_('./_listCacheHas'),
listCacheSet = _dereq_('./_listCacheSet');
/**
* Creates an list cache object.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function ListCache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `ListCache`.
ListCache.prototype.clear = listCacheClear;
ListCache.prototype['delete'] = listCacheDelete;
ListCache.prototype.get = listCacheGet;
ListCache.prototype.has = listCacheHas;
ListCache.prototype.set = listCacheSet;
module.exports = ListCache;
},{"./_listCacheClear":138,"./_listCacheDelete":139,"./_listCacheGet":140,"./_listCacheHas":141,"./_listCacheSet":142}],8:[function(_dereq_,module,exports){
var getNative = _dereq_('./_getNative'),
root = _dereq_('./_root');
/* Built-in method references that are verified to be native. */
var Map = getNative(root, 'Map');
module.exports = Map;
},{"./_getNative":112,"./_root":158}],9:[function(_dereq_,module,exports){
var mapCacheClear = _dereq_('./_mapCacheClear'),
mapCacheDelete = _dereq_('./_mapCacheDelete'),
mapCacheGet = _dereq_('./_mapCacheGet'),
mapCacheHas = _dereq_('./_mapCacheHas'),
mapCacheSet = _dereq_('./_mapCacheSet');
/**
* Creates a map cache object to store key-value pairs.
*
* @private
* @constructor
* @param {Array} [entries] The key-value pairs to cache.
*/
function MapCache(entries) {
var index = -1,
length = entries == null ? 0 : entries.length;
this.clear();
while (++index < length) {
var entry = entries[index];
this.set(entry[0], entry[1]);
}
}
// Add methods to `MapCache`.
MapCache.prototype.clear = mapCacheClear;
MapCache.prototype['delete'] = mapCacheDelete;
M