discerner 1.1.18

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +97 -0
  4. data/Rakefile +29 -0
  5. data/app/assets/images/discerner/add.png +0 -0
  6. data/app/assets/images/discerner/ajax-loader.gif +0 -0
  7. data/app/assets/images/discerner/bar.gif +0 -0
  8. data/app/assets/images/discerner/bullet_arrow_down.png +0 -0
  9. data/app/assets/images/discerner/bullet_arrow_up.png +0 -0
  10. data/app/assets/images/discerner/cog.png +0 -0
  11. data/app/assets/images/discerner/delete.png +0 -0
  12. data/app/assets/images/discerner/edit.png +0 -0
  13. data/app/assets/images/discerner/excel.png +0 -0
  14. data/app/assets/images/discerner/greencheck.gif +0 -0
  15. data/app/assets/images/discerner/rails.png +0 -0
  16. data/app/assets/images/discerner/show.png +0 -0
  17. data/app/assets/images/discerner/switch_minus.gif +0 -0
  18. data/app/assets/images/discerner/switch_plus.gif +0 -0
  19. data/app/assets/javascripts/discerner/application.js +20 -0
  20. data/app/assets/javascripts/discerner/combobox.js +301 -0
  21. data/app/assets/javascripts/discerner/discerner.js +19 -0
  22. data/app/assets/javascripts/discerner/export_parameters.js +13 -0
  23. data/app/assets/javascripts/discerner/jquery/jquery.blockUI.js +576 -0
  24. data/app/assets/javascripts/discerner/jquery/jquery.form.js +1074 -0
  25. data/app/assets/javascripts/discerner/nested_attributes.js +69 -0
  26. data/app/assets/javascripts/discerner/search_combinations.js +49 -0
  27. data/app/assets/javascripts/discerner/search_parameter.js +131 -0
  28. data/app/assets/javascripts/discerner/search_parameter_value.js +172 -0
  29. data/app/assets/javascripts/discerner/searches.js +93 -0
  30. data/app/assets/javascripts/discerner/url.js +42 -0
  31. data/app/assets/stylesheets/discerner/application.css +16 -0
  32. data/app/assets/stylesheets/discerner/buttons.sass +13 -0
  33. data/app/assets/stylesheets/discerner/categorized_autocompleter.sass +53 -0
  34. data/app/assets/stylesheets/discerner/discerner.sass +51 -0
  35. data/app/assets/stylesheets/discerner/export_parameters.sass +43 -0
  36. data/app/assets/stylesheets/discerner/links.sass +29 -0
  37. data/app/assets/stylesheets/discerner/searches.sass +205 -0
  38. data/app/assets/stylesheets/discerner/tables.sass +32 -0
  39. data/app/controllers/discerner/application_controller.rb +2 -0
  40. data/app/controllers/discerner/export_parameters_controller.rb +5 -0
  41. data/app/controllers/discerner/parameters_controller.rb +5 -0
  42. data/app/controllers/discerner/searches_controller.rb +5 -0
  43. data/app/helpers/discerner/application_helper.rb +4 -0
  44. data/app/helpers/discerner/parameters_helper.rb +5 -0
  45. data/app/helpers/discerner/searches_helper.rb +5 -0
  46. data/app/models/discerner/dictionary.rb +5 -0
  47. data/app/models/discerner/export_parameter.rb +5 -0
  48. data/app/models/discerner/operator.rb +5 -0
  49. data/app/models/discerner/parameter.rb +5 -0
  50. data/app/models/discerner/parameter_category.rb +5 -0
  51. data/app/models/discerner/parameter_type.rb +5 -0
  52. data/app/models/discerner/parameter_value.rb +5 -0
  53. data/app/models/discerner/parameter_value_categorization.rb +5 -0
  54. data/app/models/discerner/parameter_value_category.rb +5 -0
  55. data/app/models/discerner/search.rb +5 -0
  56. data/app/models/discerner/search_combination.rb +5 -0
  57. data/app/models/discerner/search_parameter.rb +5 -0
  58. data/app/models/discerner/search_parameter_value.rb +5 -0
  59. data/app/views/discerner/export_parameters/index.html.haml +55 -0
  60. data/app/views/discerner/parameters/_values_autocompleter.html.haml +49 -0
  61. data/app/views/discerner/parameters/values.html.haml +1 -0
  62. data/app/views/discerner/searches/_form.html.haml +21 -0
  63. data/app/views/discerner/searches/_form_combined_searches.html.haml +32 -0
  64. data/app/views/discerner/searches/_form_controls.html.haml +8 -0
  65. data/app/views/discerner/searches/_form_header.html.haml +39 -0
  66. data/app/views/discerner/searches/_form_search_parameters.html.haml +28 -0
  67. data/app/views/discerner/searches/_list.html.haml +17 -0
  68. data/app/views/discerner/searches/_search_combination_fields.html.haml +22 -0
  69. data/app/views/discerner/searches/_search_parameter_fields.html.haml +48 -0
  70. data/app/views/discerner/searches/_search_parameter_value_fields.html.haml +62 -0
  71. data/app/views/discerner/searches/_summary.html.haml +25 -0
  72. data/app/views/discerner/searches/edit.html.haml +8 -0
  73. data/app/views/discerner/searches/index.html.haml +13 -0
  74. data/app/views/discerner/searches/index.js.haml +1 -0
  75. data/app/views/discerner/searches/new.html.haml +3 -0
  76. data/app/views/discerner/searches/rename.html.haml +6 -0
  77. data/app/views/discerner/searches/update.js.haml +7 -0
  78. data/app/views/discerner/shared/_categorized_autocompleter_items.html.haml +15 -0
  79. data/app/views/discerner/shared/_error_messages.html.haml +5 -0
  80. data/app/views/layouts/discerner/searches.html.erb +17 -0
  81. data/config/cucumber.yml +8 -0
  82. data/config/routes.rb +17 -0
  83. data/db/migrate/20121004040716_create_discerner_dictionaries.rb +11 -0
  84. data/db/migrate/20121004153043_create_discerner_parameter_categories.rb +12 -0
  85. data/db/migrate/20121005194843_create_discerner_parameter_types.rb +11 -0
  86. data/db/migrate/20121005203223_create_discerner_parameters.rb +14 -0
  87. data/db/migrate/20121008154855_create_discerner_operators.rb +13 -0
  88. data/db/migrate/20121008160313_create_discerner_operators_parameter_types.rb +8 -0
  89. data/db/migrate/20121008161455_create_discerner_parameter_values.rb +13 -0
  90. data/db/migrate/20121008180829_create_discerner_searches.rb +11 -0
  91. data/db/migrate/20121008182443_create_discerner_search_parameters.rb +11 -0
  92. data/db/migrate/20121011205130_create_discerner_search_parameter_values.rb +15 -0
  93. data/db/migrate/20121211213215_add_dictionary_id_to_discerner_searches.rb +5 -0
  94. data/db/migrate/20130205193602_create_discerner_search_combinations.rb +12 -0
  95. data/db/migrate/20130211230636_create_discerner_export_parameters.rb +9 -0
  96. data/db/migrate/20130213185818_add_search_columns_to_discerner_parameters.rb +38 -0
  97. data/db/migrate/20130213205255_rename_database_name_to_search_value_in_discerner_parameter_values.rb +5 -0
  98. data/db/migrate/20130215165416_add_searchable_to_discerner_parameters.rb +5 -0
  99. data/db/migrate/20130218230257_add_exclusive_to_discerner_parameters.rb +5 -0
  100. data/db/migrate/20130220163015_replace_integer_type_with_numeric.rb +22 -0
  101. data/db/migrate/20130221172826_add_unique_identifier_to_discerner_parameters.rb +5 -0
  102. data/db/migrate/20130222052924_change_search_attribute_to_method.rb +29 -0
  103. data/db/migrate/20130222070959_add_export_columns_to_discerner_parameters.rb +6 -0
  104. data/db/migrate/20130227031747_add_unique_identifier_to_discerner_operators.rb +16 -0
  105. data/db/migrate/20130306015019_change_discerner_parameter_values_name.rb +9 -0
  106. data/db/migrate/20130306212430_add_deleted_at_to_discerner_search_parameters.rb +5 -0
  107. data/db/migrate/20130306212504_add_deleted_at_to_discerner_search_parameter_values.rb +5 -0
  108. data/db/migrate/20130306212527_add_deleted_at_to_discerner_search_combinations.rb +5 -0
  109. data/db/migrate/20130306212818_add_deleted_at_to_discerner_export_parameters.rb +5 -0
  110. data/db/migrate/20130311190717_add_operator_type_to_discerner_operators.rb +5 -0
  111. data/db/migrate/20131212175110_remove_extra_search_parameter_values.rb +10 -0
  112. data/db/migrate/20140204170625_create_discerner_parameter_value_categories.rb +16 -0
  113. data/db/migrate/20140204170646_create_discerner_parameter_value_categorizations.rb +12 -0
  114. data/db/migrate/20140227191827_remove_blank_parameter_values_from_export_parameters.rb +10 -0
  115. data/db/seeds.rb +0 -0
  116. data/lib/discerner/engine.rb +16 -0
  117. data/lib/discerner/methods/controllers/export_parameters_controller.rb +38 -0
  118. data/lib/discerner/methods/controllers/parameters_controller.rb +30 -0
  119. data/lib/discerner/methods/controllers/searches_controller.rb +204 -0
  120. data/lib/discerner/methods/helpers/searches_helper.rb +145 -0
  121. data/lib/discerner/methods/models/dictionary.rb +54 -0
  122. data/lib/discerner/methods/models/export_parameter.rb +35 -0
  123. data/lib/discerner/methods/models/operator.rb +42 -0
  124. data/lib/discerner/methods/models/parameter.rb +90 -0
  125. data/lib/discerner/methods/models/parameter_category.rb +60 -0
  126. data/lib/discerner/methods/models/parameter_type.rb +33 -0
  127. data/lib/discerner/methods/models/parameter_value.rb +87 -0
  128. data/lib/discerner/methods/models/parameter_value_categorization.rb +21 -0
  129. data/lib/discerner/methods/models/parameter_value_category.rb +45 -0
  130. data/lib/discerner/methods/models/search.rb +147 -0
  131. data/lib/discerner/methods/models/search_combination.rb +50 -0
  132. data/lib/discerner/methods/models/search_parameter.rb +128 -0
  133. data/lib/discerner/methods/models/search_parameter_value.rb +130 -0
  134. data/lib/discerner/methods/models/soft_delete.rb +35 -0
  135. data/lib/discerner/methods/models/warning.rb +15 -0
  136. data/lib/discerner/parser.rb +497 -0
  137. data/lib/discerner/version.rb +3 -0
  138. data/lib/discerner.rb +4 -0
  139. data/lib/generators/discerner/dictionary/dictionary_generator.rb +38 -0
  140. data/lib/generators/discerner/dictionary/templates/model.rb +15 -0
  141. data/lib/generators/discerner/dictionary/templates/show.xls.erb +37 -0
  142. data/lib/generators/discerner/dictionary/templates/view.html.haml +2 -0
  143. data/lib/generators/discerner/install/install_generator.rb +153 -0
  144. data/lib/generators/discerner/install/templates/controllers/export_parameters_controller.rb +20 -0
  145. data/lib/generators/discerner/install/templates/controllers/parameters_controller.rb +15 -0
  146. data/lib/generators/discerner/install/templates/controllers/searches_controller.rb +39 -0
  147. data/lib/generators/discerner/install/templates/dictionaries.yml +236 -0
  148. data/lib/generators/discerner/install/templates/helpers/searches_helper.rb +9 -0
  149. data/lib/generators/discerner/install/templates/models/book.rb +15 -0
  150. data/lib/generators/discerner/install/templates/models/dictionary.rb +9 -0
  151. data/lib/generators/discerner/install/templates/models/export_parameter.rb +9 -0
  152. data/lib/generators/discerner/install/templates/models/operator.rb +9 -0
  153. data/lib/generators/discerner/install/templates/models/parameter.rb +10 -0
  154. data/lib/generators/discerner/install/templates/models/parameter_category.rb +9 -0
  155. data/lib/generators/discerner/install/templates/models/parameter_type.rb +9 -0
  156. data/lib/generators/discerner/install/templates/models/parameter_value.rb +9 -0
  157. data/lib/generators/discerner/install/templates/models/parameter_value_categorization.rb +9 -0
  158. data/lib/generators/discerner/install/templates/models/parameter_value_category.rb +9 -0
  159. data/lib/generators/discerner/install/templates/models/search.rb +9 -0
  160. data/lib/generators/discerner/install/templates/models/search_combination.rb +9 -0
  161. data/lib/generators/discerner/install/templates/models/search_parameter.rb +9 -0
  162. data/lib/generators/discerner/install/templates/models/search_parameter_value.rb +9 -0
  163. data/lib/generators/discerner/install/templates/views/layouts/searches.html.erb +17 -0
  164. data/lib/setup/operators.yml +91 -0
  165. data/lib/tasks/cucumber.rake +65 -0
  166. data/lib/tasks/discerner_tasks.rake +30 -0
  167. metadata +531 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: ecb4c17f2e220beb34f78081d0343faed81e933d
