diff --git a/Gruntfile.js b/Gruntfile.js index 81e7bf20..c1cc5e8e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,4 +1,5 @@ var deepmerge = require('deepmerge'); + module.exports = function(grunt) { grunt.util.linefeed = '\n'; @@ -17,8 +18,8 @@ module.exports = function(grunt) { grunt.config.set('lang_author', content.__author); var header = grunt.template.process('<%= langBanner %>'); - loaded_modules.forEach(function(m) { - var plugin_file = 'src/plugins/'+ m +'/i18n/'+ lang +'.json'; + loaded_plugins.forEach(function(p) { + var plugin_file = 'src/plugins/'+ p +'/i18n/'+ lang +'.json'; if (grunt.file.exists(plugin_file)) { content = deepmerge(content, grunt.file.readJSON(plugin_file)); @@ -36,9 +37,9 @@ module.exports = function(grunt) { } - var all_modules = {}, + var all_plugins = {}, all_langs = {}, - loaded_modules = [], + loaded_plugins = [], loaded_langs = [], js_core_files = [ 'src/main.js', @@ -59,11 +60,11 @@ module.exports = function(grunt) { (function(){ - // list available modules and languages + // list available plugins and languages grunt.file.expand('src/plugins/*/plugin.js') .forEach(function(f) { var n = f.split('/')[2]; - all_modules[n] = f; + all_plugins[n] = f; }); grunt.file.expand('src/i18n/*.json') @@ -72,23 +73,23 @@ module.exports = function(grunt) { all_langs[n] = f; }); - // parse 'modules' parameter - var arg_modules = grunt.option('modules'); - if (typeof arg_modules === 'string') { - arg_modules.replace(/ /g, '').split(',').forEach(function(m) { - if (all_modules[m]) { - js_files_to_load.push(all_modules[m]); - loaded_modules.push(m); + // parse 'plugins' parameter + var arg_plugins = grunt.option('plugins'); + if (typeof arg_plugins === 'string') { + arg_plugins.replace(/ /g, '').split(',').forEach(function(p) { + if (all_plugins[p]) { + js_files_to_load.push(all_plugins[p]); + loaded_plugins.push(p); } else { - grunt.fail.warn('Module '+ m +' unknown'); + grunt.fail.warn('Plugin '+ p +' unknown'); } }); } - else if (arg_modules === undefined) { - for (var m in all_modules) { - js_files_to_load.push(all_modules[m]); - loaded_modules.push(m); + else if (arg_plugins === undefined) { + for (var p in all_plugins) { + js_files_to_load.push(all_plugins[p]); + loaded_plugins.push(p); } } @@ -135,7 +136,10 @@ module.exports = function(grunt) { // bump version bump: { options: { - files: ['package.json', 'bower.json', 'composer.json'] + files: ['package.json', 'bower.json', 'composer.json'], + createTag: false, + commit: false, + push: false } }, @@ -166,7 +170,7 @@ module.exports = function(grunt) { }] }, sass_plugins: { - files: loaded_modules.map(function(name) { + files: loaded_plugins.map(function(name) { return { src: 'src/plugins/'+ name +'/plugin.scss', dest: 'dist/scss/plugins/' + name + '.scss' @@ -209,7 +213,7 @@ module.exports = function(grunt) { files: Object.keys(all_langs).map(function(name) { return { src: 'src/i18n/'+ name +'.json', - dest: 'dist/i18n/' + name + '.js' + dest: 'dist/i18n/query-builder.' + name + '.js' }; }), options: { @@ -258,8 +262,8 @@ module.exports = function(grunt) { wrapper: function() { var wrapper = grunt.file.read('src/.wrapper.js').replace(/\r\n/g, '\n').split(/@@js\n/); - if (loaded_modules.length) { - wrapper[0] = '// Modules: ' + loaded_modules.join(', ') + '\n' + wrapper[0]; + if (loaded_plugins.length) { + wrapper[0] = '// Plugins: ' + loaded_plugins.join(', ') + '\n' + wrapper[0]; } if (loaded_langs.length) { wrapper[0] = '// Languages: ' + loaded_langs.join(', ') + '\n' + wrapper[0]; @@ -277,7 +281,7 @@ module.exports = function(grunt) { options: { separator: '', wrapper: function() { - return ['', loaded_modules.reduce(function(wrapper, name) { + return ['', loaded_plugins.reduce(function(wrapper, name) { if (grunt.file.exists('dist/scss/plugins/' + name + '.scss')) { wrapper+= '\n@import \'plugins/' + name + '\';'; } @@ -370,8 +374,8 @@ module.exports = function(grunt) { scripts+= '\n'; - for (var m in all_modules) { - scripts+= '\n'; + for (var p in all_plugins) { + scripts+= '\n'; } return m1 + scripts + m2; @@ -462,10 +466,10 @@ module.exports = function(grunt) { grunt.registerTask('list_modules', 'List QueryBuilder plugins and languages.', function() { grunt.log.writeln('\nAvailable QueryBuilder plugins:\n'); - for (var m in all_modules) { - grunt.log.write(m['cyan']); + for (var p in all_plugins) { + grunt.log.write(p['cyan']); - if (grunt.file.exists(all_modules[m].replace(/js$/, 'scss'))) { + if (grunt.file.exists(all_plugins[p].replace(/js$/, 'scss'))) { grunt.log.write(' + CSS'); } diff --git a/README.md b/README.md index bfc34f6a..056b74ad 100644 --- a/README.md +++ b/README.md @@ -43,20 +43,20 @@ Install Node and Bower dependencies `npm install & bower install` then run `grun #### Options -You can choose which plugins to include with `--modules` : +You can choose which plugins to include with `--plugins` : ```bash # include "sql-support" plugin -grunt --modules=sql-support +grunt --plugins=sql-support -# disable all modules -grunt --modules=false +# disable all plugins +grunt --plugins=false ``` All plugins are included by default. -You can also include ONE language with `--lang` : +You can also include language files with `--languages` : ```bash -# include French translation -grunt --lang=fr +# include French & Italian translation +grunt --languages=fr,it ``` #### Other commands diff --git a/bower.json b/bower.json index 95a0f64e..253a6ca8 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jQuery-QueryBuilder", - "version": "2.0.1", + "version": "2.1.0", "authors": [{ "name": "Damien \"Mistic\" Sorel", "email": "contact@git.strangeplanet.fr", diff --git a/composer.json b/composer.json index da280c6b..7adf4bef 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "mistic100/jquery-querybuilder", - "version": "2.0.1", + "version": "2.1.0", "authors": [{ "name": "Damien \"Mistic\" Sorel", "email": "contact@git.strangeplanet.fr", diff --git a/dist/css/query-builder.dark.css b/dist/css/query-builder.dark.css index cf6e9874..a44b4f6c 100644 --- a/dist/css/query-builder.dark.css +++ b/dist/css/query-builder.dark.css @@ -1,5 +1,5 @@ /*! - * jQuery QueryBuilder 2.0.1 + * jQuery QueryBuilder 2.1.0 * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr) * Licensed under MIT (http://opensource.org/licenses/MIT) */ diff --git a/dist/css/query-builder.dark.min.css b/dist/css/query-builder.dark.min.css index 169024e5..39f994ce 100644 --- a/dist/css/query-builder.dark.min.css +++ b/dist/css/query-builder.dark.min.css @@ -1,5 +1,5 @@ /*! - * jQuery QueryBuilder 2.0.1 + * jQuery QueryBuilder 2.1.0 * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr) * Licensed under MIT (http://opensource.org/licenses/MIT) */ diff --git a/dist/css/query-builder.default.css b/dist/css/query-builder.default.css index efae555b..1c09b80b 100644 --- a/dist/css/query-builder.default.css +++ b/dist/css/query-builder.default.css @@ -1,5 +1,5 @@ /*! - * jQuery QueryBuilder 2.0.1 + * jQuery QueryBuilder 2.1.0 * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr) * Licensed under MIT (http://opensource.org/licenses/MIT) */ diff --git a/dist/css/query-builder.default.min.css b/dist/css/query-builder.default.min.css index 73599d9c..de15150a 100644 --- a/dist/css/query-builder.default.min.css +++ b/dist/css/query-builder.default.min.css @@ -1,5 +1,5 @@ /*! - * jQuery QueryBuilder 2.0.1 + * jQuery QueryBuilder 2.1.0 * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr) * Licensed under MIT (http://opensource.org/licenses/MIT) */ diff --git a/dist/i18n/es.js b/dist/i18n/es.js deleted file mode 100644 index e6539f0f..00000000 --- a/dist/i18n/es.js +++ /dev/null @@ -1,57 +0,0 @@ -/*! - * jQuery QueryBuilder 2.0.1 - * Spanish translation by "pyarza" - * Licensed under MIT (http://opensource.org/licenses/MIT) - */ - -jQuery.fn.queryBuilder.defaults({ lang: { - "add_rule": "Añadir regla", - "add_group": "Añadir grupo", - "delete_rule": "Borrar", - "delete_group": "Borrar", - "conditions": { - "AND": "Y", - "OR": "O" - }, - "operators": { - "equal": "igual", - "not_equal": "distinto", - "in": "en", - "not_in": "no en", - "less": "menor", - "less_or_equal": "menor o igual", - "greater": "mayor", - "greater_or_equal": "mayor o igual", - "between": "entre", - "begins_with": "empieza por", - "not_begins_with": "no empieza por", - "contains": "contiene", - "not_contains": "no contiene", - "ends_with": "acaba con", - "not_ends_with": "no acaba con", - "is_empty": "esta vacio", - "is_not_empty": "no esta vacio", - "is_null": "es nulo", - "is_not_null": "no es nulo" - }, - "errors": { - "no_filter": "No se ha seleccionado ningun filtro", - "empty_group": "El grupo esta vacio", - "radio_empty": "Ningun valor seleccionado", - "checkbox_empty": "Ningun valor seleccionado", - "select_empty": "Ningun valor seleccionado", - "string_empty": "Cadena vacia", - "string_exceed_min_length": "Debe contener al menos {0} caracteres", - "string_exceed_max_length": "No debe contener mas de {0} caracteres", - "string_invalid_format": "Formato invalido ({0})", - "number_nan": "No es un numero", - "number_not_integer": "No es un numero entero", - "number_not_double": "No es un numero real", - "number_exceed_min": "Debe ser mayor que {0}", - "number_exceed_max": "Debe ser menot que {0}", - "number_wrong_step": "Debe ser multiplo de {0}", - "datetime_invalid": "Formato de fecha invalido ({0})", - "datetime_exceed_min": "Debe ser posterior a {0}", - "datetime_exceed_max": "Debe ser anterior a {0}" - } -}}); \ No newline at end of file diff --git a/dist/i18n/da.js b/dist/i18n/query-builder.da.js similarity index 63% rename from dist/i18n/da.js rename to dist/i18n/query-builder.da.js index 1dec663c..b73db58a 100644 --- a/dist/i18n/da.js +++ b/dist/i18n/query-builder.da.js @@ -1,10 +1,25 @@ /*! - * jQuery QueryBuilder 2.0.1 - * Oversat af Jna Borup Coyle, github@coyle.dk + * jQuery QueryBuilder 2.1.0 + * Locale: Danish (da) + * Author: Jna Borup Coyle, github@coyle.dk * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['da'] = { + "__locale": "Danish (da)", + "__author": "Jna Borup Coyle, github@coyle.dk", "add_rule": "Tilføj regel", "add_group": "Tilføj gruppe", "delete_rule": "Slet regel", @@ -35,4 +50,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "is_null": "er null", "is_not_null": "er ikke null" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'da' }); +})); \ No newline at end of file diff --git a/dist/i18n/de.js b/dist/i18n/query-builder.de.js similarity index 78% rename from dist/i18n/de.js rename to dist/i18n/query-builder.de.js index 4c57d669..e9b3f998 100644 --- a/dist/i18n/de.js +++ b/dist/i18n/query-builder.de.js @@ -1,10 +1,25 @@ /*! - * jQuery QueryBuilder 2.0.1 - * German translation by "raimu" + * jQuery QueryBuilder 2.1.0 + * Locale: German (de) + * Author: "raimu" * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['de'] = { + "__locale": "German (de)", + "__author": "\"raimu\"", "add_rule": "neue Regel", "add_group": "neue Gruppe", "delete_rule": "löschen", @@ -53,4 +68,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "datetime_exceed_min": "Muss nach dem {0} sein", "datetime_exceed_max": "Muss vor dem {0} sein" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'de' }); +})); \ No newline at end of file diff --git a/dist/i18n/en.js b/dist/i18n/query-builder.en.js similarity index 77% rename from dist/i18n/en.js rename to dist/i18n/query-builder.en.js index b98a13e8..da7eb17d 100644 --- a/dist/i18n/en.js +++ b/dist/i18n/query-builder.en.js @@ -1,10 +1,25 @@ /*! - * jQuery QueryBuilder 2.0.1 - * Reference language file + * jQuery QueryBuilder 2.1.0 + * Locale: English (en) + * Author: Damien "Mistic" Sorel, http://www.strangeplanet.fr * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['en'] = { + "__locale": "English (en)", + "__author": "Damien \"Mistic\" Sorel, http://www.strangeplanet.fr", "add_rule": "Add rule", "add_group": "Add group", "delete_rule": "Delete", @@ -57,4 +72,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "boolean_not_valid": "Not a boolean", "operator_not_multiple": "Operator {0} cannot accept multiple values" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'en' }); +})); \ No newline at end of file diff --git a/dist/i18n/query-builder.es.js b/dist/i18n/query-builder.es.js new file mode 100644 index 00000000..82a88996 --- /dev/null +++ b/dist/i18n/query-builder.es.js @@ -0,0 +1,75 @@ +/*! + * jQuery QueryBuilder 2.1.0 + * Locale: Spanish (es) + * Author: "pyarza", "kddlb" + * Licensed under MIT (http://opensource.org/licenses/MIT) + */ + +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['es'] = { + "__locale": "Spanish (es)", + "__author": "\"pyarza\", \"kddlb\"", + "add_rule": "Añadir regla", + "add_group": "Añadir grupo", + "delete_rule": "Borrar", + "delete_group": "Borrar", + "conditions": { + "AND": "Y", + "OR": "O" + }, + "operators": { + "equal": "igual", + "not_equal": "distinto", + "in": "en", + "not_in": "no en", + "less": "menor", + "less_or_equal": "menor o igual", + "greater": "mayor", + "greater_or_equal": "mayor o igual", + "between": "entre", + "begins_with": "empieza por", + "not_begins_with": "no empieza por", + "contains": "contiene", + "not_contains": "no contiene", + "ends_with": "acaba con", + "not_ends_with": "no acaba con", + "is_empty": "está vacío", + "is_not_empty": "no está vacío", + "is_null": "es nulo", + "is_not_null": "no es nulo" + }, + "errors": { + "no_filter": "No se ha seleccionado ningún filtro", + "empty_group": "El grupo está vacío", + "radio_empty": "Ningún valor seleccionado", + "checkbox_empty": "Ningún valor seleccionado", + "select_empty": "Ningún valor seleccionado", + "string_empty": "Cadena vacía", + "string_exceed_min_length": "Debe contener al menos {0} caracteres", + "string_exceed_max_length": "No debe contener más de {0} caracteres", + "string_invalid_format": "Formato inválido ({0})", + "number_nan": "No es un número", + "number_not_integer": "No es un número entero", + "number_not_double": "No es un número real", + "number_exceed_min": "Debe ser mayor que {0}", + "number_exceed_max": "Debe ser menor que {0}", + "number_wrong_step": "Debe ser múltiplo de {0}", + "datetime_invalid": "Formato de fecha inválido ({0})", + "datetime_exceed_min": "Debe ser posterior a {0}", + "datetime_exceed_max": "Debe ser anterior a {0}" + } +}; + +QueryBuilder.defaults({ lang_code: 'es' }); +})); \ No newline at end of file diff --git a/dist/i18n/fr.js b/dist/i18n/query-builder.fr.js similarity index 78% rename from dist/i18n/fr.js rename to dist/i18n/query-builder.fr.js index b9e9c82b..832c92c5 100644 --- a/dist/i18n/fr.js +++ b/dist/i18n/query-builder.fr.js @@ -1,10 +1,25 @@ /*! - * jQuery QueryBuilder 2.0.1 - * French translation by Damien "Mistic" Sorel + * jQuery QueryBuilder 2.1.0 + * Locale: French (fr) + * Author: Damien "Mistic" Sorel, http://www.strangeplanet.fr * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['fr'] = { + "__locale": "French (fr)", + "__author": "Damien \"Mistic\" Sorel, http://www.strangeplanet.fr", "add_rule": "Ajouter une règle", "add_group": "Ajouter un groupe", "delete_rule": "Supprimer", @@ -57,4 +72,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "boolean_not_valid": "N'est pas un booléen", "operator_not_multiple": "L'opérateur {0} ne peut utiliser plusieurs valeurs" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'fr' }); +})); \ No newline at end of file diff --git a/dist/i18n/it.js b/dist/i18n/query-builder.it.js similarity index 65% rename from dist/i18n/it.js rename to dist/i18n/query-builder.it.js index ffdd513b..1b1fb3ac 100644 --- a/dist/i18n/it.js +++ b/dist/i18n/query-builder.it.js @@ -1,10 +1,23 @@ /*! - * jQuery QueryBuilder 2.0.1 - * Italian translation + * jQuery QueryBuilder 2.1.0 + * Locale: Italian (it) * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['it'] = { + "__locale": "Italian (it)", "add_rule": "Aggiungi regola", "add_group": "Aggiungi gruppo", "delete_rule": "Elimina", @@ -33,4 +46,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "is_null": "è nullo", "is_not_null": "non è nullo" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'it' }); +})); \ No newline at end of file diff --git a/dist/i18n/nl.js b/dist/i18n/query-builder.nl.js similarity index 79% rename from dist/i18n/nl.js rename to dist/i18n/query-builder.nl.js index c4571cf5..b5403b82 100644 --- a/dist/i18n/nl.js +++ b/dist/i18n/query-builder.nl.js @@ -1,10 +1,25 @@ /*! - * jQuery QueryBuilder 2.0.1 - * Dutch translation by "Roywcm" + * jQuery QueryBuilder 2.1.0 + * Locale: Dutch (nl) + * Author: "Roywcm" * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['nl'] = { + "__locale": "Dutch (nl)", + "__author": "\"Roywcm\"", "add_rule": "Nieuwe regel", "add_group": "Nieuwe groep", "delete_rule": "Verwijder", @@ -54,4 +69,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "datetime_exceed_min": "Dient na {0}", "datetime_exceed_max": "Dient voor {0}" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'nl' }); +})); \ No newline at end of file diff --git a/dist/i18n/no.js b/dist/i18n/query-builder.no.js similarity index 62% rename from dist/i18n/no.js rename to dist/i18n/query-builder.no.js index 4cb671f3..62f933dc 100644 --- a/dist/i18n/no.js +++ b/dist/i18n/query-builder.no.js @@ -1,10 +1,25 @@ /*! - * jQuery QueryBuilder 2.0.1 - * Oversat af Jna Borup Coyle, github@coyle.dk + * jQuery QueryBuilder 2.1.0 + * Locale: Norwegian (no) + * Author: Jna Borup Coyle, github@coyle.dk * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['no'] = { + "__locale": "Norwegian (no)", + "__author": "Jna Borup Coyle, github@coyle.dk", "add_rule": "Legg til regel", "add_group": "Legg til gruppe", "delete_rule": "Slett regel", @@ -33,4 +48,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "is_null": "er null", "is_not_null": "er ikke null" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'no' }); +})); \ No newline at end of file diff --git a/dist/i18n/pl.js b/dist/i18n/query-builder.pl.js similarity index 79% rename from dist/i18n/pl.js rename to dist/i18n/query-builder.pl.js index b02b029f..dc1e4f19 100644 --- a/dist/i18n/pl.js +++ b/dist/i18n/query-builder.pl.js @@ -1,10 +1,25 @@ /*! - * jQuery QueryBuilder 2.0.1 - * Polish translation by Artur Smolarek + * jQuery QueryBuilder 2.1.0 + * Locale: Polish (pl) + * Author: Artur Smolarek * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['pl'] = { + "__locale": "Polish (pl)", + "__author": "Artur Smolarek", "add_rule": "Dodaj regułę", "add_group": "Dodaj grupę", "delete_rule": "Usuń", @@ -54,4 +69,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "datetime_exceed_min": "Musi być po {0}", "datetime_exceed_max": "Musi być przed {0}" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'pl' }); +})); \ No newline at end of file diff --git a/dist/i18n/pt-BR.js b/dist/i18n/query-builder.pt-BR.js similarity index 76% rename from dist/i18n/pt-BR.js rename to dist/i18n/query-builder.pt-BR.js index 4c04a7c4..bfb6da2d 100644 --- a/dist/i18n/pt-BR.js +++ b/dist/i18n/query-builder.pt-BR.js @@ -1,10 +1,25 @@ /*! - * jQuery QueryBuilder 2.0.1 - * Portuguese Brazilian translation by Leandro Gehlen (leandrogehlen@gmail.com) + * jQuery QueryBuilder 2.1.0 + * Locale: Brazilian Portuguese (pr-BR) + * Author: Leandro Gehlen, leandrogehlen@gmail.com * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['pt-BR'] = { + "__locale": "Brazilian Portuguese (pr-BR)", + "__author": "Leandro Gehlen, leandrogehlen@gmail.com", "add_rule": "Nova Regra", "add_group": "Novo Gruop", "delete_rule": "Excluir", @@ -54,4 +69,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "datetime_exceed_min": "É necessário ser superior a {0}", "datetime_exceed_max": "É necessário ser inferior a {0}" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'pt-BR' }); +})); \ No newline at end of file diff --git a/dist/i18n/ro.js b/dist/i18n/query-builder.ro.js similarity index 63% rename from dist/i18n/ro.js rename to dist/i18n/query-builder.ro.js index 92e59a4e..094baaa9 100644 --- a/dist/i18n/ro.js +++ b/dist/i18n/query-builder.ro.js @@ -1,10 +1,25 @@ /*! - * jQuery QueryBuilder 2.0.1 - * Romanian translation by ArianServ + * jQuery QueryBuilder 2.1.0 + * Locale: Romanian (ro) + * Author: ArianServ * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['ro'] = { + "__locale": "Romanian (ro)", + "__author": "ArianServ", "add_rule": "Adaugă regulă", "add_group": "Adaugă grup", "delete_rule": "Şterge", @@ -33,4 +48,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "is_null": "e nul", "is_not_null": "nu e nul" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'ro' }); +})); \ No newline at end of file diff --git a/dist/i18n/ru.js b/dist/i18n/query-builder.ru.js similarity index 85% rename from dist/i18n/ru.js rename to dist/i18n/query-builder.ru.js index 5266210e..fae6482f 100644 --- a/dist/i18n/ru.js +++ b/dist/i18n/query-builder.ru.js @@ -1,10 +1,23 @@ /*! - * jQuery QueryBuilder 2.0.1 - * Локализационный файл + * jQuery QueryBuilder 2.1.0 + * Locale: Russian (ru) * Licensed under MIT (http://opensource.org/licenses/MIT) */ -jQuery.fn.queryBuilder.defaults({ lang: { +(function(root, factory) { + if (typeof define === 'function' && define.amd) { + define(['jquery', 'query-builder'], factory); + } + else { + factory(root.jQuery); + } +}(this, function($) { +"use strict"; + +var QueryBuilder = $.fn.queryBuilder; + +QueryBuilder.regional['ru'] = { + "__locale": "Russian (ru)", "add_rule": "Добавить", "add_group": "Добавить группу", "delete_rule": "Удалить", @@ -57,4 +70,7 @@ jQuery.fn.queryBuilder.defaults({ lang: { "boolean_not_valid": "Не логическое", "operator_not_multiple": "Оператор {0} не поддерживает много значений" } -}}); \ No newline at end of file +}; + +QueryBuilder.defaults({ lang_code: 'ru' }); +})); \ No newline at end of file diff --git a/dist/js/query-builder.js b/dist/js/query-builder.js index b159e8f7..42669064 100644 --- a/dist/js/query-builder.js +++ b/dist/js/query-builder.js @@ -1,10 +1,11 @@ /*! - * jQuery QueryBuilder 2.0.1 + * jQuery QueryBuilder 2.1.0 * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr) * Licensed under MIT (http://opensource.org/licenses/MIT) */ -// Modules: bt-checkbox, bt-selectpicker, bt-tooltip-errors, filter-description, loopback-support, mongodb-support, sortable, sql-support, unique-filter +// Languages: en +// Plugins: bt-checkbox, bt-selectpicker, bt-tooltip-errors, filter-description, loopback-support, mongodb-support, sortable, sql-support, unique-filter (function(root, factory) { if (typeof define === 'function' && define.amd) { define(['jquery', 'jQuery.extendext'], factory); @@ -143,6 +144,9 @@ QueryBuilder.prototype.initPlugins = function() { }, this); }; +/** + * Allowed types and their internal representation + */ QueryBuilder.types = { 'string': 'string', 'integer': 'number', @@ -153,6 +157,9 @@ QueryBuilder.types = { 'boolean': 'boolean' }; +/** + * Allowed inputs + */ QueryBuilder.inputs = [ 'text', 'textarea', @@ -161,12 +168,23 @@ QueryBuilder.inputs = [ 'select' ]; +/** + * Runtime modifiable options with `setOptions` method + */ QueryBuilder.modifiable_options = [ 'display_errors', 'allow_groups', 'allow_empty' ]; +/** + * Localized strings (populated by `i18n` files) + */ +QueryBuilder.regional = {}; + +/** + * Default configuration + */ QueryBuilder.DEFAULTS = { filters: [], plugins: [], @@ -191,63 +209,8 @@ QueryBuilder.DEFAULTS = { rule: null }, - lang: { - "add_rule": 'Add rule', - "add_group": 'Add group', - "delete_rule": 'Delete', - "delete_group": 'Delete', - - "conditions": { - "AND": "AND", - "OR": "OR" - }, - - "operators": { - "equal": "equal", - "not_equal": "not equal", - "in": "in", - "not_in": "not in", - "less": "less", - "less_or_equal": "less or equal", - "greater": "greater", - "greater_or_equal": "greater or equal", - "between": "between", - "begins_with": "begins with", - "not_begins_with": "doesn't begin with", - "contains": "contains", - "not_contains": "doesn't contain", - "ends_with": "ends with", - "not_ends_with": "doesn't end with", - "is_empty": "is empty", - "is_not_empty": "is not empty", - "is_null": "is null", - "is_not_null": "is not null" - }, - - "errors": { - "no_filter": "No filter selected", - "empty_group": "The group is empty", - "radio_empty": "No value selected", - "checkbox_empty": "No value selected", - "select_empty": "No value selected", - "string_empty": "Empty value", - "string_exceed_min_length": "Must contain at least {0} characters", - "string_exceed_max_length": "Must not contain more than {0} characters", - "string_invalid_format": "Invalid format ({0})", - "number_nan": "Not a number", - "number_not_integer": "Not an integer", - "number_not_double": "Not a real number", - "number_exceed_min": "Must be greater than {0}", - "number_exceed_max": "Must be lower than {0}", - "number_wrong_step": "Must be a multiple of {0}", - "datetime_empty": "Empty value", - "datetime_invalid": "Invalid date format ({0})", - "datetime_exceed_min": "Must be after {0}", - "datetime_exceed_max": "Must be before {0}", - "boolean_not_valid": "Not a boolean", - "operator_not_multiple": "Operator {0} cannot accept multiple values" - } - }, + lang_code: 'en', + lang: {}, operators: [ {type: 'equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean']}, @@ -295,7 +258,8 @@ QueryBuilder.prototype.init = function($el, options) { rule_id: 0, generated_id: false, has_optgroup: false, - id: null + id: null, + updating_value: false }; // "allow_groups" can be boolean or int @@ -308,11 +272,16 @@ QueryBuilder.prototype.init = function($el, options) { // SETTINGS SHORTCUTS this.filters = this.settings.filters; - this.lang = this.settings.lang; this.icons = this.settings.icons; this.operators = this.settings.operators; this.template = this.settings.template; this.plugins = this.settings.plugins; + + // translations : english << 'lang_code' << custom + if (QueryBuilder.regional['en'] === undefined) { + error('"i18n/en.js" not loaded.'); + } + this.lang = $.extendext(true, 'replace', {}, QueryBuilder.regional['en'], QueryBuilder.regional[this.settings.lang_code], this.settings.lang); if (this.template.group === null) { this.template.group = this.getGroupTemplate; @@ -521,6 +490,10 @@ QueryBuilder.prototype.bindEvents = function() { case 'flags': that.applyRuleFlags(node); break; + + case 'value': + that.updateRuleValue(node); + break; } } }); @@ -529,9 +502,10 @@ QueryBuilder.prototype.bindEvents = function() { /** * Create the root group * @param addRule {bool,optional} add a default empty rule + * @param data {mixed,optional} group custom data * @return group {Root} */ -QueryBuilder.prototype.setRoot = function(addRule) { +QueryBuilder.prototype.setRoot = function(addRule, data) { addRule = (addRule === undefined || addRule === true); var group_id = this.nextGroupId(), @@ -542,6 +516,10 @@ QueryBuilder.prototype.setRoot = function(addRule) { this.model.root.model = this.model; this.model.root.condition = this.settings.default_condition; + if (data !== undefined) { + this.model.root.data = data; + } + if (addRule) { this.addRule(this.model.root); } @@ -553,9 +531,10 @@ QueryBuilder.prototype.setRoot = function(addRule) { * Add a new group * @param parent {Group} * @param addRule {bool,optional} add a default empty rule + * @param data {mixed,optional} group custom data * @return group {Group} */ -QueryBuilder.prototype.addGroup = function(parent, addRule) { +QueryBuilder.prototype.addGroup = function(parent, addRule, data) { addRule = (addRule === undefined || addRule === true); var level = parent.level + 1; @@ -569,6 +548,10 @@ QueryBuilder.prototype.addGroup = function(parent, addRule) { $group = $(this.template.group.call(this, group_id, level)), model = parent.addGroup($group); + if (data !== undefined) { + model.data = data; + } + this.trigger('afterAddGroup', model); model.condition = this.settings.default_condition; @@ -621,14 +604,17 @@ QueryBuilder.prototype.updateGroupCondition = function(group) { $this.prop('checked', $this.val() === group.condition); $this.parent().toggleClass('active', $this.val() === group.condition); }); + + this.trigger('afterUpdateGroupCondition', group); }; /** * Add a new rule * @param parent {Group} + * @param data {mixed,optional} rule custom data * @return rule {Rule} */ -QueryBuilder.prototype.addRule = function(parent) { +QueryBuilder.prototype.addRule = function(parent, data) { var e = this.trigger('beforeAddRule', parent); if (e.isDefaultPrevented()) { return null; @@ -638,6 +624,10 @@ QueryBuilder.prototype.addRule = function(parent) { $rule = $(this.template.rule.call(this, rule_id)), model = parent.addRule($rule); + if (data !== undefined) { + model.data = data; + } + this.trigger('afterAddRule', model); this.createRuleFilters(model); @@ -685,7 +675,7 @@ QueryBuilder.prototype.createRuleFilters = function(rule) { * Create the operators '+g+" "}return this.change("getGroupConditions",c,b)},j.prototype.getRuleTemplate=function(a){var b='
  • "+(this.settings.display_errors?'
    ':"")+'
  • ';return this.change("getRuleTemplate",b)},j.prototype.getRuleFilterSelect=function(a,b){var c=null,d='",this.change("getRuleFilterSelect",d,a)},j.prototype.getRuleOperatorSelect=function(a,b){for(var c='",this.change("getRuleOperatorSelect",c,a)},j.prototype.getRuleInput=function(a,b){var d=a.filter,e=a.filter.validation||{},f=a.id+"_value_"+b,g=d.vertical?" class=block":"",h="";if("function"==typeof d.input)h=d.input.call(this,a,f);else switch(d.input){case"radio":c(d.values,function(a,b){h+=" '+b+" "});break;case"checkbox":c(d.values,function(a,b){h+=" '+b+" "});break;case"select":h+='";break;case"textarea":h+='";break;default:switch(j.types[d.type]){case"number":h+='=f:f>=e},i=!1;h()&&(this.rules[e]instanceof m?void 0!==c&&(i=c.call(d,this.rules[e])===!1):i=b.call(d,this.rules[e])===!1,!i);e+=g);return!i},m.prototype.contains=function(a,b){return-1!==this.getNodePos(a)?!0:b?!this.each(function(){return!0},function(b){return!b.contains(a,!0)}):!1};var n=function(a,b){return this instanceof n?(l.call(this,a,b),this.__.filter=null,this.__.operator=null,this.__.flags={},void(this.__.value=void 0)):new n(a,b)};n.prototype=Object.create(l.prototype),n.prototype.constructor=n,b(n,["filter","operator","flags","value"]),j.Group=m,j.Rule=n,$.fn.queryBuilder=function(a){this.length>1&&e("Unable to initialize on multiple target");var b=this.data("queryBuilder"),c="object"==typeof a&&a||{};return b||"destroy"!=a?(b||this.data("queryBuilder",new j(this,c)),"string"==typeof a?b[a].apply(b,Array.prototype.slice.call(arguments,1)):this):this},$.fn.queryBuilder.constructor=j,$.fn.queryBuilder.defaults=j.defaults,$.fn.queryBuilder.extend=j.extend,$.fn.queryBuilder.define=j.define,$.fn.queryBuilder.regional=j.regional,j.define("bt-checkbox",function(a){if("glyphicons"==a.font){var b=document.createElement("style");b.innerHTML='.checkbox input[type=checkbox]:checked + label:after { font-family: "Glyphicons Halflings"; content: "\\e013"; } .checkbox label:after { padding-left: 4px; padding-top: 2px; font-size: 9px; }',document.body.appendChild(b)}this.on("getRuleInput.filter",function(b,d,e){var f=d.filter;if(("radio"===f.input||"checkbox"===f.input)&&!f.plugin){b.value="",f.colors||(f.colors={}),f.color&&(f.colors._def_=f.color);var g,h,i=f.vertical?' style="display:block"':"",j=0;c(f.values,function(c,d){g=f.colors[c]||f.colors._def_||a.color,h=e+"_"+j++,b.value+=" "})}})},{font:"glyphicons",color:"default"}),j.define("bt-selectpicker",function(a){$.fn.selectpicker&&$.fn.selectpicker.Constructor||e('Bootstrap Select is required to use "bt-selectpicker" plugin. Get it here: http://silviomoreto.github.io/bootstrap-select'),this.on("afterCreateRuleFilters",function(b,c){c.$el.find(".rule-filter-container select").removeClass("form-control").selectpicker(a)}),this.on("afterCreateRuleOperators",function(b,c){c.$el.find(".rule-operator-container select").removeClass("form-control").selectpicker(a)}),this.on("afterUpdateRuleFilter",function(a,b){b.$el.find(".rule-filter-container select").selectpicker("render")}),this.on("afterUpdateRuleOperator",function(a,b){b.$el.find(".rule-operator-container select").selectpicker("render")})},{container:"body",style:"btn-inverse btn-xs",width:"auto",showIcon:!1}),j.define("bt-tooltip-errors",function(a){$.fn.tooltip&&$.fn.tooltip.Constructor&&$.fn.tooltip.Constructor.prototype.fixTitle||e('Bootstrap Tooltip is required to use "bt-tooltip-errors" plugin. Get it here: http://getbootstrap.com');var b=this;this.on("getRuleTemplate.filter",function(a){a.value=a.value.replace('class="error-container"','class="error-container" data-toggle="tooltip"')}),this.on("getGroupTemplate.filter",function(a){a.value=a.value.replace('class="error-container"','class="error-container" data-toggle="tooltip"')}),this.model.on("update",function(c,d,e){"error"==e&&b.settings.display_errors&&d.$el.find(".error-container").eq(0).tooltip(a).tooltip("hide").tooltip("fixTitle")})},{placement:"right"}),j.define("filter-description",function(a){"inline"===a.mode?this.on("afterUpdateRuleFilter",function(b,c){var d=c.$el.find("p.filter-description");c.filter&&c.filter.description?(0===d.length?(d=$('

    '),d.appendTo(c.$el)):d.show(),d.html(' '+c.filter.description)):d.hide()}):"popover"===a.mode?($.fn.popover&&$.fn.popover.Constructor&&$.fn.popover.Constructor.prototype.fixTitle||e('Bootstrap Popover is required to use "filter-description" plugin. Get it here: http://getbootstrap.com'), +this.on("afterUpdateRuleFilter",function(b,c){var d=c.$el.find("button.filter-description");c.filter&&c.filter.description?(0===d.length?(d=$(''),d.prependTo(c.$el.find(".rule-actions")),d.popover({placement:"left",container:"body",html:!0}),d.on("mouseout",function(){d.popover("hide")})):d.show(),d.data("bs.popover").options.content=c.filter.description,d.attr("aria-describedby")&&d.popover("show")):(d.hide(),d.data("bs.popover")&&d.popover("hide"))})):"bootbox"===a.mode&&("bootbox"in window||e('Bootbox is required to use "filter-description" plugin. Get it here: http://bootboxjs.com'),this.on("afterUpdateRuleFilter",function(b,c){var d=c.$el.find("button.filter-description");c.filter&&c.filter.description?(0===d.length&&(d=$(''),d.prependTo(c.$el.find(".rule-actions")),d.on("click",function(){bootbox.alert(d.data("description"))})),d.data("description",c.filter.description)):d.hide()}))},{icon:"glyphicon glyphicon-info-sign",mode:"popover"}),j.defaults({loopbackOperators:{equal:function(a){return a[0]},not_equal:function(a){return{neq:a[0]}},"in":function(a){return{inq:a}},not_in:function(a){return{nin:a}},less:function(a){return{lt:a[0]}},less_or_equal:function(a){return{lte:a[0]}},greater:function(a){return{gt:a[0]}},greater_or_equal:function(a){return{gte:a[0]}},between:function(a){return{between:a}},begins_with:function(a){return{like:"^"+h(a[0])}},not_begins_with:function(a){return{nlike:"^"+h(a[0])}},contains:function(a){return{like:h(a[0])}},not_contains:function(a){return{nlike:h(a[0])}},ends_with:function(a){return{like:h(a[0])+"$"}},not_ends_with:function(a){return{nlike:h(a[0])+"$"}},is_empty:function(){return""},is_not_empty:function(){return{neq:""}},is_null:function(){return null},is_not_null:function(){return{neq:null}}}}),j.extend({getLoopback:function(a){a=void 0===a?this.getRules():a;var b=this;return function c(a){if(a.condition||(a.condition=b.settings.default_condition),-1===["AND","OR"].indexOf(a.condition.toUpperCase())&&e('Unable to build Loopback query with condition "{0}"',a.condition),!a.rules)return{};var d=[];a.rules.forEach(function(a){if(a.rules&&a.rules.length>0)d.push(c(a));else{var g=b.settings.loopbackOperators[a.operator],h=b.getOperatorByType(a.operator),i=[];void 0===g&&e('Unknown Loopback operation for operator "{0}"',a.operator),0!==h.nb_inputs&&(a.value instanceof Array||(a.value=[a.value]),a.value.forEach(function(b){i.push(f(b,a.type))}));var j={};j[a.field]=g.call(b,i),d.push(j)}});var g={};return d.length>0&&(g[a.condition.toLowerCase()]=d),g}(a)}}),j.defaults({mongoOperators:{equal:function(a){return a[0]},not_equal:function(a){return{$ne:a[0]}},"in":function(a){return{$in:a}},not_in:function(a){return{$nin:a}},less:function(a){return{$lt:a[0]}},less_or_equal:function(a){return{$lte:a[0]}},greater:function(a){return{$gt:a[0]}},greater_or_equal:function(a){return{$gte:a[0]}},between:function(a){return{$gte:a[0],$lte:a[1]}},begins_with:function(a){return{$regex:"^"+h(a[0])}},not_begins_with:function(a){return{$regex:"^(?!"+h(a[0])+")"}},contains:function(a){return{$regex:h(a[0])}},not_contains:function(a){return{$regex:"^((?!"+h(a[0])+").)*$",$options:"s"}},ends_with:function(a){return{$regex:h(a[0])+"$"}},not_ends_with:function(a){return{$regex:"(?0)d.push(c(a));else{var g=b.settings.mongoOperators[a.operator],h=b.getOperatorByType(a.operator),i=[];void 0===g&&e('Unknown MongoDB operation for operator "{0}"',a.operator),0!==h.nb_inputs&&(a.value instanceof Array||(a.value=[a.value]),a.value.forEach(function(b){i.push(f(b,a.type,!1))}));var j={};j[a.field]=g.call(b,i),d.push(j)}});var g={};return d.length>0&&(g["$"+a.condition.toLowerCase()]=d),g}(a)},getRulesFromMongo:function(a){if(void 0===a||null===a)return null;var b=this,c=["$and","$or"];return function d(a){var f=Object.keys(a);f.length>1&&e("Invalid MongoDB query format."),-1===c.indexOf(f[0].toLowerCase())&&e('Unable to build Rule from MongoDB query with condition "{0}"',f[0]);var g=f[0].toLowerCase()===c[0]?"AND":"OR",h=a[f[0]],i=[];h.forEach(function(a){var f=Object.keys(a);if(-1!==c.indexOf(f[0].toLowerCase()))i.push(d(a));else{var g=f[0],h=a[g],j=b.determineMongoOperator(h,g);void 0===j&&e("Invalid MongoDB query format.");var k=b.settings.mongoRuleOperators[j];void 0===k&&e('JSON Rule operation unknown for operator "{0}"',j);var l=k.call(b,h);i.push({id:b.change("getMongoDBFieldID",g,h),field:g,operator:l.op,value:l.val})}});var j={};return i.length>0&&(j.condition=g,j.rules=i),j}(a)},determineMongoOperator:function(a){if(null!==a&&"object"==typeof a){var b=Object.keys(a);return 1===b.length?b[0]:void 0!==a.$gte&&void 0!==a.$lte?"between":void 0!==a.$regex?"$regex":void 0}return"eq"},setRulesFromMongo:function(a){this.setRules(this.getRulesFromMongo(a))}}),j.define("sortable",function(b){this.on("afterInit",function(b){$.event.props.push("dataTransfer");var c,d,e=b.builder;e.$el.on("mouseover",".drag-handle",function(){e.$el.find(".rule-container, .rules-group-container").attr("draggable",!0)}),e.$el.on("mouseout",".drag-handle",function(){e.$el.find(".rule-container, .rules-group-container").removeAttr("draggable")}),e.$el.on("dragstart","[draggable]",function(b){b.stopPropagation(),b.dataTransfer.setData("text","drag"),d=a(b.target),setTimeout(function(){var a=$('
     
    ');a.css("min-height",d.$el.height()),c=d.parent.addRule(a,d.getPos()),d.$el.hide()},0)}),e.$el.on("dragenter","[draggable]",function(a){a.preventDefault(),a.stopPropagation(),c&&i(c,$(a.target))}),e.$el.on("dragover","[draggable]",function(a){a.preventDefault(),a.stopPropagation()}),e.$el.on("drop",function(a){a.preventDefault(),a.stopPropagation(),i(d,$(a.target))}),e.$el.on("dragend","[draggable]",function(a){a.preventDefault(),a.stopPropagation(),d.$el.show(),c.drop(),d=c=null,e.$el.find(".rule-container, .rules-group-container").removeAttr("draggable")})}),this.on("parseRuleFlags.filter",function(a){void 0===a.value.no_sortable&&(a.value.no_sortable=b.default_no_sortable)}),this.on("afterApplyRuleFlags",function(a,b){b.flags.no_sortable&&b.$el.find(".drag-handle").remove()}),this.on("getGroupTemplate.filter",function(a,c){if(c>1){var d=$(a.value);d.find(".group-conditions").after('
    '),a.value=d.prop("outerHTML")}}),this.on("getRuleTemplate.filter",function(a){var c=$(a.value);c.find(".rule-header").after('
    '),a.value=c.prop("outerHTML")})},{default_no_sortable:!1,icon:"glyphicon glyphicon-sort"}),j.defaults({sqlOperators:{equal:"= ?",not_equal:"!= ?","in":{op:"IN(?)",sep:", "},not_in:{op:"NOT IN(?)",sep:", "},less:"< ?",less_or_equal:"<= ?",greater:"> ?",greater_or_equal:">= ?",between:{op:"BETWEEN ?",sep:" AND "},begins_with:{op:"LIKE(?)",fn:function(a){return a+"%"}},not_begins_with:{op:"NOT LIKE(?)",fn:function(a){return a+"%"}},contains:{op:"LIKE(?)",fn:function(a){return"%"+a+"%"}},not_contains:{op:"NOT LIKE(?)",fn:function(a){return"%"+a+"%"}},ends_with:{op:"LIKE(?)",fn:function(a){return"%"+a}},not_ends_with:{op:"NOT LIKE(?)",fn:function(a){return"%"+a}},is_empty:'== ""',is_not_empty:'!= ""',is_null:"IS NULL",is_not_null:"IS NOT NULL"},sqlStatements:{question_mark:function(){var a=[];return{add:function(b,c){return a.push(c),"?"},run:function(){return a}}},numbered:function(){var a=0,b=[];return{add:function(c,d){return b.push(d),a++,"$"+a},run:function(){return b}}},named:function(){var a={},b={};return{add:function(c,d){a[c.field]||(a[c.field]=0),a[c.field]++;var e=c.field+"_"+a[c.field];return b[e]=d,":"+e},run:function(){return b}}}}}),j.extend({getSQL:function(a,b,c){c=void 0===c?this.getRules():c,b=b===!0?"\n":" ",(a===!0||void 0===a)&&(a="question_mark"),"string"==typeof a&&(a=this.settings.sqlStatements[a]());var d=this,h=function i(c){if(c.condition||(c.condition=d.settings.default_condition),-1===["AND","OR"].indexOf(c.condition.toUpperCase())&&e('Unable to build SQL query with condition "{0}"',c.condition),!c.rules)return"";var h=[];return c.rules.forEach(function(c){if(c.rules&&c.rules.length>0)h.push("("+b+i(c)+b+")"+b);else{var j=d.getSqlOperator(c.operator),k=d.getOperatorByType(c.operator),l="";j===!1&&e('Unknown SQL operation for operator "{0}"',c.operator),0!==k.nb_inputs&&(c.value instanceof Array||(c.value=[c.value]),c.value.forEach(function(b,d){d>0&&(l+=j.sep),"integer"==c.type||"double"==c.type||"boolean"==c.type?b=f(b,c.type,!0):a||(b=g(b)),j.fn&&(b=j.fn(b)),a?l+=a.add(c,b):("string"==typeof b&&(b="'"+b+"'"),l+=b)})),h.push(c.field+" "+j.op.replace(/\?/,l))}}),h.join(" "+c.condition+b)}(c);return a?{sql:h,params:a.run()}:{sql:h}},getSqlOperator:function(a){var b=this.settings.sqlOperators[a];return void 0===b?!1:("string"==typeof b&&(b={op:b}),b.list&&!b.sep&&(b.sep=", "),b)}}),j.define("unique-filter",function(){this.status.used_filters={},this.on("afterUpdateRuleFilter",this.updateDisabledFilters),this.on("afterDeleteRule",this.updateDisabledFilters),this.on("afterCreateRuleFilters",this.applyDisabledFilters)}),j.extend({updateDisabledFilters:function(a){var b=a.builder;b.status.used_filters={},b.model&&(!function c(a){a.each(function(a){a.filter&&a.filter.unique&&(b.status.used_filters[a.filter.id]||(b.status.used_filters[a.filter.id]=[]),"group"==a.filter.unique&&b.status.used_filters[a.filter.id].push(a.parent))},function(a){c(a)})}(b.model.root),b.applyDisabledFilters(a))},applyDisabledFilters:function(a){var b=a.builder;b.$el.find(".rule-filter-container option").prop("disabled",!1),$.each(b.status.used_filters,function(a,c){0===c.length?b.$el.find('.rule-filter-container option[value="'+a+'"]:not(:selected)').prop("disabled",!0):c.forEach(function(b){b.each(function(b){b.$el.find('.rule-filter-container option[value="'+a+'"]:not(:selected)').prop("disabled",!0)})})}),b.settings.plugins&&b.settings.plugins["bt-selectpicker"]&&b.$el.find(".rule-filter-container select").selectpicker("render")}}),j.regional.en={__locale:"English (en)",__author:'Damien "Mistic" Sorel, http://www.strangeplanet.fr',add_rule:"Add rule",add_group:"Add group",delete_rule:"Delete",delete_group:"Delete",conditions:{AND:"AND",OR:"OR"},operators:{equal:"equal",not_equal:"not equal","in":"in",not_in:"not in",less:"less",less_or_equal:"less or equal",greater:"greater",greater_or_equal:"greater or equal",between:"between",begins_with:"begins with",not_begins_with:"doesn't begin with",contains:"contains",not_contains:"doesn't contain",ends_with:"ends with",not_ends_with:"doesn't end with",is_empty:"is empty",is_not_empty:"is not empty",is_null:"is null",is_not_null:"is not null"},errors:{no_filter:"No filter selected",empty_group:"The group is empty",radio_empty:"No value selected",checkbox_empty:"No value selected",select_empty:"No value selected",string_empty:"Empty value",string_exceed_min_length:"Must contain at least {0} characters",string_exceed_max_length:"Must not contain more than {0} characters",string_invalid_format:"Invalid format ({0})",number_nan:"Not a number",number_not_integer:"Not an integer",number_not_double:"Not a real number",number_exceed_min:"Must be greater than {0}",number_exceed_max:"Must be lower than {0}",number_wrong_step:"Must be a multiple of {0}",datetime_empty:"Empty value",datetime_invalid:"Invalid date format ({0})",datetime_exceed_min:"Must be after {0}",datetime_exceed_max:"Must be before {0}",boolean_not_valid:"Not a boolean",operator_not_multiple:"Operator {0} cannot accept multiple values"}},j.defaults({lang_code:"en"})}); \ No newline at end of file diff --git a/dist/js/query-builder.standalone.js b/dist/js/query-builder.standalone.js index 1f7bc4f0..d1fcec19 100644 --- a/dist/js/query-builder.standalone.js +++ b/dist/js/query-builder.standalone.js @@ -124,12 +124,13 @@ })); /*! - * jQuery QueryBuilder 2.0.1 + * jQuery QueryBuilder 2.1.0 * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr) * Licensed under MIT (http://opensource.org/licenses/MIT) */ -// Modules: bt-checkbox, bt-selectpicker, bt-tooltip-errors, filter-description, loopback-support, mongodb-support, sortable, sql-support, unique-filter +// Languages: en +// Plugins: bt-checkbox, bt-selectpicker, bt-tooltip-errors, filter-description, loopback-support, mongodb-support, sortable, sql-support, unique-filter (function(root, factory) { if (typeof define === 'function' && define.amd) { define('query-builder', ['jquery', 'jQuery.extendext'], factory); @@ -268,6 +269,9 @@ QueryBuilder.prototype.initPlugins = function() { }, this); }; +/** + * Allowed types and their internal representation + */ QueryBuilder.types = { 'string': 'string', 'integer': 'number', @@ -278,6 +282,9 @@ QueryBuilder.types = { 'boolean': 'boolean' }; +/** + * Allowed inputs + */ QueryBuilder.inputs = [ 'text', 'textarea', @@ -286,12 +293,23 @@ QueryBuilder.inputs = [ 'select' ]; +/** + * Runtime modifiable options with `setOptions` method + */ QueryBuilder.modifiable_options = [ 'display_errors', 'allow_groups', 'allow_empty' ]; +/** + * Localized strings (populated by `i18n` files) + */ +QueryBuilder.regional = {}; + +/** + * Default configuration + */ QueryBuilder.DEFAULTS = { filters: [], plugins: [], @@ -316,63 +334,8 @@ QueryBuilder.DEFAULTS = { rule: null }, - lang: { - "add_rule": 'Add rule', - "add_group": 'Add group', - "delete_rule": 'Delete', - "delete_group": 'Delete', - - "conditions": { - "AND": "AND", - "OR": "OR" - }, - - "operators": { - "equal": "equal", - "not_equal": "not equal", - "in": "in", - "not_in": "not in", - "less": "less", - "less_or_equal": "less or equal", - "greater": "greater", - "greater_or_equal": "greater or equal", - "between": "between", - "begins_with": "begins with", - "not_begins_with": "doesn't begin with", - "contains": "contains", - "not_contains": "doesn't contain", - "ends_with": "ends with", - "not_ends_with": "doesn't end with", - "is_empty": "is empty", - "is_not_empty": "is not empty", - "is_null": "is null", - "is_not_null": "is not null" - }, - - "errors": { - "no_filter": "No filter selected", - "empty_group": "The group is empty", - "radio_empty": "No value selected", - "checkbox_empty": "No value selected", - "select_empty": "No value selected", - "string_empty": "Empty value", - "string_exceed_min_length": "Must contain at least {0} characters", - "string_exceed_max_length": "Must not contain more than {0} characters", - "string_invalid_format": "Invalid format ({0})", - "number_nan": "Not a number", - "number_not_integer": "Not an integer", - "number_not_double": "Not a real number", - "number_exceed_min": "Must be greater than {0}", - "number_exceed_max": "Must be lower than {0}", - "number_wrong_step": "Must be a multiple of {0}", - "datetime_empty": "Empty value", - "datetime_invalid": "Invalid date format ({0})", - "datetime_exceed_min": "Must be after {0}", - "datetime_exceed_max": "Must be before {0}", - "boolean_not_valid": "Not a boolean", - "operator_not_multiple": "Operator {0} cannot accept multiple values" - } - }, + lang_code: 'en', + lang: {}, operators: [ {type: 'equal', nb_inputs: 1, multiple: false, apply_to: ['string', 'number', 'datetime', 'boolean']}, @@ -420,7 +383,8 @@ QueryBuilder.prototype.init = function($el, options) { rule_id: 0, generated_id: false, has_optgroup: false, - id: null + id: null, + updating_value: false }; // "allow_groups" can be boolean or int @@ -433,11 +397,16 @@ QueryBuilder.prototype.init = function($el, options) { // SETTINGS SHORTCUTS this.filters = this.settings.filters; - this.lang = this.settings.lang; this.icons = this.settings.icons; this.operators = this.settings.operators; this.template = this.settings.template; this.plugins = this.settings.plugins; + + // translations : english << 'lang_code' << custom + if (QueryBuilder.regional['en'] === undefined) { + error('"i18n/en.js" not loaded.'); + } + this.lang = $.extendext(true, 'replace', {}, QueryBuilder.regional['en'], QueryBuilder.regional[this.settings.lang_code], this.settings.lang); if (this.template.group === null) { this.template.group = this.getGroupTemplate; @@ -646,6 +615,10 @@ QueryBuilder.prototype.bindEvents = function() { case 'flags': that.applyRuleFlags(node); break; + + case 'value': + that.updateRuleValue(node); + break; } } }); @@ -654,9 +627,10 @@ QueryBuilder.prototype.bindEvents = function() { /** * Create the root group * @param addRule {bool,optional} add a default empty rule + * @param data {mixed,optional} group custom data * @return group {Root} */ -QueryBuilder.prototype.setRoot = function(addRule) { +QueryBuilder.prototype.setRoot = function(addRule, data) { addRule = (addRule === undefined || addRule === true); var group_id = this.nextGroupId(), @@ -667,6 +641,10 @@ QueryBuilder.prototype.setRoot = function(addRule) { this.model.root.model = this.model; this.model.root.condition = this.settings.default_condition; + if (data !== undefined) { + this.model.root.data = data; + } + if (addRule) { this.addRule(this.model.root); } @@ -678,9 +656,10 @@ QueryBuilder.prototype.setRoot = function(addRule) { * Add a new group * @param parent {Group} * @param addRule {bool,optional} add a default empty rule + * @param data {mixed,optional} group custom data * @return group {Group} */ -QueryBuilder.prototype.addGroup = function(parent, addRule) { +QueryBuilder.prototype.addGroup = function(parent, addRule, data) { addRule = (addRule === undefined || addRule === true); var level = parent.level + 1; @@ -694,6 +673,10 @@ QueryBuilder.prototype.addGroup = function(parent, addRule) { $group = $(this.template.group.call(this, group_id, level)), model = parent.addGroup($group); + if (data !== undefined) { + model.data = data; + } + this.trigger('afterAddGroup', model); model.condition = this.settings.default_condition; @@ -746,14 +729,17 @@ QueryBuilder.prototype.updateGroupCondition = function(group) { $this.prop('checked', $this.val() === group.condition); $this.parent().toggleClass('active', $this.val() === group.condition); }); + + this.trigger('afterUpdateGroupCondition', group); }; /** * Add a new rule * @param parent {Group} + * @param data {mixed,optional} rule custom data * @return rule {Rule} */ -QueryBuilder.prototype.addRule = function(parent) { +QueryBuilder.prototype.addRule = function(parent, data) { var e = this.trigger('beforeAddRule', parent); if (e.isDefaultPrevented()) { return null; @@ -763,6 +749,10 @@ QueryBuilder.prototype.addRule = function(parent) { $rule = $(this.template.rule.call(this, rule_id)), model = parent.addRule($rule); + if (data !== undefined) { + model.data = data; + } + this.trigger('afterAddRule', model); this.createRuleFilters(model); @@ -810,7 +800,7 @@ QueryBuilder.prototype.createRuleFilters = function(rule) { * Create the operators '+g+" "}return this.change("getGroupConditions",c,b)},j.prototype.getRuleTemplate=function(a){var b='
  • "+(this.settings.display_errors?'
    ':"")+'
  • ';return this.change("getRuleTemplate",b)},j.prototype.getRuleFilterSelect=function(a,b){var c=null,d='",this.change("getRuleFilterSelect",d,a)},j.prototype.getRuleOperatorSelect=function(a,b){for(var c='",this.change("getRuleOperatorSelect",c,a)},j.prototype.getRuleInput=function(a,b){var d=a.filter,e=a.filter.validation||{},f=a.id+"_value_"+b,g=d.vertical?" class=block":"",h="";if("function"==typeof d.input)h=d.input.call(this,a,f);else switch(d.input){case"radio":c(d.values,function(a,b){h+=" '+b+" "});break;case"checkbox":c(d.values,function(a,b){h+=" '+b+" "});break;case"select":h+='";break;case"textarea":h+='";break;default:switch(j.types[d.type]){case"number":h+='=f:f>=e},i=!1;h()&&(this.rules[e]instanceof m?void 0!==c&&(i=c.call(d,this.rules[e])===!1):i=b.call(d,this.rules[e])===!1,!i);e+=g);return!i},m.prototype.contains=function(a,b){return-1!==this.getNodePos(a)?!0:b?!this.each(function(){return!0},function(b){return!b.contains(a,!0)}):!1};var n=function(a,b){return this instanceof n?(l.call(this,a,b),this.__.filter=null,this.__.operator=null,this.__.flags={},void(this.__.value=void 0)):new n(a,b)};n.prototype=Object.create(l.prototype),n.prototype.constructor=n,b(n,["filter","operator","flags","value"]),j.Group=m,j.Rule=n,$.fn.queryBuilder=function(a){this.length>1&&e("Unable to initialize on multiple target");var b=this.data("queryBuilder"),c="object"==typeof a&&a||{};return b||"destroy"!=a?(b||this.data("queryBuilder",new j(this,c)),"string"==typeof a?b[a].apply(b,Array.prototype.slice.call(arguments,1)):this):this},$.fn.queryBuilder.constructor=j,$.fn.queryBuilder.defaults=j.defaults,$.fn.queryBuilder.extend=j.extend,$.fn.queryBuilder.define=j.define,$.fn.queryBuilder.regional=j.regional,j.define("bt-checkbox",function(a){if("glyphicons"==a.font){var b=document.createElement("style");b.innerHTML='.checkbox input[type=checkbox]:checked + label:after { font-family: "Glyphicons Halflings"; content: "\\e013"; } .checkbox label:after { padding-left: 4px; padding-top: 2px; font-size: 9px; }',document.body.appendChild(b)}this.on("getRuleInput.filter",function(b,d,e){var f=d.filter;if(("radio"===f.input||"checkbox"===f.input)&&!f.plugin){b.value="",f.colors||(f.colors={}),f.color&&(f.colors._def_=f.color);var g,h,i=f.vertical?' style="display:block"':"",j=0;c(f.values,function(c,d){g=f.colors[c]||f.colors._def_||a.color,h=e+"_"+j++,b.value+=" "})}})},{font:"glyphicons",color:"default"}),j.define("bt-selectpicker",function(a){$.fn.selectpicker&&$.fn.selectpicker.Constructor||e('Bootstrap Select is required to use "bt-selectpicker" plugin. Get it here: http://silviomoreto.github.io/bootstrap-select'),this.on("afterCreateRuleFilters",function(b,c){c.$el.find(".rule-filter-container select").removeClass("form-control").selectpicker(a)}),this.on("afterCreateRuleOperators",function(b,c){c.$el.find(".rule-operator-container select").removeClass("form-control").selectpicker(a)}),this.on("afterUpdateRuleFilter",function(a,b){b.$el.find(".rule-filter-container select").selectpicker("render")}),this.on("afterUpdateRuleOperator",function(a,b){b.$el.find(".rule-operator-container select").selectpicker("render")})},{container:"body",style:"btn-inverse btn-xs",width:"auto",showIcon:!1}),j.define("bt-tooltip-errors",function(a){$.fn.tooltip&&$.fn.tooltip.Constructor&&$.fn.tooltip.Constructor.prototype.fixTitle||e('Bootstrap Tooltip is required to use "bt-tooltip-errors" plugin. Get it here: http://getbootstrap.com'); + +var b=this;this.on("getRuleTemplate.filter",function(a){a.value=a.value.replace('class="error-container"','class="error-container" data-toggle="tooltip"')}),this.on("getGroupTemplate.filter",function(a){a.value=a.value.replace('class="error-container"','class="error-container" data-toggle="tooltip"')}),this.model.on("update",function(c,d,e){"error"==e&&b.settings.display_errors&&d.$el.find(".error-container").eq(0).tooltip(a).tooltip("hide").tooltip("fixTitle")})},{placement:"right"}),j.define("filter-description",function(a){"inline"===a.mode?this.on("afterUpdateRuleFilter",function(b,c){var d=c.$el.find("p.filter-description");c.filter&&c.filter.description?(0===d.length?(d=$('

    '),d.appendTo(c.$el)):d.show(),d.html(' '+c.filter.description)):d.hide()}):"popover"===a.mode?($.fn.popover&&$.fn.popover.Constructor&&$.fn.popover.Constructor.prototype.fixTitle||e('Bootstrap Popover is required to use "filter-description" plugin. Get it here: http://getbootstrap.com'),this.on("afterUpdateRuleFilter",function(b,c){var d=c.$el.find("button.filter-description");c.filter&&c.filter.description?(0===d.length?(d=$(''),d.prependTo(c.$el.find(".rule-actions")),d.popover({placement:"left",container:"body",html:!0}),d.on("mouseout",function(){d.popover("hide")})):d.show(),d.data("bs.popover").options.content=c.filter.description,d.attr("aria-describedby")&&d.popover("show")):(d.hide(),d.data("bs.popover")&&d.popover("hide"))})):"bootbox"===a.mode&&("bootbox"in window||e('Bootbox is required to use "filter-description" plugin. Get it here: http://bootboxjs.com'),this.on("afterUpdateRuleFilter",function(b,c){var d=c.$el.find("button.filter-description");c.filter&&c.filter.description?(0===d.length&&(d=$(''),d.prependTo(c.$el.find(".rule-actions")),d.on("click",function(){bootbox.alert(d.data("description"))})),d.data("description",c.filter.description)):d.hide()}))},{icon:"glyphicon glyphicon-info-sign",mode:"popover"}),j.defaults({loopbackOperators:{equal:function(a){return a[0]},not_equal:function(a){return{neq:a[0]}},"in":function(a){return{inq:a}},not_in:function(a){return{nin:a}},less:function(a){return{lt:a[0]}},less_or_equal:function(a){return{lte:a[0]}},greater:function(a){return{gt:a[0]}},greater_or_equal:function(a){return{gte:a[0]}},between:function(a){return{between:a}},begins_with:function(a){return{like:"^"+h(a[0])}},not_begins_with:function(a){return{nlike:"^"+h(a[0])}},contains:function(a){return{like:h(a[0])}},not_contains:function(a){return{nlike:h(a[0])}},ends_with:function(a){return{like:h(a[0])+"$"}},not_ends_with:function(a){return{nlike:h(a[0])+"$"}},is_empty:function(){return""},is_not_empty:function(){return{neq:""}},is_null:function(){return null},is_not_null:function(){return{neq:null}}}}),j.extend({getLoopback:function(a){a=void 0===a?this.getRules():a;var b=this;return function c(a){if(a.condition||(a.condition=b.settings.default_condition),-1===["AND","OR"].indexOf(a.condition.toUpperCase())&&e('Unable to build Loopback query with condition "{0}"',a.condition),!a.rules)return{};var d=[];a.rules.forEach(function(a){if(a.rules&&a.rules.length>0)d.push(c(a));else{var g=b.settings.loopbackOperators[a.operator],h=b.getOperatorByType(a.operator),i=[];void 0===g&&e('Unknown Loopback operation for operator "{0}"',a.operator),0!==h.nb_inputs&&(a.value instanceof Array||(a.value=[a.value]),a.value.forEach(function(b){i.push(f(b,a.type))}));var j={};j[a.field]=g.call(b,i),d.push(j)}});var g={};return d.length>0&&(g[a.condition.toLowerCase()]=d),g}(a)}}),j.defaults({mongoOperators:{equal:function(a){return a[0]},not_equal:function(a){return{$ne:a[0]}},"in":function(a){return{$in:a}},not_in:function(a){return{$nin:a}},less:function(a){return{$lt:a[0]}},less_or_equal:function(a){return{$lte:a[0]}},greater:function(a){return{$gt:a[0]}},greater_or_equal:function(a){return{$gte:a[0]}},between:function(a){return{$gte:a[0],$lte:a[1]}},begins_with:function(a){return{$regex:"^"+h(a[0])}},not_begins_with:function(a){return{$regex:"^(?!"+h(a[0])+")"}},contains:function(a){return{$regex:h(a[0])}},not_contains:function(a){return{$regex:"^((?!"+h(a[0])+").)*$",$options:"s"}},ends_with:function(a){return{$regex:h(a[0])+"$"}},not_ends_with:function(a){return{$regex:"(?0)d.push(c(a));else{var g=b.settings.mongoOperators[a.operator],h=b.getOperatorByType(a.operator),i=[];void 0===g&&e('Unknown MongoDB operation for operator "{0}"',a.operator),0!==h.nb_inputs&&(a.value instanceof Array||(a.value=[a.value]),a.value.forEach(function(b){i.push(f(b,a.type,!1))}));var j={};j[a.field]=g.call(b,i),d.push(j)}});var g={};return d.length>0&&(g["$"+a.condition.toLowerCase()]=d),g}(a)},getRulesFromMongo:function(a){if(void 0===a||null===a)return null;var b=this,c=["$and","$or"];return function d(a){var f=Object.keys(a);f.length>1&&e("Invalid MongoDB query format."),-1===c.indexOf(f[0].toLowerCase())&&e('Unable to build Rule from MongoDB query with condition "{0}"',f[0]);var g=f[0].toLowerCase()===c[0]?"AND":"OR",h=a[f[0]],i=[];h.forEach(function(a){var f=Object.keys(a);if(-1!==c.indexOf(f[0].toLowerCase()))i.push(d(a));else{var g=f[0],h=a[g],j=b.determineMongoOperator(h,g);void 0===j&&e("Invalid MongoDB query format.");var k=b.settings.mongoRuleOperators[j];void 0===k&&e('JSON Rule operation unknown for operator "{0}"',j);var l=k.call(b,h);i.push({id:b.change("getMongoDBFieldID",g,h),field:g,operator:l.op,value:l.val})}});var j={};return i.length>0&&(j.condition=g,j.rules=i),j}(a)},determineMongoOperator:function(a){if(null!==a&&"object"==typeof a){var b=Object.keys(a);return 1===b.length?b[0]:void 0!==a.$gte&&void 0!==a.$lte?"between":void 0!==a.$regex?"$regex":void 0}return"eq"},setRulesFromMongo:function(a){this.setRules(this.getRulesFromMongo(a))}}),j.define("sortable",function(b){this.on("afterInit",function(b){$.event.props.push("dataTransfer");var c,d,e=b.builder;e.$el.on("mouseover",".drag-handle",function(){e.$el.find(".rule-container, .rules-group-container").attr("draggable",!0)}),e.$el.on("mouseout",".drag-handle",function(){e.$el.find(".rule-container, .rules-group-container").removeAttr("draggable")}),e.$el.on("dragstart","[draggable]",function(b){b.stopPropagation(),b.dataTransfer.setData("text","drag"),d=a(b.target),setTimeout(function(){var a=$('
     
    ');a.css("min-height",d.$el.height()),c=d.parent.addRule(a,d.getPos()),d.$el.hide()},0)}),e.$el.on("dragenter","[draggable]",function(a){a.preventDefault(),a.stopPropagation(),c&&i(c,$(a.target))}),e.$el.on("dragover","[draggable]",function(a){a.preventDefault(),a.stopPropagation()}),e.$el.on("drop",function(a){a.preventDefault(),a.stopPropagation(),i(d,$(a.target))}),e.$el.on("dragend","[draggable]",function(a){a.preventDefault(),a.stopPropagation(),d.$el.show(),c.drop(),d=c=null,e.$el.find(".rule-container, .rules-group-container").removeAttr("draggable")})}),this.on("parseRuleFlags.filter",function(a){void 0===a.value.no_sortable&&(a.value.no_sortable=b.default_no_sortable)}),this.on("afterApplyRuleFlags",function(a,b){b.flags.no_sortable&&b.$el.find(".drag-handle").remove()}),this.on("getGroupTemplate.filter",function(a,c){if(c>1){var d=$(a.value);d.find(".group-conditions").after('
    '),a.value=d.prop("outerHTML")}}),this.on("getRuleTemplate.filter",function(a){var c=$(a.value);c.find(".rule-header").after('
    '),a.value=c.prop("outerHTML")})},{default_no_sortable:!1,icon:"glyphicon glyphicon-sort"}),j.defaults({sqlOperators:{equal:"= ?",not_equal:"!= ?","in":{op:"IN(?)",sep:", "},not_in:{op:"NOT IN(?)",sep:", "},less:"< ?",less_or_equal:"<= ?",greater:"> ?",greater_or_equal:">= ?",between:{op:"BETWEEN ?",sep:" AND "},begins_with:{op:"LIKE(?)",fn:function(a){return a+"%"}},not_begins_with:{op:"NOT LIKE(?)",fn:function(a){return a+"%"}},contains:{op:"LIKE(?)",fn:function(a){return"%"+a+"%"}},not_contains:{op:"NOT LIKE(?)",fn:function(a){return"%"+a+"%"}},ends_with:{op:"LIKE(?)",fn:function(a){return"%"+a}},not_ends_with:{op:"NOT LIKE(?)",fn:function(a){return"%"+a}},is_empty:'== ""',is_not_empty:'!= ""',is_null:"IS NULL",is_not_null:"IS NOT NULL"},sqlStatements:{question_mark:function(){var a=[];return{add:function(b,c){return a.push(c),"?"},run:function(){return a}}},numbered:function(){var a=0,b=[];return{add:function(c,d){return b.push(d),a++,"$"+a},run:function(){return b}}},named:function(){var a={},b={};return{add:function(c,d){a[c.field]||(a[c.field]=0),a[c.field]++;var e=c.field+"_"+a[c.field];return b[e]=d,":"+e},run:function(){return b}}}}}),j.extend({getSQL:function(a,b,c){c=void 0===c?this.getRules():c,b=b===!0?"\n":" ",(a===!0||void 0===a)&&(a="question_mark"),"string"==typeof a&&(a=this.settings.sqlStatements[a]());var d=this,h=function i(c){if(c.condition||(c.condition=d.settings.default_condition),-1===["AND","OR"].indexOf(c.condition.toUpperCase())&&e('Unable to build SQL query with condition "{0}"',c.condition),!c.rules)return"";var h=[];return c.rules.forEach(function(c){if(c.rules&&c.rules.length>0)h.push("("+b+i(c)+b+")"+b);else{var j=d.getSqlOperator(c.operator),k=d.getOperatorByType(c.operator),l="";j===!1&&e('Unknown SQL operation for operator "{0}"',c.operator),0!==k.nb_inputs&&(c.value instanceof Array||(c.value=[c.value]),c.value.forEach(function(b,d){d>0&&(l+=j.sep),"integer"==c.type||"double"==c.type||"boolean"==c.type?b=f(b,c.type,!0):a||(b=g(b)),j.fn&&(b=j.fn(b)),a?l+=a.add(c,b):("string"==typeof b&&(b="'"+b+"'"),l+=b)})),h.push(c.field+" "+j.op.replace(/\?/,l))}}),h.join(" "+c.condition+b)}(c);return a?{sql:h,params:a.run()}:{sql:h}},getSqlOperator:function(a){var b=this.settings.sqlOperators[a];return void 0===b?!1:("string"==typeof b&&(b={op:b}),b.list&&!b.sep&&(b.sep=", "),b)}}),j.define("unique-filter",function(){this.status.used_filters={},this.on("afterUpdateRuleFilter",this.updateDisabledFilters),this.on("afterDeleteRule",this.updateDisabledFilters),this.on("afterCreateRuleFilters",this.applyDisabledFilters)}),j.extend({updateDisabledFilters:function(a){var b=a.builder;b.status.used_filters={},b.model&&(!function c(a){a.each(function(a){a.filter&&a.filter.unique&&(b.status.used_filters[a.filter.id]||(b.status.used_filters[a.filter.id]=[]),"group"==a.filter.unique&&b.status.used_filters[a.filter.id].push(a.parent))},function(a){c(a)})}(b.model.root),b.applyDisabledFilters(a))},applyDisabledFilters:function(a){var b=a.builder;b.$el.find(".rule-filter-container option").prop("disabled",!1),$.each(b.status.used_filters,function(a,c){0===c.length?b.$el.find('.rule-filter-container option[value="'+a+'"]:not(:selected)').prop("disabled",!0):c.forEach(function(b){b.each(function(b){b.$el.find('.rule-filter-container option[value="'+a+'"]:not(:selected)').prop("disabled",!0)})})}),b.settings.plugins&&b.settings.plugins["bt-selectpicker"]&&b.$el.find(".rule-filter-container select").selectpicker("render")}}),j.regional.en={__locale:"English (en)",__author:'Damien "Mistic" Sorel, http://www.strangeplanet.fr',add_rule:"Add rule",add_group:"Add group",delete_rule:"Delete",delete_group:"Delete",conditions:{AND:"AND",OR:"OR"},operators:{equal:"equal",not_equal:"not equal","in":"in",not_in:"not in",less:"less",less_or_equal:"less or equal",greater:"greater",greater_or_equal:"greater or equal",between:"between",begins_with:"begins with",not_begins_with:"doesn't begin with",contains:"contains",not_contains:"doesn't contain",ends_with:"ends with",not_ends_with:"doesn't end with",is_empty:"is empty",is_not_empty:"is not empty",is_null:"is null",is_not_null:"is not null"},errors:{no_filter:"No filter selected",empty_group:"The group is empty",radio_empty:"No value selected",checkbox_empty:"No value selected",select_empty:"No value selected",string_empty:"Empty value",string_exceed_min_length:"Must contain at least {0} characters",string_exceed_max_length:"Must not contain more than {0} characters",string_invalid_format:"Invalid format ({0})",number_nan:"Not a number",number_not_integer:"Not an integer",number_not_double:"Not a real number",number_exceed_min:"Must be greater than {0}",number_exceed_max:"Must be lower than {0}",number_wrong_step:"Must be a multiple of {0}",datetime_empty:"Empty value",datetime_invalid:"Invalid date format ({0})",datetime_exceed_min:"Must be after {0}",datetime_exceed_max:"Must be before {0}",boolean_not_valid:"Not a boolean",operator_not_multiple:"Operator {0} cannot accept multiple values"}},j.defaults({lang_code:"en"})}); \ No newline at end of file diff --git a/dist/scss/dark.scss b/dist/scss/dark.scss index 346769c0..cae34e8d 100644 --- a/dist/scss/dark.scss +++ b/dist/scss/dark.scss @@ -1,5 +1,5 @@ /*! - * jQuery QueryBuilder 2.0.1 + * jQuery QueryBuilder 2.1.0 * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr) * Licensed under MIT (http://opensource.org/licenses/MIT) */ diff --git a/dist/scss/default.scss b/dist/scss/default.scss index a872d4d6..8555eda8 100644 --- a/dist/scss/default.scss +++ b/dist/scss/default.scss @@ -1,5 +1,5 @@ /*! - * jQuery QueryBuilder 2.0.1 + * jQuery QueryBuilder 2.1.0 * Copyright 2014-2015 Damien "Mistic" Sorel (http://www.strangeplanet.fr) * Licensed under MIT (http://opensource.org/licenses/MIT) */ diff --git a/package.json b/package.json index d83905cc..940acc6f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jQuery-QueryBuilder", - "version": "2.0.1", + "version": "2.1.0", "author": { "name": "Damien \"Mistic\" Sorel", "email": "contact@git.strangeplanet.fr", diff --git a/tests/common.js b/tests/common.js index 710d4d6a..2cf5cb44 100644 --- a/tests/common.js +++ b/tests/common.js @@ -5,7 +5,7 @@ QUnit.begin(function() { $.ajax({ async: false, - url: '../dist/i18n/en.js', + url: '../dist/i18n/query-builder.en.js', dataType: 'script' }); }); diff --git a/tests/core.module.js b/tests/core.module.js index 55cd7ffb..c83ab784 100644 --- a/tests/core.module.js +++ b/tests/core.module.js @@ -352,7 +352,7 @@ $(function(){ assert.expect(2); var done = assert.async(); - $.getScript('../dist/i18n/fr.js', function() { + $.getScript('../dist/i18n/query-builder.fr.js', function() { $b.queryBuilder({ filters: basic_filters });