sortable_tree_rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0373aa113f25bc22e733601b2a8f8dd20eeb18e6
4
+ data.tar.gz: 7bafb1232ef6f952f5711bd25a547ceb56b65445
5
+ SHA512:
6
+ metadata.gz: 3bb39be2172073da11f3a66dfa5f279be979b2572d7e43207b0b8da7dc8897784249330ec28adb8b361befe23655d474ad89b2683162126e560390f6caf56ebc
7
+ data.tar.gz: 2e2f98fe24e840d9ca97d94db442c127f1562018c75b7c8b93857777911ebb3e03ae3c7af86eefb8f05ddee8b5f8ec2c52982fa5efb55ec1d5f4b900583f9136
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 Max Ivak
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/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'SortableTreeRails'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('readme.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+
21
+ load 'rails/tasks/statistics.rake'
22
+
23
+
24
+
25
+ Bundler::GemHelper.install_tasks
26
+
@@ -0,0 +1,53 @@
1
+ require 'active_support/concern'
2
+
3
+ module SortableTreeController
4
+ module Sort
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ helper SortableTreeHelper
9
+ end
10
+
11
+ module ClassMethods
12
+
13
+ def sortable_tree(class_name, options = {})
14
+ define_method("sort") do
15
+ resource_class = class_name.to_s.camelize.constantize
16
+
17
+ # options
18
+ options[:tree] = true
19
+ options[:sorting_attribute] ||= 'pos'
20
+ options[:parent_method] ||= 'parent'
21
+
22
+ records = params[:cat].inject({}) do |res, (resource, parent_resource)|
23
+ res[resource_class.find(resource)] = resource_class.find(parent_resource) rescue nil
24
+ res
25
+ end
26
+
27
+ errors = []
28
+ ActiveRecord::Base.transaction do
29
+ records.each_with_index do |(record, parent_record), position|
30
+ record.send "#{options[:sorting_attribute]}=", position
31
+ if options[:tree]
32
+ record.send "#{options[:parent_method]}=", parent_record
33
+ end
34
+ errors << {record.id => record.errors} if !record.save
35
+ end
36
+ end
37
+
38
+ #
39
+ if errors.empty?
40
+ head 200
41
+ else
42
+ render json: errors, status: 422
43
+ end
44
+
45
+
46
+ end
47
+ end
48
+ end
49
+
50
+
51
+
52
+ end
53
+ end
@@ -0,0 +1,37 @@
1
+ module SortableTreeHelper
2
+
3
+ def render_sortable_tree(items, opts={})
4
+ render :partial=>'sortable_tree/sortable_tree', locals: {items: items, options: opts}
5
+ end
6
+
7
+
8
+ def sortable_tree_render_nested_groups(groups, opts={})
9
+ content_tag(:ol) do
10
+ groups.map do |item, sub_groups|
11
+ content_tag(:li, {id: "cat_#{item.id}"} ) do
12
+ #(item.title + sortable_tree_render_nested_groups(sub_groups, opts)).html_safe
13
+
14
+ s = content_tag(:div, {class: 'item'}) do
15
+ (
16
+ #'<div class="cell left"><i class="handle"></i></div>'\
17
+ '<h3 class="cell left">'+item.send(opts[:name_method] || :name)+'</h3>'\
18
+ '<div class="cell right controls">'+sortable_tree_build_actions(item, opts)+'</div>'
19
+ ).html_safe
20
+ end
21
+ (s + sortable_tree_render_nested_groups(sub_groups, opts)).html_safe
22
+ end
23
+
24
+ end.join.html_safe
25
+ end
26
+ end
27
+
28
+ def sortable_tree_build_actions(item, opts={})
29
+ partial = opts[:controls_partial] || nil
30
+
31
+ if partial
32
+ render :partial=>partial, locals: {item: item, options: opts}
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -0,0 +1,75 @@
1
+ .sortable_tree_wrapper
2
+ %ol.sortable_tree{data: {'sortable-url' => options[:sort_url]} }
3
+ - items.each do |root, children|
4
+ %li{id: "cat_#{root.id}"}
5
+ .item
6
+ /.cell.left
7
+ / %i.handle
8
+ %h4.cell.left
9
+ =root.send(options[:name_method] || :name)
10
+ .cell.right.controls
11
+ - if options[:controls_partial]
12
+ = render options[:controls_partial], item: root
13
+
14
+ = sortable_tree_render_nested_groups(children, options.merge({list_tag: :ol, element_class: 'item'}))
15
+
16
+
17
+
18
+ :javascript
19
+ $(document).ready(function(){
20
+ $('.sortable_tree').nestedSortable({
21
+ forceHelperSizeType: true,
22
+ errorClass: 'cantdoit',
23
+ disableNesting: 'cantdoit',
24
+ handle: '> .item',
25
+ helper: 'clone',
26
+ listType: 'ol',
27
+ items: 'li',
28
+ opacity: 0.6,
29
+ placeholder: 'placeholder',
30
+ revert: 250,
31
+ maxLevels: #{options[:max_levels] || 5},
32
+ //tabSize: 20,
33
+ // protectRoot: $(this).data('protect-root'),
34
+
35
+ // prevent drag flickers
36
+ tolerance: 'pointer',
37
+ toleranceElement: '> div',
38
+ isTree: true,
39
+ startCollapsed: false,
40
+ //startCollapsed: $(this).data("start-collapsed"),
41
+
42
+ relocate: function(){
43
+ //$(this).nestedSortable("disable");
44
+ var data = $(this).nestedSortable("serialize");
45
+ var url = $(this).data("sortable-url");
46
+
47
+ // update on server
48
+ $.ajax({
49
+ url: url,
50
+ type: "post",
51
+ data: data
52
+ }).always(function(){
53
+ //$(this).nestedSortable("enable");
54
+
55
+ $(this).find('.item').each(function(index){
56
+ if (index % 2){
57
+ $(this).removeClass('odd').addClass('even');
58
+ }else{
59
+ $(this).removeClass('even').addClass('odd');
60
+ }
61
+ });
62
+
63
+ }).done(function(data){
64
+
65
+ }).fail(function(jqXHR, textStatus){
66
+
67
+ });
68
+
69
+
70
+ //$(this).nestedSortable("enable");
71
+ }
72
+ }); // nested tree
73
+ }); // document.ready
74
+
75
+
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end