criteria_operator-ui_component 0.1.0 → 0.2.0
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.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/Gemfile +16 -16
- data/README.md +9 -4
- data/Rakefile +10 -13
- data/app/assets/config/criteria_operator_ui_component_manifest.js +2 -2
- data/app/assets/javascripts/criteria_operator/ui_component/application.js +16 -13
- data/app/assets/javascripts/criteria_operator/ui_component/criteria_editor.js +341 -0
- data/app/assets/stylesheets/criteria_operator/ui_component/application.css +49 -15
- data/app/cells/criteria_operator/ui_component/base_cell.rb +13 -0
- data/app/cells/criteria_operator/ui_component/criteria_editor/show.erb +5 -0
- data/app/cells/criteria_operator/ui_component/criteria_editor_cell.rb +27 -0
- data/app/cells/criteria_operator/ui_component/expression/show.erb +11 -0
- data/app/cells/criteria_operator/ui_component/expression_cell.rb +48 -0
- data/app/cells/criteria_operator/ui_component/group/show.erb +23 -0
- data/app/cells/criteria_operator/ui_component/group_cell.rb +49 -0
- data/app/controllers/criteria_operator/ui_component/ajax_controller.rb +146 -0
- data/app/controllers/criteria_operator/ui_component/application_controller.rb +7 -7
- data/bin/rails +14 -13
- data/config/routes.rb +8 -2
- data/criteria_operator-ui_component.gemspec +6 -3
- data/lib/criteria_operator/ui_component.rb +2 -1
- data/lib/criteria_operator/ui_component/engine.rb +5 -0
- data/lib/criteria_operator/ui_component/version.rb +1 -1
- metadata +69 -9
- data/app/helpers/criteria_operator/ui_component/application_helper.rb +0 -6
- data/app/jobs/criteria_operator/ui_component/application_job.rb +0 -6
- data/app/mailers/criteria_operator/ui_component/application_mailer.rb +0 -8
- data/app/models/criteria_operator/ui_component/application_record.rb +0 -7
- data/app/views/layouts/criteria_operator/ui_component/application.html.erb +0 -14
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e59209173c826deb5e89edbd128dc8875980a835
|
|
4
|
+
data.tar.gz: 9a6b936f6fd41493dfe9d8e4ee581a4c7d3198c1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5b5f5596ee42e83b0a33f38309ff529aaf98e7b02b983d59d6b1993f2528a517c909d1666606530ecaf6be0f5b5f32ebf0c27856994d271ca7531e53f30e7177
|
|
7
|
+
data.tar.gz: 57340e412354213ef57c2753d289c08aa0a2f1a74333c8626dfafdb2843c9fcc7cc8e52662bff3fc2a37d1a44b861aab45083061eb73e90c692b1d3c2d046f2b
|
data/.gitignore
CHANGED
data/Gemfile
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
source 'https://rubygems.org'
|
|
2
|
-
|
|
3
|
-
# Declare your gem's dependencies in criteria_operator-ui_component.gemspec.
|
|
4
|
-
# Bundler will treat runtime dependencies like base dependencies, and
|
|
5
|
-
# development dependencies will be added by default to the :development group.
|
|
6
|
-
gemspec
|
|
7
|
-
|
|
8
|
-
# Declare any dependencies that are still in development here instead of in
|
|
9
|
-
# your gemspec. These might include edge Rails or gems from your path or
|
|
10
|
-
# Git. Remember to move these dependencies to your gemspec before releasing
|
|
11
|
-
# your gem to rubygems.org.
|
|
12
|
-
|
|
13
|
-
# To use a debugger
|
|
14
|
-
# gem 'byebug', group: [:development, :test]
|
|
15
|
-
|
|
16
|
-
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
# Declare your gem's dependencies in criteria_operator-ui_component.gemspec.
|
|
4
|
+
# Bundler will treat runtime dependencies like base dependencies, and
|
|
5
|
+
# development dependencies will be added by default to the :development group.
|
|
6
|
+
gemspec
|
|
7
|
+
|
|
8
|
+
# Declare any dependencies that are still in development here instead of in
|
|
9
|
+
# your gemspec. These might include edge Rails or gems from your path or
|
|
10
|
+
# Git. Remember to move these dependencies to your gemspec before releasing
|
|
11
|
+
# your gem to rubygems.org.
|
|
12
|
+
|
|
13
|
+
# To use a debugger
|
|
14
|
+
# gem 'byebug', group: [:development, :test]
|
|
15
|
+
|
|
16
|
+
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
|
data/README.md
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
[](https://rubygems.org/gems/criteria_operator-ui_component)
|
|
2
|
+
[](http://TheFlow0360.mit-license.org)
|
|
3
|
+
[](https://travis-ci.org/TheFlow0360/criteria_operator-ui_component)
|
|
4
|
+
[](https://gemnasium.com/TheFlow0360/criteria_operator-ui_component)
|
|
5
|
+
[](https://codeclimate.com/github/TheFlow0360/criteria_operator-ui_component)
|
|
6
|
+
[](https://coveralls.io/github/TheFlow0360/criteria_operator-ui_component?branch=master)
|
|
7
|
+
[](http://inch-ci.org/github/TheFlow0360/criteria_operator-ui_component)
|
|
8
|
+
[](https://bestpractices.coreinfrastructure.org/projects/963)
|
|
9
|
+
|
|
1
10
|
# CriteriaOperator::UiComponent
|
|
2
11
|
|
|
3
12
|
This gem is an extension to the [criteria_operator](https://github.com/TheFlow0360/criteria_operator) gem and provides UI to be used in a Rails application. This component allows easy editing of filter statements represented by the criteria_operator classes.
|
|
@@ -21,10 +30,6 @@ Or install it yourself as:
|
|
|
21
30
|
|
|
22
31
|
TODO: provide usage instructions
|
|
23
32
|
|
|
24
|
-
## Contributing
|
|
25
|
-
|
|
26
|
-
Contribution directions go here.
|
|
27
|
-
|
|
28
33
|
## Development
|
|
29
34
|
|
|
30
35
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/Rakefile
CHANGED
|
@@ -4,21 +4,18 @@ rescue LoadError
|
|
|
4
4
|
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
|
5
5
|
end
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
RDoc::Task.new(:rdoc) do |rdoc|
|
|
10
|
-
rdoc.rdoc_dir = 'rdoc'
|
|
11
|
-
rdoc.title = 'CriteriaOperator::UiComponent'
|
|
12
|
-
rdoc.options << '--line-numbers'
|
|
13
|
-
rdoc.rdoc_files.include('README.md')
|
|
14
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
|
|
7
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
|
8
|
+
load 'rails/tasks/engine.rake'
|
|
18
9
|
|
|
19
10
|
load 'rails/tasks/statistics.rake'
|
|
20
11
|
|
|
21
|
-
|
|
22
|
-
|
|
23
12
|
require 'bundler/gem_tasks'
|
|
13
|
+
require 'rake/testtask'
|
|
14
|
+
|
|
15
|
+
Rake::TestTask.new(:test) do |t|
|
|
16
|
+
t.libs << "test"
|
|
17
|
+
t.libs << "lib"
|
|
18
|
+
t.test_files = FileList['test/**/*_test.rb']
|
|
19
|
+
end
|
|
24
20
|
|
|
21
|
+
task :default => :test
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
//= link_directory ../javascripts/criteria_operator/ui_component .js
|
|
2
|
-
//= link_directory ../stylesheets/criteria_operator/ui_component .css
|
|
1
|
+
//= link_directory ../javascripts/criteria_operator/ui_component .js
|
|
2
|
+
//= link_directory ../stylesheets/criteria_operator/ui_component .css
|
|
@@ -1,13 +1,16 @@
|
|
|
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 any plugin's vendor/assets/javascripts directory 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
|
-
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
|
9
|
-
//
|
|
10
|
-
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
|
11
|
-
// about supported directives.
|
|
12
|
-
//
|
|
13
|
-
//=
|
|
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 any plugin's vendor/assets/javascripts directory 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
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
|
9
|
+
//
|
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
|
11
|
+
// about supported directives.
|
|
12
|
+
//
|
|
13
|
+
//= require jquery
|
|
14
|
+
//= require jquery_ujs
|
|
15
|
+
//= require criteria_operator/ui_component/criteria_editor
|
|
16
|
+
//= require_tree .
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
// ---------------------------------
|
|
2
|
+
// ----- Criteria Editor Plugin ----
|
|
3
|
+
// ---------------------------------
|
|
4
|
+
// Using John Dugan's boilerplate: https://john-dugan.com/jquery-plugin-boilerplate-explained/
|
|
5
|
+
// ---------------------------------
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
The semi-colon before the function invocation is a safety net against
|
|
9
|
+
concatenated scripts and/or other plugins which may not be closed properly.
|
|
10
|
+
|
|
11
|
+
"undefined" is used because the undefined global variable in ECMAScript 3
|
|
12
|
+
is mutable (ie. it can be changed by someone else). Because we don't pass a
|
|
13
|
+
value to undefined when the anonymyous function is invoked, we ensure that
|
|
14
|
+
undefined is truly undefined. Note, in ECMAScript 5 undefined can no
|
|
15
|
+
longer be modified.
|
|
16
|
+
|
|
17
|
+
"window" and "document" are passed as local variables rather than global.
|
|
18
|
+
This (slightly) quickens the resolution process.
|
|
19
|
+
*/
|
|
20
|
+
;(function ( $, window, document, undefined ) {
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
Store the name of the plugin in the "pluginName" variable. This
|
|
24
|
+
variable is used in the "Plugin" constructor below, as well as the
|
|
25
|
+
plugin wrapper to construct the key for the "$.data" method.
|
|
26
|
+
|
|
27
|
+
More: http://api.jquery.com/jquery.data/
|
|
28
|
+
*/
|
|
29
|
+
var pluginName = 'criteriaEditor';
|
|
30
|
+
|
|
31
|
+
/*
|
|
32
|
+
The "Plugin" constructor, builds a new instance of the plugin for the
|
|
33
|
+
DOM node(s) that the plugin is called on. For example,
|
|
34
|
+
"$('h1').pluginName();" creates a new instance of pluginName for
|
|
35
|
+
all h1's.
|
|
36
|
+
*/
|
|
37
|
+
// Create the plugin constructor
|
|
38
|
+
function Plugin ( element, options ) {
|
|
39
|
+
/*
|
|
40
|
+
Provide local access to the DOM node(s) that called the plugin,
|
|
41
|
+
as well local access to the plugin name and default options.
|
|
42
|
+
*/
|
|
43
|
+
this.element = element;
|
|
44
|
+
this._name = pluginName;
|
|
45
|
+
this._defaults = $.fn.criteriaEditor.defaults;
|
|
46
|
+
/*
|
|
47
|
+
The "$.extend" method merges the contents of two or more objects,
|
|
48
|
+
and stores the result in the first object. The first object is
|
|
49
|
+
empty so that we don't alter the default options for future
|
|
50
|
+
instances of the plugin.
|
|
51
|
+
|
|
52
|
+
More: http://api.jquery.com/jquery.extend/
|
|
53
|
+
*/
|
|
54
|
+
this.options = $.extend( {}, this._defaults, options );
|
|
55
|
+
|
|
56
|
+
/*
|
|
57
|
+
The "init" method is the starting point for all plugin logic.
|
|
58
|
+
Calling the init method here in the "Plugin" constructor function
|
|
59
|
+
allows us to store all methods (including the init method) in the
|
|
60
|
+
plugin's prototype. Storing methods required by the plugin in its
|
|
61
|
+
prototype lowers the memory footprint, as each instance of the
|
|
62
|
+
plugin does not need to duplicate all of the same methods. Rather,
|
|
63
|
+
each instance can inherit the methods from the constructor
|
|
64
|
+
function's prototype.
|
|
65
|
+
*/
|
|
66
|
+
this.init();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Avoid Plugin.prototype conflicts
|
|
70
|
+
$.extend(Plugin.prototype, {
|
|
71
|
+
|
|
72
|
+
// Initialization logic
|
|
73
|
+
init: function () {
|
|
74
|
+
/*
|
|
75
|
+
Create additional methods below and call them via
|
|
76
|
+
"this.myFunction(arg1, arg2)", ie: "this.buildCache();".
|
|
77
|
+
|
|
78
|
+
Note, you can access the DOM node(s), plugin name, default
|
|
79
|
+
plugin options and custom plugin options for a each instance
|
|
80
|
+
of the plugin by using the variables "this.element",
|
|
81
|
+
"this._name", "this._defaults" and "this.options" created in
|
|
82
|
+
the "Plugin" constructor function (as shown in the buildCache
|
|
83
|
+
method below).
|
|
84
|
+
*/
|
|
85
|
+
this.buildCache();
|
|
86
|
+
this.bindEvents();
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
// Remove plugin instance completely
|
|
90
|
+
destroy: function() {
|
|
91
|
+
/*
|
|
92
|
+
The destroy method unbinds all events for the specific instance
|
|
93
|
+
of the plugin, then removes all plugin data that was stored in
|
|
94
|
+
the plugin instance using jQuery's .removeData method.
|
|
95
|
+
|
|
96
|
+
Since we store data for each instance of the plugin in its
|
|
97
|
+
instantiating element using the $.data method (as explained
|
|
98
|
+
in the plugin wrapper below), we can call methods directly on
|
|
99
|
+
the instance outside of the plugin initialization, ie:
|
|
100
|
+
$('selector').data('plugin_myPluginName').someOtherFunction();
|
|
101
|
+
|
|
102
|
+
Consequently, the destroy method can be called using:
|
|
103
|
+
$('selector').data('plugin_myPluginName').destroy();
|
|
104
|
+
*/
|
|
105
|
+
this.unbindEvents();
|
|
106
|
+
this.$element.removeData();
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
// Cache DOM nodes for performance
|
|
110
|
+
buildCache: function () {
|
|
111
|
+
/*
|
|
112
|
+
Create variable(s) that can be accessed by other plugin
|
|
113
|
+
functions. For example, "this.$element = $(this.element);"
|
|
114
|
+
will cache a jQuery reference to the element that initialized
|
|
115
|
+
the plugin. Cached variables can then be used in other methods.
|
|
116
|
+
*/
|
|
117
|
+
this.$element = $(this.element);
|
|
118
|
+
this.$valueInput = this.$element.find(this.options.valueInput)
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
// Bind events that trigger methods
|
|
122
|
+
bindEvents: function() {
|
|
123
|
+
var plugin = this;
|
|
124
|
+
|
|
125
|
+
/*
|
|
126
|
+
Bind event(s) to handlers that trigger other functions, ie:
|
|
127
|
+
"plugin.$element.on('click', function() {});". Note the use of
|
|
128
|
+
the cached variable we created in the buildCache method.
|
|
129
|
+
|
|
130
|
+
All events are namespaced, ie:
|
|
131
|
+
".on('click'+'.'+this._name', function() {});".
|
|
132
|
+
This allows us to unbind plugin-specific events using the
|
|
133
|
+
unbindEvents method below.
|
|
134
|
+
*/
|
|
135
|
+
//plugin.$element.on('click'+'.'+plugin._name, function() {
|
|
136
|
+
/*
|
|
137
|
+
Use the "call" method so that inside of the method being
|
|
138
|
+
called, ie: "someOtherFunction", the "this" keyword refers
|
|
139
|
+
to the plugin instance, not the event handler.
|
|
140
|
+
|
|
141
|
+
More: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call
|
|
142
|
+
*/
|
|
143
|
+
// plugin.someOtherFunction.call(plugin);
|
|
144
|
+
//});
|
|
145
|
+
plugin.$element.find(plugin.options.newExpression).on('click'+'.'+plugin._name, function(event) {
|
|
146
|
+
plugin.createElement.call(plugin, 'expression', plugin.options, event.target);
|
|
147
|
+
});
|
|
148
|
+
plugin.$element.find(plugin.options.newGroup).on('click'+'.'+plugin._name, function(event) {
|
|
149
|
+
plugin.createElement.call(plugin, 'group', plugin.options, event.target);
|
|
150
|
+
});
|
|
151
|
+
plugin.$element.find(plugin.options.deleteExpression).on('click'+'.'+plugin._name, function(event) {
|
|
152
|
+
plugin.deleteElement.call(plugin, plugin.options, event.target);
|
|
153
|
+
});
|
|
154
|
+
plugin.$element.find(plugin.options.deleteGroup).on('click'+'.'+plugin._name, function(event) {
|
|
155
|
+
plugin.deleteElement.call(plugin, plugin.options, event.target);
|
|
156
|
+
});
|
|
157
|
+
plugin.$element.find(plugin.options.operandInput).on('change'+'.'+plugin._name, function(event) {
|
|
158
|
+
plugin.operandChanged.call(plugin, plugin.options, event.target);
|
|
159
|
+
});
|
|
160
|
+
plugin.$element.find(plugin.options.operatorTypeInput).on('change'+'.'+plugin._name, function(event) {
|
|
161
|
+
plugin.operatorTypeChanged.call(plugin, plugin.options, event.target);
|
|
162
|
+
});
|
|
163
|
+
},
|
|
164
|
+
|
|
165
|
+
// Unbind events that trigger methods
|
|
166
|
+
unbindEvents: function() {
|
|
167
|
+
/*
|
|
168
|
+
Unbind all events in our plugin's namespace that are attached
|
|
169
|
+
to child elements.
|
|
170
|
+
*/
|
|
171
|
+
this.$element.find("*").off('.'+this._name);
|
|
172
|
+
},
|
|
173
|
+
|
|
174
|
+
createElement: function(type, options, element) {
|
|
175
|
+
var plugin = this;
|
|
176
|
+
var requestData = {};
|
|
177
|
+
requestData["root_operator"] = plugin.$valueInput.val();
|
|
178
|
+
requestData["locator"] = plugin.buildLocatorChain(element, options);
|
|
179
|
+
requestData["child_count"] = $(element).parent().data("childcount");
|
|
180
|
+
$.ajax({
|
|
181
|
+
url: "/criteria_operator-ui_component/create_" + type,
|
|
182
|
+
data: requestData,
|
|
183
|
+
method: "POST"
|
|
184
|
+
}).done(function(data) {
|
|
185
|
+
var wrapper = $(element).parent().children(options.rowWrapper);
|
|
186
|
+
wrapper.children(options.placeholder).remove();
|
|
187
|
+
wrapper.append(data['html']);
|
|
188
|
+
$(element).parent().data("childcount", $(element).parent().data("childcount") + 1);
|
|
189
|
+
plugin.$valueInput.val(data['operator']);
|
|
190
|
+
plugin.rebind();
|
|
191
|
+
});
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
deleteElement: function(options, element) {
|
|
195
|
+
var plugin = this;
|
|
196
|
+
var requestData = {};
|
|
197
|
+
requestData["root_operator"] = plugin.$valueInput.val();
|
|
198
|
+
requestData["locator"] = plugin.buildLocatorChain(element, options);
|
|
199
|
+
$.ajax({
|
|
200
|
+
url: "/criteria_operator-ui_component/delete_element",
|
|
201
|
+
data: requestData,
|
|
202
|
+
method: "POST"
|
|
203
|
+
}).done(function(data) {
|
|
204
|
+
$(element).parent().nextAll().each(function() {
|
|
205
|
+
$( this ).attr('data-locator', $( this ).attr('data-locator') - 1);
|
|
206
|
+
});
|
|
207
|
+
var parentGroup = $(element).parent().parent().parent();
|
|
208
|
+
parentGroup.data("childcount", parentGroup.data("childcount") - 1);
|
|
209
|
+
$(element).parent().remove()
|
|
210
|
+
plugin.$valueInput.val(data['operator']);
|
|
211
|
+
});
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
operandChanged: function(options, element) {
|
|
215
|
+
var plugin = this;
|
|
216
|
+
var requestData = {};
|
|
217
|
+
requestData["root_operator"] = plugin.$valueInput.val();
|
|
218
|
+
requestData["locator"] = plugin.buildLocatorChain(element, options);
|
|
219
|
+
if ($(element).hasClass(options.binaryLeftOperandClass)) {
|
|
220
|
+
requestData["operand_type"] = "left";
|
|
221
|
+
} else if ($(element).hasClass(options.binaryRightOperandClass)) {
|
|
222
|
+
requestData["operand_type"] = "right";
|
|
223
|
+
} else { return }
|
|
224
|
+
requestData["operand_value"] = $(element).val();
|
|
225
|
+
$.ajax({
|
|
226
|
+
url: "/criteria_operator-ui_component/operand_change",
|
|
227
|
+
data: requestData,
|
|
228
|
+
method: "POST"
|
|
229
|
+
}).done(function(data) {
|
|
230
|
+
plugin.$valueInput.val(data['operator']);
|
|
231
|
+
});
|
|
232
|
+
},
|
|
233
|
+
|
|
234
|
+
operatorTypeChanged: function(options, element) {
|
|
235
|
+
var plugin = this;
|
|
236
|
+
var requestData = {};
|
|
237
|
+
requestData["root_operator"] = plugin.$valueInput.val();
|
|
238
|
+
requestData["locator"] = plugin.buildLocatorChain(element, options);
|
|
239
|
+
requestData["operator_type_value"] = $(element).val();
|
|
240
|
+
var type;
|
|
241
|
+
if ($(element).hasClass(options.expressionOperatorTypeClass)) {
|
|
242
|
+
type = "expression_type_change"
|
|
243
|
+
} else if ($(element).hasClass(options.groupOperatorTypeClass)) {
|
|
244
|
+
type = "group_type_change"
|
|
245
|
+
} else { return }
|
|
246
|
+
$.ajax({
|
|
247
|
+
url: "/criteria_operator-ui_component/" + type,
|
|
248
|
+
data: requestData,
|
|
249
|
+
method: "POST"
|
|
250
|
+
}).done(function(data) {
|
|
251
|
+
plugin.$valueInput.val(data['operator']);
|
|
252
|
+
});
|
|
253
|
+
},
|
|
254
|
+
|
|
255
|
+
rebind: function() {
|
|
256
|
+
// TODO: reduce workload by just binding new instead of rebinding all
|
|
257
|
+
var plugin = this;
|
|
258
|
+
plugin.unbindEvents();
|
|
259
|
+
plugin.bindEvents();
|
|
260
|
+
},
|
|
261
|
+
|
|
262
|
+
buildLocatorChain: function(element, options) {
|
|
263
|
+
if ($(element).hasClass(options.rootElementClass)) {
|
|
264
|
+
return ""
|
|
265
|
+
} else {
|
|
266
|
+
var chain = this.buildLocatorChain($(element).parent(), options);
|
|
267
|
+
var locator = $(element).attr("data-locator");
|
|
268
|
+
if (typeof locator !== typeof undefined && locator !== false) {
|
|
269
|
+
chain = (chain === "" ? "" : chain + "," ) + locator;
|
|
270
|
+
}
|
|
271
|
+
return chain;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
/*
|
|
277
|
+
Create a lightweight plugin wrapper around the "Plugin" constructor,
|
|
278
|
+
preventing against multiple instantiations.
|
|
279
|
+
|
|
280
|
+
More: http://learn.jquery.com/plugins/basic-plugin-creation/
|
|
281
|
+
*/
|
|
282
|
+
$.fn.criteriaEditor = function ( options ) {
|
|
283
|
+
this.each(function() {
|
|
284
|
+
if ( !$.data( this, "plugin_" + pluginName ) ) {
|
|
285
|
+
/*
|
|
286
|
+
Use "$.data" to save each instance of the plugin in case
|
|
287
|
+
the user wants to modify it. Using "$.data" in this way
|
|
288
|
+
ensures the data is removed when the DOM element(s) are
|
|
289
|
+
removed via jQuery methods, as well as when the user leaves
|
|
290
|
+
the page. It's a smart way to prevent memory leaks.
|
|
291
|
+
|
|
292
|
+
More: http://api.jquery.com/jquery.data/
|
|
293
|
+
*/
|
|
294
|
+
$.data( this, "plugin_" + pluginName, new Plugin( this, options ) );
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
/*
|
|
298
|
+
"return this;" returns the original jQuery object. This allows
|
|
299
|
+
additional jQuery methods to be chained.
|
|
300
|
+
*/
|
|
301
|
+
return this;
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
/*
|
|
305
|
+
Attach the default plugin options directly to the plugin object. This
|
|
306
|
+
allows users to override default plugin options globally, instead of
|
|
307
|
+
passing the same option(s) every time the plugin is initialized.
|
|
308
|
+
|
|
309
|
+
For example, the user could set the "property" value once for all
|
|
310
|
+
instances of the plugin with
|
|
311
|
+
"$.fn.pluginName.defaults.property = 'myValue';". Then, every time
|
|
312
|
+
plugin is initialized, "property" will be set to "myValue".
|
|
313
|
+
|
|
314
|
+
More: http://learn.jquery.com/plugins/advanced-plugin-concepts/
|
|
315
|
+
*/
|
|
316
|
+
$.fn.criteriaEditor.defaults = {
|
|
317
|
+
property: 'value',
|
|
318
|
+
onComplete: null,
|
|
319
|
+
rootElementClass: 'criteria_editor',
|
|
320
|
+
newExpression: '.criteria_editor_new_expression',
|
|
321
|
+
newGroup: '.criteria_editor_new_group',
|
|
322
|
+
placeholder: '.criteria_editor_empty_placeholder',
|
|
323
|
+
rowWrapper: '.criteria_editor_row_wrapper',
|
|
324
|
+
deleteExpression: '.criteria_expression_delete',
|
|
325
|
+
deleteGroup: '.criteria_group_delete',
|
|
326
|
+
valueInput: '.criteria_editor_root_operator',
|
|
327
|
+
operandInput: '.criteria_operand_input',
|
|
328
|
+
operatorTypeInput: '.criteria_operator_type_input',
|
|
329
|
+
binaryLeftOperandClass: 'binary_operator_left_operand',
|
|
330
|
+
binaryRightOperandClass: 'binary_operator_right_operand',
|
|
331
|
+
expressionOperatorTypeClass: 'expression_operator_type',
|
|
332
|
+
groupOperatorTypeClass: 'group_operator_type'
|
|
333
|
+
};
|
|
334
|
+
|
|
335
|
+
})( jQuery, window, document );
|
|
336
|
+
|
|
337
|
+
$(document).ready(function() {
|
|
338
|
+
$('.criteria_editor').criteriaEditor({
|
|
339
|
+
rootElementClass: 'criteria_editor'
|
|
340
|
+
});
|
|
341
|
+
});
|
|
@@ -1,15 +1,49 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
-
* listed below.
|
|
4
|
-
*
|
|
5
|
-
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
-
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
|
7
|
-
*
|
|
8
|
-
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
|
9
|
-
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
|
10
|
-
* files in this directory. Styles in this file should be added after the last require_* statement.
|
|
11
|
-
* It is generally better to create a new file per style scope.
|
|
12
|
-
*
|
|
13
|
-
*= require_tree .
|
|
14
|
-
*= require_self
|
|
15
|
-
*/
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
|
11
|
+
* It is generally better to create a new file per style scope.
|
|
12
|
+
*
|
|
13
|
+
*= require_tree .
|
|
14
|
+
*= require_self
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
.criteria_editor {
|
|
18
|
+
border: dashed #2E2F30 thin;
|
|
19
|
+
padding: 5px;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.criteria_editor_header {
|
|
23
|
+
font-size: large;
|
|
24
|
+
font-weight: bold;
|
|
25
|
+
margin-bottom: 10px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.criteria_group_row {
|
|
29
|
+
border: dashed #666666 thin;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.criteria_group_row_header {
|
|
33
|
+
font-size: medium;
|
|
34
|
+
font-weight: bold;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.criteria_expression_row {
|
|
38
|
+
border: dotted #999999 thin;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.criteria_editor_empty_placeholder {
|
|
42
|
+
color: #999999;
|
|
43
|
+
padding: 15px;
|
|
44
|
+
border: dashed #999999;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.criteria_editor_row_wrapper {
|
|
48
|
+
margin-left: 10px;
|
|
49
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<div class="criteria_editor">
|
|
2
|
+
<span class="criteria_editor_header">This is the header</span>
|
|
3
|
+
<%= cell('criteria_operator/ui_component/group', model).(:show, allow_delete: false) %>
|
|
4
|
+
<input type="hidden" class="criteria_editor_root_operator" value="<%= serialized_operator %>" />
|
|
5
|
+
</div>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
require 'yaml'
|
|
2
|
+
|
|
3
|
+
module CriteriaOperator
|
|
4
|
+
module UiComponent
|
|
5
|
+
class CriteriaEditorCell < BaseCell
|
|
6
|
+
|
|
7
|
+
def show
|
|
8
|
+
render
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def choose_template(options = {})
|
|
12
|
+
if model.kind_of? BinaryOperator
|
|
13
|
+
ExpressionCell.call(model).call(:show, options)
|
|
14
|
+
else
|
|
15
|
+
GroupCell.call(model).call(:show, options)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def serialized_operator
|
|
22
|
+
YAML.dump(model) if model.is_a? BaseOperator
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<div class="criteria_expression_row" data-locator="<%= @locator %>">
|
|
2
|
+
<input type="text" class="criteria_operand_input binary_operator_left_operand" placeholder="property" value="<%= property_name %>" />
|
|
3
|
+
<select class="criteria_operator_type_input expression_operator_type">
|
|
4
|
+
<% operators.each do |op| %>
|
|
5
|
+
<option value="<%= op[:value] %>" <% if op[:value] == operator_type %>selected<% end %>><%= op[:text] %></option>
|
|
6
|
+
<% end %>
|
|
7
|
+
</select>
|
|
8
|
+
<input type="text" class="criteria_operand_input binary_operator_right_operand" placeholder="value" value="<%= value %>" />
|
|
9
|
+
<a href="#" class="criteria_expression_delete">Delete</a>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module CriteriaOperator
|
|
2
|
+
module UiComponent
|
|
3
|
+
class ExpressionCell < BaseCell
|
|
4
|
+
|
|
5
|
+
def show(options = {})
|
|
6
|
+
@locator = options.has_key?(:locator) ? options[:locator] : ''
|
|
7
|
+
render
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
def property_name
|
|
13
|
+
if model.kind_of?(BinaryOperator) && model.left_operand.kind_of?(OperandProperty)
|
|
14
|
+
model.left_operand.property_name
|
|
15
|
+
else
|
|
16
|
+
''
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def value
|
|
21
|
+
if model.kind_of?(BinaryOperator) && model.right_operand.kind_of?(OperandValue)
|
|
22
|
+
model.right_operand.value
|
|
23
|
+
else
|
|
24
|
+
''
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def operator_type
|
|
29
|
+
if model.kind_of?(BinaryOperator)
|
|
30
|
+
model.operator_type
|
|
31
|
+
else
|
|
32
|
+
0
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def operators
|
|
37
|
+
ops = []
|
|
38
|
+
ops << { value: BinaryOperatorType::EQUAL, text: 'equal to' }
|
|
39
|
+
ops << { value: BinaryOperatorType::NOT_EQUAL, text: 'not equal to' }
|
|
40
|
+
ops << { value: BinaryOperatorType::GREATER, text: 'greater than' }
|
|
41
|
+
ops << { value: BinaryOperatorType::GREATER_OR_EQUAL, text: 'greater than or equal to' }
|
|
42
|
+
ops << { value: BinaryOperatorType::LESS, text: 'less than' }
|
|
43
|
+
ops << { value: BinaryOperatorType::LESS_OR_EQUAL, text: 'less than or equal to' }
|
|
44
|
+
ops
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<div class="criteria_group_row" data-locator="<%= @locator %>" data-childcount="<%= @group.operand_collection.count %>">
|
|
2
|
+
<select class="criteria_operator_type_input group_operator_type">
|
|
3
|
+
<% operators.each do |op| %>
|
|
4
|
+
<option value="<%= op[:value] %>" <% if op[:value] == operator_type %>selected<% end %>><%= op[:text] %></option>
|
|
5
|
+
<% end %>
|
|
6
|
+
</select>
|
|
7
|
+
<% if @allow_delete %>
|
|
8
|
+
<a href="#" class="criteria_group_delete">Delete</a>
|
|
9
|
+
<% end %>
|
|
10
|
+
<div class="criteria_editor_row_wrapper">
|
|
11
|
+
<% if empty? %>
|
|
12
|
+
<div class="criteria_editor_empty_placeholder">It's lonely inside here...</div>
|
|
13
|
+
<% else %>
|
|
14
|
+
<% c = 0 %>
|
|
15
|
+
<% @group.operand_collection.each do |operand| %>
|
|
16
|
+
<%= cell('criteria_operator/ui_component/criteria_editor', operand).(:choose_template, locator: c) %>
|
|
17
|
+
<% c += 1 %>
|
|
18
|
+
<% end %>
|
|
19
|
+
<% end %>
|
|
20
|
+
</div>
|
|
21
|
+
<a href="#" class="criteria_editor_new_group">Add group</a><br />
|
|
22
|
+
<a href="#" class="criteria_editor_new_expression">Add expression</a>
|
|
23
|
+
</div>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module CriteriaOperator
|
|
2
|
+
module UiComponent
|
|
3
|
+
class GroupCell < BaseCell
|
|
4
|
+
|
|
5
|
+
def show(options = {})
|
|
6
|
+
@allow_delete = options.has_key?(:allow_delete) ? options[:allow_delete] : true
|
|
7
|
+
@locator = options.has_key?(:locator) ? options[:locator] : ''
|
|
8
|
+
if model.kind_of? GroupOperator
|
|
9
|
+
@group = model
|
|
10
|
+
elsif model_negated_group?
|
|
11
|
+
@group = model.operand
|
|
12
|
+
else
|
|
13
|
+
@group = nil
|
|
14
|
+
end
|
|
15
|
+
render
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
private
|
|
19
|
+
|
|
20
|
+
def operator_type
|
|
21
|
+
if model.kind_of? GroupOperator
|
|
22
|
+
model.operator_type
|
|
23
|
+
elsif model_negated_group?
|
|
24
|
+
model.operand.operator_type * -1
|
|
25
|
+
else
|
|
26
|
+
0
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def operators
|
|
31
|
+
ops = []
|
|
32
|
+
ops << { value: GroupOperatorType::AND, text: 'AND' }
|
|
33
|
+
ops << { value: GroupOperatorType::OR, text: 'OR' }
|
|
34
|
+
ops << { value: -1 * GroupOperatorType::AND, text: 'NAND' }
|
|
35
|
+
ops << { value: -1 * GroupOperatorType::OR, text: 'NOR' }
|
|
36
|
+
ops
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def empty?
|
|
40
|
+
!@group.kind_of?(GroupOperator) || @group.operand_collection.empty?
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def model_negated_group?
|
|
44
|
+
model.kind_of?(UnaryOperator) && (model.operator_type == UnaryOperatorType::NOT) && model.operand.kind_of?(GroupOperator)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
require_dependency "criteria_operator/ui_component/application_controller"
|
|
2
|
+
require 'cell'
|
|
3
|
+
require 'cell/erb'
|
|
4
|
+
require 'yaml'
|
|
5
|
+
|
|
6
|
+
module CriteriaOperator
|
|
7
|
+
module UiComponent
|
|
8
|
+
class AjaxController < ApplicationController
|
|
9
|
+
def create_expression
|
|
10
|
+
return unless ajax_params.has_key? :root_operator
|
|
11
|
+
root_operator = root_op_from_params
|
|
12
|
+
operator = BinaryOperator.new
|
|
13
|
+
add_sub_operator root_operator, operator, ajax_params[:locator]
|
|
14
|
+
html = ExpressionCell.call(operator).call(:show, locator: new_locator)
|
|
15
|
+
render json: { html: html, operator: YAML.dump(root_operator) }
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def create_group
|
|
19
|
+
return unless ajax_params.has_key? :root_operator
|
|
20
|
+
root_operator = root_op_from_params
|
|
21
|
+
operator = GroupOperator.new
|
|
22
|
+
add_sub_operator root_operator, operator, ajax_params[:locator]
|
|
23
|
+
html = GroupCell.call(operator).call(:show, locator: new_locator)
|
|
24
|
+
render json: { html: html, operator: YAML.dump(root_operator) }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def delete_element
|
|
28
|
+
return unless (ajax_params.has_key? :root_operator) && (ajax_params.has_key? :locator)
|
|
29
|
+
root_operator = root_op_from_params
|
|
30
|
+
remove_sub_operator root_operator, ajax_params[:locator]
|
|
31
|
+
render json: { operator: YAML.dump(root_operator) }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def operand_change
|
|
35
|
+
return unless (ajax_params.has_key? :root_operator) && (ajax_params.has_key? :locator)
|
|
36
|
+
root_operator = root_op_from_params
|
|
37
|
+
op = locate_sub_operator root_operator, ajax_params[:locator]
|
|
38
|
+
op.left_operand = OperandProperty.new(ajax_params[:operand_value]) if ajax_params[:operand_type] == 'left'
|
|
39
|
+
op.right_operand = OperandValue.new(ajax_params[:operand_value]) if ajax_params[:operand_type] == 'right'
|
|
40
|
+
render json: { operator: YAML.dump(root_operator) }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def expression_type_change
|
|
44
|
+
return unless (ajax_params.has_key? :root_operator) && (ajax_params.has_key? :locator)
|
|
45
|
+
root_operator = root_op_from_params
|
|
46
|
+
op = locate_sub_operator root_operator, ajax_params[:locator]
|
|
47
|
+
op.operator_type = ajax_params[:operator_type_value]
|
|
48
|
+
render json: { operator: YAML.dump(root_operator) }
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def group_type_change
|
|
52
|
+
return unless (ajax_params.has_key? :root_operator) && (ajax_params.has_key? :locator)
|
|
53
|
+
root_operator = root_op_from_params
|
|
54
|
+
root_operator = change_sub_group_type root_operator, ajax_params[:locator], ajax_params[:operator_type_value].to_i
|
|
55
|
+
render json: { operator: YAML.dump(root_operator) }
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def ajax_params
|
|
61
|
+
params.permit :root_operator, :locator, :child_count, :operand_type, :operand_value, :operator_type_value
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def root_op_from_params
|
|
65
|
+
YAML.safe_load ajax_params[:root_operator], (ObjectSpace.each_object(Class).select { |klass| klass < BaseOperator })
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def new_locator
|
|
69
|
+
if ajax_params.has_key? :child_count
|
|
70
|
+
ajax_params[:child_count].to_s
|
|
71
|
+
else
|
|
72
|
+
'0'
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def locate_sub_operator(operator, locator)
|
|
77
|
+
op = get_negated_group_if_exist operator
|
|
78
|
+
locator.split(',').map(&:to_i).each do |pos|
|
|
79
|
+
# TODO: some kind of error handling beside cancelling?
|
|
80
|
+
return nil unless op.is_a? GroupOperator
|
|
81
|
+
op = op.operand_collection[pos]
|
|
82
|
+
op = get_negated_group_if_exist op
|
|
83
|
+
end
|
|
84
|
+
op
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def add_sub_operator(root_op, extend_op, locator)
|
|
88
|
+
op = locate_sub_operator root_op, locator
|
|
89
|
+
op.operand_collection << extend_op
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def remove_sub_operator(root_op, locator)
|
|
93
|
+
locator_array = locator.split(',')
|
|
94
|
+
pos = locator_array.pop
|
|
95
|
+
op = root_op
|
|
96
|
+
unless locator_array.empty?
|
|
97
|
+
op = locate_sub_operator op, locator_array.join(',')
|
|
98
|
+
end
|
|
99
|
+
op = get_negated_group_if_exist op
|
|
100
|
+
op.operand_collection.delete_at pos.to_i
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def change_sub_group_type(root_op, locator, op_type)
|
|
104
|
+
op = root_op
|
|
105
|
+
last_pos = -1
|
|
106
|
+
parent_op = nil
|
|
107
|
+
locator_array = locator.split(',')
|
|
108
|
+
locator_array.map(&:to_i).each do |pos|
|
|
109
|
+
op = get_negated_group_if_exist op
|
|
110
|
+
last_pos = pos
|
|
111
|
+
parent_op = op
|
|
112
|
+
op = op.operand_collection[pos]
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
if negation? op
|
|
116
|
+
if op_type > 0
|
|
117
|
+
parent_op.operand_collection[last_pos] = op.operand
|
|
118
|
+
op.operand.operator_type = op_type
|
|
119
|
+
else
|
|
120
|
+
op.operand.operator_type = op_type * -1
|
|
121
|
+
end
|
|
122
|
+
else
|
|
123
|
+
if op_type < 0
|
|
124
|
+
parent_op.operand_collection[last_pos] = UnaryOperator.new op, UnaryOperatorType::NOT
|
|
125
|
+
op.operator_type = op_type * -1
|
|
126
|
+
else
|
|
127
|
+
op.operator_type = op_type
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
root_op
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def get_negated_group_if_exist(op)
|
|
134
|
+
if negation? op
|
|
135
|
+
op.operand
|
|
136
|
+
else
|
|
137
|
+
op
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def negation?(op)
|
|
142
|
+
op.is_a?(UnaryOperator) && (op.operator_type == UnaryOperatorType::NOT)
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
module CriteriaOperator
|
|
2
|
-
module UiComponent
|
|
3
|
-
class ApplicationController < ActionController::Base
|
|
4
|
-
protect_from_forgery with: :exception
|
|
5
|
-
end
|
|
6
|
-
end
|
|
7
|
-
end
|
|
1
|
+
module CriteriaOperator
|
|
2
|
+
module UiComponent
|
|
3
|
+
class ApplicationController < ActionController::Base
|
|
4
|
+
protect_from_forgery with: :exception
|
|
5
|
+
end
|
|
6
|
+
end
|
|
7
|
+
end
|
data/bin/rails
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
#!/usr/bin/env ruby.exe
|
|
2
|
-
# This command will automatically be run when you run "rails" with Rails gems
|
|
3
|
-
# installed from the root of your application.
|
|
4
|
-
|
|
5
|
-
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
|
6
|
-
ENGINE_PATH = File.expand_path('../../lib/criteria_operator/ui_component/engine', __FILE__)
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
require 'rails/
|
|
1
|
+
#!/usr/bin/env ruby.exe
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
|
3
|
+
# installed from the root of your application.
|
|
4
|
+
|
|
5
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
|
6
|
+
ENGINE_PATH = File.expand_path('../../lib/criteria_operator/ui_component/engine', __FILE__)
|
|
7
|
+
APP_PATH = File.expand_path('../../test/dummy/config/application', __FILE__)
|
|
8
|
+
|
|
9
|
+
# Set up gems listed in the Gemfile.
|
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
|
11
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
|
12
|
+
|
|
13
|
+
require 'rails/all'
|
|
14
|
+
require 'rails/engine/commands'
|
data/config/routes.rb
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
CriteriaOperator::UiComponent::Engine.routes.draw do
|
|
2
|
-
|
|
1
|
+
CriteriaOperator::UiComponent::Engine.routes.draw do
|
|
2
|
+
post 'create_expression', controller: :ajax, action: :create_expression
|
|
3
|
+
post 'create_group', controller: :ajax, action: :create_group
|
|
4
|
+
post 'delete_element', controller: :ajax, action: :delete_element
|
|
5
|
+
post 'operand_change', controller: :ajax, action: :operand_change
|
|
6
|
+
post 'expression_type_change', controller: :ajax, action: :expression_type_change
|
|
7
|
+
post 'group_type_change', controller: :ajax, action: :group_type_change
|
|
8
|
+
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# coding: utf-8
|
|
1
2
|
$:.push File.expand_path("../lib", __FILE__)
|
|
2
3
|
|
|
3
4
|
# Maintain your gem's version:
|
|
@@ -37,13 +38,15 @@ Gem::Specification.new do |spec|
|
|
|
37
38
|
spec.add_development_dependency "minitest", "~> 5.0"
|
|
38
39
|
spec.add_development_dependency "minitest-reporters", "~> 1.1"
|
|
39
40
|
spec.add_development_dependency "coveralls", "~> 0.8"
|
|
41
|
+
spec.add_development_dependency "sqlite3"
|
|
40
42
|
|
|
41
|
-
spec.add_dependency "rails", "~> 5.
|
|
43
|
+
spec.add_dependency "rails", "~> 5.1"
|
|
42
44
|
spec.add_dependency "cells", "~> 4.1"
|
|
45
|
+
spec.add_dependency "cells-rails", "~> 0.0"
|
|
46
|
+
spec.add_dependency "cells-erb", "~> 0.1"
|
|
47
|
+
spec.add_dependency "jquery-rails", "~> 4.3"
|
|
43
48
|
spec.add_dependency "criteria_operator", "~> 0.2"
|
|
44
49
|
|
|
45
50
|
# let yard run on install
|
|
46
51
|
spec.metadata["yard.run"] = "yri"
|
|
47
|
-
|
|
48
|
-
|
|
49
52
|
end
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
module CriteriaOperator
|
|
2
2
|
module UiComponent
|
|
3
3
|
class Engine < ::Rails::Engine
|
|
4
|
+
require 'jquery-rails'
|
|
5
|
+
require 'criteria_operator'
|
|
4
6
|
isolate_namespace CriteriaOperator::UiComponent
|
|
7
|
+
|
|
8
|
+
# config.assets.paths << File.expand_path("../../../app/assets/stylesheets/application", __FILE__)
|
|
9
|
+
# config.assets.paths << File.expand_path("../../../app/assets/javascripts/application", __FILE__)
|
|
5
10
|
end
|
|
6
11
|
end
|
|
7
12
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: criteria_operator-ui_component
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Florian Koch
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2017-05-
|
|
11
|
+
date: 2017-05-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -80,20 +80,34 @@ dependencies:
|
|
|
80
80
|
- - "~>"
|
|
81
81
|
- !ruby/object:Gem::Version
|
|
82
82
|
version: '0.8'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: sqlite3
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - ">="
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0'
|
|
83
97
|
- !ruby/object:Gem::Dependency
|
|
84
98
|
name: rails
|
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
|
86
100
|
requirements:
|
|
87
101
|
- - "~>"
|
|
88
102
|
- !ruby/object:Gem::Version
|
|
89
|
-
version: 5.
|
|
103
|
+
version: '5.1'
|
|
90
104
|
type: :runtime
|
|
91
105
|
prerelease: false
|
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
93
107
|
requirements:
|
|
94
108
|
- - "~>"
|
|
95
109
|
- !ruby/object:Gem::Version
|
|
96
|
-
version: 5.
|
|
110
|
+
version: '5.1'
|
|
97
111
|
- !ruby/object:Gem::Dependency
|
|
98
112
|
name: cells
|
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -108,6 +122,48 @@ dependencies:
|
|
|
108
122
|
- - "~>"
|
|
109
123
|
- !ruby/object:Gem::Version
|
|
110
124
|
version: '4.1'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: cells-rails
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0.0'
|
|
132
|
+
type: :runtime
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '0.0'
|
|
139
|
+
- !ruby/object:Gem::Dependency
|
|
140
|
+
name: cells-erb
|
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
|
142
|
+
requirements:
|
|
143
|
+
- - "~>"
|
|
144
|
+
- !ruby/object:Gem::Version
|
|
145
|
+
version: '0.1'
|
|
146
|
+
type: :runtime
|
|
147
|
+
prerelease: false
|
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
149
|
+
requirements:
|
|
150
|
+
- - "~>"
|
|
151
|
+
- !ruby/object:Gem::Version
|
|
152
|
+
version: '0.1'
|
|
153
|
+
- !ruby/object:Gem::Dependency
|
|
154
|
+
name: jquery-rails
|
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
|
156
|
+
requirements:
|
|
157
|
+
- - "~>"
|
|
158
|
+
- !ruby/object:Gem::Version
|
|
159
|
+
version: '4.3'
|
|
160
|
+
type: :runtime
|
|
161
|
+
prerelease: false
|
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - "~>"
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '4.3'
|
|
111
167
|
- !ruby/object:Gem::Dependency
|
|
112
168
|
name: criteria_operator
|
|
113
169
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -141,13 +197,17 @@ files:
|
|
|
141
197
|
- app/assets/config/criteria_operator_ui_component_manifest.js
|
|
142
198
|
- app/assets/images/criteria_operator/ui_component/.keep
|
|
143
199
|
- app/assets/javascripts/criteria_operator/ui_component/application.js
|
|
200
|
+
- app/assets/javascripts/criteria_operator/ui_component/criteria_editor.js
|
|
144
201
|
- app/assets/stylesheets/criteria_operator/ui_component/application.css
|
|
202
|
+
- app/cells/criteria_operator/ui_component/base_cell.rb
|
|
203
|
+
- app/cells/criteria_operator/ui_component/criteria_editor/show.erb
|
|
204
|
+
- app/cells/criteria_operator/ui_component/criteria_editor_cell.rb
|
|
205
|
+
- app/cells/criteria_operator/ui_component/expression/show.erb
|
|
206
|
+
- app/cells/criteria_operator/ui_component/expression_cell.rb
|
|
207
|
+
- app/cells/criteria_operator/ui_component/group/show.erb
|
|
208
|
+
- app/cells/criteria_operator/ui_component/group_cell.rb
|
|
209
|
+
- app/controllers/criteria_operator/ui_component/ajax_controller.rb
|
|
145
210
|
- app/controllers/criteria_operator/ui_component/application_controller.rb
|
|
146
|
-
- app/helpers/criteria_operator/ui_component/application_helper.rb
|
|
147
|
-
- app/jobs/criteria_operator/ui_component/application_job.rb
|
|
148
|
-
- app/mailers/criteria_operator/ui_component/application_mailer.rb
|
|
149
|
-
- app/models/criteria_operator/ui_component/application_record.rb
|
|
150
|
-
- app/views/layouts/criteria_operator/ui_component/application.html.erb
|
|
151
211
|
- bin/console
|
|
152
212
|
- bin/rails
|
|
153
213
|
- bin/setup
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html>
|
|
3
|
-
<head>
|
|
4
|
-
<title>Criteria operator ui component</title>
|
|
5
|
-
<%= stylesheet_link_tag "criteria_operator/ui_component/application", media: "all" %>
|
|
6
|
-
<%= javascript_include_tag "criteria_operator/ui_component/application" %>
|
|
7
|
-
<%= csrf_meta_tags %>
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
|
|
11
|
-
<%= yield %>
|
|
12
|
-
|
|
13
|
-
</body>
|
|
14
|
-
</html>
|