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
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
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
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'> </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
|
+
}
|