discerner 1.1.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }