Skip to content

Commit

Permalink
possibility to load multiple language files #112
Browse files Browse the repository at this point in the history
  • Loading branch information
mistic100 committed May 4, 2015
1 parent 2c4bdbe commit 4305bc7
Show file tree
Hide file tree
Showing 7 changed files with 165 additions and 102 deletions.
72 changes: 41 additions & 31 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
var deepmerge = require('deepmerge');

function removeJshint(src) {
return src
.replace(/\/\*jshint [a-z:]+ \*\/\r?\n\r?\n?/g, '')
.replace(/\/\*jshint -[EWI]{1}[0-9]{3} \*\/\r?\n\r?\n?/g, '');
}

module.exports = function(grunt) {
grunt.util.linefeed = '\n';

var all_modules = {},
all_langs = {},
loaded_modules = [],
loaded_lang = '',
loaded_langs = [],
js_core_files = [
'src/main.js',
'src/defaults.js',
Expand Down Expand Up @@ -59,27 +65,27 @@ module.exports = function(grunt) {
}
}

// default language
js_files_to_load.push('dist/i18n/en.js');
loaded_langs.push('en');

// parse 'lang' parameter
var arg_lang = grunt.option('lang');
if (typeof arg_lang === 'string') {
if (all_langs[arg_lang]) {
if (arg_lang != 'en') {
js_files_to_load.push(all_langs[arg_lang].replace(/^src/, 'dist'));
loaded_lang = arg_lang;
var arg_langs = grunt.option('languages');
if (typeof arg_langs === 'string') {
arg_langs.replace(/ /g, '').split(',').forEach(function(l) {
if (all_langs[l]) {
if (l !== 'en') {
js_files_to_load.push(all_langs[l].replace(/^src/, 'dist').replace(/json$/, 'js'));
loaded_langs.push(l);
}
}
}
else {
grunt.fail.warn('Lang '+ arg_lang +' unknown');
}
else {
grunt.fail.warn('Language '+ l +' unknown');
}
});
}
}());

function removeJshint(src) {
return src
.replace(/\/\*jshint [a-z:]+ \*\/\r?\n\r?\n?/g, '')
.replace(/\/\*jshint -[EWI]{1}[0-9]{3} \*\/\r?\n\r?\n?/g, '');
}


grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
Expand Down Expand Up @@ -181,12 +187,11 @@ module.exports = function(grunt) {
options: {
stripBanners: false,
process: function(src, file) {
var lang = file.split(/[\/\.]/)[2],
content = JSON.parse(src),
header;
var lang = file.split(/[\/\.]/)[2];
var content = JSON.parse(src);

grunt.config.set('lang_copyright', content.__copyright || (l + ' translation'));
header = grunt.template.process('<%= langBanner %>\n\n');
grunt.config.set('lang_copyright', content.__copyright || (lang + ' translation'));
var header = grunt.template.process('<%= langBanner %>');
delete content.__copyright;

loaded_modules.forEach(function(m) {
Expand All @@ -196,8 +201,13 @@ module.exports = function(grunt) {
content = deepmerge(content, grunt.file.readJSON(plugin_file));
}
});

return header + 'jQuery.fn.queryBuilder.defaults({ lang: ' + JSON.stringify(content, null, 2) + '});';

return header
+ '\n\n'
+ 'jQuery.fn.queryBuilder.regional[\'' + lang + '\'] = '
+ JSON.stringify(content, null, 2)
+ ';\n\n'
+ 'jQuery.fn.queryBuilder.defaults({ lang_code: \'' + lang + '\' });'
}
}
},
Expand All @@ -223,14 +233,13 @@ module.exports = function(grunt) {
options: {
separator: '',
wrapper: function() {
var wrapper = grunt.file.read('src/.wrapper.js').replace(/\r\n/g, '\n')
wrapper = wrapper.split(/@@js\n/);
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_lang.length) {
wrapper[0] = '// Language: ' + loaded_lang + '\n' + wrapper[0];
if (loaded_langs.length) {
wrapper[0] = '// Languages: ' + loaded_langs.join(', ') + '\n' + wrapper[0];
}
wrapper[0] = grunt.template.process('<%= banner %>\n\n') + wrapper[0];

Expand Down Expand Up @@ -311,9 +320,10 @@ module.exports = function(grunt) {
// jshint tests
jshint: {
lib: {
files: {
src: js_files_to_load
}
options: {
'-W069': true // accesses to "regional" in language files
},
src: js_files_to_load
}
},

Expand Down
63 changes: 57 additions & 6 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<link rel="stylesheet" href="bower_components/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">
</head>

<body>
Expand All @@ -26,10 +28,32 @@ <h1>jQuery QueryBuilder <small>Example</small></h1>
You must execute <code>bower install</code> in the example directory to run this demo.
</div>

<div class="btn-group">
<button class="btn btn-default btn-sm" disabled>Theme:</button>
<button class="btn btn-primary btn-sm change-theme" data-qb="../dist/css/query-builder.default.min.css" data-bt="bower_components/bootstrap/dist/css/bootstrap.min.css">Default</button>
<button class="btn btn-primary btn-sm change-theme" data-qb="../dist/css/query-builder.dark.min.css" data-bt="bower_components/bootswatch-dist/css/bootstrap.min.css">Dark</button>
<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.min.css" data-bt="bower_components/bootstrap/dist/css/bootstrap.min.css">Default</button>
<button class="btn btn-primary btn-sm change-theme" data-qb="../dist/css/query-builder.dark.min.css" data-bt="bower_components/bootswatch-dist/css/bootstrap.min.css">Dark</button>
</div>

<label>Language:</label>
<select name="language" class="selectpicker show-tick show-menu-arrow" data-width="auto">
<optgroup label="Complete">
<option value="de" data-icon="flag flag-de">German</option>
<option value="en" data-icon="flag flag-gb" selected>English</option>
<option value="es" data-icon="flag flag-es">Spanish</option>
<option value="fr" data-icon="flag flag-fr">French</option>
<option value="nl" data-icon="flag flag-nl">Dutch</option>
<option value="pl" data-icon="flag flag-pl">Polish</option>
<option value="pt-BR" data-icon="flag flag-pt">Portuguese</option>
<option value="ru" data-icon="flag flag-ru">Russian</option>
</optgroup>
<optgroup label="Partial">
<option value="da" data-icon="flag flag-dk">Danish</option>
<option value="it" data-icon="flag flag-it">Italian</option>
<option value="no" data-icon="flag flag-no">Norwegian</option>
<option value="ro" data-icon="flag flag-ro">Romanian</option>
</optgroup>
</select>
</div>

<div id="builder"></div>
Expand Down Expand Up @@ -67,8 +91,10 @@ <h3>Output</h3>
<script src="../dist/js/query-builder.js"></script>

<script>
var $b = $('#builder');

// define filters
$('#builder').queryBuilder({
var options = {
allow_empty: true,

plugins: {
Expand Down Expand Up @@ -292,7 +318,10 @@ <h3>Output</h3>
}
}
}]
});
};

// init
$('#builder').queryBuilder(options);

$('#builder').on('afterCreateRuleInput.queryBuilder', function(e, rule) {
if (rule.filter.plugin == 'selectize') {
Expand All @@ -301,6 +330,28 @@ <h3>Output</h3>
}
});

// 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;
}
options.lang_code = lang;
$b.queryBuilder('destroy');
$('#builder').queryBuilder(options);
};

