From 845017c85bf73125a1dea5f657099fdb139cb63e Mon Sep 17 00:00:00 2001 From: mistic100 Date: Mon, 17 Apr 2017 10:30:21 +0200 Subject: [PATCH 1/5] Fix #469 [sql-support] add boolean_as_integer global option --- src/core.js | 33 --------------- src/plugins.js | 62 +++++++++++++++++++++++++++++ src/plugins/sql-support/plugin.js | 10 ++++- tests/plugins.sql-support.module.js | 38 ++++++++++++++++++ 4 files changed, 109 insertions(+), 34 deletions(-) diff --git a/src/core.js b/src/core.js index d9f1a85a..b3e2d2ec 100644 --- a/src/core.js +++ b/src/core.js @@ -1,36 +1,3 @@ -/** - * Initializes plugins for an instance - * @throws ConfigError - * @private - */ -QueryBuilder.prototype.initPlugins = function() { - if (!this.plugins) { - return; - } - - if ($.isArray(this.plugins)) { - var tmp = {}; - this.plugins.forEach(function(plugin) { - tmp[plugin] = null; - }); - this.plugins = tmp; - } - - Object.keys(this.plugins).forEach(function(plugin) { - if (plugin in QueryBuilder.plugins) { - this.plugins[plugin] = $.extend(true, {}, - QueryBuilder.plugins[plugin].def, - this.plugins[plugin] || {} - ); - - QueryBuilder.plugins[plugin].fct.call(this, this.plugins[plugin]); - } - else { - Utils.error('Config', 'Unable to find plugin "{0}"', plugin); - } - }, this); -}; - /** * Checks the configuration of each filter * @param {QueryBuilder.Filter[]} filters diff --git a/src/plugins.js b/src/plugins.js index 35108e3e..036f9cc4 100644 --- a/src/plugins.js +++ b/src/plugins.js @@ -50,3 +50,65 @@ QueryBuilder.define = function(name, fct, def) { QueryBuilder.extend = function(methods) { $.extend(QueryBuilder.prototype, methods); }; + +/** + * Initializes plugins for an instance + * @throws ConfigError + * @private + */ +QueryBuilder.prototype.initPlugins = function() { + if (!this.plugins) { + return; + } + + if ($.isArray(this.plugins)) { + var tmp = {}; + this.plugins.forEach(function(plugin) { + tmp[plugin] = null; + }); + this.plugins = tmp; + } + + Object.keys(this.plugins).forEach(function(plugin) { + if (plugin in QueryBuilder.plugins) { + this.plugins[plugin] = $.extend(true, {}, + QueryBuilder.plugins[plugin].def, + this.plugins[plugin] || {} + ); + + QueryBuilder.plugins[plugin].fct.call(this, this.plugins[plugin]); + } + else { + Utils.error('Config', 'Unable to find plugin "{0}"', plugin); + } + }, this); +}; + +/** + * Returns the config of a plugin, if the plugin is not loaded, returns the default config. + * @param {string} name + * @param {string} [property] + * @throws ConfigError + * @returns {*} + */ +QueryBuilder.prototype.getPluginOptions = function(name, property) { + var plugin; + if (this.plugins && this.plugins[name]) { + plugin = this.plugins[name]; + } + else if (QueryBuilder.plugins[name]) { + plugin = QueryBuilder.plugins[name].def; + } + + if (plugin) { + if (property) { + return plugin[property]; + } + else { + return plugin; + } + } + else { + Utils.error('Config', 'Unable to find plugin "{0}"', name); + } +}; diff --git a/src/plugins/sql-support/plugin.js b/src/plugins/sql-support/plugin.js index e3676825..6abc101a 100644 --- a/src/plugins/sql-support/plugin.js +++ b/src/plugins/sql-support/plugin.js @@ -2,7 +2,14 @@ * @class SqlSupport * @memberof module:plugins * @description Allows to export rules as a SQL WHERE statement as well as populating the builder from an SQL query. + * @param {object} [options] + * @param {boolean} [options.boolean_as_integer=true] - `true` to convert boolean values to integer in the SQL output */ +QueryBuilder.define('sql-support', function(options) { + +}, { + boolean_as_integer: true +}); QueryBuilder.defaults({ // operators for internal -> SQL conversion @@ -242,6 +249,7 @@ QueryBuilder.extend(/** @lends module:plugins.SqlSupport.prototype */ { getSQL: function(stmt, nl, data) { data = (data === undefined) ? this.getRules() : data; nl = !!nl ? '\n' : ' '; + var boolean_as_integer = this.getPluginOptions('sql-support', 'boolean_as_integer'); if (stmt === true) stmt = 'question_mark'; if (typeof stmt == 'string') { @@ -289,7 +297,7 @@ QueryBuilder.extend(/** @lends module:plugins.SqlSupport.prototype */ { } if (rule.type == 'integer' || rule.type == 'double' || rule.type == 'boolean') { - v = Utils.changeType(v, rule.type, true); + v = Utils.changeType(v, rule.type, boolean_as_integer); } else if (!stmt) { v = Utils.escapeString(v); diff --git a/tests/plugins.sql-support.module.js b/tests/plugins.sql-support.module.js index a64ecf4a..7d2da34e 100644 --- a/tests/plugins.sql-support.module.js +++ b/tests/plugins.sql-support.module.js @@ -307,6 +307,44 @@ $(function() { ); }); + QUnit.test('Cast booleans', function(assert) { + $b.queryBuilder({ + plugins: { + 'sql-support': { + boolean_as_integer: true + } + }, + filters: [ + { + id: 'done', + type: 'boolean' + } + ], + rules: [ + { + id: 'done', + operator: 'equal', + value: true + } + ] + }); + + assert.rulesMatch( + $b.queryBuilder('getSQL'), + 'done = 1', + 'Should convert boolean value to integer' + ); + + // don't do that in real life ! + $b[0].queryBuilder.plugins['sql-support'].boolean_as_integer = false; + + assert.rulesMatch( + $b.queryBuilder('getSQL'), + 'done = true', + 'Should not convert boolean value to integer' + ); + }); + var basic_rules_sql_raw = { sql: 'price < 10.25 AND name IS NULL AND ( category IN(\'mo\', \'mu\') OR id != \'1234-azer-5678\' ) ' From 3924938b16703a4cd83c4735804e3dc9fecce3ed Mon Sep 17 00:00:00 2001 From: mistic100 Date: Mon, 24 Apr 2017 19:07:01 +0200 Subject: [PATCH 2/5] Switch CDN to unpkg --- .github/ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index a9007708..931f097a 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -3,4 +3,4 @@ - Please search in the [documentation](http://querybuilder.js.org) before asking. - Any issue without enough details won't get any answer and will be closed. - Help requests must be exhaustive, precise and come with some code explaining the need (use Markdown code highlight). -- Bug reports must come with a simple test case, preferably on jsFiddle, Plunker, etc. (QueryBuilder is available on [jsDelivr](https://www.jsdelivr.com/projects/jquery.query-builder) to be used on such platforms). +- Bug reports must come with a simple test case, preferably on jsFiddle, Plunker, etc. (QueryBuilder is available on [unpkg](https://unpkg.com/jQuery-QueryBuilder/dist/) to be used on such platforms). From ed5f6b4670a4e90ffab1de0ba51caa36095c3800 Mon Sep 17 00:00:00 2001 From: mistic100 Date: Mon, 8 May 2017 21:34:31 +0200 Subject: [PATCH 3/5] Close #486 move `defineModelProperties` to Utils --- Gruntfile.js | 2 +- examples/index.html | 2 +- src/model.js | 44 +++------------------------------ src/plugins/not-group/plugin.js | 2 +- src/utils.js | 38 ++++++++++++++++++++++++++++ tests/index.html | 2 +- 6 files changed, 45 insertions(+), 45 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index bdb40cc2..cfb31c00 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -22,8 +22,8 @@ module.exports = function(grunt) { 'src/public.js', 'src/data.js', 'src/template.js', - 'src/model.js', 'src/utils.js', + 'src/model.js', 'src/jquery.js' ], js_files_for_standalone: [ diff --git a/examples/index.html b/examples/index.html index ff6592b0..369c9eda 100644 --- a/examples/index.html +++ b/examples/index.html @@ -133,8 +133,8 @@

