filter-tree
Advanced tools
Comparing version 0.3.25 to 0.3.26
@@ -303,7 +303,5 @@ /** @module conditionals */ | ||
/** Default operator menu when consisting of all of the groups in {@link module:conditionals.groups|groups}. This menu is used when none of the following is otherwise defined: | ||
* * The `opMenu` property of the column.* | ||
* * The entry in the node's `typeOpMenu` hash corresponding to the `type` property of the column.* | ||
* * The `opMenu` property of the column schema. | ||
* * The entry in the node's `typeOpMap` hash corresponding to the `type` property of the column schema. | ||
* * The node's `treeOpMenu` object. | ||
* | ||
* \* The phrase _of the column_ as used here means in the element of the node's `schema` array named for the currently selected column. | ||
* @type {menuItem[]} | ||
@@ -310,0 +308,0 @@ * @memberOf Conditionals |
@@ -7,3 +7,4 @@ 'use strict'; | ||
/** | ||
* Similar to {@link FilterLeaf} except: | ||
* @summary Prototype additions object for extending {@link FilterLeaf}. | ||
* @desc Resulting object is similar to {@link FilterLeaf} except: | ||
* 1. The `operand` property names another column rather than contains a literal. | ||
@@ -35,3 +36,3 @@ * 2. Operators are limited to equality, inequalities, and sets (IN/NOT IN). Omitted are the string and pattern scans (BEGINS/NOT BEGINS, ENDS/NOT ENDS, CONTAINS/NOT CONTAINS, and LIKE/NOT LIKE). | ||
treeOpMenu: [ | ||
opMenu: [ | ||
Conditionals.groups.equality, | ||
@@ -38,0 +39,0 @@ Conditionals.groups.inequalities, |
@@ -37,3 +37,3 @@ /* eslint-env browser */ | ||
* | ||
* @property operator - A drop-down with options from {@link columnOpMenu}, {@link typeOpMenu}, or {@link treeOpMenu}. Value is the string representation of the operator. | ||
* @property operator - A drop-down with options from {@link columnOpMenu}, {@link typeOpMap}, or {@link treeOpMenu}. Value is the string representation of the operator. | ||
* | ||
@@ -92,3 +92,3 @@ * @property operand - An input element, such as a drop-down or a text box. | ||
*/ | ||
createView: function() { | ||
createView: function(state) { | ||
var el = this.el = document.createElement('span'); | ||
@@ -98,3 +98,3 @@ | ||
if (this.state.column) { | ||
if (state && state.column) { | ||
// State includes column: | ||
@@ -105,6 +105,6 @@ // Operator menu is built later in loadState; we don't need to build it now. The call to | ||
// When state does NOT include column, it's because either: | ||
// a. column is unknown and no op menu will be empty until user chooses a column; or | ||
// a. column is unknown and op menu will be empty until user chooses a column; or | ||
// b. column is hard-coded when there's only one possible column as inferable from schema: | ||
var schema = this.schema && this.schema.length === 1 && this.schema[0], | ||
columnName = schema && (schema.name || schema); | ||
columnName = schema && schema.name || schema; | ||
} | ||
@@ -121,5 +121,3 @@ | ||
loadState: function() { | ||
var state = this.state; | ||
loadState: function(state) { | ||
if (state) { | ||
@@ -194,3 +192,4 @@ var value, el, i, b, selected, notes = []; | ||
* | ||
* @param {boolean} [options.focus=true] - Move focus to offending control. | ||
* @param {boolean} [options.throw=false] - Throw an error if missing or invalid value. | ||
* @param {boolean} [options.focus=false] - Move focus to offending control. | ||
* @returns {undefined} This is the normal return when valid; otherwise throws error when invalid. | ||
@@ -207,4 +206,8 @@ * @memberOf FilterLeaf.prototype | ||
if (value === '') { | ||
if (options && options.focus) { clickIn(el); } | ||
throw new this.Error('Blank ' + elementName + ' control.\nComplete the filter or delete it.', this); | ||
if (options && options.focus) { | ||
clickIn(el); | ||
} | ||
if (options && options.throw) { | ||
throw new this.Error('Missing or invalid ' + elementName + ' in conditional expression. Complete the expression or remove it.', this); | ||
} | ||
} else { | ||
@@ -311,2 +314,3 @@ // Copy each controls's value as a new similarly named property of this object. | ||
* @param {null|string} [prompt=''] - Adds an initial `<option>...</option>` element to the drop-down with this value, parenthesized, as its `text`; and empty string as its `value`. Omitting creates a blank prompt; `null` suppresses. | ||
* @param [sort] | ||
* @memberOf FilterLeaf.prototype | ||
@@ -416,5 +420,5 @@ */ | ||
|| | ||
this.typeOpMenu && this.typeOpMenu[column.type || this.type] | ||
this.typeOpMap && this.typeOpMap[column.type || this.type] | ||
|| | ||
this.treeOpMenu | ||
this.opMenu | ||
); | ||
@@ -421,0 +425,0 @@ } |
@@ -118,3 +118,3 @@ /* eslint-env browser */ | ||
* | ||
* @property {object} [typeOpMenu] - A hash of type names. Each member thus defined contains a specific operator menu for all descendant leaf nodes that: | ||
* @property {object} [typeOpMap] - A hash of type names. Each member thus defined contains a specific operator menu for all descendant leaf nodes that: | ||
* 1. do not have their own operator menu (`opMenu` property) of their own; and | ||
@@ -155,78 +155,38 @@ * 2. whose columns resolve to that type. | ||
* | ||
* @param {FilterTreeStateObject|FilterTreeOptionsObject} [optionsOrState] - The node state; or an options object possibly containing `state` among other options. Although you can instantiate a filter without specifying state or options, this is generally not useful. See *Instantiating a filter* in the {@link http://joneit.github.io/filter-tree/index.html|readme} for a practical discussion of minimum options. | ||
* @param {FilterTreeOptionsObject} [options] - The node state; or an options object possibly containing `state` among other options. Although you can instantiate a filter without any options, this is generally not useful. See *Instantiating a filter* in the {@link http://joneit.github.io/filter-tree/index.html|readme} for a practical discussion of minimum options. | ||
* | ||
* * @memberOf FilterNode.prototype | ||
*/ | ||
initialize: function(optionsOrState) { | ||
var self = this, | ||
isObject = typeof optionsOrState === 'object', | ||
isOptions = isObject && !optionsOrState.children, | ||
options = isOptions && optionsOrState || {}, | ||
state = isOptions && options.state || // options object with state property | ||
(!isObject || optionsOrState.children) && optionsOrState, // state string or object | ||
parent = this.parent = options.parent, | ||
root = this.root = parent && parent.root || this, | ||
findOptions = root.findOptions = root.findOptions || {}, | ||
dontPersist = this.dontPersist = {}; // hash of truthy values | ||
initialize: function(options) { | ||
options = options || {}; | ||
if (state) { | ||
this.state = this.parseStateString(state, options); | ||
} | ||
var parent = this.parent = this.parent || options.parent, | ||
root = parent && parent.root; | ||
root.stylesheet = root.stylesheet || | ||
cssInjector(options.cssStylesheetReferenceElement); | ||
if (!root) { | ||
root = this; | ||
// Create each standard option from when found on the `options` or `state` objects, respectively; or if not an "own" option, on the `parent` object or from the options schema default (if any) | ||
_(FilterNode.optionsSchema).each(function(optionSchema, key) { | ||
if (!self.hasOwnProperty(key) && !optionSchema.ignore) { | ||
var option; | ||
this.stylesheet = this.stylesheet || | ||
cssInjector(options.cssStylesheetReferenceElement); | ||
dontPersist[key] = // truthy if from `options` or `default` | ||
(option = options[key]) || | ||
!(option = state && state[key]) && | ||
!optionSchema.own && | ||
!(option = parent && parent[key]) && | ||
(option = optionSchema.default); | ||
this.conditionals = new Conditionals(options); // .sqlIdQts | ||
if (option) { | ||
if (key === 'schema') { | ||
// attach the `walk` and `find` convenience methods to the `schema` array | ||
option.walk = popMenu.walk.bind(option); | ||
option.lookup = popMenu.lookup.bind(option, findOptions); | ||
} | ||
self[key] = option; | ||
} | ||
} | ||
}); | ||
this.ParserSQL = new ParserSQL(options); // .schema, .caseSensitiveColumnNames, .resolveAliases | ||
// copy all remaining options directly to the new instance, overriding prototype members of the same name | ||
_(options).each(function(value, key) { | ||
if (!FilterNode.optionsSchema[key]) { | ||
self[key] = value; | ||
var keys = ['name']; | ||
if (options.resolveAliases) { | ||
keys.push('alias'); | ||
} | ||
}); | ||
if (this === root) { | ||
var sqlOptions = {}; | ||
this.findOptions = { | ||
caseSensitive: options.caseSensitiveColumnNames, | ||
keys: keys | ||
}; | ||
} | ||
if (this.sqlIdQts) { | ||
sqlOptions.sqlIdQts = this.sqlIdQts; | ||
} | ||
this.root = root; | ||
this.conditionals = new Conditionals(sqlOptions); | ||
this.dontPersist = {}; // hash of truthy values | ||
sqlOptions.schema = this.schema; | ||
sqlOptions.caseSensitiveColumnNames = this.caseSensitiveColumnNames; | ||
sqlOptions.resolveAliases = this.resolveAliases; | ||
this.ParserSQL = new ParserSQL(sqlOptions); | ||
findOptions.caseSensitive = this.caseSensitiveColumnNames; | ||
findOptions.keys = ['name']; | ||
if (this.resolveAliases) { | ||
findOptions.keys.push('alias'); | ||
} | ||
} | ||
this.setState(state, options); | ||
this.setState(options.state, options); | ||
}, | ||
@@ -246,3 +206,3 @@ | ||
if (!(this.state && this.state.locked)) { | ||
if (!this.keep) { | ||
var el = this.templates.get('removeButton'); | ||
@@ -267,6 +227,11 @@ el.addEventListener('click', this.remove.bind(this)); | ||
var oldEl = this.el; | ||
this.state = this.parseStateString(state, options); | ||
this.createView(); | ||
this.loadState(); | ||
state = this.parseStateString(state, options); | ||
this.mixInStandardOptions(state, options); | ||
this.mixInNonstandardOptions(options); | ||
this.createView(state); | ||
this.loadState(state); | ||
this.render(); | ||
if (oldEl) { | ||
@@ -340,2 +305,50 @@ var newEl = this.el; | ||
/** | ||
* Create each standard option from when found on the `options` or `state` objects, respectively; or if not an "own" option, on the `parent` object or from the options schema default (if any) | ||
* @param state | ||
* @param options | ||
*/ | ||
mixInStandardOptions: function(state, options) { | ||
var node = this; | ||
_(FilterNode.optionsSchema).each(function(optionSchema, key) { | ||
if (!optionSchema.ignore && (this !== this.root || optionSchema.rootBound)) { | ||
var option; | ||
node.dontPersist[key] = // truthy if from `options` or `default` | ||
(option = options[key]) !== undefined || | ||
(option = state && state[key]) === undefined && | ||
!(optionSchema.own || node.hasOwnProperty(key) && option !== null) && | ||
!(option = node.parent && node.parent[key]) && | ||
(option = optionSchema.default); | ||
if (option === null) { | ||
delete node[key]; | ||
node.dontPersist[key] = false; | ||
} else if (option) { | ||
if (key === 'schema' && !option.walk) { | ||
// attach the `walk` and `find` convenience methods to the `schema` array | ||
option.walk = popMenu.walk.bind(option); | ||
option.lookup = popMenu.lookup.bind(option, node.root.findOptions); | ||
} | ||
node[key] = option; | ||
} | ||
} | ||
}); | ||
}, | ||
/** | ||
* @param options | ||
*/ | ||
mixInNonstandardOptions: function(options) { | ||
var node = this; | ||
// copy all remaining options directly to the new instance, overriding prototype members of the same name | ||
_(options).each(function(value, key) { | ||
if (!FilterNode.optionsSchema[key]) { | ||
node[key] = value; | ||
} | ||
}); | ||
}, | ||
/** Remove both: | ||
@@ -378,2 +391,11 @@ * * `this` filter node from it's `parent`'s `children` collection; and | ||
/** @typedef optionsSchemaObject | ||
* @summary Standard option schema | ||
* @desc Standard options are automatically added to nodes. Data sources for standard options include `options`, `state`, `parent` and `default` (in that order). Describes standard options through various properties: | ||
* @property {boolean} [ignore] - Do not automatically add to nodes (processed elsewhere). | ||
* @property {boolean} [own] - Do not automatically add from `parent` or `default`. | ||
* @property {boolean} [rootBound] - Automatically add to root node only. | ||
* @property {*} [default] - This is the default data source when all other strategies fail. | ||
*/ | ||
/** | ||
@@ -387,2 +409,4 @@ * @summary Defines the standard options available to a node. | ||
state: { ignore: true }, | ||
cssStylesheetReferenceElement: { ignore: true }, | ||
@@ -427,6 +451,10 @@ | ||
*/ | ||
treeOpMenu: { default: Conditionals.defaultOpMenu }, | ||
opMenu: { default: Conditionals.defaultOpMenu }, | ||
typeOpMenu: {}, | ||
typeOpMap: { rootBound: true }, | ||
/** @summary Truthy will sort the column menus. | ||
* @type {boolean} | ||
* @memberOf FilterNode.optionsSchema | ||
*/ | ||
sortColumnMenu: {} | ||
@@ -433,0 +461,0 @@ }; |
@@ -147,5 +147,3 @@ /* eslint-env browser */ | ||
*/ | ||
loadState: function() { | ||
var state = this.state; | ||
loadState: function(state) { | ||
this.operator = 'op-and'; | ||
@@ -272,4 +270,4 @@ this.children = []; | ||
// Throw when requested OR when unexpected (not a filter tree error) | ||
if (options.throw || !(err instanceof this.Error)) { | ||
// Throw when unexpected (not a filter tree error) | ||
if (!(err instanceof this.Error)) { | ||
throw err; | ||
@@ -279,4 +277,10 @@ } | ||
if (result && options.alert) { | ||
window.alert(result.message || result); // eslint-disable-line no-alert | ||
// Alter and/or throw when requested | ||
if (result) { | ||
if (options.alert) { | ||
window.alert(result.message || result); // eslint-disable-line no-alert | ||
} | ||
if (options.throw) { | ||
throw result; | ||
} | ||
} | ||
@@ -421,7 +425,7 @@ | ||
_(FilterNode.optionsSchema).each(function(item, key) { | ||
_(FilterNode.optionsSchema).each(function(optionSchema, key) { | ||
if ( | ||
self[key] && // there is a standard option on the node which may need to be output | ||
!self.dontPersist[key] && ( | ||
item.own || // output because it's an "own" option (belongs to the node) | ||
optionSchema.own || // output because it's an "own" option (belongs to the node) | ||
!self.parent || // output because it's the root node | ||
@@ -428,0 +432,0 @@ self[key] !== self.parent[key] // output because it differs from its parent's version |
{ | ||
"name": "filter-tree", | ||
"version": "0.3.25", | ||
"version": "0.3.26", | ||
"description": "Complex table filter expressions with GUI editor.", | ||
@@ -5,0 +5,0 @@ "repository": { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
104009
2104