4
+ data.tar.gz: e9a87d805da56897978848a1b18a222ade053255
5
+ SHA512:
6
+ metadata.gz: 7bb80f4d67f66ef9de64556061661afc6b33c1f3f8864d1ee7bd52b138e34e897ff3e64ef41bec204a1b39590bb818384d43d33a5a73284ccaf0d6252f2c0163
7
+ data.tar.gz: 00a4af1d6d7021621496f8fb684db7244b4f1ca0ee60914de05a4ad68524c1af8573ba4a56ef7c18f88b05b1200259b601dc852e4828d01a9f77f904a06218ce
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2012 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Discerner
2
+
3
+ Discerner is an engine for Rails that provides basic search UI, search reqults export UI and allows to configure available search parameters/values. Discerner is not aimed to be a SQL-generator, but it allows the host application to access stored search conditions and provide search results.
4
+
5
+ Reader's note: this README uses [YARD][] markup to provide links to
6
+ Discerner's API documentation. If you aren't already, consider reading it
7
+ on [rubydoc.info][] so that the links will be followable.
8
+
9
+ [YARD]: http://yardoc.org/
10
+ [rubydoc.info]: http://rubydoc.info/github/NUBIC/discerner/master/file/README.md
11
+
12
+ # Requirements
13
+
14
+ This code has been run and tested on Ruby 1.9. and Ruby 2.1
15
+
16
+ # Dependencies
17
+
18
+ * haml
19
+ * sass
20
+ * jquery-rails
21
+ * jquery-ui-rails
22
+
23
+ # Installation
24
+
25
+ ## Install gem with Bundler
26
+
27
+ ```ruby
28
+ gem 'discerner'
29
+ bundle install
30
+ ```
31
+ ## Run the installer
32
+
33
+ ```ruby
34
+ rails generate discerner:install
35
+ ```
36
+
37
+ By default, Discerner installer performs following tasks:
38
+
39
+ * it copies Discerner's migrations into db/migrate and runs migrations
40
+ * it sets up default Discerner operators. As of now, default operators cannot be changed.
41
+ * it prompts for current_user helper name and inserts `discerner_user` method into the application controller. This allows Discerner to attibure created searches to the current user.
42
+ * it adds discerner helpers used for configuring dicerner functionality into application helper. This will be changed in the future.
43
+ * show_discerner_results? - helper used to determine if search results should be displayed.
44
+ * export_discerner_results? - helper used to determine if search results should be exportable.
45
+ * enable_combined_searches? - helper used to determine if search interface should allow to combine searches
46
+ * it mounts Discerner::Engine
47
+ * it copies sample search dictionary into lib/setup
48
+
49
+ Discerner installer accepts following parameters:
50
+
51
+ * --no-migrate - prevent installer from running migrations. If this flag is set, Discerner operators would have to be loaded manually using **rake discerner:setup:operators**
52
+ * --current-user-helper - allows to specify current user method name
53
+ * --customize-controllers - copy Discerner controllers into application, so they can be customized
54
+ * --customize-models - copy Discerner models into application, so they can be customized
55
+ * --customize-helpers - copy Discerner helpers into application, so they can be customized
56
+ * --customize-layout - copy Discerner layout into application, so it can be customized
57
+ * --customize-all - copy Discerner controllers, models, helpers, and layout into application, so they can be customized
58
+
59
+
60
+ # Usage
61
+ ## Setting up dictionaries
62
+
63
+ ```ruby
64
+ rails generate discerner:dictionary [FILENAME]
65
+ ```
66
+ Discerner uses dictionaries to define parameters and values that can be used for constructing searches. Discerner dictionary generator performs following tasks:
67
+
68
+ * it parses provided file and sets up or updates corresponding search dictionary, its parameter categories, parameters and parameter values
69
+ * it creates a model for each specified dictionary that is expected to implement "search" and "export" methods.
70
+ * it generates template views for search results and export.
71
+
72
+ Discerner dictionary generator accepts following parameters:
73
+
74
+ * --no-load - skip dictionary generation/update
75
+ * --no-models - skip models generation
76
+ * --no-views - skip views generation
77
+
78
+ Installer adds a sample dictionary than can be used as a template anr/or can be parsed and used to explore Discerner Search UI:
79
+
80
+ ```ruby
81
+ rails generate discerner:dictionary lib/setup/dictionaries.yml
82
+ ```
83
+
84
+ ## Updating dictionaries
85
+
86
+ In most cases, dictionary generator needs to be run only once per dictionary. Dictionary updates, excluding name change, should be handled by re-parcing definition file with Discerner parser:
87
+
88
+ ```ruby
89
+ rails discerner:setup:dictionaries FILE=xxx
90
+ ```
91
+
92
+ Discerner parser processes YML definition file line by line, detecting and creating/updating dictionaries, parameter categories, parameters and parameter values. It runs in silent mode by default, --trace option can be used to make it verbose.
93
+
94
+ ## User Interface
95
+
96
+ Index of all saved searches scoped by current user (if available) can be accessed from '/searches' route.
97
+
data/Rakefile ADDED
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ require 'cucumber/rake/task'
5
+ require 'rspec/core/rake_task'
6
+ require 'rubygems/package_task'
7
+ end
8
+
9
+ gemspec = eval(File.read('discerner.gemspec'), binding, 'discerner.gemspec')
10
+ Gem::PackageTask.new(gemspec).define
11
+ APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
12
+ $:.unshift File.join(File.dirname(__FILE__), 'spec','support')
13
+ load 'rails/tasks/engine.rake' if File.exists?(APP_RAKEFILE)
14
+ load 'lib/tasks/discerner_tasks.rake'
15
+ load 'test/lib/tasks/discerner_test_tasks.rake'
16
+ RSpec::Core::RakeTask.new(:spec)
17
+ task :default => :spec
18
+
19
+ namespace :cucumber do
20
+ Cucumber::Rake::Task.new(:wip, 'Run features that are being worked on') do |t|
21
+ t.profile = 'wip'
22
+ end
23
+
24
+ Cucumber::Rake::Task.new(:features) do |t|
25
+ t.cucumber_opts = "features --format pretty"
26
+ end
27
+ end
28
+
29
+ task :cucumber => 'cucumber:features'
Binary file
Binary file
Binary file
@@ -0,0 +1,20 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require jquery.ui.widget
16
+ //= require jquery.ui.autocomplete
17
+ //= require jquery.ui.datepicker
18
+ //= require jquery.ui.button
19
+ //= require discerner/jquery/jquery.blockUI
20
+ //= require_tree .
@@ -0,0 +1,301 @@
1
+ // courtesy of https://github.com/garyzhu/jquery.ui.combobox/blob/master/jquery.ui.combobox.js
2
+ // more courtesy https://github.com/garyzhu/jquery.ui.combobox/commit/65433ee5af6e9b87b594e5bb5c4b16b030806e24
3
+ /*
4
+ * Combobox widget. This widget extends the jQuery UI autocomplete widget.
5
+ *
6
+ * usage: $("#select_element").combox();
7
+ * $("#input_element").combox( {minLength: 2, delay: 200, source: anArray} );
8
+ *
9
+ * For select elements, the source list is automatically generated from the option elements.
10
+ *
11
+ * To configure a label decorator (i.e. "[admin]"), set the decoratorField when you
12
+ * initialize the combobox. The field corresponds to the object field, if the source is
13
+ * an array of objects. Or it's the attribute in <option> if the source is a select drop-down menu.
14
+ */
15
+
16
+ (function($) {
17
+ $.widget("ui.combobox", $.ui.autocomplete, {
18
+ options: {
19
+ /* override default values here */
20
+ minLength: 2,
21
+ /* the argument to pass to ajax to get the complete list */
22
+ ajaxGetAll: {
23
+ get: "all"
24
+ },
25
+ /* you can specify the field to use as a label decorator,
26
+ * it's appended to the end of the label and is excluded
27
+ * from pattern matching.
28
+ */
29
+ decoratorField: null
30
+ },
31
+
32
+ _create: function() {
33
+ if (this.element.is("SELECT")) {
34
+ this._selectInit();
35
+ return;
36
+ }
37
+ $.ui.autocomplete.prototype._create.call(this);
38
+ var input = this.element,
39
+ watermark = ('Search for ' + this.options.watermark); // custom watermark
40
+
41
+ // custom part - setting and removing watermark
42
+ function clearWatermark () {
43
+ if (input.val() === watermark) {
44
+ input.val('');
45
+ }
46
+ };
47
+
48
+ function setWatermark () {
49
+ input.val(watermark);
50
+ input.bind('focus', clearWatermark);
51
+ };
52
+
53
+ if (input.not("SELECT")) {
54
+ input.blur( function (e) {
55
+ if ($(this).val() === '') {
56
+ input.val(watermark);
57
+ }
58
+ e.preventDefault();
59
+ return false;
60
+ });
61
+
62
+ $(document).ready(function () {
63
+ if ($(input).val() === '') {
64
+ setWatermark();
65
+ }
66
+ });
67
+ }
68
+ // end of custom part
69
+
70
+ input.addClass("ui-widget ui-widget-content ui-corner-left").click(function() {
71
+ this.select();
72
+ });
73
+
74
+ this.button = $("<button type='button'>&nbsp;</button>")
75
+ .attr("tabIndex", -1)
76
+ .attr("title", "Show All Items")
77
+ .insertAfter(input).button({
78
+ disabled: true,
79
+ // to be enabled when the menu is ready.
80
+ icons: {
81
+ primary: "ui-icon-triangle-1-s"
82
+ },
83
+ text: false
84
+ })
85
+ .removeClass("ui-corner-all")
86
+ .addClass("ui-corner-right ui-button-icon")
87
+ .click(function(event) {
88
+ // when user clicks the show all button, we display the cached full menu
89
+ var data = input.data("ui-combobox");
90
+ clearTimeout(data.closing);
91
+ if (!input.isFullMenu) {
92
+ data._swapMenu();
93
+ }
94
+ /* input/select that are initially hidden (display=none, i.e. second level menus),
95
+ will not have position cordinates until they are visible. */
96
+ input.combobox("widget").css("display", "block").position($.extend({
97
+ of: input
98
+ }, data.options.position));
99
+ input.focus();
100
+ data._trigger("open");
101
+ // containers such as jquery-ui dialog box will adjust it's zIndex to overlay above other elements.
102
+ // this becomes a problem if the combobox is inside of a dialog box, the full drop down will show
103
+ // under the dialog box.
104
+ if (input.combobox("widget").zIndex() <= input.parent().zIndex()) {
105
+ input.combobox("widget").zIndex(input.parent().zIndex() + 1);
106
+ }
107
+ });
108
+
109
+ /* to better handle large lists, put in a queue and process sequentially */
110
+ $(document).queue(function() {
111
+ var data = input.data("ui-combobox");
112
+ if ($.isArray(data.options.source)) {
113
+ $.ui.combobox.prototype._renderFullMenu.call(data, data.options.source);
114
+ } else if (typeof data.options.source === "string") {
115
+ $.getJSON(data.options.source, data.options.ajaxGetAll, function(source) {
116
+ $.ui.combobox.prototype._renderFullMenu.call(data, source);
117
+ });
118
+ } else {
119
+ $.ui.combobox.prototype._renderFullMenu.call(data, data.source());
120
+ }
121
+ });
122
+ },
123
+
124
+ /* initialize the full list of items, this menu will be reused whenever the user clicks the show all button */
125
+ _renderFullMenu: function(source) {
126
+ var self = this,
127
+ input = this.element,
128
+ ul = input.data("ui-combobox").menu.element,
129
+ lis = [];
130
+ source = this._normalize(source);
131
+ input.data("ui-combobox").menuAll = input.data("ui-combobox").menu.element.clone(true).appendTo("body")[0];
132
+ for (var i = 0; i < source.length; i++) {
133
+ var item = source[i],
134
+ label = item.label;
135
+ if (this.options.decoratorField != null) {
136
+ var d = item[this.options.decoratorField] || (item.option && $(item.option).attr(this.options.decoratorField));
137
+ if (d != undefined) label = label + " " + d;
138
+ }
139
+ lis[i] = "<li class=\"ui-menu-item\" role=\"menuitem\"><a class=\"ui-corner-all\" tabindex=\"-1\">" + label + "</a></li>";
140
+ }
141
+ ul[0].innerHTML = lis.join("");
142
+ this._resizeMenu();
143
+
144
+ var items = $("li", ul).on("mouseover", "mouseout", function(event) {
145
+ if (event.type == "mouseover") {
146
+ self.menu.focus(event, $(this));
147
+ } else {
148
+ self.menu.blur();
149
+ }
150
+ });
151
+ for (var i = 0; i < items.length; i++) {
152
+ $(items[i]).data("ui-autocomplete-item", source[i]);
153
+ }
154
+ input.isFullMenu = true;
155
+ this._swapMenu()
156
+ // full menu has been rendered, now we can enable the show all button.
157
+ self.button.button("enable");
158
+ setTimeout(function() {
159
+ $(document).dequeue();
160
+ }, 0);
161
+ },
162
+
163
+ /* overwrite. make the matching string bold and added label decorator */
164
+ _renderItem: function(ul, item) {
165
+ var label = item.label.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(this.term) + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
166
+ if (this.options.decoratorField != null) {
167
+ var d = item[this.options.decoratorField] || (item.option && $(item.option).attr(this.options.decoratorField));
168
+ if (d != undefined) {
169
+ label = label + " " + d;
170
+ }
171
+ }
172
+ return $("<li></li>")
173
+ .data("ui-autocomplete-item", item)
174
+ .append("<a>" + label + "</a>")
175
+ .appendTo(ul);
176
+ },
177
+
178
+ close: function() {
179
+ if (this.element.isFullMenu) {
180
+ this._swapMenu();
181
+ }
182
+ // super()
183
+ $.ui.autocomplete.prototype.close.call(this);
184
+ },
185
+
186
+ /* overwrite. to cleanup additional stuff that was added */
187
+ destroy: function() {
188
+ if (this.element.is("SELECT")) {
189
+ this.input.removeData("ui-combobox", "menuAll");
190
+ this.input.remove();
191
+ this.element.removeData().show();
192
+ return;
193
+ }
194
+ // super()
195
+ $.ui.autocomplete.prototype.destroy.call(this);
196
+ // clean up new stuff
197
+ this.element.removeClass("ui-widget ui-widget-content ui-corner-left");
198
+ this.button.remove();
199
+ },
200
+
201
+ /* overwrite. to swap out and preserve the full menu */
202
+ search: function(value, event) {
203
+ var input = this.element;
204
+ if (input.isFullMenu) {
205
+ this._swapMenu();
206
+ }
207
+ // super()
208
+ $.ui.autocomplete.prototype.search.call(this, value, event);
209
+ },
210
+
211
+ _change: function(event) {
212
+ if (!this.selectedItem) {
213
+ var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(this.element.val()) + "$", "i"),
214
+ match = $.grep(this.options.source, function(value) {
215
+ return matcher.test(value.label);
216
+ });
217
+ if (match.length) {
218
+ if (match[0].option != undefined) match[0].option.selected = true;
219
+ } else {
220
+ // remove invalid value, as it didn't match anything
221
+ if (this.options.selectElement) {
222
+ var firstItem = this.options.selectElement.children("option:first");
223
+ this.element.val(firstItem.text());
224
+ firstItem.prop("selected", true);
225
+ } else {
226
+ this.element.val("");
227
+ }
228
+ $(event.target).data("ui-combobox").previous = null; // this will force a change event
229
+ }
230
+ }
231
+ // super()
232
+ $.ui.autocomplete.prototype._change.call(this, event);
233
+ },
234
+
235
+ _swapMenu: function() {
236
+ var input = this.element,
237
+ data = input.data("ui-combobox"),
238
+ tmp = data.menuAll;
239
+ data.menuAll = data.menu.element.hide()[0];
240
+ data.menu.element[0] = tmp;
241
+ input.isFullMenu = !input.isFullMenu;
242
+ },
243
+
244
+ /* build the source array from the options of the select element */
245
+ _selectInit: function() {
246
+ var select = this.element,
247
+ selectClass = select.attr("class"),
248
+ selectStyle = select.attr("style"),
249
+ selected = select.children(":selected"),
250
+ value = $.trim(selected.text());
251
+ select.hide();
252
+ this.options.source = select.children("option").map(function() {
253
+ return {
254
+ label: $.trim(this.text),
255
+ option: this
256
+ };
257
+ }).toArray();
258
+ var userSelectCallback = this.options.select;
259
+ var userSelectedCallback = this.options.selected;
260
+ this.options.select = function(event, ui) {
261
+ ui.item.option.selected = true;
262
+ select.change();
263
+ if (userSelectCallback) userSelectCallback(event, ui);
264
+ // compatibility with jQuery UI's combobox.
265
+ if (userSelectedCallback) userSelectedCallback(event, ui);
266
+ };
267
+ this.options.selectElement = select;
268
+ this.input = $("<input>").insertAfter(select).val(value);
269
+ if (selectStyle) {
270
+ this.input.attr("style", selectStyle);
271
+ }
272
+ if (selectClass) {
273
+ this.input.attr("class", selectClass);
274
+ }
275
+ this.input.combobox(this.options);
276
+ },
277
+ inputbox: function() {
278
+ if (this.element.is("SELECT")) {
279
+ return this.input;
280
+ } else {
281
+ return this.element;
282
+ }
283
+ },
284
+
285
+ // custom part - setting combobox value
286
+ setValue: function (value) {
287
+ var input = $(this.element[0]).siblings('input.ui-autocomplete-input').first(),
288
+ selectEl = document.getElementById(this.element.attr('id')),
289
+ options = selectEl.options,
290
+ length = options.length;
291
+ for (var a = 0; a < length; a += 1) {
292
+ if (options[a].text === value) {
293
+ selectEl.selectedIndex = a;
294
+ input.val(options[a].text);
295
+ return false;
296
+ }
297
+ };
298
+ }
299
+ // end of custom part
300
+ });
301
+ })(jQuery);
@@ -0,0 +1,19 @@
1
+ Discerner = {};
2
+ Discerner.Constants = {};
3
+ Discerner.Search = {};
4
+ Discerner.SearchParameter = {};
5
+ Discerner.SearchParameterValue = {}
6
+ Discerner.SearchCombination = {};
7
+ Discerner.CategorizedAutocomplter = {};
8
+ Discerner.ExportParameters = {};
9
+ Discerner.Url = {};
10
+ NestedAttributes = {};
11
+
12
+ Discerner.Constants.EFFECT_SPEED = 1750;
13
+
14
+ $(function() {
15
+ $(document).on('keyup', '#discerner_searches_filter input[type="text"]', function() {
16
+ $.get($("#discerner_searches_filter").attr("action"), $("#discerner_searches_filter").serialize(), null, "script");
17
+ return false;
18
+ });
19
+ })
@@ -0,0 +1,13 @@
1
+ Discerner.ExportParameters.UI = function() {
2
+ $(document).on('click','#discerner_exportable_fields a.select_all_parameters', function(){
3
+ $(this).closest("div[class^='parameter_category_']").find("input[type='checkbox']:not(:checked)").prop('checked', true);
4
+ $(this).removeClass('select_all_parameters').addClass('deselect_all_parameters').html('Deselect all');
5
+ return false
6
+ });
7
+
8
+ $(document).on('click','#discerner_exportable_fields a.deselect_all_parameters', function(){
9
+ $(this).closest("div[class^='parameter_category_']").find("input[type='checkbox']:checked").prop('checked', false);
10
+ $(this).removeClass('deselect_all_parameters').addClass('select_all_parameters').html('Select all');
11
+ return false
12
+ });
13
+ }