Output

- + diff --git a/src/model.js b/src/model.js index af13aac7..a397c98f 100644 --- a/src/model.js +++ b/src/model.js @@ -64,44 +64,6 @@ $.extend(Model.prototype, /** @lends Model.prototype */ { } }); -/** - * Defines properties on an Node prototype with getter and setter.
- * Update events are emitted in the setter through root Model (if any).
- * The object must have a `__` object, non enumerable property to store values. - * @param {function} obj - * @param {string[]} fields - */ -Model.defineModelProperties = function(obj, fields) { - fields.forEach(function(field) { - Object.defineProperty(obj.prototype, field, { - enumerable: true, - get: function() { - return this.__[field]; - }, - set: function(value) { - var previousValue = (this.__[field] !== null && typeof this.__[field] == 'object') ? - $.extend({}, this.__[field]) : - this.__[field]; - - this.__[field] = value; - - if (this.model !== null) { - /** - * After a value of the model changed - * @event model:update - * @memberof Model - * @param {Node} node - * @param {string} field - * @param {*} value - * @param {*} previousValue - */ - this.model.trigger('update', this, field, value, previousValue); - } - } - }); - }); -}; - /** * Root abstract object @@ -177,7 +139,7 @@ var Node = function(parent, $el) { this.parent = parent; }; -Model.defineModelProperties(Node, ['level', 'error', 'data', 'flags']); +Utils.defineModelProperties(Node, ['level', 'error', 'data', 'flags']); Object.defineProperty(Node.prototype, 'parent', { enumerable: true, @@ -340,7 +302,7 @@ var Group = function(parent, $el) { Group.prototype = Object.create(Node.prototype); Group.prototype.constructor = Group; -Model.defineModelProperties(Group, ['condition']); +Utils.defineModelProperties(Group, ['condition']); /** * Removes group's content @@ -561,7 +523,7 @@ var Rule = function(parent, $el) { Rule.prototype = Object.create(Node.prototype); Rule.prototype.constructor = Rule; -Model.defineModelProperties(Rule, ['filter', 'operator', 'value']); +Utils.defineModelProperties(Rule, ['filter', 'operator', 'value']); /** * Checks if this Node is the root diff --git a/src/plugins/not-group/plugin.js b/src/plugins/not-group/plugin.js index 6596a817..da6f98b0 100644 --- a/src/plugins/not-group/plugin.js +++ b/src/plugins/not-group/plugin.js @@ -104,7 +104,7 @@ QueryBuilder.define('not-group', function(options) { * @memberof Group * @instance */ -Model.defineModelProperties(Group, ['not']); +Utils.defineModelProperties(Group, ['not']); QueryBuilder.selectors.group_not = QueryBuilder.selectors.group_header + ' [data-not=group]'; diff --git a/src/utils.js b/src/utils.js index 8f6150f2..94af0956 100644 --- a/src/utils.js +++ b/src/utils.js @@ -202,3 +202,41 @@ Utils.groupSort = function(items, key) { return newItems; }; + +/** + * Defines properties on an Node prototype with getter and setter.
+ * Update events are emitted in the setter through root Model (if any).
+ * The object must have a `__` object, non enumerable property to store values. + * @param {function} obj + * @param {string[]} fields + */ +Utils.defineModelProperties = function(obj, fields) { + fields.forEach(function(field) { + Object.defineProperty(obj.prototype, field, { + enumerable: true, + get: function() { + return this.__[field]; + }, + set: function(value) { + var previousValue = (this.__[field] !== null && typeof this.__[field] == 'object') ? + $.extend({}, this.__[field]) : + this.__[field]; + + this.__[field] = value; + + if (this.model !== null) { + /** + * After a value of the model changed + * @event model:update + * @memberof Model + * @param {Node} node + * @param {string} field + * @param {*} value + * @param {*} previousValue + */ + this.model.trigger('update', this, field, value, previousValue); + } + } + }); + }); +}; diff --git a/tests/index.html b/tests/index.html index 343c9210..3af96d4d 100644 --- a/tests/index.html +++ b/tests/index.html @@ -38,8 +38,8 @@ - + From d552fde68147ec6a8f654be409a51155af2e4171 Mon Sep 17 00:00:00 2001 From: Damien SOREL Date: Wed, 17 May 2017 08:58:02 +0200 Subject: [PATCH 4/5] Fix #487 Temporary fix CommonJS loader --- package.json | 1 + src/.wrapper.js | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index af0dbb90..f9cc0c5e 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "url": "http://www.strangeplanet.fr" }, "description": "jQuery plugin for user friendly query/filter creator", + "main": "dist/js/query-builder.js", "dependencies": { "jquery": ">=1.9.0", "bootstrap": ">=3.1.0", diff --git a/src/.wrapper.js b/src/.wrapper.js index b4b9da8d..732ae480 100644 --- a/src/.wrapper.js +++ b/src/.wrapper.js @@ -1,6 +1,9 @@ (function(root, factory) { if (typeof define == 'function' && define.amd) { - define(['jquery', 'doT', 'jQuery.extendext'], factory); + define(['jquery', 'dot/doT', 'jquery-extendext'], factory); + } + else if (typeof module === 'object' && module.exports) { + module.exports = factory(require('jquery'), require('dot/doT'), require('jquery-extendext')); } else { factory(root.jQuery, root.doT); @@ -10,4 +13,6 @@ @@js -})); \ No newline at end of file +return QueryBuilder; + +})); From d8fbbafc7993be06cbf8c235b9e06130c51bffa7 Mon Sep 17 00:00:00 2001 From: Damien SOREL Date: Mon, 10 Jul 2017 12:56:37 +0200 Subject: [PATCH 5/5] Update README.md --- .github/ISSUE_TEMPLATE.md | 2 +- LICENSE | 4 ++-- README.md | 4 ++++ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 931f097a..7a8c011b 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -3,4 +3,4 @@ - Please search in the [documentation](http://querybuilder.js.org) before asking. - Any issue without enough details won't get any answer and will be closed. - Help requests must be exhaustive, precise and come with some code explaining the need (use Markdown code highlight). -- Bug reports must come with a simple test case, preferably on jsFiddle, Plunker, etc. (QueryBuilder is available on [unpkg](https://unpkg.com/jQuery-QueryBuilder/dist/) to be used on such platforms). +- Bug reports must come with a simple test case, preferably on jsFiddle, Plunker, etc. (QueryBuilder is available on [jsDelivr](https://cdn.jsdelivr.net/npm/jQuery-QueryBuilder/dist/) and [unpkg](https://unpkg.com/jQuery-QueryBuilder/dist/) to be used on such platforms). diff --git a/LICENSE b/LICENSE index 99070e3d..50b5d4bd 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2015 Damien Sorel +Copyright (c) 2014-2017 Damien Sorel Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. \ No newline at end of file +SOFTWARE. diff --git a/README.md b/README.md index e48cf2e2..1fe97bb1 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,10 @@ $ bower install jQuery-QueryBuilder $ npm install jQuery-QueryBuilder ``` +#### Via CDN + +jQuery-QueryBuilder is available on [jsDelivr](https://cdn.jsdelivr.net/npm/jQuery-QueryBuilder/dist/) and [unpkg](https://unpkg.com/jQuery-QueryBuilder/dist/)) + ### Dependencies * jQuery >= 1.10 * Bootstrap >= 3.1 (CSS only)