grapple 0.0.8 → 0.0.9
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/README.md +1 -3
- data/app/assets/javascripts/grapple-history.js +22 -10
- data/app/assets/javascripts/grapple-jquery.js +4 -8
- data/lib/grapple/ajax_data_grid_builder.rb +10 -10
- data/lib/grapple/base_table_builder.rb +12 -2
- data/lib/grapple/components/base_component.rb +5 -0
- data/lib/grapple/components/column_headings.rb +3 -2
- data/lib/grapple/components/html_component.rb +9 -1
- data/lib/grapple/components/will_paginate_pagination.rb +1 -0
- data/lib/grapple/helpers/table_helper.rb +11 -5
- data/lib/grapple/html_table_builder.rb +19 -7
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ef0f88b129f8fe4ca4d9e9b2c1e8c458f819dc2
|
4
|
+
data.tar.gz: 54f77fef01ea33ab190ca13e8e94089fdf212206
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a8506f028c52cb5a49f7275c9bdf647cddd954c31c748c9e4bdd6c362b9d77006949aa45a32eb120f712c1cf360e8008f3c60180e142365f8cc2254ce88b93f2
|
7
|
+
data.tar.gz: 70244d224b0fc8e8f3c885e2c4f3f222dbff4ce22432bacca7c217587c36aaa050b010cd5220dfb3a8bb94e991f08dc628fbeb8c9f02f266918373904383e8e7
|
data/README.md
CHANGED
@@ -182,9 +182,7 @@ end
|
|
182
182
|
Create a container around the table that can be updated by the JavaScript
|
183
183
|
``` HTML+ERB
|
184
184
|
<%# app/views/posts/index.html.erb %>
|
185
|
-
<%=
|
186
|
-
<%= render :partial => 'table' %>
|
187
|
-
<% end %>
|
185
|
+
<%= render partial: 'table' %>
|
188
186
|
```
|
189
187
|
|
190
188
|
Render the table using `table_for` in `app/views/posts/_table.html.erb`
|
@@ -4,7 +4,8 @@
|
|
4
4
|
var urlQuery = Grapple.Util.urlQuery,
|
5
5
|
parseUrlQuery = Grapple.Util.parseUrlQuery;
|
6
6
|
|
7
|
-
var GrappleHistory = function() {
|
7
|
+
var GrappleHistory = function(namespace) {
|
8
|
+
this.namespace = namespace;
|
8
9
|
if(History.init) {
|
9
10
|
// https://github.com/browserstate/history.js/
|
10
11
|
this.api = History;
|
@@ -29,7 +30,8 @@ GrappleHistory.IGNORE_PARAMS = { 'utf8': true, 'authenticity_token': true };
|
|
29
30
|
|
30
31
|
GrappleHistory.prototype = {
|
31
32
|
|
32
|
-
add: function(
|
33
|
+
add: function(params) {
|
34
|
+
var namespace = this.namespace;
|
33
35
|
var state = this.api.getState();
|
34
36
|
var historyParams = parseUrlQuery(urlQuery(state.url));
|
35
37
|
var newParams = parseUrlQuery(params);
|
@@ -39,9 +41,9 @@ GrappleHistory.prototype = {
|
|
39
41
|
for(var x in historyParams) {
|
40
42
|
var remove = namespace ?
|
41
43
|
// Remove any parameters in the tables namespace
|
42
|
-
x.indexOf(namespace + '
|
44
|
+
x.indexOf(namespace + '[') === 0 :
|
43
45
|
// Table is in the global namespace, remove any parameters that aren't namespaced
|
44
|
-
x.indexOf('
|
46
|
+
x.indexOf('[') === -1;
|
45
47
|
|
46
48
|
if(remove) {
|
47
49
|
delete historyParams[x];
|
@@ -51,18 +53,28 @@ GrappleHistory.prototype = {
|
|
51
53
|
// Add the new parameters
|
52
54
|
for(var x in newParams) {
|
53
55
|
if(GrappleHistory.IGNORE_PARAMS[x]) continue;
|
54
|
-
var key = namespace ? namespace + '
|
55
|
-
historyParams[
|
56
|
+
//var key = namespace ? namespace + '[' + x + ']' : x;
|
57
|
+
historyParams[x] = newParams[x];
|
56
58
|
}
|
57
|
-
|
59
|
+
|
58
60
|
this.api.pushState(null, document.title, '?' + $.param(historyParams));
|
59
61
|
},
|
60
62
|
|
61
63
|
subscribe: function(callback) {
|
62
|
-
var api = this.api;
|
64
|
+
var api = this.api, namespace = this.namespace;
|
63
65
|
this.changeCallback = function(event) {
|
64
66
|
var state = api.getState();
|
65
|
-
|
67
|
+
var params = parseUrlQuery(urlQuery(state.url));
|
68
|
+
// Only include the parameters for this namespace
|
69
|
+
if(namespace) {
|
70
|
+
var r = new RegExp('^' + namespace + '\\[([^\\]]+)\\]$')
|
71
|
+
for(var x in params) {
|
72
|
+
if(r.exec(x) === null) {
|
73
|
+
delete params[x];
|
74
|
+
}
|
75
|
+
}
|
76
|
+
}
|
77
|
+
callback(params);
|
66
78
|
};
|
67
79
|
$(window).bind('statechange', this.changeCallback);
|
68
80
|
},
|
@@ -78,4 +90,4 @@ GrappleHistory.prototype = {
|
|
78
90
|
|
79
91
|
Grapple.History = GrappleHistory;
|
80
92
|
|
81
|
-
})(window, Grapple, $);
|
93
|
+
})(window, Grapple, $);
|
@@ -28,7 +28,7 @@ var GrappleTable = function(element, options) {
|
|
28
28
|
this.history = options.history;
|
29
29
|
}
|
30
30
|
else if(this.element.data('grapple-ajax-history') == 1 || options.history === true) {
|
31
|
-
this.history = new Grapple.History();
|
31
|
+
this.history = new Grapple.History(this.namespace);
|
32
32
|
}
|
33
33
|
else {
|
34
34
|
this.history = null;
|
@@ -65,7 +65,7 @@ GrappleTable.prototype = {
|
|
65
65
|
if(this.history) {
|
66
66
|
var self = this;
|
67
67
|
this.history.unsubscribe();
|
68
|
-
this.history = new Grapple.History();
|
68
|
+
this.history = new Grapple.History(this.namespace);
|
69
69
|
this.history.subscribe(function(params) {
|
70
70
|
self.onHistoryChange(params);
|
71
71
|
});
|
@@ -85,7 +85,7 @@ GrappleTable.prototype = {
|
|
85
85
|
|
86
86
|
if(this.history) {
|
87
87
|
this.history.unsubscribe();
|
88
|
-
this.history.add(
|
88
|
+
this.history.add(params);
|
89
89
|
}
|
90
90
|
|
91
91
|
this._updateTable(params);
|
@@ -114,7 +114,6 @@ GrappleTable.prototype = {
|
|
114
114
|
if(params.length) {
|
115
115
|
url += '?' + params;
|
116
116
|
}
|
117
|
-
|
118
117
|
$.ajax(url, {
|
119
118
|
success: function(data) {
|
120
119
|
// HACK
|
@@ -129,10 +128,7 @@ GrappleTable.prototype = {
|
|
129
128
|
},
|
130
129
|
error: function(a, b, c) {
|
131
130
|
// TODO: handle loading errors
|
132
|
-
console.log("Failed to load table");
|
133
|
-
console.log(a);
|
134
|
-
console.log(b);
|
135
|
-
console.log(c);
|
131
|
+
console.log("Failed to load table", a, b, c);
|
136
132
|
}
|
137
133
|
});
|
138
134
|
},
|
@@ -5,25 +5,25 @@ module Grapple
|
|
5
5
|
|
6
6
|
@@next_id = 1000
|
7
7
|
|
8
|
-
def
|
8
|
+
def container_attributes
|
9
9
|
@@next_id += 1
|
10
|
-
options[:id] ||= "grapple_ajax_table_#{@@next_id}"
|
10
|
+
@options[:id] ||= "grapple_ajax_table_#{@@next_id}"
|
11
11
|
css = CONTAINER_CLASSES
|
12
|
-
css += " #{options[:container_class]}" unless options[:container_class].nil?
|
12
|
+
css += " #{@options[:container_class]}" unless @options[:container_class].nil?
|
13
13
|
|
14
14
|
data = {
|
15
|
-
"grapple-ajax-url" => options[:url] || template.url_for(action: 'table'),
|
15
|
+
"grapple-ajax-url" => @options[:url] || template.url_for(action: 'table'),
|
16
16
|
# History is disabled by default, override container_attributes
|
17
17
|
# in an initializer to enable it by default
|
18
|
-
"grapple-ajax-history" => options[:history] == true ? '1' : '0'
|
18
|
+
"grapple-ajax-history" => @options[:history] == true ? '1' : '0'
|
19
19
|
}
|
20
20
|
|
21
21
|
# The namespace allows the query parameters to be namespaced so
|
22
22
|
# multiple tables can exist on the same page
|
23
|
-
data["grapple-ajax-namespace"] = options[:namespace] unless options[:namespace].nil?
|
23
|
+
data["grapple-ajax-namespace"] = @options[:namespace] unless @options[:namespace].nil?
|
24
24
|
|
25
25
|
return {
|
26
|
-
:id => options[:id],
|
26
|
+
:id => @options[:id],
|
27
27
|
:class => css,
|
28
28
|
:data => data
|
29
29
|
}
|
@@ -31,11 +31,11 @@ module Grapple
|
|
31
31
|
|
32
32
|
def after_table
|
33
33
|
style = 'background-image: url(' + template.image_path("grapple/loading-bar.gif") + ')'
|
34
|
-
template.content_tag :div, '', :
|
34
|
+
template.content_tag :div, '', class: 'loading-overlay', style: style
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
38
|
-
selector = '#' + options[:id]
|
37
|
+
def after_container
|
38
|
+
selector = '#' + @options[:id]
|
39
39
|
js = "$(#{selector.to_json}).grapple();"
|
40
40
|
return template.javascript_tag(js)
|
41
41
|
end
|
@@ -24,16 +24,22 @@ module Grapple
|
|
24
24
|
define_singleton_method(method) { settings }
|
25
25
|
end
|
26
26
|
|
27
|
-
attr_reader :columns, :records, :template, :params
|
27
|
+
attr_reader :columns, :records, :template, :params, :namespace
|
28
28
|
|
29
29
|
def initialize(template, columns, records, params = {}, *options)
|
30
30
|
@template = template
|
31
31
|
@columns = columns
|
32
32
|
@records = records
|
33
|
+
@options = default_options.merge(options[0] || {})
|
34
|
+
@namespace = @options[:namespace]
|
33
35
|
@params = params
|
34
|
-
@
|
36
|
+
@params = @params[@namespace] || {} if @namespace
|
35
37
|
@helper_instances = {}
|
36
38
|
end
|
39
|
+
|
40
|
+
def default_options
|
41
|
+
{ }
|
42
|
+
end
|
37
43
|
|
38
44
|
def before_table
|
39
45
|
''
|
@@ -42,6 +48,10 @@ module Grapple
|
|
42
48
|
def after_table
|
43
49
|
''
|
44
50
|
end
|
51
|
+
|
52
|
+
def container(inner_html)
|
53
|
+
inner_html
|
54
|
+
end
|
45
55
|
|
46
56
|
protected
|
47
57
|
|
@@ -22,13 +22,14 @@ module Grapple
|
|
22
22
|
|
23
23
|
label = t(column[:label] || '')
|
24
24
|
|
25
|
-
if column[:sort]
|
25
|
+
if column[:sort]
|
26
26
|
cell_classes << 'sortable'
|
27
27
|
if column[:sort] == params[:sort]
|
28
28
|
liner_classes << (params[:dir] == 'desc' ? 'sort-desc' : 'sort-asc')
|
29
29
|
cell_classes << 'sorted'
|
30
30
|
end
|
31
|
-
|
31
|
+
url = table_url(additional_parameters.merge({sort: column[:sort]}))
|
32
|
+
content = template.link_to(label, url)
|
32
33
|
else
|
33
34
|
content = label
|
34
35
|
end
|
@@ -16,7 +16,15 @@ module Grapple
|
|
16
16
|
if options[:sort] == params[:sort]
|
17
17
|
options[:dir] = (params[:dir] == 'desc') ? 'asc' : 'desc'
|
18
18
|
end
|
19
|
-
|
19
|
+
url_params = params.stringify_keys().merge(options.stringify_keys())
|
20
|
+
if @builder.namespace
|
21
|
+
tmp = {}
|
22
|
+
url_params.each do |key, value|
|
23
|
+
tmp[url_parameter(key)] = value
|
24
|
+
end
|
25
|
+
url_params = tmp
|
26
|
+
end
|
27
|
+
template.url_for url_params
|
20
28
|
end
|
21
29
|
|
22
30
|
end
|
@@ -19,6 +19,7 @@ module Grapple
|
|
19
19
|
elsif !params[:query].blank? and records.empty?
|
20
20
|
html = h(t(no_results_message))
|
21
21
|
else
|
22
|
+
paginate_parameters[:param_name] = url_parameter(:page) if builder.namespace
|
22
23
|
html = template.will_paginate(records, paginate_parameters) || ' '
|
23
24
|
end
|
24
25
|
|
@@ -4,17 +4,23 @@ module Grapple
|
|
4
4
|
|
5
5
|
@@builder = Grapple::DataGridBuilder
|
6
6
|
mattr_accessor :builder
|
7
|
-
|
7
|
+
|
8
8
|
def table_for(columns, records, *args, &block)
|
9
9
|
options = args[0] || {}
|
10
|
+
render_container = (options[:container].nil? ? !request.xhr? : options[:container]) rescue false
|
10
11
|
table_html_attributes = options[:html] || {}
|
11
|
-
|
12
|
+
options[:builder] = options[:builder] || @@builder
|
12
13
|
# params might not be defined (being called from a mailer)
|
13
14
|
# HACK: "defined? params" is returning method but when it gets called the method is not defined
|
14
|
-
request_params = params() rescue {}
|
15
|
-
builder =
|
15
|
+
request_params = request.params() rescue {}
|
16
|
+
builder = options[:builder].new(self, columns, records, request_params, options)
|
16
17
|
output = capture(builder, &block)
|
17
|
-
(builder.before_table + builder.table(output, table_html_attributes) + builder.after_table)
|
18
|
+
table_html = (builder.before_table + builder.table(output, table_html_attributes) + builder.after_table)
|
19
|
+
if render_container
|
20
|
+
builder.container(table_html)
|
21
|
+
else
|
22
|
+
table_html.html_safe
|
23
|
+
end
|
18
24
|
end
|
19
25
|
|
20
26
|
def grapple_container(*args, &block)
|
@@ -13,18 +13,30 @@ module Grapple
|
|
13
13
|
def table(content, attributes = {})
|
14
14
|
"#{template.content_tag('table', content, attributes)}\n".html_safe
|
15
15
|
end
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
|
17
|
+
# Wrap the table in a div
|
18
|
+
def container(inner_html)
|
19
|
+
html = ''
|
20
|
+
html << before_container
|
21
|
+
html << template.tag('div', container_attributes, true) + "\n"
|
22
|
+
html << inner_html
|
23
|
+
html << "</div>\n"
|
24
|
+
html << after_container
|
25
|
+
return html.html_safe
|
26
|
+
end
|
27
|
+
|
28
|
+
# HTML attributes for the container
|
29
|
+
def container_attributes
|
30
|
+
{ class: 'grapple' }
|
21
31
|
end
|
22
32
|
|
23
|
-
|
33
|
+
# HTML to render before the container
|
34
|
+
def before_container
|
24
35
|
''
|
25
36
|
end
|
26
37
|
|
27
|
-
|
38
|
+
# HTML to render after the container
|
39
|
+
def after_container
|
28
40
|
''
|
29
41
|
end
|
30
42
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: grapple
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Edward Potocko
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-
|
12
|
+
date: 2016-06-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|