if ($.fn.queryBuilder.regional[lang] === undefined) {
$.getScript('../dist/i18n/' + lang + '.js', done);
}
else {
done();
}
});

// set rules
$('.set').on('click', function() {
$('#builder').queryBuilder('setRules', {
Expand Down
7 changes: 6 additions & 1 deletion src/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,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;
Expand Down
76 changes: 19 additions & 57 deletions src/defaults.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/**
* Allowed types and their internal representation
*/
QueryBuilder.types = {
'string': 'string',
'integer': 'number',
Expand All @@ -8,6 +11,9 @@ QueryBuilder.types = {
'boolean': 'boolean'
};

/**
* Allowed inputs
*/
QueryBuilder.inputs = [
'text',
'textarea',
Expand All @@ -16,12 +22,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: [],
Expand All @@ -46,63 +63,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']},
Expand Down
3 changes: 2 additions & 1 deletion src/jquery.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ $.fn.queryBuilder = function(option) {
$.fn.queryBuilder.constructor = QueryBuilder;
$.fn.queryBuilder.defaults = QueryBuilder.defaults;
$.fn.queryBuilder.extend = QueryBuilder.extend;
$.fn.queryBuilder.define = QueryBuilder.define;
$.fn.queryBuilder.define = QueryBuilder.define;
$.fn.queryBuilder.regional = QueryBuilder.regional;
14 changes: 14 additions & 0 deletions tests/common.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
/**
* Sync load of language file once QUnit and Blanket are ready
* Otherwise the language file is loaded before instrumented files
*/
QUnit.begin(function() {
$.ajax({
async: false,
url: '../dist/i18n/en.js',
dataType: 'script'
});
});

/**
* Add GitHub link in header
*/
Expand All @@ -23,6 +35,7 @@ QUnit.done(function(){
});
});


/**
* Custom assert to compare rules objects
*/
Expand Down Expand Up @@ -130,6 +143,7 @@ QUnit.assert.match = function(actual, regex, message) {
this.push(regex.test(actual), actual, regex, message);
};


/**
* Drag & Drop simulation
* https://gist.github.com/mistic100/37c95fab77b5626c5623
Expand Down
Loading

0 comments on commit 4305bc7

Please sign in to comment.