(function ($) {
$.conditionBuilder = function (element, options) {
var defaults = {
placeholder: {
operators: 'Select a operator...',
values: 'Enter a value...'
},
dictionary: [],
values: [],
input: '',
debug: false,
show: false,
numericConfig: {
aSep: '',
aDec: '.',
aSign: ''
},
select2Config: {
theme: "bootstrap",
width: 'auto',
placeholder: '',
allowClear: false,
dropdownAutoWidth: 'true',
tags: false,
language: "en"
}
};
var plugin = this;
var $element = $(element), element = element;
var jsonCache = {};
plugin.parameters = {};
plugin.result = function (data) {
};
$element.addClass('condition-builder');
//~~~ PUBLIC
plugin.add_condition = function (field_name) {
var fieldObj = getFieldByName(field_name);
var new_id = new Date().getTime();
var $elField, $elOperators, $elValues;
//BLOCK ELEMENTS HTML
var block = $('
');
block.append('');
if (typeof fieldObj !== 'object') {
block.append('' + field_name + ' ✖');
} else {
var field_label = fieldObj.label;
if (!is_blank(fieldObj.group)) {
field_label = Object.values(fieldObj.group)[0] + ' : ' + field_label;
}
block.append('');
block.append('' + field_label + ' ✖');
block.append('');
block.append('');
block.append('');
block.append('');
if (plugin.parameters.debug == true) {
block.append('');
}
$elField = block.find('#field_' + new_id);
$elOperators = block.find('#operators_' + new_id);
$elValues = block.find('#values_' + new_id + ', #fixed_value_' + new_id);
}
//EVENTS
block.find('#remove_condition_' + new_id).on('click', event_remove_condition);
$element.append(block);
//LOAD OPERATORS
if (typeof $elField != 'undefined') {
$elOperators.on('change', event_load_values);
plugin.load_operators($elField);
}
return block;
}; //END add_condition
plugin.clear_rows = function () {
if (confirm('Essa ação removerá todos os itens. Deseja continuar?') == true) {
$element.find('.group-conditions').remove();
plugin.getResult();
}
};
plugin.load_operators = function (fieldEl) {
if (typeof fieldEl == 'undefined') {
return;
}
var $fieldElement = $(fieldEl);
var groupConditionId = $fieldElement.attr('data-group-id');
var field_name = getFieldValue($fieldElement);
var field = getFieldByName(field_name);
var $operators = $('#operators_' + groupConditionId);
var $fixedOperator = $('#fixed_operator_' + groupConditionId);
var $values = $('.values_' + groupConditionId);
var $fixedValue = $('.fixed_value_' + groupConditionId);
var operators = field.operators;
remove_plugins_elements(groupConditionId);
$operators.html('').addClass('hide');
$fixedOperator.val('').addClass('hide');
$values.html('').addClass('hide');
$fixedValue.val('').addClass('hide');
operators = normalize_operators(operators);
$.each(operators, function (op_i, op_el) {
var op_option = $('');
$operators.append(op_option);
});
if (operators != undefined && operators.length == 1) {
$fixedOperator.html(getLabel(operators[0])).removeClass('hide');
} else {
$operators.removeClass('hide');
}
$operators.trigger('change');
};
plugin.fill_condition = function (groupConditionId, data) {
if (data != undefined && data.length > 0 && groupConditionId != undefined) {
var groupConditions = getGroupConditionById(groupConditionId)
var $elOperators = getOperatorElement(groupConditions);
$elOperators.val(data[1]).trigger('change');
var $elOperator = $elOperators.find('option:selected');
var multiple = $elOperator.attr('data-multiple');
var $elValues = getValueElement(groupConditions);
if ($elValues.length > 1) {
var values = (typeof data[2] == 'string') ? [data[2]] : data[2];
$.each($elValues, function (i, elValue) {
$(elValue).val(values[i]);
});
} else if (multiple == 'true' || $elValues.attr('data-ajax-values') !== undefined) {
var values = (typeof data[2] == 'string') ? [data[2]] : data[2];
if (values != undefined) {
$.each(values, function (i, value) {
if ($elValues.find('option[value="' + value + '"]').length <= 0) {
$elValues.append('');
}
});
$elValues.val(values).trigger('change');
// triggerEl = false;
}
} else {
$elValues.val(data[2]);
}
$elValues.trigger('change');
}
}; //END fill_condition
plugin.load_values = function (values) {
if (typeof values == 'string' && !is_blank(values)) {
plugin.parameters.values = getJson(values);
} else if (is_blank(values) && !is_blank(plugin.parameters.input)) {
var $elInput = $(plugin.parameters.input);
if ($elInput.length > 0 && !is_blank($elInput.val())) {
plugin.parameters.values = JSON.parse($elInput.val());
}
} else {
plugin.parameters.values = values;
}
if (plugin.parameters.show == true) {
show_rows();
} else {
build_rows();
}
}; //END load_values
plugin.load_values_from_input = function (element_input) {
var $elInput = $(element_input);
if ($elInput.length > 0) {
try {
plugin.parameters.values = JSON.parse($elInput.val());
} catch (e) {
plugin.parameters.values = '';
}
}
plugin.load_values(plugin.parameters.values);
}; //END load_values_from_input
plugin.getResult = function () {
var data = [];
$element.find('.group-conditions').each(function (i, groupConditions) {
var field_name = getFieldValue(groupConditions);
var operator = getOperator(groupConditions);
var value = getValue(groupConditions);
if (!is_blank(field_name) && !is_blank(operator) && !is_blank(value)) {
data.push([field_name, operator, value]);
}
});
if (typeof plugin.result === 'function') {
plugin.result(data); //CB
}
if (!is_blank(plugin.parameters.input)) {
$(plugin.parameters.input).val(JSON.stringify(data));
}
return data;
}; //END getResult;
//~~~ PRIVATE
var getGroupConditionById = function (groupConditionId) {
return $('#group_conditions_' + groupConditionId);
}; //END getFieldElement
var getFieldByName = function (field_name) {
var f = $.map(plugin.parameters.dictionary, function (h, i) {
if (h.field == field_name) {
return h;
}
});
if (jQuery.isArray(f)) {
f = f[0];
}
return f;
}; //END getFieldByName
var getOperatorFromField = function (operator_name, field_name_or_operators) {
if (jQuery.isArray(field_name_or_operators)) {
var operators = field_name_or_operators;
} else {
var fieldObj = getFieldByName(field_name);
var operators = fieldObj.operators;
}
var f = $.map(operators, function (h, i) {
if (h.operator == operator_name) {
return h;
}
});
if (jQuery.isArray(f)) {
f = f[0];
}
return f;
}; //END getFieldByName
var getLabel = function (obj) {
if (!is_blank(obj.label)) {
return String(obj.label);
} else {
return '';
}
};
var getFieldElement = function (groupConditions) {
return $(groupConditions).find('.field:input:first');
}; //END getFieldElement
var getFieldValue = function (element) {
if (typeof element == 'undefined') {
return;
}
var value;
var $el = $(element);
if ($el.hasClass('field')) {
value = $el.val();
} else {
var el = getFieldElement(element);
if (el.length > 0) {
value = !is_blank(el) ? getFieldValue(el) : '';
}
}
return value;
}; //END getFieldValue
var getOperatorElement = function (groupConditions) {
return $(groupConditions).find('.operators:first');
}; //END getOperatorElement
var getOperator = function (groupConditions) {
var operator = getOperatorElement(groupConditions).val();
if (is_blank(operator)) {
operator = ''
}
return operator;
}; //END getOperator
var getValueElement = function (groupConditions) {
var element = $(groupConditions).find('.values');
if (element.hasClass('hide')) {
element = $(groupConditions).find('.fixed_value');
}
return element;
}; //END getValues
var getValue = function (groupConditions) {
var values = getValueElement(groupConditions);
var value = [];
var op_el = getOperatorElement(groupConditions);
if (op_el.hasClass('operators')) {
op_el = op_el.find('option:selected');
}
if (op_el != undefined && op_el.length > 0 && op_el.attr('data-no-value') == 'false') {
$.each(values, function (i, elValue) {
value.push($(elValue).val());
});
}
return normalize_values(value);
}; //END getValue
var normalize_values = function (values) {
// if (typeof values=='string') {values = [values]}
if (typeof values == 'object') {
if (typeof values[0] == 'object') {
values = flatten(values);
}
$.each(values, function (i, v) {
if (is_blank(v)) {
values[i] = ''
}
});
}
if (typeof values[0] == 'string' && values.length == 1) {
values = values[0];
}
if (is_blank(values)) {
values = ''
}
return values;
}; //END normalize_values
var event_remove_condition = function (ev) {
ev.preventDefault();
$(this).closest('.group-conditions').remove();
$element.find('.conditions').trigger('change');
}; //END event_remove_condition
var event_load_values = function (ev) {
var $target = $(ev.target);
var groupConditionId = $target.attr('data-group-id');
var $groupConditions = getGroupConditionById(groupConditionId);
var field_name = getFieldValue($groupConditions);
var field = getFieldByName(field_name);
var op_el = $target.hasClass('operators') ? $target.find('option:selected') : $target;
var values = field.values;
build_values(op_el, values, groupConditionId);
}; //END event_load_values
var event_build_expression = function (ev) {
if (plugin.parameters.debug == true) {
var $groupConditions = $(this).closest('.group-conditions');
var index = $groupConditions.attr('data-index');
var $expression = $groupConditions.find('.expression');
var $field = getFieldValue($groupConditions);
var $operator = getOperator($groupConditions);
var $value = getValue($groupConditions);
$expression.html($field + ' ' + $operator + ' ' + $value);
}
plugin.getResult();
}; //END event_build_expression
/* UNDER CONSTRUCTION */
var show_rows = function () {
$element.find('.conditions').html('');
if (!is_blank(plugin.parameters.values) && plugin.parameters.values.length > 0) {
var $listUl = $('');
$.each(plugin.parameters.values, function (i, data) {
var fieldObj = getFieldByName(data[0]);
var operatorObj = getOperatorFromField(data[1], fieldObj.operators);
var $listItem = $('');
$listItem.append('' + getLabel(fieldObj) + '');
$listItem.append('' + getLabel(operatorObj) + '');
$listItem.append('' + data[2] + '');
$listItem.appendTo($listUl);
});
$element.append($listUl);
}
};
var build_rows = function () {
$element.find('.conditions').html('');
if (!is_blank(plugin.parameters.values) && plugin.parameters.values.length > 0) {
$.each(plugin.parameters.values, function (i, data) {
var field = data[0];
var groupConditions = plugin.add_condition(field);
if (typeof groupConditions != 'undefined') {
var groupConditionId = groupConditions.attr('data-id');
plugin.fill_condition(groupConditionId, data);
}
});
}
};
var build_values = function (op_el, values, groupConditionId) {
var $groupConditions = getGroupConditionById(groupConditionId);
var no_value = op_el.attr('data-no-value');
var $values = $groupConditions.find('.values');
var $fixedValue = $groupConditions.find('.fixed_value');
var multiple = op_el.attr('data-multiple');
multiple = (multiple == 'true' ? 'true' : 'false');
$values.html('').removeAttr('data-ajax-values').addClass('hide');
$fixedValue.removeAttr('data-ajax-values').addClass('hide');
if (typeof values === 'string') {
$values.attr('data-ajax-values', values);
$fixedValue.attr('data-ajax-values', values);
values = [''];
}
var list_with_item = (values != undefined && values.length > 0);
if (no_value == 'false') {
if (list_with_item) {
$.each(values, function (val_i, val_el) {
if (typeof val_el == 'object') {
var _id = val_el.id;
var _label = getLabel(val_el);
if (is_blank(_label)) {
_label = _id;
}
} else {
var _id = val_el;
var _label = _id;
}
$values.append('');
});
$values.removeClass('hide');
$values.trigger('change');
} else {
if (multiple == 'true') {
$values.removeClass('hide');
$values.trigger('change');
} else {
$fixedValue.removeClass('hide');
$fixedValue.trigger('change');
}
}
}
validate_multiple_values(groupConditionId);
normalize_values_type(groupConditionId, list_with_item, multiple);
}; //END build_values
var validate_multiple_values = function (groupConditionId) {
var $groupConditions = getGroupConditionById(groupConditionId);
var $operatorEl = getOperatorElement($groupConditions);
var $valueEl = getValueElement($groupConditions);
if ($operatorEl.hasClass('operators')) {
$operatorEl = $operatorEl.find('option:selected');
}
var multiple = $operatorEl.attr('data-multiple');
remove_plugins_elements(groupConditionId);
if (!isNaN(multiple)) {
for (var i = 1; i < parseInt(multiple); i++) {
var $valueElClone = $valueEl.clone();
$valueElClone.addClass('clone').removeClass('hide');
$valueElClone.insertAfter($valueEl);
}
} else {
$valueEl.attr('multiple', multiple == 'true');
}
$valueEl.attr('multiple', multiple == 'true');
}; //END validate_multiple_values
var remove_plugins_elements = function (groupConditionId) {
var $groupConditions = getGroupConditionById(groupConditionId);
$groupConditions.find('.fixed_value[class*="select2-"], .values[class*="select2-"]').select2('destroy');
$groupConditions.find('.values.clone, .fixed_value.clone').remove();
}; //END remove_plugins_elements
var normalize_values_type = function (groupConditionId, list_with_item, multiple) {
var $groupConditions = getGroupConditionById(groupConditionId);
var $fieldEl = getFieldElement($groupConditions);
var $valueEl = getValueElement($groupConditions);
var uTypeField = $fieldEl.attr('data-type'); //.toUpperCase();
var field_name = getFieldValue($groupConditions);
$.each($valueEl, function (i, el) {
var $el = $(el);
//RESET ELEMENT
$el.autoNumeric('destroy');
// $element.tooltip('destroy');
if (plugin.parameters.debug == true) {
$el.parent().find('.type_field').remove();
}
//VALIDATE TYPE
switch (true) {
case /^DATE$/.test(uTypeField):
$el.attr('type', 'date');
break;
case /^TIME$/.test(uTypeField):
$el.attr('type', 'time');
break;
case /^DATETIME$/.test(uTypeField):
$el.attr('type', 'datetime');
break;
case /^DECIMAL/.test(uTypeField):
$el.attr('type', 'text');
var decimal_places = uTypeField.match(/\(([0-9]+)\)$/);
if (decimal_places == undefined || decimal_places == null) {
decimal_places = /Vl[A-Z]/.test(field_name) == true ? 2 : 4;
} else {
decimal_places = decimal_places[1];
}
$el.autoNumeric("init", plugin.parameters.numericConfig);
$el.autoNumeric("update", {mDec: decimal_places});
window.setTimeout(function () {
if ($el.autoNumeric('getSettings') != undefined) {
$el.trigger('blur'); //FORCE REFRESH
}
}, 500);
// $element.tooltip({
// placement: 'top',
// title: 'Use DOT as decimal separator',
// trigger: 'hover focus active'
// });
break;
case /^INTEGER$/.test(uTypeField):
$el.attr('type', 'number');
break;
case /^STRING$/.test(uTypeField):
default:
$el.attr('type', 'text');
break;
}
if (plugin.parameters.debug == true) {
console.log(field_name, uTypeField);
$el.parent().append('
' + uTypeField + '');
}
if (($el.hasClass('values') && !$el.hasClass('hide'))) {
// build_select2_element($el, (!list_with_item && multiple == 'true'));
build_select2_element($el);
}
});
}; //END normalize_values_type
var normalize_operators = function (operators) {
if (operators != undefined && typeof operators == 'object' && operators.length > 0) {
$.each(operators, function (i, row) {
var label = getLabel(row);
if (is_blank(label)) {
operators[i].label = row.operator;
}
if (is_blank(row.multiple)) {
operators[i].multiple = 'false';
}
if (is_blank(row.no_value)) {
operators[i].no_value = 'false';
}
});
}
return operators;
}; //END normalize_operators
var is_blank = function (value) {
return (value === undefined || value === null || value === [] || value === '')
}; //END is_blank
var flatten = function (arrays) {
return [].concat.apply([], arrays);
}; //END flatten
var getJson = function (url, force, cb) {
if (force == undefined || force == null) {
force = false;
}
if (force == true) {
jsonCache[url] = undefined;
}
if (jsonCache[url] == undefined) {
$.ajax({
url: url,
async: false,
dataType: 'json',
success: function (dates) {
jsonCache[url] = dates;
if (cb != undefined && typeof cb == 'function') {
cb(dates)
}
}, errorr: function (errorr) {
alert("Could not load url " + url);
}
});
}
return jsonCache[url];
}; //END getJson
var build_select2_element = function (el, tags) {
if (tags == undefined) tags = true;
var $el = $(el);
var select2Config = $.extend({}, plugin.parameters.select2Config);
var ajax_url = $el.attr('data-ajax-values');
if (ajax_url !== undefined) {
$.extend(select2Config, {
ajax: {
url: ajax_url,
dataType: 'json',
delay: 250,
data: function (params) {
return {
key: params.term, // search term
page: params.page
};
},
processResults: function (data, params) {
return {
results: $.map(data, function (item) {
return {
text: getLabel(item),
id: item.id
}
})
};
},
cache: true
},
initSelection: function (element, callback) {
var initVal = $(element).val();
if (initVal !== "") {
$.ajax(ajax_url, {
dataType: 'json',
data: {init: initVal}
}).done(function (data) {
var row = $.isArray(data) ? data[0] : data;
if (row !== undefined && row.id !== undefined && row.label !== undefined) {
callback({id: row.id, text: row.label});
} else {
callback({id: initVal, text: initVal});
}
});
}
},
minimumInputLength: 1
});
}
var totalItems = $el.find('option').length;
if ($el.hasClass('operators')) {
$.extend(select2Config, {placeholder: plugin.parameters.placeholder.operators});
} else if ($el.hasClass('values')) {
$.extend(select2Config, {placeholder: plugin.parameters.placeholder.values});
}
if (tags == true) {
$.extend(select2Config, {tags: true, tokenSeparators: [',', ';']});
}
$.fn.select2.defaults.set("theme", (select2Config.theme || 'bootstrap'));
var select2El = $el.select2(select2Config);
var select2DefaultValue = (totalItems == 1 ? $el.find('option:first').val() : null);
select2El.val(select2DefaultValue).trigger("change"); //FORCE RESET DO SET PLACEHOLDER
};
plugin.init = function () {
plugin.parameters = $.extend(true, defaults, options);
//~~~ INIT
$element.append('');
$element.on('change', '.conditions, .operators, .values, .fixed_value', event_build_expression);
if (typeof plugin.parameters.dictionary == 'string') {
plugin.parameters.dictionary = getJson(plugin.parameters.dictionary);
}
if (!is_blank(plugin.parameters.input)) {
plugin.load_values_from_input(plugin.parameters.input);
$(document).on('change', plugin.parameters.input, function (ev) {
plugin.load_values_from_input(plugin.parameters.input);
});
} else {
plugin.load_values(plugin.parameters.values);
}
Sortable.create(element, {
handle: '.conditions-move',
animation: 150,
onSort: function (evt) {
plugin.getResult();
}
});
};
plugin.init();
};
$.fn.conditionBuilder = function (options) {
return this.each(function () {
if (undefined == $(this).data('conditionBuilder')) {
var plugin = new $.conditionBuilder(this, options);
$(this).data('conditionBuilder', plugin);
}
});
};
})
(jQuery);
$(document).on('click', '.add-condition-field', function (ev) {
ev.preventDefault();
var container = $(this).closest('.add-condition').attr('data-target');
var field_name = $(this).attr('data-field');
var $conditionBuilder = $(container).data('conditionBuilder');
$conditionBuilder.add_condition(field_name);
});
//DROPDOWN WITH SEARCH
$(document).on('keyup', '.dropdown-filter-control', function (ev) {
var ulEl = $(this).closest('ul.dropdown-menu');
var searchTerm = $(this).val().toLowerCase();
ulEl.find('li.dropdown-menu-item').each(function () {
var filter = $(this).filter(function () {
return $(this).attr('data-search-term').toLowerCase().indexOf(searchTerm) > -1;
});
// $(this).filter('[data-search-term *= ' + searchTerm + ']')
if (searchTerm.length < 1 || filter.length > 0) {
$(this).show();
} else {
$(this).hide();
}
});
});
//AUTO FOCUS
$(document).on('shown.bs.dropdown', '.dropdown.add-condition', function () {
$(this).find('input.dropdown-filter-control:first').focus();
});