discerner 1.1.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +97 -0
- data/Rakefile +29 -0
- data/app/assets/images/discerner/add.png +0 -0
- data/app/assets/images/discerner/ajax-loader.gif +0 -0
- data/app/assets/images/discerner/bar.gif +0 -0
- data/app/assets/images/discerner/bullet_arrow_down.png +0 -0
- data/app/assets/images/discerner/bullet_arrow_up.png +0 -0
- data/app/assets/images/discerner/cog.png +0 -0
- data/app/assets/images/discerner/delete.png +0 -0
- data/app/assets/images/discerner/edit.png +0 -0
- data/app/assets/images/discerner/excel.png +0 -0
- data/app/assets/images/discerner/greencheck.gif +0 -0
- data/app/assets/images/discerner/rails.png +0 -0
- data/app/assets/images/discerner/show.png +0 -0
- data/app/assets/images/discerner/switch_minus.gif +0 -0
- data/app/assets/images/discerner/switch_plus.gif +0 -0
- data/app/assets/javascripts/discerner/application.js +20 -0
- data/app/assets/javascripts/discerner/combobox.js +301 -0
- data/app/assets/javascripts/discerner/discerner.js +19 -0
- data/app/assets/javascripts/discerner/export_parameters.js +13 -0
- data/app/assets/javascripts/discerner/jquery/jquery.blockUI.js +576 -0
- data/app/assets/javascripts/discerner/jquery/jquery.form.js +1074 -0
- data/app/assets/javascripts/discerner/nested_attributes.js +69 -0
- data/app/assets/javascripts/discerner/search_combinations.js +49 -0
- data/app/assets/javascripts/discerner/search_parameter.js +131 -0
- data/app/assets/javascripts/discerner/search_parameter_value.js +172 -0
- data/app/assets/javascripts/discerner/searches.js +93 -0
- data/app/assets/javascripts/discerner/url.js +42 -0
- data/app/assets/stylesheets/discerner/application.css +16 -0
- data/app/assets/stylesheets/discerner/buttons.sass +13 -0
- data/app/assets/stylesheets/discerner/categorized_autocompleter.sass +53 -0
- data/app/assets/stylesheets/discerner/discerner.sass +51 -0
- data/app/assets/stylesheets/discerner/export_parameters.sass +43 -0
- data/app/assets/stylesheets/discerner/links.sass +29 -0
- data/app/assets/stylesheets/discerner/searches.sass +205 -0
- data/app/assets/stylesheets/discerner/tables.sass +32 -0
- data/app/controllers/discerner/application_controller.rb +2 -0
- data/app/controllers/discerner/export_parameters_controller.rb +5 -0
- data/app/controllers/discerner/parameters_controller.rb +5 -0
- data/app/controllers/discerner/searches_controller.rb +5 -0
- data/app/helpers/discerner/application_helper.rb +4 -0
- data/app/helpers/discerner/parameters_helper.rb +5 -0
- data/app/helpers/discerner/searches_helper.rb +5 -0
- data/app/models/discerner/dictionary.rb +5 -0
- data/app/models/discerner/export_parameter.rb +5 -0
- data/app/models/discerner/operator.rb +5 -0
- data/app/models/discerner/parameter.rb +5 -0
- data/app/models/discerner/parameter_category.rb +5 -0
- data/app/models/discerner/parameter_type.rb +5 -0
- data/app/models/discerner/parameter_value.rb +5 -0
- data/app/models/discerner/parameter_value_categorization.rb +5 -0
- data/app/models/discerner/parameter_value_category.rb +5 -0
- data/app/models/discerner/search.rb +5 -0
- data/app/models/discerner/search_combination.rb +5 -0
- data/app/models/discerner/search_parameter.rb +5 -0
- data/app/models/discerner/search_parameter_value.rb +5 -0
- data/app/views/discerner/export_parameters/index.html.haml +55 -0
- data/app/views/discerner/parameters/_values_autocompleter.html.haml +49 -0
- data/app/views/discerner/parameters/values.html.haml +1 -0
- data/app/views/discerner/searches/_form.html.haml +21 -0
- data/app/views/discerner/searches/_form_combined_searches.html.haml +32 -0
- data/app/views/discerner/searches/_form_controls.html.haml +8 -0
- data/app/views/discerner/searches/_form_header.html.haml +39 -0
- data/app/views/discerner/searches/_form_search_parameters.html.haml +28 -0
- data/app/views/discerner/searches/_list.html.haml +17 -0
- data/app/views/discerner/searches/_search_combination_fields.html.haml +22 -0
- data/app/views/discerner/searches/_search_parameter_fields.html.haml +48 -0
- data/app/views/discerner/searches/_search_parameter_value_fields.html.haml +62 -0
- data/app/views/discerner/searches/_summary.html.haml +25 -0
- data/app/views/discerner/searches/edit.html.haml +8 -0
- data/app/views/discerner/searches/index.html.haml +13 -0
- data/app/views/discerner/searches/index.js.haml +1 -0
- data/app/views/discerner/searches/new.html.haml +3 -0
- data/app/views/discerner/searches/rename.html.haml +6 -0
- data/app/views/discerner/searches/update.js.haml +7 -0
- data/app/views/discerner/shared/_categorized_autocompleter_items.html.haml +15 -0
- data/app/views/discerner/shared/_error_messages.html.haml +5 -0
- data/app/views/layouts/discerner/searches.html.erb +17 -0
- data/config/cucumber.yml +8 -0
- data/config/routes.rb +17 -0
- data/db/migrate/20121004040716_create_discerner_dictionaries.rb +11 -0
- data/db/migrate/20121004153043_create_discerner_parameter_categories.rb +12 -0
- data/db/migrate/20121005194843_create_discerner_parameter_types.rb +11 -0
- data/db/migrate/20121005203223_create_discerner_parameters.rb +14 -0
- data/db/migrate/20121008154855_create_discerner_operators.rb +13 -0
- data/db/migrate/20121008160313_create_discerner_operators_parameter_types.rb +8 -0
- data/db/migrate/20121008161455_create_discerner_parameter_values.rb +13 -0
- data/db/migrate/20121008180829_create_discerner_searches.rb +11 -0
- data/db/migrate/20121008182443_create_discerner_search_parameters.rb +11 -0
- data/db/migrate/20121011205130_create_discerner_search_parameter_values.rb +15 -0
- data/db/migrate/20121211213215_add_dictionary_id_to_discerner_searches.rb +5 -0
- data/db/migrate/20130205193602_create_discerner_search_combinations.rb +12 -0
- data/db/migrate/20130211230636_create_discerner_export_parameters.rb +9 -0
- data/db/migrate/20130213185818_add_search_columns_to_discerner_parameters.rb +38 -0
- data/db/migrate/20130213205255_rename_database_name_to_search_value_in_discerner_parameter_values.rb +5 -0
- data/db/migrate/20130215165416_add_searchable_to_discerner_parameters.rb +5 -0
- data/db/migrate/20130218230257_add_exclusive_to_discerner_parameters.rb +5 -0
- data/db/migrate/20130220163015_replace_integer_type_with_numeric.rb +22 -0
- data/db/migrate/20130221172826_add_unique_identifier_to_discerner_parameters.rb +5 -0
- data/db/migrate/20130222052924_change_search_attribute_to_method.rb +29 -0
- data/db/migrate/20130222070959_add_export_columns_to_discerner_parameters.rb +6 -0
- data/db/migrate/20130227031747_add_unique_identifier_to_discerner_operators.rb +16 -0
- data/db/migrate/20130306015019_change_discerner_parameter_values_name.rb +9 -0
- data/db/migrate/20130306212430_add_deleted_at_to_discerner_search_parameters.rb +5 -0
- data/db/migrate/20130306212504_add_deleted_at_to_discerner_search_parameter_values.rb +5 -0
- data/db/migrate/20130306212527_add_deleted_at_to_discerner_search_combinations.rb +5 -0
- data/db/migrate/20130306212818_add_deleted_at_to_discerner_export_parameters.rb +5 -0
- data/db/migrate/20130311190717_add_operator_type_to_discerner_operators.rb +5 -0
- data/db/migrate/20131212175110_remove_extra_search_parameter_values.rb +10 -0
- data/db/migrate/20140204170625_create_discerner_parameter_value_categories.rb +16 -0
- data/db/migrate/20140204170646_create_discerner_parameter_value_categorizations.rb +12 -0
- data/db/migrate/20140227191827_remove_blank_parameter_values_from_export_parameters.rb +10 -0
- data/db/seeds.rb +0 -0
- data/lib/discerner/engine.rb +16 -0
- data/lib/discerner/methods/controllers/export_parameters_controller.rb +38 -0
- data/lib/discerner/methods/controllers/parameters_controller.rb +30 -0
- data/lib/discerner/methods/controllers/searches_controller.rb +204 -0
- data/lib/discerner/methods/helpers/searches_helper.rb +145 -0
- data/lib/discerner/methods/models/dictionary.rb +54 -0
- data/lib/discerner/methods/models/export_parameter.rb +35 -0
- data/lib/discerner/methods/models/operator.rb +42 -0
- data/lib/discerner/methods/models/parameter.rb +90 -0
- data/lib/discerner/methods/models/parameter_category.rb +60 -0
- data/lib/discerner/methods/models/parameter_type.rb +33 -0
- data/lib/discerner/methods/models/parameter_value.rb +87 -0
- data/lib/discerner/methods/models/parameter_value_categorization.rb +21 -0
- data/lib/discerner/methods/models/parameter_value_category.rb +45 -0
- data/lib/discerner/methods/models/search.rb +147 -0
- data/lib/discerner/methods/models/search_combination.rb +50 -0
- data/lib/discerner/methods/models/search_parameter.rb +128 -0
- data/lib/discerner/methods/models/search_parameter_value.rb +130 -0
- data/lib/discerner/methods/models/soft_delete.rb +35 -0
- data/lib/discerner/methods/models/warning.rb +15 -0
- data/lib/discerner/parser.rb +497 -0
- data/lib/discerner/version.rb +3 -0
- data/lib/discerner.rb +4 -0
- data/lib/generators/discerner/dictionary/dictionary_generator.rb +38 -0
- data/lib/generators/discerner/dictionary/templates/model.rb +15 -0
- data/lib/generators/discerner/dictionary/templates/show.xls.erb +37 -0
- data/lib/generators/discerner/dictionary/templates/view.html.haml +2 -0
- data/lib/generators/discerner/install/install_generator.rb +153 -0
- data/lib/generators/discerner/install/templates/controllers/export_parameters_controller.rb +20 -0
- data/lib/generators/discerner/install/templates/controllers/parameters_controller.rb +15 -0
- data/lib/generators/discerner/install/templates/controllers/searches_controller.rb +39 -0
- data/lib/generators/discerner/install/templates/dictionaries.yml +236 -0
- data/lib/generators/discerner/install/templates/helpers/searches_helper.rb +9 -0
- data/lib/generators/discerner/install/templates/models/book.rb +15 -0
- data/lib/generators/discerner/install/templates/models/dictionary.rb +9 -0
- data/lib/generators/discerner/install/templates/models/export_parameter.rb +9 -0
- data/lib/generators/discerner/install/templates/models/operator.rb +9 -0
- data/lib/generators/discerner/install/templates/models/parameter.rb +10 -0
- data/lib/generators/discerner/install/templates/models/parameter_category.rb +9 -0
- data/lib/generators/discerner/install/templates/models/parameter_type.rb +9 -0
- data/lib/generators/discerner/install/templates/models/parameter_value.rb +9 -0
- data/lib/generators/discerner/install/templates/models/parameter_value_categorization.rb +9 -0
- data/lib/generators/discerner/install/templates/models/parameter_value_category.rb +9 -0
- data/lib/generators/discerner/install/templates/models/search.rb +9 -0
- data/lib/generators/discerner/install/templates/models/search_combination.rb +9 -0
- data/lib/generators/discerner/install/templates/models/search_parameter.rb +9 -0
- data/lib/generators/discerner/install/templates/models/search_parameter_value.rb +9 -0
- data/lib/generators/discerner/install/templates/views/layouts/searches.html.erb +17 -0
- data/lib/setup/operators.yml +91 -0
- data/lib/tasks/cucumber.rake +65 -0
- data/lib/tasks/discerner_tasks.rake +30 -0
- metadata +531 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
NestedAttributes = function (config) {
|
2
|
+
var that = this,
|
3
|
+
defaultConfig = {
|
4
|
+
removeStyle: 'hide',
|
5
|
+
undeleteOnChange: false,
|
6
|
+
add: true,
|
7
|
+
remove: true
|
8
|
+
};
|
9
|
+
this.config = $.extend(defaultConfig, config);
|
10
|
+
|
11
|
+
if (this.config.undeleteOnChange) {
|
12
|
+
$(this.config.container).find("input, select, textarea").change(function () {
|
13
|
+
$(that.config.container).find('.delete_' + that.config.association).prev("input[type=hidden]").val("0");
|
14
|
+
});
|
15
|
+
}
|
16
|
+
|
17
|
+
$(this.config.container).find("input, select, textarea").focus(function () {
|
18
|
+
$(this).select();
|
19
|
+
});
|
20
|
+
|
21
|
+
if (this.config.remove) {
|
22
|
+
var link = $(this.config.container).find('.delete_' + this.config.association)
|
23
|
+
$(document).off('click', link.selector)
|
24
|
+
$(document).on('click', link.selector, function() {
|
25
|
+
that.remove_fields(this, that.config.removeStyle);
|
26
|
+
|
27
|
+
if (that.config.removeHandler) {
|
28
|
+
that.config.removeHandler.call(that.config.caller);
|
29
|
+
}
|
30
|
+
});
|
31
|
+
}
|
32
|
+
|
33
|
+
if (this.config.add) {
|
34
|
+
var link = $(this.config.container).find('.add_' + this.config.association)
|
35
|
+
$(document).off('click', link.selector)
|
36
|
+
$(document).on('click', link.selector, function() {
|
37
|
+
that.add_fields(this, that.config.association, that.config.content);
|
38
|
+
|
39
|
+
if (that.config.addHandler) {
|
40
|
+
that.config.addHandler.call(that.config.caller);
|
41
|
+
}
|
42
|
+
});
|
43
|
+
}
|
44
|
+
};
|
45
|
+
|
46
|
+
NestedAttributes.prototype = {
|
47
|
+
remove_fields: function (link, removeStyle) {
|
48
|
+
$(link).prev("input[type=hidden]").val("1");
|
49
|
+
if (removeStyle === 'hide' ) {
|
50
|
+
$(link).closest(".fields").hide();
|
51
|
+
$(link).closest(".fields").prev('.error').hide();
|
52
|
+
}
|
53
|
+
else if (removeStyle === 'clear' ) {
|
54
|
+
$(link).closest(".fields").find('input').clearFields();
|
55
|
+
$(link).closest(".fields").find('select').clearFields();
|
56
|
+
$(link).closest(".fields").find('textarea').clearFields();
|
57
|
+
}
|
58
|
+
},
|
59
|
+
|
60
|
+
add_fields: function(link, association, content) {
|
61
|
+
var new_id = new Date().getTime(),
|
62
|
+
regexp1 = new RegExp("new_" + association, "g"),
|
63
|
+
regexp2 = new RegExp("new_nested_record", "g");
|
64
|
+
|
65
|
+
content = content.replace(regexp1, new_id);
|
66
|
+
content = content.replace(regexp2, 'new_nested_record_' + new_id);
|
67
|
+
$(link).closest("." + association).find('.nested_records_' + association).append(content);
|
68
|
+
}
|
69
|
+
};
|
@@ -0,0 +1,49 @@
|
|
1
|
+
// Place all the behaviors and hooks related to the matching controller here.
|
2
|
+
// All this logic will automatically be available in application.js.
|
3
|
+
|
4
|
+
Discerner.SearchCombination.UI = function (config) {
|
5
|
+
var dictionarySelector = $('.discerner_search_dictionary select#search_dictionary_id'),
|
6
|
+
selectedDictionaryOption = $(dictionarySelector).find('option:selected:last'),
|
7
|
+
|
8
|
+
setupCombinedSearches = function () {
|
9
|
+
var search_combinations = $('.search_combinations').find('.nested_records_search_combinations tr.search_combination'),
|
10
|
+
display_orders = search_combinations.find('input[name$="[display_order]"]'),
|
11
|
+
i = 0;
|
12
|
+
|
13
|
+
// set up predicate for selected searches
|
14
|
+
search_combinations.filter(':visible:not(:first)').find('.combined_search_operator span').html('and');
|
15
|
+
|
16
|
+
// get max display order
|
17
|
+
$.each(display_orders, function(){
|
18
|
+
var val = parseInt($(this).val());
|
19
|
+
if (val >= i) { i = val }
|
20
|
+
});
|
21
|
+
|
22
|
+
// assign display order to combined searches without it
|
23
|
+
$.each(display_orders, function(){
|
24
|
+
if ($(this).val().length == 0) {
|
25
|
+
i = i + 1
|
26
|
+
$(this).val(i);
|
27
|
+
}
|
28
|
+
})
|
29
|
+
|
30
|
+
// hide combined searches options that do not belong to selected dictionary
|
31
|
+
if (dictionarySelector.length > 0){
|
32
|
+
dictionary_class = $(dictionarySelector).find('option:selected:last').attr('class')
|
33
|
+
$('.search_combinations_combobox_autocompleter').find('option:not(.' + dictionary_class +'):not([value=""])').detach();
|
34
|
+
};
|
35
|
+
|
36
|
+
// setup autocompleters for newly added row
|
37
|
+
$(".search_combinations_combobox_autocompleter").combobox({watermark:'an existing search'});
|
38
|
+
};
|
39
|
+
|
40
|
+
searchCombinationNestedAttributesForm = new NestedAttributes({
|
41
|
+
container: $('.search_combinations'),
|
42
|
+
association: 'search_combinations',
|
43
|
+
content: config.searchCombinationsTemplate,
|
44
|
+
addHandler: setupCombinedSearches,
|
45
|
+
caller: this
|
46
|
+
});
|
47
|
+
|
48
|
+
setupCombinedSearches();
|
49
|
+
}
|
@@ -0,0 +1,131 @@
|
|
1
|
+
// Place all the behaviors and hooks related to the matching controller here.
|
2
|
+
// All this logic will automatically be available in application.js.
|
3
|
+
|
4
|
+
Discerner.SearchParameter.UI = function (config) {
|
5
|
+
var parametersUrl = new Discerner.Url(config.parametersUrl),
|
6
|
+
dictionarySelector = $('.discerner_search_dictionary select#search_dictionary_id'),
|
7
|
+
selectedDictionaryOption = $(dictionarySelector).find('option:selected:last'),
|
8
|
+
|
9
|
+
setupParameters = function () {
|
10
|
+
var search_parameters = $('.search_parameters').find('.nested_records_search_parameters tr.search_parameter'),
|
11
|
+
display_orders = search_parameters.find('input:not([name*="search_parameter_values_attributes"])[name$="[display_order]"]'),
|
12
|
+
i = 0;
|
13
|
+
|
14
|
+
search_parameters.filter(':visible:not(:first)').find('.parameter_boolean_operator span').html('and');
|
15
|
+
|
16
|
+
// remove parameter options that do not belong to selected dictionary
|
17
|
+
if (dictionarySelector.length > 0){
|
18
|
+
dictionary_class = $(dictionarySelector).find('option:selected:last').attr('class');
|
19
|
+
$.each($('div.parameter_category'), function(){
|
20
|
+
if (!$(this).hasClass(dictionary_class)) {
|
21
|
+
$(this).remove();
|
22
|
+
}
|
23
|
+
});
|
24
|
+
$.each($('select.parameters_combobox_autocompleter option'), function(){
|
25
|
+
if (!($(this).hasClass(dictionary_class) || $(this).val() == '')) {
|
26
|
+
$(this).remove();
|
27
|
+
}
|
28
|
+
});
|
29
|
+
};
|
30
|
+
$(".parameters_combobox_autocompleter").combobox({watermark:'a criteria'});
|
31
|
+
|
32
|
+
// get max display order
|
33
|
+
$.each(display_orders, function(){
|
34
|
+
var val = parseInt($(this).val());
|
35
|
+
if (val >= i) { i = val }
|
36
|
+
});
|
37
|
+
|
38
|
+
// assign display order to search predicates without it
|
39
|
+
$.each(display_orders, function(){
|
40
|
+
if ($(this).val().length == 0) {
|
41
|
+
i = i + 1
|
42
|
+
$(this).val(i);
|
43
|
+
}
|
44
|
+
})
|
45
|
+
},
|
46
|
+
searchParametersNestedAttributesForm = new NestedAttributes({
|
47
|
+
container: $('.search_parameters'),
|
48
|
+
association: 'search_parameters',
|
49
|
+
content: config.searchParametersTemplate,
|
50
|
+
addHandler: setupParameters,
|
51
|
+
caller: this
|
52
|
+
});
|
53
|
+
|
54
|
+
// handle criteria autocompleter button click
|
55
|
+
$(document).on('click', '.parameter .categorized_autocompleter_link', function () {
|
56
|
+
var popup = $(this).siblings('.div-category-popup'),
|
57
|
+
select = $(this).siblings('select').first(),
|
58
|
+
// get all the "sibling" dropdowns
|
59
|
+
sibling_selects = $('select.' + select.attr('class')).filter(function(){
|
60
|
+
return $(this).closest('tr').find('td.remove input[name$="[_destroy]"]:not([name*="[search_parameter_values_attributes]"])').filter(function() { return this.value === '1'; }).length == 0 // exclude rows marked for destroy
|
61
|
+
}),
|
62
|
+
// get all selected parameter options from sibling selects
|
63
|
+
matching_selected_options = sibling_selects.find('option.exclusive:selected');
|
64
|
+
// match selected options from sibling selects with the source select options
|
65
|
+
// (they will have different base ids for each set but same value)
|
66
|
+
popup.find('.criteria a.categorized_autocompleter_item_link').removeClass('selection_disabled');
|
67
|
+
$.each(matching_selected_options, function(){
|
68
|
+
option = select.find('option[value=' + $(this).val() + ']');
|
69
|
+
popup.find('.parameter_category .criteria a.categorized_autocompleter_item_link[rel="' + $(option).attr('id') + '"]').addClass('selection_disabled');
|
70
|
+
})
|
71
|
+
toggleCategorizedAutocompleterPopup(this);
|
72
|
+
toggleCategorizedAutocompleterPopup($(this).closest('.search_parameter').find('.parameter_value a.expanded_categorized_autocompleter_link'));
|
73
|
+
});
|
74
|
+
|
75
|
+
// handle criteria popup list link click
|
76
|
+
$(document).on('click', '.parameter .categorized_autocompleter_item_link:not(.selection_disabled)', function () {
|
77
|
+
var autocompleter = $(this).parents('.categorized_autocompleter').find('select.parameters_combobox_autocompleter'),
|
78
|
+
categorizedItemEl = document.getElementById($(this).attr('rel'));
|
79
|
+
categorizedAutocompleterLink = $(this).parents('.categorized_autocompleter').find('.categorized_autocompleter_link');
|
80
|
+
autocompleter.combobox('setValue', categorizedItemEl.text);
|
81
|
+
autocompleter.change();
|
82
|
+
toggleCategorizedAutocompleterPopup(categorizedAutocompleterLink);
|
83
|
+
});
|
84
|
+
|
85
|
+
// toggle criteria popup
|
86
|
+
var toggleCategorizedAutocompleterPopup = function (link) {
|
87
|
+
var popup = $(link).parents('.categorized_autocompleter').find('.div-category-popup');
|
88
|
+
if ($(link).hasClass('collapsed_categorized_autocompleter_link')) {
|
89
|
+
popup.show();
|
90
|
+
$(link).removeClass('collapsed_categorized_autocompleter_link');
|
91
|
+
$(link).addClass('expanded_categorized_autocompleter_link');
|
92
|
+
}
|
93
|
+
else {
|
94
|
+
popup.hide();
|
95
|
+
$(link).removeClass('expanded_categorized_autocompleter_link');
|
96
|
+
$(link).addClass('collapsed_categorized_autocompleter_link');
|
97
|
+
}
|
98
|
+
};
|
99
|
+
|
100
|
+
// handle changing selections for criteria autocompleter
|
101
|
+
$(document).on('change', '.parameter select.parameters_combobox_autocompleter', function () {
|
102
|
+
var that = this,
|
103
|
+
predicate = $(that).closest('.search_parameter'),
|
104
|
+
selected_option = $(that).find('option:selected:last'),
|
105
|
+
add_button = $(predicate).find('a.add_search_parameter_values');
|
106
|
+
|
107
|
+
$(predicate).find('.nested_records_search_parameter_values .search_parameter_value .delete_search_parameter_values').click();
|
108
|
+
if ($(selected_option).length == 0 || $(selected_option).val() == ''){
|
109
|
+
$(add_button).hide();
|
110
|
+
}
|
111
|
+
else if ($(selected_option).hasClass('list')){
|
112
|
+
$($(predicate).find('.tmp_link')).remove();
|
113
|
+
console.log(parametersUrl.sub({ question_id: this.value }))
|
114
|
+
$.get(parametersUrl.sub({ question_id: this.value }), function (data) {
|
115
|
+
$.each(data.parameter_values, function() {
|
116
|
+
$(add_button).click();
|
117
|
+
var row = $(predicate).find('.nested_records_search_parameter_values .search_parameter_value').filter(':last');
|
118
|
+
row.find('.parameter_value span').text(this.name);
|
119
|
+
row.find('.parameter_value_id').val(this.parameter_value_id);
|
120
|
+
$(add_button).hide();
|
121
|
+
});
|
122
|
+
});
|
123
|
+
} else {
|
124
|
+
$(add_button).show();
|
125
|
+
$(add_button).click();
|
126
|
+
}
|
127
|
+
});
|
128
|
+
|
129
|
+
setupParameters();
|
130
|
+
};
|
131
|
+
|
@@ -0,0 +1,172 @@
|
|
1
|
+
Discerner.SearchParameterValue.UI = function (config) {
|
2
|
+
var that = this,
|
3
|
+
parametersUrl = new Discerner.Url(config.parametersUrl),
|
4
|
+
hideValue = function(e){
|
5
|
+
if (!$(e).hasClass('invisible')){
|
6
|
+
$(e).addClass('invisible');
|
7
|
+
}
|
8
|
+
};
|
9
|
+
showValue = function(e){
|
10
|
+
if ($(e).hasClass('invisible')){
|
11
|
+
$(e).removeClass('invisible');
|
12
|
+
}
|
13
|
+
};
|
14
|
+
setupOperator = function(o){
|
15
|
+
var row = $(o).closest('tr');
|
16
|
+
option = $(o).find('option:selected');
|
17
|
+
if (option.hasClass('range')){
|
18
|
+
showValue($(row).find('.additional_value'));
|
19
|
+
} else {
|
20
|
+
hideValue($(row).find('.additional_value'));
|
21
|
+
}
|
22
|
+
if (option.hasClass('presence')){
|
23
|
+
hideValue($(row).find('.value'));
|
24
|
+
} else {
|
25
|
+
showValue($(row).find('.value'));
|
26
|
+
}
|
27
|
+
},
|
28
|
+
setupParameterValues = function(){
|
29
|
+
var row = $(config.container).find('.nested_records_search_parameter_values .search_parameter_value').last(),
|
30
|
+
selectedParameter = $(config.container).find('select.parameters_combobox_autocompleter option:selected:last');
|
31
|
+
|
32
|
+
row.find('td').hide();
|
33
|
+
hideValue($(row).find('.additional_value').show());
|
34
|
+
row.find('.parameter_values_boolean_operator').show();
|
35
|
+
|
36
|
+
if ($(selectedParameter).hasClass('list')) { // list parameters
|
37
|
+
row.find('.chosen, .parameter_value').show();
|
38
|
+
$(config.container).find('a.add_search_parameter_values').hide();
|
39
|
+
$(config.container).find('.additional_value').hide();
|
40
|
+
} else if ($(selectedParameter).hasClass('combobox')) { // combobox parameters
|
41
|
+
var input = $(row).find('input.parameter_value_id');
|
42
|
+
$(config.container).find('.additional_value').hide();
|
43
|
+
if (input.length > 0) {
|
44
|
+
$.get( parametersUrl.sub({ question_id: selectedParameter.val(), search_parameter_value_id: input.closest('tr.search_parameter_value').attr('id') }), function( data ) {
|
45
|
+
container = $(input).closest('td');
|
46
|
+
$(input).detach();
|
47
|
+
container.append( data );
|
48
|
+
container.find('select').attr('id', input.attr('id')).attr('name', input.attr('name')).combobox({ watermark:'a value'});
|
49
|
+
handleParameterValuelPopupListClick(row);
|
50
|
+
handleParameterValueAutocompleterButtonLink(row);
|
51
|
+
});
|
52
|
+
}
|
53
|
+
$(config.container).find('.parameter_value, .remove').show();
|
54
|
+
$(config.container).find('a.add_search_parameter_values').show();
|
55
|
+
} else { // date, text and numeric parameters
|
56
|
+
var parameter_classes = ['date', 'numeric', 'text', 'string'];
|
57
|
+
for (var i in parameter_classes) {
|
58
|
+
if ($(selectedParameter).hasClass(parameter_classes[i])) {
|
59
|
+
row.find('.operator option:not(.' + parameter_classes[i] +')').detach();
|
60
|
+
row.find('.operator, .value, .remove').show();
|
61
|
+
$(config.container).find('a.add_search_parameter_values').show();
|
62
|
+
if (parameter_classes[i] == 'date') {
|
63
|
+
row.find('.value input, .additional_value input').addClass('datepicker');
|
64
|
+
}
|
65
|
+
}
|
66
|
+
}
|
67
|
+
}
|
68
|
+
$(config.container).find('.nested_records_search_parameter_values tr.search_parameter_value:visible:not(:first)')
|
69
|
+
.find('.parameter_values_boolean_operator span').html('or');
|
70
|
+
|
71
|
+
var i = 0,
|
72
|
+
display_orders = config.container.find('input[name*="search_parameter_values_attributes"][name$="[display_order]"]');
|
73
|
+
|
74
|
+
// get max display order
|
75
|
+
$.each(display_orders, function(){
|
76
|
+
var val = parseInt($(this).val());
|
77
|
+
if (val >= i) { i = val }
|
78
|
+
});
|
79
|
+
// assign display order to search predicates without it
|
80
|
+
$.each(display_orders, function(){
|
81
|
+
if ($(this).val().length == 0) {
|
82
|
+
i = i + 1
|
83
|
+
$(this).val(i);
|
84
|
+
}
|
85
|
+
});
|
86
|
+
$(config.container).find(".parameter_values_combobox_autocompleter").combobox({watermark:'a value'});
|
87
|
+
},
|
88
|
+
searchParameterValuesNestedAttributesForm = new NestedAttributes({
|
89
|
+
container: config.container,
|
90
|
+
association: 'search_parameter_values',
|
91
|
+
content: config.searchParameterValuesTemplate,
|
92
|
+
addHandler: setupParameterValues,
|
93
|
+
caller: this
|
94
|
+
});
|
95
|
+
|
96
|
+
// toggle parameter value popup
|
97
|
+
var toggleCategorizedAutocompleterPopup = function (link) {
|
98
|
+
var popup = $(link).parents('.categorized_autocompleter').find('.div-category-popup');
|
99
|
+
if ($(link).hasClass('collapsed_categorized_autocompleter_link')) {
|
100
|
+
popup.show();
|
101
|
+
$(link).removeClass('collapsed_categorized_autocompleter_link');
|
102
|
+
$(link).addClass('expanded_categorized_autocompleter_link');
|
103
|
+
}
|
104
|
+
else {
|
105
|
+
popup.hide();
|
106
|
+
$(link).removeClass('expanded_categorized_autocompleter_link');
|
107
|
+
$(link).addClass('collapsed_categorized_autocompleter_link');
|
108
|
+
}
|
109
|
+
};
|
110
|
+
|
111
|
+
// handle parameter value autocompleter button click
|
112
|
+
var handleParameterValueAutocompleterButtonLink = function(container){
|
113
|
+
$(container).find('.parameter_value .categorized_autocompleter_link').on('click', function(){
|
114
|
+
var popup = $(this).siblings('.div-category-popup'),
|
115
|
+
select = $(this).siblings('select').first(),
|
116
|
+
// get all the "sibling" dropdowns
|
117
|
+
sibling_selects = $('select.' + select.attr('class')).filter(function(){
|
118
|
+
return $(this).closest('tr').find('td.remove input[name$="[_destroy]"]:not([name*="[search_parameter_values_attributes]"])').filter(function() { return this.value === '1'; }).length == 0 // exclude rows marked for destroy
|
119
|
+
}),
|
120
|
+
// get all selected parameter options from sibling selects
|
121
|
+
matching_selected_options = sibling_selects.find('option.exclusive:selected');
|
122
|
+
// match selected options from sibling selects with the source select options
|
123
|
+
// (they will have different base ids for each set but same value)
|
124
|
+
popup.find('.parameter value a.categorized_autocompleter_item_link').removeClass('selection_disabled');
|
125
|
+
$.each(matching_selected_options, function(){
|
126
|
+
option = select.find('option[value=' + $(this).val() + ']');
|
127
|
+
popup.find('.search_parameter .parameter value a.categorized_autocompleter_item_link[rel="' + $(option).attr('id') + '"]').addClass('selection_disabled');
|
128
|
+
})
|
129
|
+
toggleCategorizedAutocompleterPopup(this);
|
130
|
+
toggleCategorizedAutocompleterPopup($(this).closest('.search_parameter').find('.parameter a.expanded_categorized_autocompleter_link'));
|
131
|
+
});
|
132
|
+
}
|
133
|
+
|
134
|
+
// handle parameter value popup list link click
|
135
|
+
var handleParameterValuelPopupListClick = function(container) {
|
136
|
+
$(container).find('.parameter_value .categorized_autocompleter_item_link:not(.selection_disabled)').on('click', function(e){
|
137
|
+
e.preventDefault();
|
138
|
+
var autocompleter = $(this).parents('.categorized_autocompleter').find('select.parameter_values_combobox_autocompleter'),
|
139
|
+
categorizedItemEl = document.getElementById($(this).attr('rel'));
|
140
|
+
categorizedAutocompleterLink = $(this).parents('.categorized_autocompleter').find('.categorized_autocompleter_link');
|
141
|
+
autocompleter.combobox('setValue', categorizedItemEl.text);
|
142
|
+
autocompleter.change();
|
143
|
+
toggleCategorizedAutocompleterPopup(categorizedAutocompleterLink);
|
144
|
+
});
|
145
|
+
}
|
146
|
+
|
147
|
+
setupParameterValues();
|
148
|
+
handleParameterValuelPopupListClick(config.container);
|
149
|
+
handleParameterValueAutocompleterButtonLink(config.container);
|
150
|
+
|
151
|
+
$.each($('.operator'), function() { setupOperator(this); });
|
152
|
+
|
153
|
+
$(document).on('change', '.operator select', function(){
|
154
|
+
setupOperator(this);
|
155
|
+
});
|
156
|
+
|
157
|
+
$(document).on('click', '.show-category-items', function(e) {
|
158
|
+
e.preventDefault();
|
159
|
+
$(this).closest('.categorized-parameter-values, .uncategorized-parameter-values').find('.category-items').show();
|
160
|
+
$(this).addClass('hide-category-items');
|
161
|
+
$(this).removeClass('show-category-items');
|
162
|
+
$(this).html('less')
|
163
|
+
});
|
164
|
+
|
165
|
+
$(document).on('click', '.hide-category-items', function(e) {
|
166
|
+
e.preventDefault();
|
167
|
+
$(this).closest('.categorized-parameter-values, .uncategorized-parameter-values').find('.category-items').hide();
|
168
|
+
$(this).addClass('show-category-items');
|
169
|
+
$(this).removeClass('hide-category-items');
|
170
|
+
$(this).html('more')
|
171
|
+
});
|
172
|
+
};
|
@@ -0,0 +1,93 @@
|
|
1
|
+
// Place all the behaviors and hooks related to the matching controller here.
|
2
|
+
// All this logic will automatically be available in application.js.
|
3
|
+
|
4
|
+
Discerner.Search.UI = function (config) {
|
5
|
+
var dictionarySelector = $('.discerner_search_dictionary select#search_dictionary_id'),
|
6
|
+
dictionaryContainer = $('.discerner_search_dictionary span'),
|
7
|
+
selectedDictionaryOption = $(dictionarySelector).find('option:selected:last');
|
8
|
+
|
9
|
+
var toggleControls = function() {
|
10
|
+
selectedDictionaryOption = $(dictionarySelector).find('option:selected:last');
|
11
|
+
if (dictionarySelector.length > 0 && selectedDictionaryOption.length == 0 || selectedDictionaryOption.val() == '') {
|
12
|
+
$('.search_parameters').hide();
|
13
|
+
$('.search_combinations').hide();
|
14
|
+
$('.discerner_dictionary_required_message').show();
|
15
|
+
} else {
|
16
|
+
$('.search_parameters').show();
|
17
|
+
$('.search_combinations').show();
|
18
|
+
$('.discerner_dictionary_required_message').hide();
|
19
|
+
}
|
20
|
+
}
|
21
|
+
|
22
|
+
// handle dictionary selection change
|
23
|
+
$(dictionarySelector).bind('change', function(){
|
24
|
+
$('a.delete_search_parameters').trigger('click');
|
25
|
+
$('a.delete_search_combinations').trigger('click');
|
26
|
+
toggleControls();
|
27
|
+
$('a.add_search_parameters').trigger('click');
|
28
|
+
$('a.add_search_combinations').trigger('click');
|
29
|
+
});
|
30
|
+
|
31
|
+
// block UI on form submit
|
32
|
+
$('#discerner_search_form form, #results form').bind('submit', function(){
|
33
|
+
$.blockUI({
|
34
|
+
title: 'Loading ... ',
|
35
|
+
message: '<p>Please be patient</p>',
|
36
|
+
fadeIn: 0,
|
37
|
+
timeout: 20000000,
|
38
|
+
showOverlay: true,
|
39
|
+
centerY: true,
|
40
|
+
theme: true
|
41
|
+
});
|
42
|
+
});
|
43
|
+
|
44
|
+
$(document).on('mouseover', '.datepicker', function() {
|
45
|
+
$(this).datepicker({
|
46
|
+
altFormat: 'yy-mm-dd',
|
47
|
+
dateFormat: 'yy-mm-dd',
|
48
|
+
changeMonth: true,
|
49
|
+
changeYear: true,
|
50
|
+
yearRange: config.yearRange
|
51
|
+
});
|
52
|
+
});
|
53
|
+
|
54
|
+
// handle search name editing
|
55
|
+
$('#discerner_search_form .discerner_search_name_edit a').bind('click', function(){
|
56
|
+
$(this).closest('span.discerner_search_name_edit').hide();
|
57
|
+
$(this).closest('span.discerner_search_name_edit').siblings('span.discerner_search_name').hide();
|
58
|
+
$(this).closest('div').append($('<span>').load(config.renameUrl + ' form').addClass('discerner_search_name_edit_dialog'));
|
59
|
+
return false;
|
60
|
+
});
|
61
|
+
|
62
|
+
// handle search name editing (submit the form)
|
63
|
+
$(document).on('click','#discerner_search_form .discerner_search_name_edit_dialog input[type="submit"]', function(){
|
64
|
+
var form = $(this).closest('form');
|
65
|
+
$.ajax({
|
66
|
+
type: form.attr('method'),
|
67
|
+
url: form.attr('action'),
|
68
|
+
data: form.serializeArray(),
|
69
|
+
dataType: 'script'
|
70
|
+
});
|
71
|
+
|
72
|
+
return false;
|
73
|
+
})
|
74
|
+
|
75
|
+
// handle cancel on search name editing
|
76
|
+
$(document).on('click', '#discerner_search_form .discerner_search_name_edit_dialog a.cancel', function() {
|
77
|
+
$('span.discerner_search_name_edit_dialog').siblings('span.discerner_search_name').show();
|
78
|
+
$('span.discerner_search_name_edit_dialog').siblings('span.discerner_search_name_edit').show();
|
79
|
+
$('span.discerner_search_name_edit_dialog').remove();
|
80
|
+
$("#messages").html('');
|
81
|
+
return false;
|
82
|
+
});
|
83
|
+
|
84
|
+
$(document).ready(function(){
|
85
|
+
if ((dictionarySelector.length == 0 || selectedDictionaryOption.length != 0) && ($('tr.search_parameter:visible').length == 0)){
|
86
|
+
$('a.add_search_parameters').trigger('click');
|
87
|
+
$('a.add_search_combinations').trigger('click');
|
88
|
+
}
|
89
|
+
});
|
90
|
+
|
91
|
+
toggleControls();
|
92
|
+
};
|
93
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
Discerner.Url = function (url) {
|
2
|
+
this.url = url;
|
3
|
+
};
|
4
|
+
|
5
|
+
Discerner.Url.prototype = {
|
6
|
+
sub: function (params) {
|
7
|
+
var url = this.url,
|
8
|
+
newUrl = this.url,
|
9
|
+
queryString = [],
|
10
|
+
encodedArg = undefined,
|
11
|
+
encodeParam = undefined,
|
12
|
+
param = undefined;
|
13
|
+
|
14
|
+
for (param in params) {
|
15
|
+
if (params.hasOwnProperty(param)) {
|
16
|
+
encodedParam = encodeURIComponent(param);
|
17
|
+
encodedArg = encodeURIComponent(params[param]);
|
18
|
+
newUrl = url.replace(':' + param, encodedArg);
|
19
|
+
if (url == newUrl) {
|
20
|
+
queryString.push(encodedParam + '=' + encodedArg);
|
21
|
+
}
|
22
|
+
url = newUrl;
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
if (queryString.length > 0) {
|
27
|
+
if (url.indexOf('?') > 0) {
|
28
|
+
return url + queryString.join('&');
|
29
|
+
} else {
|
30
|
+
return url + '?' + queryString.join('&');
|
31
|
+
}
|
32
|
+
} else {
|
33
|
+
return url;
|
34
|
+
}
|
35
|
+
},
|
36
|
+
|
37
|
+
parameters: function () {
|
38
|
+
return $.map(this.url.match(/:\w+/g) || [], function (o, i) {
|
39
|
+
return o.substring(1);
|
40
|
+
});
|
41
|
+
}
|
42
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
10
|
+
*
|
11
|
+
*= require_self
|
12
|
+
*= require jquery.ui.autocomplete
|
13
|
+
*= require jquery.ui.datepicker
|
14
|
+
*= require jquery.ui.button
|
15
|
+
*= require_tree .
|
16
|
+
*/
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#discerner_searches, #discerner_search
|
2
|
+
div.discerner-buttons
|
3
|
+
:margin 1em 0
|
4
|
+
|
5
|
+
a.discerner-button-negative, button.discerner-button-negative, input.discerner-button-negative
|
6
|
+
:color #800000
|
7
|
+
:font-weight bold
|
8
|
+
|
9
|
+
a.discerner-button-positive, button.discerner-button-positive, input.discerner-button-positive
|
10
|
+
:color #529214
|
11
|
+
:font-weight bold
|
12
|
+
|
13
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#discerner_searches, #discerner_search
|
2
|
+
.categorized_autocompleter_link, .categorized_autocompleter_link:hover
|
3
|
+
:padding 2px 20px 2px 2px
|
4
|
+
:text-decoration none !important
|
5
|
+
|
6
|
+
.collapsed_categorized_autocompleter_link, .collapsed_categorized_autocompleter_link:hover
|
7
|
+
:background url(bullet_arrow_down.png) 48px 2px no-repeat
|
8
|
+
.expanded_categorized_autocompleter_link, .expanded_categorized_autocompleter_link:hover
|
9
|
+
:background url(bullet_arrow_up.png) 48px 2px no-repeat
|
10
|
+
|
11
|
+
.div-category-popup
|
12
|
+
:position absolute
|
13
|
+
:z-index 1000
|
14
|
+
:background white
|
15
|
+
|
16
|
+
.div-category-list
|
17
|
+
:overflow auto
|
18
|
+
|
19
|
+
.category
|
20
|
+
:padding-bottom 5px
|
21
|
+
:padding-left 5px
|
22
|
+
:padding-right 5px
|
23
|
+
:padding-top 15px
|
24
|
+
:clear both
|
25
|
+
|
26
|
+
.category-name
|
27
|
+
:font-weight bold
|
28
|
+
:margin-bottom 0
|
29
|
+
:margin-left 0
|
30
|
+
:margin-right 0
|
31
|
+
:margin-top 0
|
32
|
+
:padding-bottom 0
|
33
|
+
:padding-left 0
|
34
|
+
:padding-right 0
|
35
|
+
:padding-top 0
|
36
|
+
|
37
|
+
.column
|
38
|
+
:float left
|
39
|
+
:margin-right 5px
|
40
|
+
:width 225px
|
41
|
+
|
42
|
+
.criteria
|
43
|
+
:margin-bottom 3px
|
44
|
+
:margin-left 0
|
45
|
+
:margin-right 0
|
46
|
+
:margin-top 3px
|
47
|
+
|
48
|
+
.categorized_autocompleter
|
49
|
+
:position relative
|
50
|
+
|
51
|
+
button.ui-button
|
52
|
+
:display none
|
53
|
+
|