inkwell_timelines 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +187 -0
- data/Rakefile +40 -0
- data/app/assets/images/inkwell_timelines/checkbox-checked.png +0 -0
- data/app/assets/images/inkwell_timelines/checkbox-unchecked.png +0 -0
- data/app/assets/images/inkwell_timelines/minus.png +0 -0
- data/app/assets/images/inkwell_timelines/plus.png +0 -0
- data/app/assets/images/inkwell_timelines/radiobutton_no.png +0 -0
- data/app/assets/images/inkwell_timelines/radiobutton_yes.png +0 -0
- data/app/assets/images/inkwell_timelines/up-down.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-comment-hover.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-comment.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-favorite-active.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-favorite-hover.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-favorite.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-reblog-active.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-reblog-hover.png +0 -0
- data/app/assets/images/inkwell_timelines/wi-reblog.png +0 -0
- data/app/assets/javascripts/inkwell_timelines/index.js.erb +17 -0
- data/app/assets/javascripts/inkwell_timelines/inkwell_multi_selector.js +216 -0
- data/app/assets/javascripts/inkwell_timelines/inkwell_timeline.js.erb +149 -0
- data/app/assets/stylesheets/inkwell_timelines/index.css +30 -0
- data/app/assets/stylesheets/inkwell_timelines/multi_selector.css.erb +112 -0
- data/app/assets/stylesheets/inkwell_timelines/tab-menu.css +26 -0
- data/app/assets/stylesheets/inkwell_timelines/wall_item.css.erb +106 -0
- data/app/controllers/inkwell_timelines/application_controller.rb +4 -0
- data/app/helpers/inkwell_timelines/application_helper.rb +4 -0
- data/app/views/default_partials/_comment.html.erb +21 -0
- data/app/views/default_partials/_multi_selector.html.erb +15 -0
- data/app/views/default_partials/_multi_selector_items.html.erb +8 -0
- data/app/views/default_partials/_post.html.erb +22 -0
- data/app/views/default_partials/_tab_menu.html.erb +9 -0
- data/app/views/layouts/inkwell_timelines/application.html.erb +14 -0
- data/config/routes.rb +2 -0
- data/lib/inkwell_timelines.rb +6 -0
- data/lib/inkwell_timelines/engine.rb +5 -0
- data/lib/inkwell_timelines/version.rb +3 -0
- data/lib/main/to_controller.rb +22 -0
- data/lib/main/to_helpers.rb +93 -0
- data/lib/tasks/inkwell_timelines_tasks.rake +4 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +16 -0
- data/test/dummy/app/assets/javascripts/test.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.css +14 -0
- data/test/dummy/app/assets/stylesheets/test.css +4 -0
- data/test/dummy/app/controllers/application_controller.rb +9 -0
- data/test/dummy/app/controllers/test_controller.rb +5 -0
- data/test/dummy/app/controllers/timeline_controller.rb +11 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/helpers/test_helper.rb +2 -0
- data/test/dummy/app/models/blogline.rb +3 -0
- data/test/dummy/app/models/bloglines_categories.rb +3 -0
- data/test/dummy/app/models/category.rb +7 -0
- data/test/dummy/app/models/comment.rb +16 -0
- data/test/dummy/app/models/favoriteline.rb +3 -0
- data/test/dummy/app/models/post.rb +16 -0
- data/test/dummy/app/models/user.rb +109 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/test/show.html.erb +1 -0
- data/test/dummy/app/views/timeline/show.html.erb +1 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/inkwell_timelines.rb +42 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +5 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20130422111954_create_posts.rb +16 -0
- data/test/dummy/db/migrate/20130422112200_create_users.rb +10 -0
- data/test/dummy/db/migrate/20130422112350_create_comments.rb +16 -0
- data/test/dummy/db/migrate/20130422112504_create_bloglines.rb +13 -0
- data/test/dummy/db/migrate/20130422112804_create_favoritelines.rb +11 -0
- data/test/dummy/db/migrate/20130422112954_create_categories.rb +14 -0
- data/test/dummy/db/migrate/20130422113135_create_bloglines_categories.rb +12 -0
- data/test/dummy/db/schema.rb +92 -0
- data/test/dummy/db/seeds.rb +625 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +104306 -0
- data/test/dummy/log/test.log +815 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/spec/helpers/test_helper_spec.rb +8 -0
- data/test/dummy/spec/spec_helper.rb +52 -0
- data/test/dummy/spec/watir/autoload_spec.rb +33 -0
- data/test/dummy/spec/watir/main_spec.rb +80 -0
- data/test/dummy/spec/watir/selector_spec.rb +103 -0
- data/test/dummy/spec/watir/tab_menu_spec.rb +36 -0
- data/test/dummy/tmp/cache/assets/C56/8F0/sprockets%2F1ad046fb9937420d5382984483fc8401 +0 -0
- data/test/dummy/tmp/cache/assets/C63/420/sprockets%2F5daa64d9601a1dd14726112003d08364 +0 -0
- data/test/dummy/tmp/cache/assets/C65/790/sprockets%2Feacce513669090988829f66e61634451 +0 -0
- data/test/dummy/tmp/cache/assets/C77/DD0/sprockets%2F055f9cd12326c5150492b8c584314fa3 +0 -0
- data/test/dummy/tmp/cache/assets/C84/E70/sprockets%2F0530f24346bbf970634035b6e55f886e +0 -0
- data/test/dummy/tmp/cache/assets/C85/420/sprockets%2F4734da42d41574596ab532629d0867ec +0 -0
- data/test/dummy/tmp/cache/assets/C87/A50/sprockets%2F667342f892546b573c52d11f814ae4f3 +0 -0
- data/test/dummy/tmp/cache/assets/CA1/750/sprockets%2Fa8471b3ea18986e7368e8273a95865e8 +0 -0
- data/test/dummy/tmp/cache/assets/CAC/DB0/sprockets%2Fc424393ee4e4f66aa4014619048753cb +0 -0
- data/test/dummy/tmp/cache/assets/CB2/170/sprockets%2F4479eb189646408ec3130b45153ebf7b +0 -0
- data/test/dummy/tmp/cache/assets/CB9/630/sprockets%2Fe5952cc2ece61727517547af4232892e +0 -0
- data/test/dummy/tmp/cache/assets/CBD/960/sprockets%2F5a35c922c979e889b0338374a9b3f4b0 +0 -0
- data/test/dummy/tmp/cache/assets/CC4/730/sprockets%2F78d0941e0543313bbb0a9f0cf630030d +0 -0
- data/test/dummy/tmp/cache/assets/CD1/F50/sprockets%2Fbf2261613d1c32c54a6e38a7673531fa +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/CD9/1E0/sprockets%2F293460f7bea2aea456231b769212f36f +0 -0
- data/test/dummy/tmp/cache/assets/CDC/EC0/sprockets%2Ff9a21d40846491577ab5ebe00de07077 +0 -0
- data/test/dummy/tmp/cache/assets/CE6/8D0/sprockets%2F9e823d2b49662dbb4389f2841a23e8c1 +0 -0
- data/test/dummy/tmp/cache/assets/CEE/110/sprockets%2Faf0654ff711843e082592cd70cf89a88 +0 -0
- data/test/dummy/tmp/cache/assets/CEE/490/sprockets%2F97139dc7ad35759531fc7fa572f0c761 +0 -0
- data/test/dummy/tmp/cache/assets/CF9/6F0/sprockets%2F952426cea414c6c2a04cc1216a1f36f5 +0 -0
- data/test/dummy/tmp/cache/assets/CFA/DE0/sprockets%2F25bf1e7766a300a4c37195df0cbb1107 +0 -0
- data/test/dummy/tmp/cache/assets/CFB/A10/sprockets%2F72699e3ed6f9c3984a718b62932ba66e +0 -0
- data/test/dummy/tmp/cache/assets/CFC/640/sprockets%2Fc7f89943cb904e76b2437e59348cc5c9 +0 -0
- data/test/dummy/tmp/cache/assets/D13/0C0/sprockets%2F218a6e24bfe5005a8a86798baa2585c8 +0 -0
- data/test/dummy/tmp/cache/assets/D13/3B0/sprockets%2F00cf5d507582a705af9694cde93ba186 +0 -0
- data/test/dummy/tmp/cache/assets/D13/6A0/sprockets%2F4819aa020210496ecf49ee70b78e8be6 +0 -0
- data/test/dummy/tmp/cache/assets/D15/560/sprockets%2Ff0007939832a29a27abe3a9579eed81c +0 -0
- data/test/dummy/tmp/cache/assets/D16/860/sprockets%2Fb45890d98668c132fee5cae4b15320d9 +0 -0
- data/test/dummy/tmp/cache/assets/D1A/150/sprockets%2F49ad9f8620b7712e6f2d4fc2e354e545 +0 -0
- data/test/dummy/tmp/cache/assets/D20/4F0/sprockets%2Fb15d3257899ad89007d1348eb9a5f5fe +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D36/810/sprockets%2Fb84416b6a4f5a39b0bc23ab72ad94279 +0 -0
- data/test/dummy/tmp/cache/assets/D39/390/sprockets%2F3c87a321da4296312f18efc704cd6d2f +0 -0
- data/test/dummy/tmp/cache/assets/D3A/260/sprockets%2F69551919ec05c0eb11e55bb59dc143ec +0 -0
- data/test/dummy/tmp/cache/assets/D41/350/sprockets%2F2111b16bc0081c14b803cfd350eb4baa +0 -0
- data/test/dummy/tmp/cache/assets/D43/D20/sprockets%2Fbcbf2f35591e507593ec6116eac6e924 +0 -0
- data/test/dummy/tmp/cache/assets/D48/3C0/sprockets%2F41be77d9f6b62168967ca14ccc6b51d6 +0 -0
- data/test/dummy/tmp/cache/assets/D4D/7C0/sprockets%2F5f4f24c2540cffe8b3c5e835756c35f7 +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D51/6A0/sprockets%2F80b05d6f75c78bdb1e450c898e47d97a +0 -0
- data/test/dummy/tmp/cache/assets/D56/4C0/sprockets%2F66059379b6c72ffe570f4ae394a89eda +0 -0
- data/test/dummy/tmp/cache/assets/D56/D30/sprockets%2Fe910c76d93fd4da6984d82e469f62f0c +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D65/600/sprockets%2Fdaa0e3c217673cb0ebb89d97438a1b80 +0 -0
- data/test/dummy/tmp/cache/assets/D66/6C0/sprockets%2Fa06355ade2a095c01afd8c6f5e67019d +0 -0
- data/test/dummy/tmp/cache/assets/D6A/E70/sprockets%2Fc9f71142e4d4a807cb6be80451f74adb +0 -0
- data/test/dummy/tmp/cache/assets/D76/E50/sprockets%2F6289e3eb865565eab3fdfb4fae810702 +0 -0
- data/test/dummy/tmp/cache/assets/D86/6A0/sprockets%2Fac97d7e4e37faa819a833c7c52c9e687 +0 -0
- data/test/dummy/tmp/cache/assets/D91/C00/sprockets%2Fb1cf6c48f161db0a058d10817ddd5e5b +0 -0
- data/test/dummy/tmp/cache/assets/D9C/C90/sprockets%2Fa903431f8703bbaafcae42e4f4692ff8 +0 -0
- data/test/dummy/tmp/cache/assets/DA0/C60/sprockets%2F90d8e40e6baa19d6556ab9c6ac891a2e +0 -0
- data/test/dummy/tmp/cache/assets/DA1/F90/sprockets%2F3bd196480867f8e3c74b10dbcbbe1f9b +0 -0
- data/test/dummy/tmp/cache/assets/DA7/EE0/sprockets%2Ffced4a1e089dc82bf773475da4e53c46 +0 -0
- data/test/dummy/tmp/cache/assets/DA9/4D0/sprockets%2F3d68828b990fbfa9cdf51daa76c242d5 +0 -0
- data/test/dummy/tmp/cache/assets/DB5/4C0/sprockets%2F5e815df4827231fe949b2f9bffd0d9de +0 -0
- data/test/dummy/tmp/cache/assets/DB6/910/sprockets%2F3c19b64141a5ceeccf3a3baf4c452a06 +0 -0
- data/test/dummy/tmp/cache/assets/DC4/8D0/sprockets%2Fd8daccd2ece841a83a2a584c50e352d5 +0 -0
- data/test/dummy/tmp/cache/assets/DCC/6A0/sprockets%2Fa92fb625cc83fe72fc4115e2fb2ed61e +0 -0
- data/test/dummy/tmp/cache/assets/DCC/940/sprockets%2Fe7f0ee8bf122b8b72b8e3c7cd13a5d81 +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/E08/E50/sprockets%2F22c72aded517c5cdf8cce6f4b58c76b8 +0 -0
- data/test/dummy/tmp/cache/assets/E24/740/sprockets%2F2ecee9c0ae221af87da9c5d034c8dd0c +0 -0
- data/test/dummy/tmp/cache/assets/E2D/160/sprockets%2Fdb479da69eeed6322f3b8dab3bf91bb0 +0 -0
- data/test/dummy/tmp/cache/assets/E4C/810/sprockets%2Fdaf244418a8cfda1aca3e32dbdf17fd2 +0 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/screen/main.png +0 -0
- data/test/test_helper.rb +15 -0
- metadata +413 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 Sergey Sokolov
|
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,187 @@
|
|
1
|
+
# Inkwell Timelines
|
2
|
+
|
3
|
+
Inkwell Timelines provides simple way to create timelines with autoload content while scrolling with ability to transmit the additional parameters.
|
4
|
+
It allows you to place timeline blocks on the pages - one block per page.
|
5
|
+
|
6
|
+
Each block can consist of several timelines (Blog and Favorite timelines on the screenshot).
|
7
|
+
|
8
|
+
Each timeline can consist of several types objects (Posts and Comments on the screenshot) with different templates to form them.
|
9
|
+
|
10
|
+
Timeline can consist of selectors ( category selector on the screenshot) to customize received data (for example, you can get timeline with only one category's items).
|
11
|
+
|
12
|
+
Timelines autoload next items when it is scrolled to the end.
|
13
|
+
|
14
|
+
![Inkwell Timelines](https://github.com/salkar/inkwell_timelines/blob/master/test/screen/main.png?raw=true)
|
15
|
+
|
16
|
+
## Installation
|
17
|
+
|
18
|
+
Put in `Gemfile`:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
gem 'inkwell_timelines', :git => 'https://github.com/salkar/inkwell_timelines.git'
|
22
|
+
```
|
23
|
+
|
24
|
+
After it do `bundle install`
|
25
|
+
|
26
|
+
Create `inkwell_timelines.rb` file in `config/initializers` and put in it your settings:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
module InkwellTimelines
|
30
|
+
class Engine < Rails::Engine
|
31
|
+
# Pixels count between current scroll position and page's end at which the autoload start
|
32
|
+
config.load_distance = 150
|
33
|
+
config.autoload_path = 'timeline/get/' # Autoload controller path
|
34
|
+
# Optional. If defined all partials will be searched here
|
35
|
+
config.partials_dir = 'your path to partials'
|
36
|
+
config.timeline_blocks = [
|
37
|
+
{ # First timelines block
|
38
|
+
:id => 'timelines_block', # Block id
|
39
|
+
:timelines => [
|
40
|
+
{
|
41
|
+
:id => 'blogline', # First timeline id
|
42
|
+
:name => 'Blog', # First timeline displayed name
|
43
|
+
:active => true, # Defines which timeline is active at first load
|
44
|
+
:data_get => ->(options = {}) { # Lambda which get data for form this timeline
|
45
|
+
user = User.find options[:user_id]
|
46
|
+
# Function that return array of objects (for example - posts and comments in dummy app)
|
47
|
+
user.blogline options
|
48
|
+
},
|
49
|
+
# Array of params (of options in :data_get) saved on client side and sent to server on autoload
|
50
|
+
:transferred_params => [:user_id],
|
51
|
+
# Add selector to customize received data (sampling by Category on the screenshot)
|
52
|
+
:multi_selectors => [
|
53
|
+
{
|
54
|
+
:id => 'category', # Selector id
|
55
|
+
:name => 'Category', # Selector displayed name (see screenshot)
|
56
|
+
:data_get => ->(options = {}) { # Lambda which get objects for form selector
|
57
|
+
Category.where(:owner_id => options[:user_id], :owner_type => 'u')
|
58
|
+
}
|
59
|
+
|
60
|
+
}
|
61
|
+
]
|
62
|
+
},
|
63
|
+
{
|
64
|
+
:id => 'favoriteline', # Second timeline id
|
65
|
+
:name => 'Favorite', # Second timeline displayed name
|
66
|
+
:data_get => ->(options = {}) { # Lambda which get data for form this timeline
|
67
|
+
user = User.find options[:user_id]
|
68
|
+
user.favoriteline options
|
69
|
+
},
|
70
|
+
# Transferred through client params (timeline owner in this case)
|
71
|
+
:transferred_params => [:user_id]
|
72
|
+
}
|
73
|
+
]
|
74
|
+
}
|
75
|
+
]
|
76
|
+
end
|
77
|
+
end
|
78
|
+
```
|
79
|
+
|
80
|
+
Next, add ` //= require inkwell_timelines` to your js assets (for example - to application.js) and `*= require inkwell_timelines` to your stylesheets assets (for example - to application.css).
|
81
|
+
|
82
|
+
*Notice: if you want to modify CSS or JS you can add your modified files and not add default styles/js*
|
83
|
+
|
84
|
+
Default partials are located inside the gem - [here](https://github.com/salkar/inkwell_timelines/tree/master/app/views/default_partials).
|
85
|
+
You can change this directory to your adding `config.partials_dir = 'your path to partials'` parameter in your `inkwell_timelines.rb` file.
|
86
|
+
|
87
|
+
By default, there are 5 partials in this gem (you can change all of them):
|
88
|
+
|
89
|
+
```ruby
|
90
|
+
_comment.html.erb # Partial for timeline item for comment object
|
91
|
+
_multi_selector.html.erb # Partial for selector
|
92
|
+
_multi_selector_items.html.erb # Support partial for selector
|
93
|
+
_post.html.erb # Partial for post item for comment object
|
94
|
+
_tab_menu.html.erb # Partial for timelines block menu
|
95
|
+
```
|
96
|
+
|
97
|
+
If there are other objects except posts and comments - add partials for them.
|
98
|
+
|
99
|
+
## Usage
|
100
|
+
|
101
|
+
To form the timeline block for the first showing add into your view:
|
102
|
+
```ruby
|
103
|
+
<%= inkwell_timelines_tag(block_id, options = {} %>
|
104
|
+
```
|
105
|
+
For example:
|
106
|
+
```ruby
|
107
|
+
<%= inkwell_timelines_tag('timelines_block',
|
108
|
+
:user_id => User.where(:nick => 'Pushkin').first.id,
|
109
|
+
:for_user => current_user) %>
|
110
|
+
```
|
111
|
+
|
112
|
+
*Notice: config for this block should be*
|
113
|
+
|
114
|
+
To on autoload feature create controller for it, add it in the `routes`, add its route to timeline config. For example:
|
115
|
+
|
116
|
+
* add `controllers/timeline_controller.rb`
|
117
|
+
```ruby
|
118
|
+
class TimelineController < ApplicationController
|
119
|
+
def show
|
120
|
+
end
|
121
|
+
end
|
122
|
+
```
|
123
|
+
|
124
|
+
* add route for it -
|
125
|
+
```ruby
|
126
|
+
match "/timeline/get" => "timeline#show"
|
127
|
+
```
|
128
|
+
|
129
|
+
* add its route to timelines config:
|
130
|
+
```ruby
|
131
|
+
config.autoload_path = 'timeline/get/'
|
132
|
+
```
|
133
|
+
|
134
|
+
Next, add to created controller:
|
135
|
+
```ruby
|
136
|
+
@options = inkwell_timelines_get_params(request.body, :additional options => {})
|
137
|
+
```
|
138
|
+
|
139
|
+
`inkwell_timelines_get_params` forms options for autoload timeline part generation.
|
140
|
+
Additional options needs to merge stored on the server with transferred from client options.
|
141
|
+
You may want to save some options on the server for security reasons (for example - `current_user` should not be sent to the client because there it can be changed).
|
142
|
+
|
143
|
+
Here you can check the options that came with the client.
|
144
|
+
|
145
|
+
At the end of autoload controller method add
|
146
|
+
```ruby
|
147
|
+
render :layout => false
|
148
|
+
```
|
149
|
+
|
150
|
+
Example:
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
class TimelineController < ApplicationController
|
154
|
+
def show
|
155
|
+
@options = inkwell_timelines_get_params(request.body, :for_user => current_user)
|
156
|
+
|
157
|
+
#Here you can check came from js options. For exapmle:
|
158
|
+
user = User.find @options[:user_id]
|
159
|
+
raise "current user has no permissions to see #{user.nick} timeline" unless current_user.can_see_timeline user
|
160
|
+
|
161
|
+
render :layout => false
|
162
|
+
end
|
163
|
+
end
|
164
|
+
```
|
165
|
+
|
166
|
+
After it create view file for autoload method in controller (in our cases - `views/timeline/show.html.erb`) and add to it
|
167
|
+
```ruby
|
168
|
+
<%= inkwell_timelines_autoload_tag(@options) %>
|
169
|
+
```
|
170
|
+
|
171
|
+
## Sample
|
172
|
+
|
173
|
+
Sample located [here](https://github.com/salkar/inkwell_timelines/tree/master/test/dummy).
|
174
|
+
To run it:
|
175
|
+
```bash
|
176
|
+
$ cd inkwell_timelines/test/dummy
|
177
|
+
$ bundle install
|
178
|
+
$ rake db:create
|
179
|
+
$ rake db:migrate
|
180
|
+
$ rake db:seed
|
181
|
+
$ rails s
|
182
|
+
```
|
183
|
+
And go to `http://0.0.0.0:3000/` in your browser after it.
|
184
|
+
|
185
|
+
## License
|
186
|
+
|
187
|
+
Inkwell is Copyright © 2013 Sergey Sokolov. It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
rescue LoadError
|
5
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
6
|
+
end
|
7
|
+
begin
|
8
|
+
require 'rdoc/task'
|
9
|
+
rescue LoadError
|
10
|
+
require 'rdoc/rdoc'
|
11
|
+
require 'rake/rdoctask'
|
12
|
+
RDoc::Task = Rake::RDocTask
|
13
|
+
end
|
14
|
+
|
15
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
16
|
+
rdoc.rdoc_dir = 'rdoc'
|
17
|
+
rdoc.title = 'InkwellTimelines'
|
18
|
+
rdoc.options << '--line-numbers'
|
19
|
+
rdoc.rdoc_files.include('README.rdoc')
|
20
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
21
|
+
end
|
22
|
+
|
23
|
+
APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__)
|
24
|
+
load 'rails/tasks/engine.rake'
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
Bundler::GemHelper.install_tasks
|
29
|
+
|
30
|
+
require 'rake/testtask'
|
31
|
+
|
32
|
+
Rake::TestTask.new(:test) do |t|
|
33
|
+
t.libs << 'lib'
|
34
|
+
t.libs << 'test'
|
35
|
+
t.pattern = 'test/**/*_test.rb'
|
36
|
+
t.verbose = false
|
37
|
+
end
|
38
|
+
|
39
|
+
|
40
|
+
task :default => :test
|
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
|
Binary file
|
@@ -0,0 +1,17 @@
|
|
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_tree .
|
16
|
+
|
17
|
+
|
@@ -0,0 +1,216 @@
|
|
1
|
+
var inkwell_multi_selector = {
|
2
|
+
popup_shown: false,
|
3
|
+
current_state: null,
|
4
|
+
|
5
|
+
state_changed: $.Event('state_changed'),
|
6
|
+
|
7
|
+
show_popup: function (action_obj) {
|
8
|
+
this.popup_shown = true;
|
9
|
+
this.current_state = $(action_obj.parent().children('.current_state')[0]).children().text();
|
10
|
+
action_obj.addClass('on');
|
11
|
+
action_obj.find('.dropdown').show();
|
12
|
+
},
|
13
|
+
|
14
|
+
hide_popup: function (action_obj) {
|
15
|
+
if (this.popup_shown) {
|
16
|
+
if (!action_obj) {
|
17
|
+
var dropdown = $('.inkwell_multi_selector .dropdown:visible');
|
18
|
+
action_obj = dropdown.closest('.inkwell_multi_selector .action');
|
19
|
+
}
|
20
|
+
this.popup_shown = false;
|
21
|
+
action_obj.removeClass('on');
|
22
|
+
action_obj.find('.dropdown').hide();
|
23
|
+
if (inkwell_multi_selector.has_changes(action_obj)) {
|
24
|
+
$($(action_obj).closest('.inkwell_multi_selector')).trigger(this.state_changed);
|
25
|
+
}
|
26
|
+
}
|
27
|
+
},
|
28
|
+
|
29
|
+
has_changes: function (action_obj) {
|
30
|
+
result = ($(action_obj.parent().children('.current_state')[0]).children().text() != this.current_state);
|
31
|
+
current_state = null;
|
32
|
+
return result;
|
33
|
+
},
|
34
|
+
|
35
|
+
uncheck_upper_checkboxes: function (next_parent, state_panel, selector_name) {
|
36
|
+
var checkboxes = $(next_parent).children('.checked.checkbox_with_label');
|
37
|
+
if (checkboxes.length == 0) return;
|
38
|
+
$(checkboxes).each(function () {
|
39
|
+
$(state_panel).children('#inkwell_' + selector_name + '_state_' + inkwell_multi_selector.get_id_from_attr_id($(this).attr('id'))).remove();
|
40
|
+
});
|
41
|
+
$(checkboxes).removeClass('checked');
|
42
|
+
|
43
|
+
if (next_parent.hasClass('nested')) {
|
44
|
+
var same_level_divs = next_parent.parent().children('.nested');
|
45
|
+
$(same_level_divs).each(function () {
|
46
|
+
var checked_checkbox = $(this).children('.checked');
|
47
|
+
if (checked_checkbox.length != 0) {
|
48
|
+
var id = inkwell_multi_selector.get_id_from_attr_id($(checked_checkbox).attr('id'));
|
49
|
+
inkwell_multi_selector.add_state(state_panel, selector_name, id, checked_checkbox.text());
|
50
|
+
}
|
51
|
+
|
52
|
+
});
|
53
|
+
}
|
54
|
+
|
55
|
+
inkwell_multi_selector.uncheck_upper_checkboxes(next_parent.parent(), state_panel, selector_name);
|
56
|
+
},
|
57
|
+
|
58
|
+
uncheck_tree: function (checkbox) {
|
59
|
+
checkbox.parent().find('.checked').removeClass('checked');
|
60
|
+
},
|
61
|
+
|
62
|
+
action_click_handler: function (action, event) {
|
63
|
+
if ($(event.target).hasClass('dropdown') || $(event.target).closest('.inkwell_multi_selector .dropdown').length != 0) return;
|
64
|
+
inkwell_multi_selector.popup_shown ?
|
65
|
+
inkwell_multi_selector.hide_popup(action) :
|
66
|
+
inkwell_multi_selector.show_popup(action);
|
67
|
+
},
|
68
|
+
|
69
|
+
get_children_checkboxes: function (checkbox, all_levels) {
|
70
|
+
var result = [];
|
71
|
+
var child_divs = checkbox.parent().children('.nested');
|
72
|
+
child_divs.each(function () {
|
73
|
+
if (all_levels) result = $.merge(result, $(this).find('.checkbox_with_label'))
|
74
|
+
else result.push($(this).children('.checkbox_with_label')[0]);
|
75
|
+
});
|
76
|
+
return result;
|
77
|
+
},
|
78
|
+
|
79
|
+
uncheck_checkbox: function (checkbox) {
|
80
|
+
var selector = checkbox.closest('.inkwell_multi_selector');
|
81
|
+
var state_panel = selector.children('.current_state')[0];
|
82
|
+
var selector_name = inkwell_multi_selector.get_selector_name(selector);
|
83
|
+
|
84
|
+
$(checkbox).removeClass('checked');
|
85
|
+
inkwell_multi_selector.change_state_on_uncheck($(checkbox), state_panel, selector_name);
|
86
|
+
inkwell_multi_selector.uncheck_upper_checkboxes($(checkbox).parents(':eq(1)'), state_panel, selector_name);
|
87
|
+
},
|
88
|
+
|
89
|
+
add_state: function (state_panel, selector_name, id, text) {
|
90
|
+
$(state_panel).append(' <span id="inkwell_' + selector_name + '_state_' + id + '">' + text + '</span>');
|
91
|
+
},
|
92
|
+
|
93
|
+
change_state_on_uncheck: function (checkbox, state_panel, selector_name) {
|
94
|
+
var id = inkwell_multi_selector.get_id_from_attr_id(checkbox.attr('id'));
|
95
|
+
|
96
|
+
$(state_panel).children('#inkwell_' + selector_name + '_state_' + id).remove();
|
97
|
+
|
98
|
+
var child_checkboxes = inkwell_multi_selector.get_children_checkboxes(checkbox, false);
|
99
|
+
$(child_checkboxes).each(function () {
|
100
|
+
$(state_panel).append(' <span id="inkwell_' + selector_name + '_state_' + inkwell_multi_selector.get_id_from_attr_id($(this).attr('id')) + '">' + $(this).text() + '</span>');
|
101
|
+
});
|
102
|
+
|
103
|
+
var same_level_divs = checkbox.parents(':eq(1)').children('.nested');
|
104
|
+
$(same_level_divs).each(function () {
|
105
|
+
var checked_checkbox = $(this).children('.checked');
|
106
|
+
if (checked_checkbox.length != 0) {
|
107
|
+
var id = inkwell_multi_selector.get_id_from_attr_id($(checked_checkbox).attr('id'));
|
108
|
+
inkwell_multi_selector.add_state(state_panel, selector_name, id, checked_checkbox.text());
|
109
|
+
}
|
110
|
+
|
111
|
+
});
|
112
|
+
},
|
113
|
+
|
114
|
+
top_checked_checkboxes_ids: function (selector) {
|
115
|
+
var result = [];
|
116
|
+
selector.children('.current_state').children('span').each(function () {
|
117
|
+
var splitted_id = $(this).attr('id').split('_');
|
118
|
+
result.push(splitted_id[splitted_id.length - 1]);
|
119
|
+
});
|
120
|
+
return result;
|
121
|
+
},
|
122
|
+
|
123
|
+
is_all_checked: function (selector) {
|
124
|
+
var first_level_divs = selector.find('.dropdown').children('div');
|
125
|
+
var result = true;
|
126
|
+
first_level_divs.each(function () {
|
127
|
+
if (!result) return;
|
128
|
+
if (!$(this).children('.checkbox_with_label').hasClass('checked')) {
|
129
|
+
result = false;
|
130
|
+
}
|
131
|
+
});
|
132
|
+
return result;
|
133
|
+
},
|
134
|
+
|
135
|
+
change_state_on_check: function (checkbox) {
|
136
|
+
var selector = checkbox.closest('.inkwell_multi_selector');
|
137
|
+
var state_panel = selector.children('.current_state')[0];
|
138
|
+
var selector_name = inkwell_multi_selector.get_selector_name(selector);
|
139
|
+
|
140
|
+
var child_checkboxes = inkwell_multi_selector.get_children_checkboxes(checkbox, true);
|
141
|
+
$(child_checkboxes).each(function () {
|
142
|
+
$(state_panel).children('#inkwell_' + selector_name + '_state_' + inkwell_multi_selector.get_id_from_attr_id($(this).attr('id'))).remove();
|
143
|
+
});
|
144
|
+
|
145
|
+
var id = inkwell_multi_selector.get_id_from_attr_id(checkbox.attr('id'));
|
146
|
+
$(state_panel).append(' <span id="inkwell_' + selector_name + '_state_' + id + '">' + checkbox.text() + '</span>');
|
147
|
+
},
|
148
|
+
|
149
|
+
get_id_from_attr_id: function (attr_id) {
|
150
|
+
var splitted_id = attr_id.split('_');
|
151
|
+
return splitted_id[splitted_id.length - 1];
|
152
|
+
},
|
153
|
+
|
154
|
+
get_selector_name: function (selector) {
|
155
|
+
return selector.attr('id').replace('inkwell_', '');
|
156
|
+
},
|
157
|
+
|
158
|
+
state_click_handler: function (state_item) {
|
159
|
+
this.current_state = $(state_item).parent().children().text();
|
160
|
+
var selector = state_item.closest('.inkwell_multi_selector');
|
161
|
+
var dropdown = selector.find('.dropdown');
|
162
|
+
var selector_name = inkwell_multi_selector.get_selector_name(selector);
|
163
|
+
|
164
|
+
var state_items = state_item.parent().children('span');
|
165
|
+
$(state_items).each(function () {
|
166
|
+
var attr_id = $(this).attr('id');
|
167
|
+
if (attr_id != state_item.attr('id')) {
|
168
|
+
var id = inkwell_multi_selector.get_id_from_attr_id(attr_id);
|
169
|
+
var checkbox = dropdown.find('#inkwell_' + selector_name + '_checkbox_' + id);
|
170
|
+
inkwell_multi_selector.uncheck_tree(checkbox);
|
171
|
+
$(this).remove();
|
172
|
+
}
|
173
|
+
});
|
174
|
+
|
175
|
+
if ($(state_item).parent().children().text() != this.current_state) {
|
176
|
+
|
177
|
+
$(selector).trigger(this.state_changed);
|
178
|
+
}
|
179
|
+
current_state = null;
|
180
|
+
}
|
181
|
+
|
182
|
+
};
|
183
|
+
|
184
|
+
$(document).ready(function () {
|
185
|
+
$('.inkwell_timelines').on('click', '.inkwell_multi_selector .action', function (event) {
|
186
|
+
inkwell_multi_selector.action_click_handler($(this), event);
|
187
|
+
});
|
188
|
+
|
189
|
+
$(document).on('click', function (event) {
|
190
|
+
if (!inkwell_multi_selector.popup_shown) return;
|
191
|
+
if ($(event.target).closest('.inkwell_multi_selector .action').length == 0) inkwell_multi_selector.hide_popup();
|
192
|
+
});
|
193
|
+
|
194
|
+
$('.inkwell_timelines').on('click', '.inkwell_multi_selector .checkbox_with_label', function () {
|
195
|
+
if ($(this).hasClass('checked')) {
|
196
|
+
inkwell_multi_selector.uncheck_checkbox($(this));
|
197
|
+
} else {
|
198
|
+
inkwell_multi_selector.change_state_on_check($(this));
|
199
|
+
$(this).parent().find('.checkbox_with_label').addClass('checked');
|
200
|
+
}
|
201
|
+
});
|
202
|
+
|
203
|
+
$('.inkwell_timelines').on('click', '.inkwell_multi_selector .collapsed', function () {
|
204
|
+
$(this).removeClass('collapsed').addClass('expanded');
|
205
|
+
$(this).parent().children('.nested').show();
|
206
|
+
});
|
207
|
+
|
208
|
+
$('.inkwell_timelines').on('click', '.inkwell_multi_selector .expanded', function () {
|
209
|
+
$(this).removeClass('expanded').addClass('collapsed');
|
210
|
+
$(this).parent().children('.nested').hide();
|
211
|
+
});
|
212
|
+
|
213
|
+
$('.inkwell_timelines').on('click', '.inkwell_multi_selector .current_state span', function() {
|
214
|
+
inkwell_multi_selector.state_click_handler($(this));
|
215
|
+
});
|
216
|
+
});
|