diff --git a/README.md b/README.md index 9e32b24d..f0fd8ab7 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,6 @@ [![npm version](https://img.shields.io/npm/v/jQuery-QueryBuilder.svg?style=flat-square)](https://www.npmjs.com/package/jQuery-QueryBuilder) [![jsDelivr CDN](https://data.jsdelivr.com/v1/package/npm/jQuery-QueryBuilder/badge)](https://www.jsdelivr.com/package/npm/jQuery-QueryBuilder) [![Build Status](https://github.com/mistic100/jQuery-QueryBuilder/workflows/CI/badge.svg)](https://github.com/mistic100/jQuery-QueryBuilder/actions) -[![Dependencies Status](https://david-dm.org/mistic100/jQuery-QueryBuilder/status.svg?style=flat-square)](https://david-dm.org/mistic100/jQuery-QueryBuilder) [![gitlocalized](https://gitlocalize.com/repo/5259/whole_project/badge.svg)](https://gitlocalize.com/repo/5259/whole_project?utm_source=badge) jQuery plugin offering an simple interface to create complex queries. @@ -34,18 +33,14 @@ $ npm install jQuery-QueryBuilder jQuery-QueryBuilder is available on [jsDelivr](https://www.jsdelivr.com/package/npm/jQuery-QueryBuilder). ### Dependencies * [jQuery 3](https://jquery.com) - * [Bootstrap 3](https://getbootstrap.com/docs/3.3) (CSS only) + * [Bootstrap 5](https://getbootstrap.com/docs/5.3/) CSS and bundle.js which includes `Popper` for tooltips and popovers + * [Bootstrap Icons](https://icons.getbootstrap.com/) * [jQuery.extendext](https://github.com/mistic100/jQuery.extendext) - * [doT.js](https://olado.github.io/doT) * [MomentJS](https://momentjs.com) (optional, for Date/Time validation) * [SQL Parser](https://github.com/mistic100/sql-parser) (optional, for SQL methods) * Other Bootstrap/jQuery plugins used by plugins -($.extendext and doT.js are directly included in the [standalone](https://github.com/mistic100/jQuery-QueryBuilder/blob/master/dist/js/query-builder.standalone.js) file) - -### Browser support - * Internet Explorer >= 11 - * All other recent browsers +($.extendext is directly included in the [standalone](https://github.com/mistic100/jQuery-QueryBuilder/blob/master/dist/js/query-builder.standalone.js) file) diff --git a/build/jsdoc.md b/build/jsdoc.md index 029fecb1..e329af92 100644 --- a/build/jsdoc.md +++ b/build/jsdoc.md @@ -1,4 +1,4 @@ -# [Main documentation](..) +# [Main documentation](..) # Entry point: [$.fn.QueryBuilder](external-_jQuery.fn_.html) diff --git a/examples/index.html b/examples/index.html index 0b697b7d..180652b8 100644 --- a/examples/index.html +++ b/examples/index.html @@ -1,5 +1,5 @@ - + @@ -7,29 +7,21 @@ jQuery QueryBuilder Example - - - + + - - -
-
+
@@ -80,7 +72,7 @@

jQuery QueryBuilder
-
@@ -106,22 +98,23 @@

Output

- + - - - + + - - diff --git a/package.json b/package.json index af9906cf..4111f3a0 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,9 @@ "src/" ], "dependencies": { - "bootstrap": "^3.4.1", + "bootstrap": "^5.3.0", + "@popperjs/core": "^2.11.8", + "bootstrap-icons": "^1.11.3", "jquery": "^3.5.1", "jquery-extendext": "^1.0.0", "moment": "^2.29.1", @@ -22,10 +24,8 @@ "devDependencies": { "alive-server": "^1.3.0", "awesome-bootstrap-checkbox": "^0.3.7", - "bootbox": "^4.4.0", - "bootstrap-select": "^1.12.4", + "bootbox": "^6.0.0", "bootstrap-slider": "^10.0.0", - "bootswatch-dist": "git+https://github.com/dbtek/bootswatch-dist.git#slate", "chosenjs": "^1.4.3", "concurrently": "^8.2.0", "deepmerge": "^2.1.0", @@ -34,7 +34,7 @@ "interactjs": "^1.3.3", "nodemon": "^2.0.22", "sass": "^1.63.6", - "selectize": "^0.12.4" + "@selectize/selectize": "^0.15.2" }, "keywords": [ "jquery", diff --git a/src/defaults.js b/src/defaults.js index b6c5a5eb..b63b1251 100644 --- a/src/defaults.js +++ b/src/defaults.js @@ -187,10 +187,10 @@ QueryBuilder.DEFAULTS = { ], icons: { - add_group: 'glyphicon glyphicon-plus-sign', - add_rule: 'glyphicon glyphicon-plus', - remove_group: 'glyphicon glyphicon-remove', - remove_rule: 'glyphicon glyphicon-remove', - error: 'glyphicon glyphicon-warning-sign' + add_group: 'bi-plus-circle-fill', + add_rule: 'bi-plus-lg', + remove_group: 'bi-x-lg', + remove_rule: 'bi-x-lg', + error: 'bi-exclamation-triangle' } }; diff --git a/src/main.js b/src/main.js index 93137f22..0659d288 100644 --- a/src/main.js +++ b/src/main.js @@ -134,7 +134,7 @@ var QueryBuilder = function($el, options) { this.status.id = this.$el.attr('id'); // INIT - this.$el.addClass('query-builder form-inline'); + this.$el.addClass('query-builder'); this.filters = this.checkFilters(this.filters); this.operators = this.checkOperators(this.operators); diff --git a/src/plugins/bt-checkbox/plugin.js b/src/plugins/bt-checkbox/plugin.js index 7a7311c2..26b0998f 100644 --- a/src/plugins/bt-checkbox/plugin.js +++ b/src/plugins/bt-checkbox/plugin.js @@ -3,12 +3,12 @@ * @memberof module:plugins * @description Applies Awesome Bootstrap Checkbox for checkbox and radio inputs. * @param {object} [options] - * @param {string} [options.font='glyphicons'] + * @param {string} [options.font='bootstrap-icons'] * @param {string} [options.color='default'] */ QueryBuilder.define('bt-checkbox', function(options) { - if (options.font == 'glyphicons') { - this.$el.addClass('bt-checkbox-glyphicons'); + if (options.font === 'bootstrap-icons') { + this.$el.addClass('bt-checkbox-bootstrap-icons'); } this.on('getRuleInput.filter', function(h, rule, name) { @@ -31,15 +31,11 @@ QueryBuilder.define('bt-checkbox', function(options) { var color = filter.colors[key] || filter.colors._def_ || options.color; var id = name + '_' + (i++); - h.value+= '\ - \ - \ - \ -'; + h.value += `
`; }); } }); }, { - font: 'glyphicons', + font: 'bootstrap-icons', color: 'default' }); diff --git a/src/plugins/bt-checkbox/plugin.scss b/src/plugins/bt-checkbox/plugin.scss index 324f610f..22e21eed 100644 --- a/src/plugins/bt-checkbox/plugin.scss +++ b/src/plugins/bt-checkbox/plugin.scss @@ -1,12 +1,10 @@ -.query-builder.bt-checkbox-glyphicons { - .checkbox input[type='checkbox']:checked + label::after { - font-family: 'Glyphicons Halflings'; - content: '\e013'; +.query-builder.bt-checkbox-bootstrap-icons { + .checkbox input[type='checkbox'] + label::before { + outline: 0; } - .checkbox label::after { - padding-left: 4px; - padding-top: 2px; - font-size: 9px; + .checkbox input[type='checkbox']:checked + label::after { + font-family: 'bootstrap-icons'; + content: '\F633'; // https://icons.getbootstrap.com/icons/check-lg/ } } diff --git a/src/plugins/bt-selectpicker/plugin.js b/src/plugins/bt-selectpicker/plugin.js deleted file mode 100644 index d9ef2812..00000000 --- a/src/plugins/bt-selectpicker/plugin.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * @class BtSelectpicker - * @memberof module:plugins - * @descriptioon Applies Bootstrap Select on filters and operators combo-boxes. - * @param {object} [options] - * @param {string} [options.container='body'] - * @param {string} [options.style='btn-inverse btn-xs'] - * @param {int|string} [options.width='auto'] - * @param {boolean} [options.showIcon=false] - * @throws MissingLibraryError - */ -QueryBuilder.define('bt-selectpicker', function(options) { - if (!$.fn.selectpicker || !$.fn.selectpicker.Constructor) { - Utils.error('MissingLibrary', 'Bootstrap Select is required to use "bt-selectpicker" plugin. Get it here: http://silviomoreto.github.io/bootstrap-select'); - } - - var Selectors = QueryBuilder.selectors; - - // init selectpicker - this.on('afterCreateRuleFilters', function(e, rule) { - rule.$el.find(Selectors.rule_filter).removeClass('form-control').selectpicker(options); - }); - - this.on('afterCreateRuleOperators', function(e, rule) { - rule.$el.find(Selectors.rule_operator).removeClass('form-control').selectpicker(options); - }); - - // update selectpicker on change - this.on('afterUpdateRuleFilter', function(e, rule) { - rule.$el.find(Selectors.rule_filter).selectpicker('render'); - }); - - this.on('afterUpdateRuleOperator', function(e, rule) { - rule.$el.find(Selectors.rule_operator).selectpicker('render'); - }); - - this.on('beforeDeleteRule', function(e, rule) { - rule.$el.find(Selectors.rule_filter).selectpicker('destroy'); - rule.$el.find(Selectors.rule_operator).selectpicker('destroy'); - }); -}, { - container: 'body', - style: 'btn-inverse btn-xs', - width: 'auto', - showIcon: false -}); diff --git a/src/plugins/bt-tooltip-errors/plugin.js b/src/plugins/bt-tooltip-errors/plugin.js index 68423252..52f4830d 100644 --- a/src/plugins/bt-tooltip-errors/plugin.js +++ b/src/plugins/bt-tooltip-errors/plugin.js @@ -7,8 +7,9 @@ * @throws MissingLibraryError */ QueryBuilder.define('bt-tooltip-errors', function(options) { - if (!$.fn.tooltip || !$.fn.tooltip.Constructor || !$.fn.tooltip.Constructor.prototype.fixTitle) { - Utils.error('MissingLibrary', 'Bootstrap Tooltip is required to use "bt-tooltip-errors" plugin. Get it here: http://getbootstrap.com'); + if (! typeof bootstrap.Tooltip === "function") { + alert(typeof bootstrap.Tooltip ); + Utils.error('MissingLibrary', 'Bootstrap Popper is required to use "bt-tooltip-errors" plugin. Get it here: http://getbootstrap.com'); } var self = this; @@ -16,7 +17,7 @@ QueryBuilder.define('bt-tooltip-errors', function(options) { // add BT Tooltip data this.on('getRuleTemplate.filter getGroupTemplate.filter', function(h) { var $h = $($.parseHTML(h.value)); - $h.find(QueryBuilder.selectors.error_container).attr('data-toggle', 'tooltip'); + $h.find(QueryBuilder.selectors.error_container).attr('data-bs-toggle', 'tooltip'); h.value = $h.prop('outerHTML'); }); @@ -24,9 +25,7 @@ QueryBuilder.define('bt-tooltip-errors', function(options) { this.model.on('update', function(e, node, field) { if (field == 'error' && self.settings.display_errors) { node.$el.find(QueryBuilder.selectors.error_container).eq(0) - .tooltip(options) - .tooltip('hide') - .tooltip('fixTitle'); + .attr('data-bs-original-title',options).attr('data-bs-title',options).tooltip(); } }); }, { diff --git a/src/plugins/filter-description/plugin.js b/src/plugins/filter-description/plugin.js index 472dd328..3027e761 100644 --- a/src/plugins/filter-description/plugin.js +++ b/src/plugins/filter-description/plugin.js @@ -3,7 +3,7 @@ * @memberof module:plugins * @description Provides three ways to display a description about a filter: inline, Bootsrap Popover or Bootbox. * @param {object} [options] - * @param {string} [options.icon='glyphicon glyphicon-info-sign'] + * @param {string} [options.icon='bi-info-circle-fill'] * @param {string} [options.mode='popover'] - inline, popover or bootbox * @throws ConfigError */ @@ -43,30 +43,28 @@ QueryBuilder.define('filter-description', function(options) { if (!description) { $b.hide(); - if ($b.data('bs.popover')) { + if ($b.data('bs-popover')) { $b.popover('hide'); } } else { if ($b.length === 0) { - $b = $($.parseHTML('')); + $b = $($.parseHTML('')); $b.prependTo(rule.$el.find(QueryBuilder.selectors.rule_actions)); - - $b.popover({ + const popover = new bootstrap.Popover($b.get(0), { placement: 'left', container: 'body', html: true - }); - + }) $b.on('mouseout', function() { - $b.popover('hide'); + popover('hide'); }); } else { $b.css('display', ''); } - $b.data('bs.popover').options.content = description; + $b.data('bs-popover').options.content = description; if ($b.attr('aria-describedby')) { $b.popover('show'); @@ -89,7 +87,7 @@ QueryBuilder.define('filter-description', function(options) { } else { if ($b.length === 0) { - $b = $($.parseHTML('')); + $b = $($.parseHTML('')); $b.prependTo(rule.$el.find(QueryBuilder.selectors.rule_actions)); $b.on('click', function() { @@ -105,7 +103,7 @@ QueryBuilder.define('filter-description', function(options) { }); } }, { - icon: 'glyphicon glyphicon-info-sign', + icon: 'bi-info-circle-fill', mode: 'popover' }); diff --git a/src/plugins/invert/plugin.js b/src/plugins/invert/plugin.js index c0294e84..8b0ab7ef 100644 --- a/src/plugins/invert/plugin.js +++ b/src/plugins/invert/plugin.js @@ -3,7 +3,7 @@ * @memberof module:plugins * @description Allows to invert a rule operator, a group condition or the entire builder. * @param {object} [options] - * @param {string} [options.icon='glyphicon glyphicon-random'] + * @param {string} [options.icon='bi-shuffle'] * @param {boolean} [options.recursive=true] * @param {boolean} [options.invert_rules=true] * @param {boolean} [options.display_rules_button=false] @@ -33,7 +33,7 @@ QueryBuilder.define('invert', function(options) { this.on('getGroupTemplate.filter', function(h) { var $h = $($.parseHTML(h.value)); $h.find(Selectors.condition_container).after( - '' ); @@ -44,7 +44,7 @@ QueryBuilder.define('invert', function(options) { this.on('getRuleTemplate.filter', function(h) { var $h = $($.parseHTML(h.value)); $h.find(Selectors.rule_actions).prepend( - '' ); @@ -53,7 +53,7 @@ QueryBuilder.define('invert', function(options) { } } }, { - icon: 'glyphicon glyphicon-random', + icon: 'bi-shuffle', recursive: true, invert_rules: true, display_rules_button: false, diff --git a/src/plugins/not-group/plugin.js b/src/plugins/not-group/plugin.js index 9c015149..be98bb00 100644 --- a/src/plugins/not-group/plugin.js +++ b/src/plugins/not-group/plugin.js @@ -3,8 +3,8 @@ * @memberof module:plugins * @description Adds a "Not" checkbox in front of group conditions. * @param {object} [options] - * @param {string} [options.icon_checked='glyphicon glyphicon-checked'] - * @param {string} [options.icon_unchecked='glyphicon glyphicon-unchecked'] + * @param {string} [options.icon_checked='bi-check2-square'] + * @param {string} [options.icon_unchecked='bi-square'] */ QueryBuilder.define('not-group', function(options) { var self = this; @@ -34,7 +34,7 @@ QueryBuilder.define('not-group', function(options) { this.on('getGroupTemplate.filter', function(h) { var $h = $($.parseHTML(h.value)); $h.find(QueryBuilder.selectors.condition_container).prepend( - '' ); @@ -112,8 +112,8 @@ QueryBuilder.define('not-group', function(options) { e.value.not = !!data.not; }); }, { - icon_unchecked: 'glyphicon glyphicon-unchecked', - icon_checked: 'glyphicon glyphicon-check', + icon_unchecked: 'bi-square', + icon_checked: 'bi-check2-square', disable_template: false }); diff --git a/src/plugins/sortable/plugin.js b/src/plugins/sortable/plugin.js index 1eeb9dab..84b29e1f 100644 --- a/src/plugins/sortable/plugin.js +++ b/src/plugins/sortable/plugin.js @@ -5,7 +5,7 @@ * @param {object} [options] * @param {boolean} [options.inherit_no_drop=true] * @param {boolean} [options.inherit_no_sortable=true] - * @param {string} [options.icon='glyphicon glyphicon-sort'] + * @param {string} [options.icon='bi-sort-down'] * @throws MissingLibraryError, ConfigError */ QueryBuilder.define('sortable', function(options) { @@ -177,7 +177,7 @@ QueryBuilder.define('sortable', function(options) { }, { inherit_no_sortable: true, inherit_no_drop: true, - icon: 'glyphicon glyphicon-sort', + icon: 'bi-sort-down', disable_template: false }); diff --git a/src/scss/default.scss b/src/scss/default.scss index bc0a4524..9091634c 100644 --- a/src/scss/default.scss +++ b/src/scss/default.scss @@ -109,12 +109,6 @@ $ticks-position: 5px, 10px !default; display: block; } } - - select, - input[type='text'], - input[type='number'] { - padding: 1px; - } } // ERRORS diff --git a/src/template.js b/src/template.js index 036d4e94..219aa06e 100644 --- a/src/template.js +++ b/src/template.js @@ -2,24 +2,24 @@ QueryBuilder.templates.group = ({ group_id, level, conditions, icons, settings, return `
-
- ${settings.allow_groups === -1 || settings.allow_groups >= level ? ` - ` : ''} ${level > 1 ? ` - ` : ''}
${conditions.map(condition => ` -