<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>jQuery QueryBuilder Example</title> <link rel="stylesheet" href="../node_modules/bootstrap/dist/css/bootstrap.css" id="bt-theme"> <link rel="stylesheet" href="../node_modules/bootstrap-select/dist/css/bootstrap-select.css"> <link rel="stylesheet" href="../node_modules/chosenjs/chosen.css"> <link rel="stylesheet" href="../node_modules/awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css"> <link rel="stylesheet" href="../node_modules/bootstrap-slider/dist/css/bootstrap-slider.css"> <link rel="stylesheet" href="../node_modules/selectize/dist/css/selectize.bootstrap3.css"> <link rel="stylesheet" href="../dist/css/query-builder.default.css" id="qb-theme"> <link rel="stylesheet" href="http://mistic100.github.io/jQuery-QueryBuilder/assets/flags/flags.css"> <style> .flag { display: inline-block; } </style> </head> <body> <div class="container"> <div class="col-md-12 col-lg-10 col-lg-offset-1"> <div class="page-header"> <a class="pull-right" href="https://github.com/mistic100/jQuery-QueryBuilder"> <img src="https://assets.github.com/images/icons/emoji/octocat.png" width=48px height=48px> </a> <h1>jQuery QueryBuilder <small>Example</small> </h1> </div> <div class="well well-sm"> <label>Theme:</label> <div class="btn-group"> <button class="btn btn-primary btn-sm change-theme" data-qb="../dist/css/query-builder.default.css" data-bt="../node_modules/bootstrap/dist/css/bootstrap.css">Default </button> <button class="btn btn-primary btn-sm change-theme" data-qb="../dist/css/query-builder.dark.css" data-bt="../node_modules/bootswatch-dist/css/bootstrap.css">Dark </button> </div> <label>Language:</label> <select name="language" class="selectpicker show-tick show-menu-arrow" data-width="auto"> <option value="sq" data-icon="flag flag-al">Albanian</option> <option value="ar" data-icon="flag flag-ar">Arabic</option> <option value="az" data-icon="flag flag-az">Azerbaijani</option> <option value="bg" data-icon="flag flag-bg">Bulgarian</option> <option value="zh-CN" data-icon="flag flag-zh-CN">Simplified Chinese</option> <option value="cs" data-icon="flag flag-cs">Czech</option> <option value="de" data-icon="flag flag-de">German</option> <option value="da" data-icon="flag flag-dk">Danish</option> <option value="nl" data-icon="flag flag-nl">Dutch</option> <option value="en" data-icon="flag flag-gb" selected>English</option> <option value="fa-IR" data-icon="flag flag-ir">Farsi</option> <option value="fr" data-icon="flag flag-fr">French</option> <option value="el" data-icon="flag flag-el">Greek</option> <option value="he" data-icon="flag flag-he">Hebrew</option> <option value="it" data-icon="flag flag-it">Italian</option> <option value="no" data-icon="flag flag-no">Norwegian</option> <option value="pl" data-icon="flag flag-pl">Polish</option> <option value="pt-PT" data-icon="flag flag-pt-PT">Portuguese</option> <option value="pt-BR" data-icon="flag flag-pt-BR">Brazilian Portuguese</option> <option value="ro" data-icon="flag flag-ro">Romanian</option> <option value="ru" data-icon="flag flag-ru">Russian</option> <option value="es" data-icon="flag flag-es">Spanish</option> <option value="tr" data-icon="flag flag-tr">Turkish</option> <option value="ua" data-icon="flag flag-ua">Ukrainian</option> </select> </div> <div id="builder"></div> <div class="btn-group"> <button class="btn btn-danger reset">Reset</button> <button class="btn btn-warning set-filters" data-toggle="tooltip" data-container="body" data-placement="bottom" title="Adds a filter 'New filter' and removes 'Coordinates', 'State', 'BSON'">Set filters </button> </div> <div class="btn-group"> <button class="btn btn-default" disabled>Set:</button> <button class="btn btn-success set">From JSON</button> <button class="btn btn-success set-mongo">From MongoDB</button> <button class="btn btn-success set-sql">From SQL</button> </div> <div class="btn-group"> <button class="btn btn-default" disabled>Get:</button> <button class="btn btn-primary parse-json">JSON</button> <button class="btn btn-primary parse-sql" data-stmt="false">SQL</button> <button class="btn btn-primary parse-sql" data-stmt="question_mark">SQL statement</button> <button class="btn btn-primary parse-mongo">MongoDB</button> </div> <div id="result" class="hide"> <h3>Output</h3> <pre></pre> </div> </div> </div> <script src="../node_modules/jquery/dist/jquery.js"></script> <script src="../node_modules/bootstrap/dist/js/bootstrap.js"></script> <script src="../node_modules/bootstrap-select/dist/js/bootstrap-select.js"></script> <script src="../node_modules/chosenjs/chosen.jquery.js"></script> <script src="../node_modules/bootbox/bootbox.js"></script> <script src="../node_modules/bootstrap-slider/dist/bootstrap-slider.js"></script> <script src="../node_modules/selectize/dist/js/standalone/selectize.js"></script> <script src="../node_modules/jquery-extendext/jQuery.extendext.js"></script> <script src="../node_modules/sql-parser-mistic/browser/sql-parser.js"></script> <script src="../node_modules/dot/doT.js"></script> <script src="../node_modules/interactjs/dist/interact.js"></script> <!-- <script src="../dist/js/query-builder.js"></script> --> <!-- injector:js --> <script src="../src/main.js"></script> <script src="../src/defaults.js"></script> <script src="../src/plugins.js"></script> <script src="../src/core.js"></script> <script src="../src/public.js"></script> <script src="../src/data.js"></script> <script src="../src/template.js"></script> <script src="../src/utils.js"></script> <script src="../src/model.js"></script> <script src="../src/jquery.js"></script> <script src="../src/plugins/bt-checkbox/plugin.js"></script> <script src="../src/plugins/bt-selectpicker/plugin.js"></script> <script src="../src/plugins/bt-tooltip-errors/plugin.js"></script> <script src="../src/plugins/change-filters/plugin.js"></script> <script src="../src/plugins/chosen-selectpicker/plugin.js"></script> <script src="../src/plugins/filter-description/plugin.js"></script> <script src="../src/plugins/invert/plugin.js"></script> <script src="../src/plugins/mongodb-support/plugin.js"></script> <script src="../src/plugins/not-group/plugin.js"></script> <script src="../src/plugins/sortable/plugin.js"></script> <script src="../src/plugins/sql-support/plugin.js"></script> <script src="../src/plugins/unique-filter/plugin.js"></script> <script src="../dist/i18n/query-builder.en.js"></script> <!-- endinjector --> <script> $('[data-toggle="tooltip"]').tooltip(); var $b = $('#builder'); var options = { allow_empty: true, //default_filter: 'name', sort_filters: true, optgroups: { core: { en: 'Core', fr: 'Coeur' } }, plugins: { 'bt-tooltip-errors': { delay: 100 }, 'sortable': null, 'filter-description': { mode: 'bootbox' }, 'bt-selectpicker': null, // 'chosen-selectpicker': null, 'unique-filter': null, 'bt-checkbox': { color: 'primary' }, 'invert': null, 'not-group': null }, // standard operators in custom optgroups operators: [ { type: 'equal', optgroup: 'basic' }, { type: 'not_equal', optgroup: 'basic' }, { type: 'in', optgroup: 'basic' }, { type: 'not_in', optgroup: 'basic' }, { type: 'less', optgroup: 'numbers' }, { type: 'less_or_equal', optgroup: 'numbers' }, { type: 'greater', optgroup: 'numbers' }, { type: 'greater_or_equal', optgroup: 'numbers' }, { type: 'between', optgroup: 'numbers' }, { type: 'not_between', optgroup: 'numbers' }, { type: 'begins_with', optgroup: 'strings' }, { type: 'not_begins_with', optgroup: 'strings' }, { type: 'contains', optgroup: 'strings' }, { type: 'not_contains', optgroup: 'strings' }, { type: 'ends_with', optgroup: 'strings' }, { type: 'not_ends_with', optgroup: 'strings' }, { type: 'is_empty' }, { type: 'is_not_empty' }, { type: 'is_null' }, { type: 'is_not_null' } ], filters: [ /* * string with separator */ { id: 'name', field: 'username', label: { en: 'Name', fr: 'Nom' }, icon: 'glyphicon glyphicon-user', value_separator: ',', type: 'string', optgroup: 'core', default_value: 'Mistic', size: 30, validation: { allow_empty_value: true }, unique: true }, /* * integer with separator for 'in' and 'not_in' */ { id: 'age', label: 'Age', icon: 'glyphicon glyphicon-calendar', type: 'integer', input: 'text', value_separator: '|', optgroup: 'core', description: function(rule) { if (rule.operator && ['in', 'not_in'].indexOf(rule.operator.type) !== -1) { return 'Use a pipe (|) to separate multiple values with "in" and "not in" operators'; } } }, /* * textarea */ { id: 'bson', label: 'BSON', icon: 'glyphicon glyphicon-qrcode', type: 'string', input: 'textarea', operators: ['equal'], size: 30, rows: 3 }, /* * checkbox */ { id: 'category', label: 'Category', icon: 'glyphicon glyphicon-th-list', type: 'integer', input: 'checkbox', optgroup: 'core', values: { 1: 'Books', 2: 'Movies', 3: 'Music', 4: 'Tools', 5: 'Goodies', 6: 'Clothes' }, colors: { 1: 'foo', 2: 'warning', 5: 'success' }, operators: ['equal', 'not_equal', 'in', 'not_in', 'is_null', 'is_not_null'], default_operator: 'in' }, /* * select */ { id: 'continent', label: 'Continent', icon: 'glyphicon glyphicon-globe', type: 'string', input: 'select', optgroup: 'core', placeholder: 'Select something', values: [ { label: 'Europe', value: 'eur', optgroup: 'North' }, { label: 'Asia', value: 'asia', optgroup: 'North' }, { label: 'Oceania', value: 'oce', optgroup: 'South' }, { label: 'Africa', value: 'afr', optgroup: 'South' }, { label: 'North America', value: 'na', optgroup: 'North' }, { label: 'South America', value: 'sa', optgroup: 'South' }, { label: 'Mordor', value: 'mrd' } ], operators: ['equal', 'not_equal', 'is_null', 'is_not_null'] }, /* * Selectize */ { id: 'state', label: 'State', icon: 'glyphicon glyphicon-globe', type: 'string', input: 'select', multiple: true, plugin: 'selectize', plugin_config: { valueField: 'id', labelField: 'name', searchField: 'name', sortField: 'name', options: [ { id: "AL", name: "Alabama" }, { id: "AK", name: "Alaska" }, { id: "AZ", name: "Arizona" }, { id: "AR", name: "Arkansas" }, { id: "CA", name: "California" }, { id: "CO", name: "Colorado" }, { id: "CT", name: "Connecticut" }, { id: "DE", name: "Delaware" }, { id: "DC", name: "District of Columbia" }, { id: "FL", name: "Florida" }, { id: "GA", name: "Georgia" }, { id: "HI", name: "Hawaii" }, { id: "ID", name: "Idaho" } ] }, valueSetter: function(rule, value) { rule.$el.find('.rule-value-container select')[0].selectize.setValue(value); } }, /* * radio */ { id: 'in_stock', label: 'In stock', icon: 'glyphicon glyphicon-log-in', type: 'integer', input: 'radio', optgroup: 'plugin', values: { 1: 'Yes', 0: 'No' }, operators: ['equal'] }, /* * double */ { id: 'price', label: 'Price', icon: 'glyphicon glyphicon-usd', type: 'double', size: 5, validation: { min: 0, step: 0.01 }, data: { class: 'com.example.PriceTag' } }, /* * slider */ { id: 'rate', label: 'Rate', icon: 'glyphicon glyphicon-flash', type: 'integer', validation: { min: 0, max: 100 }, plugin: 'slider', plugin_config: { min: 0, max: 100, value: 0 }, onAfterSetValue: function(rule, value) { var input = rule.$el.find('.rule-value-container input'); input.slider('setValue', value); input.val(value); // don't know why I need it } }, /* * placeholder and regex validation */ { id: 'id', label: 'Identifier', icon: 'glyphicon glyphicon-sunglasses', type: 'string', optgroup: 'plugin', placeholder: '____-____-____', size: 14, operators: ['equal', 'not_equal'], validation: { format: /^.{4}-.{4}-.{4}$/, messages: { format: 'Invalid format, expected: AAAA-AAAA-AAAA' } } }, /* * custom input */ { id: 'coord', label: 'Coordinates', icon: 'glyphicon glyphicon-star-empty', type: 'string', default_value: 'C.5', description: 'The letter is the cadran identifier:\ <ul>\ <li><b>A</b>: alpha</li>\ <li><b>B</b>: beta</li>\ <li><b>C</b>: gamma</li>\ </ul>', validation: { format: /^[A-C]{1}.[1-6]{1}$/ }, input: function(rule, name) { var $container = rule.$el.find('.rule-value-container'); $container.on('change', '[name=' + name + '_1]', function() { var h = ''; switch ($(this).val()) { case 'A': h = '<option value="-1">-</option> <option value="1">1</option> <option value="2">2</option>'; break; case 'B': h = '<option value="-1">-</option> <option value="3">3</option> <option value="4">4</option>'; break; case 'C': h = '<option value="-1">-</option> <option value="5">5</option> <option value="6">6</option>'; break; } $container.find('[name$=_2]') .html(h).toggle(!!h) .val('-1').trigger('change'); }); return '\ <select name="' + name + '_1"> \ <option value="-1">-</option> \ <option value="A">A</option> \ <option value="B">B</option> \ <option value="C">C</option> \ </select> \ <select name="' + name + '_2" style="display:none;"></select>'; }, valueGetter: function(rule) { return rule.$el.find('.rule-value-container [name$=_1]').val() + '.' + rule.$el.find('.rule-value-container [name$=_2]').val(); }, valueSetter: function(rule, value) { if (rule.operator.nb_inputs > 0) { var val = value.split('.'); rule.$el.find('.rule-value-container [name$=_1]').val(val[0]).trigger('change'); rule.$el.find('.rule-value-container [name$=_2]').val(val[1]).trigger('change'); } } }] }; // init $('#builder').queryBuilder(options); $('#builder').on('afterCreateRuleInput.queryBuilder', function(e, rule) { if (rule.filter.plugin == 'selectize') { rule.$el.find('.rule-value-container').css('min-width', '200px') .find('.selectize-control').removeClass('form-control'); } }); // change language $('[name=language]').selectpicker().on('change', function() { var lang = $(this).val(); var done = function() { var rules = $b.queryBuilder('getRules'); if (!$.isEmptyObject(rules)) { options.rules = rules; } else { delete options.rules; } options.lang_code = lang; $b.queryBuilder('destroy'); $('#builder').queryBuilder(options); }; if ($.fn.queryBuilder.regional[lang] === undefined) { $.getScript('../dist/i18n/query-builder.' + lang + '.js', done); } else { done(); } }); // change theme $('.change-theme').on('click', function() { $('#qb-theme').replaceWith('<link rel="stylesheet" href="' + $(this).data('qb') + '" id="qb-theme">'); $('#bt-theme').replaceWith('<link rel="stylesheet" href="' + $(this).data('bt') + '" id="bt-theme">'); }); // set rules $('.set').on('click', function() { $('#builder').queryBuilder('setRules', { condition: 'AND', flags: { condition_readonly: true }, rules: [{ id: 'price', operator: 'between', value: [10.25, 15.52], flags: { no_delete: true, filter_readonly: true }, data: { unit: '€' } }, { id: 'state', operator: 'equal', value: 'AK' }, { condition: 'OR', not: true, flags: { no_delete: true, no_drop: true, no_sortable: true }, rules: [{ id: 'category', operator: 'equal', value: 2 }, { id: 'coord', operator: 'equal', value: undefined // will use filter's default value }] }, { id: 'name', operator: 'in', value: ['Mistic', 'Damien'] }, { id: 'age', operator: 'in', value: [20,21,22] }, { empty: true }] }); }); // set rules from MongoDB $('.set-mongo').on('click', function() { $('#builder').queryBuilder('setRulesFromMongo', { "$or": [{ "username": { "$regex": "^(?!Mistic)" } }, { "price": { "$gte": 0, "$lte": 100 } }, { "$nor": [{ "$and": [{ "category": 2 }, { "category": { "$in": [4, 5] } }] }] }] }); }); // set rules from SQL $('.set-sql').on('click', function() { $('#builder').queryBuilder('setRulesFromSQL', 'username NOT LIKE "Mistic%" OR price BETWEEN 100 OR 200 OR NOT (category IN(1, 2) AND rate <= 2)'); }); // reset builder $('.reset').on('click', function() { $('#builder').queryBuilder('reset'); $('#result').addClass('hide').find('pre').empty(); }); // get rules $('.parse-json').on('click', function() { $('#result').removeClass('hide') .find('pre').html(JSON.stringify( $('#builder').queryBuilder('getRules', { get_flags: true, skip_empty: true }), undefined, 2 )); }); $('.parse-sql').on('click', function() { var res = $('#builder').queryBuilder('getSQL', $(this).data('stmt'), false); $('#result').removeClass('hide') .find('pre').html( res.sql + (res.params ? '\n\n' + JSON.stringify(res.params, undefined, 2) : '') ); }); $('.parse-mongo').on('click', function() { $('#result').removeClass('hide') .find('pre').html(JSON.stringify( $('#builder').queryBuilder('getMongo'), undefined, 2 )); }); // set filters $('.set-filters').on('click', function() { $(this).prop('disabled', true); $(this).tooltip('hide'); // add a new filter after 'state' $('#builder').queryBuilder('addFilter', { id: 'new_one', label: 'New filter', type: 'string' }, 'state' ); // remove filter 'coord' $('#builder').queryBuilder('removeFilter', ['coord', 'state', 'bson'], true ); // also available : 'setFilters' }); </script> <script> document.write('<script src="//' + location.host.split(':')[0] + ':35729/livereload.js" async defer><' + '/script>'); </script> </body> </html>