jquery_sortable_tree 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (328) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.md +319 -0
  4. data/Rakefile +36 -0
  5. data/app/assets/images/iconza/icons/add.png +0 -0
  6. data/app/assets/images/iconza/icons/delete.png +0 -0
  7. data/app/assets/images/iconza/icons/edit.png +0 -0
  8. data/app/assets/images/iconza/icons/move.png +0 -0
  9. data/app/assets/images/iconza/icons/red_add.png +0 -0
  10. data/app/assets/images/iconza/icons/red_delete.png +0 -0
  11. data/app/assets/images/iconza/icons/red_edit.png +0 -0
  12. data/app/assets/images/iconza/icons/red_move.png +0 -0
  13. data/app/assets/javascripts/expandable_tree/expandable_tree.js.coffee +104 -0
  14. data/app/assets/javascripts/expandable_tree/hashchange.js.coffee +33 -0
  15. data/app/assets/javascripts/expandable_tree/initializer.js +6 -0
  16. data/app/assets/javascripts/expandable_tree/jquery.cookie.coffee +68 -0
  17. data/app/assets/javascripts/expandable_tree/restorable.js.coffee +125 -0
  18. data/app/assets/javascripts/nested_sortable/inline_operations.js.coffee +56 -0
  19. data/app/assets/javascripts/nested_sortable/jquery.ui.nestedSortable.js +358 -0
  20. data/app/assets/javascripts/render_tree_helper.js.coffee +82 -0
  21. data/app/assets/javascripts/sortable_tree/initializer.js +3 -0
  22. data/app/assets/javascripts/sortable_tree/sortable_tree.js.coffee +60 -0
  23. data/app/assets/stylesheets/expandable_tree.css.scss +26 -0
  24. data/app/assets/stylesheets/nested_options.css.scss +25 -0
  25. data/app/assets/stylesheets/sortable_tree.css.scss +108 -0
  26. data/app/assets/stylesheets/tree.css.scss +35 -0
  27. data/app/controllers/jquery_sortable_tree_controller.rb +93 -0
  28. data/app/helpers/jquery_sortable_tree_helper/render_expandable_tree_helper.rb +27 -0
  29. data/app/helpers/jquery_sortable_tree_helper/render_indented_options_helper.rb +37 -0
  30. data/app/helpers/jquery_sortable_tree_helper/render_nested_options_helper.rb +29 -0
  31. data/app/helpers/jquery_sortable_tree_helper/render_sortable_tree_helper.rb +65 -0
  32. data/app/helpers/jquery_sortable_tree_helper/render_tree_helper.rb +23 -0
  33. data/app/helpers/jquery_sortable_tree_helper.rb +142 -0
  34. data/app/inputs/indented_collection_select_input.rb +12 -0
  35. data/lib/fake.example +44 -0
  36. data/lib/generators/jquery_sortable_tree/views_generator.rb +56 -0
  37. data/lib/jquery_sortable_tree/engine.rb +6 -0
  38. data/lib/jquery_sortable_tree/version.rb +3 -0
  39. data/lib/jquery_sortable_tree.rb +13 -0
  40. data/spec/dummy_app/Gemfile +38 -0
  41. data/spec/dummy_app/Gemfile.lock +206 -0
  42. data/spec/dummy_app/README.md +48 -0
  43. data/spec/dummy_app/Rakefile +7 -0
  44. data/spec/dummy_app/_test/fixtures/admin/pages.yml +7 -0
  45. data/spec/dummy_app/_test/fixtures/article_categories.yml +9 -0
  46. data/spec/dummy_app/_test/fixtures/comments.yml +13 -0
  47. data/spec/dummy_app/_test/fixtures/inventory/categories.yml +9 -0
  48. data/spec/dummy_app/_test/functional/inventory/category_controller_test.rb +14 -0
  49. data/spec/dummy_app/_test/performance/browsing_test.rb +12 -0
  50. data/spec/dummy_app/_test/test_helper.rb +13 -0
  51. data/spec/dummy_app/_test/unit/admin/page_test.rb +7 -0
  52. data/spec/dummy_app/_test/unit/article_category_test.rb +7 -0
  53. data/spec/dummy_app/_test/unit/comment_test.rb +7 -0
  54. data/spec/dummy_app/_test/unit/helpers/inventory/category_helper_test.rb +4 -0
  55. data/spec/dummy_app/_test/unit/inventory/category_test.rb +7 -0
  56. data/spec/dummy_app/app/assets/images/rails.png +0 -0
  57. data/spec/dummy_app/app/assets/javascripts/application.js +11 -0
  58. data/spec/dummy_app/app/assets/stylesheets/application.css +11 -0
  59. data/spec/dummy_app/app/controllers/admin/pages_controller.rb +35 -0
  60. data/spec/dummy_app/app/controllers/application_controller.rb +3 -0
  61. data/spec/dummy_app/app/controllers/article_categories_controller.rb +11 -0
  62. data/spec/dummy_app/app/controllers/inventory/categories_controller.rb +15 -0
  63. data/spec/dummy_app/app/controllers/pages_controller.rb +30 -0
  64. data/spec/dummy_app/app/controllers/welcome_controller.rb +3 -0
  65. data/spec/dummy_app/app/models/admin/page.rb +4 -0
  66. data/spec/dummy_app/app/models/admin.rb +5 -0
  67. data/spec/dummy_app/app/models/article_category.rb +4 -0
  68. data/spec/dummy_app/app/models/inventory/category.rb +4 -0
  69. data/spec/dummy_app/app/models/inventory.rb +5 -0
  70. data/spec/dummy_app/app/models/page.rb +4 -0
  71. data/spec/dummy_app/app/views/admin/pages/indented_options.html.haml +3 -0
  72. data/spec/dummy_app/app/views/admin/pages/index.html.haml +8 -0
  73. data/spec/dummy_app/app/views/admin/pages/manage.html.haml +3 -0
  74. data/spec/dummy_app/app/views/admin/pages/namespaced_link.html.haml +3 -0
  75. data/spec/dummy_app/app/views/admin/pages/nested_options.html.haml +3 -0
  76. data/spec/dummy_app/app/views/admin/pages/node_manage.html.haml +12 -0
  77. data/spec/dummy_app/app/views/article_categories/index.html.haml +3 -0
  78. data/spec/dummy_app/app/views/article_categories/manage.html.haml +4 -0
  79. data/spec/dummy_app/app/views/inventory/categories/index.html.haml +3 -0
  80. data/spec/dummy_app/app/views/inventory/categories/manage.html.haml +4 -0
  81. data/spec/dummy_app/app/views/layouts/application.html.erb +18 -0
  82. data/spec/dummy_app/app/views/pages/expand.html.haml +8 -0
  83. data/spec/dummy_app/app/views/pages/expand_node.html.haml +1 -0
  84. data/spec/dummy_app/app/views/pages/indented_options.html.haml +3 -0
  85. data/spec/dummy_app/app/views/pages/index.html.haml +3 -0
  86. data/spec/dummy_app/app/views/pages/manage.html.haml +7 -0
  87. data/spec/dummy_app/app/views/pages/nested_options.html.haml +3 -0
  88. data/spec/dummy_app/app/views/welcome/index.html.haml +42 -0
  89. data/spec/dummy_app/config/application.rb +48 -0
  90. data/spec/dummy_app/config/boot.rb +6 -0
  91. data/spec/dummy_app/config/database.yml +7 -0
  92. data/spec/dummy_app/config/database.yml.example +7 -0
  93. data/spec/dummy_app/config/environment.rb +5 -0
  94. data/spec/dummy_app/config/environments/development.rb +30 -0
  95. data/spec/dummy_app/config/environments/production.rb +61 -0
  96. data/spec/dummy_app/config/environments/test.rb +42 -0
  97. data/spec/dummy_app/config/initializers/backtrace_silencers.rb +7 -0
  98. data/spec/dummy_app/config/initializers/inflections.rb +10 -0
  99. data/spec/dummy_app/config/initializers/mime_types.rb +5 -0
  100. data/spec/dummy_app/config/initializers/secret_token.rb +7 -0
  101. data/spec/dummy_app/config/initializers/session_store.rb +8 -0
  102. data/spec/dummy_app/config/initializers/wrap_parameters.rb +14 -0
  103. data/spec/dummy_app/config/locales/en.yml +28 -0
  104. data/spec/dummy_app/config/routes.rb +53 -0
  105. data/spec/dummy_app/config.ru +4 -0
  106. data/spec/dummy_app/db/development.db +0 -0
  107. data/spec/dummy_app/db/migrate/20120211053457_create_pages.rb +16 -0
  108. data/spec/dummy_app/db/migrate/20120503173258_create_article_categories.rb +16 -0
  109. data/spec/dummy_app/db/migrate/20120508093823_create_inventory_categories.rb +16 -0
  110. data/spec/dummy_app/db/migrate/20130128160328_create_admin_pages.rb +16 -0
  111. data/spec/dummy_app/db/schema.rb +64 -0
  112. data/spec/dummy_app/db/seeds.rb +97 -0
  113. data/spec/dummy_app/db/test.db +0 -0
  114. data/spec/dummy_app/doc/README_FOR_APP +2 -0
  115. data/spec/dummy_app/lib/tasks/db_bootstrap.rake +16 -0
  116. data/spec/dummy_app/log/development.log +22714 -0
  117. data/spec/dummy_app/public/404.html +26 -0
  118. data/spec/dummy_app/public/422.html +26 -0
  119. data/spec/dummy_app/public/500.html +26 -0
  120. data/spec/dummy_app/public/favicon.ico +0 -0
  121. data/spec/dummy_app/public/robots.txt +5 -0
  122. data/spec/dummy_app/script/rails +6 -0
  123. data/spec/dummy_app/spec/build_tree_helper.rb +39 -0
  124. data/spec/dummy_app/spec/spec_helper.rb +52 -0
  125. data/spec/dummy_app/spec/views/pages/index.html.haml_spec.rb +48 -0
  126. data/spec/dummy_app/tmp/cache/assets/development/sass/8ecb1409c36a90649b49ac975da6493b50db6d95/expandable_tree.css.scssc +0 -0
  127. data/spec/dummy_app/tmp/cache/assets/development/sass/8ecb1409c36a90649b49ac975da6493b50db6d95/nested_options.css.scssc +0 -0
  128. data/spec/dummy_app/tmp/cache/assets/development/sass/8ecb1409c36a90649b49ac975da6493b50db6d95/sortable_tree.css.scssc +0 -0
  129. data/spec/dummy_app/tmp/cache/assets/development/sass/8ecb1409c36a90649b49ac975da6493b50db6d95/tree.css.scssc +0 -0
  130. data/spec/dummy_app/tmp/cache/assets/development/sprockets/058d9080443081a540c61e79945ebf47 +0 -0
  131. data/spec/dummy_app/tmp/cache/assets/development/sprockets/06512a74da586fbbce22e1cd023f5f9b +0 -0
  132. data/spec/dummy_app/tmp/cache/assets/development/sprockets/06f9ffc86fda6ef4279cabf09f68e631 +0 -0
  133. data/spec/dummy_app/tmp/cache/assets/development/sprockets/0702872e43cbcc4c2b6d097f7fe035e7 +0 -0
  134. data/spec/dummy_app/tmp/cache/assets/development/sprockets/07400ad691b6b3bbcf10ee74e64d72b7 +0 -0
  135. data/spec/dummy_app/tmp/cache/assets/development/sprockets/0a382d7e102e254c52006bed6975001d +0 -0
  136. data/spec/dummy_app/tmp/cache/assets/development/sprockets/0a8a33aec09977105c0190f6b8c2ca49 +0 -0
  137. data/spec/dummy_app/tmp/cache/assets/development/sprockets/0b2e7c9a5645a67e6af72feeaa70b633 +0 -0
  138. data/spec/dummy_app/tmp/cache/assets/development/sprockets/0c5e7aa7ad8e39ced2e25d911b060c3a +0 -0
  139. data/spec/dummy_app/tmp/cache/assets/development/sprockets/0fc4a5842f45f40d2e1283df0025ac7e +0 -0
  140. data/spec/dummy_app/tmp/cache/assets/development/sprockets/12eb4832c22cd32076db3d3eddcd941b +0 -0
  141. data/spec/dummy_app/tmp/cache/assets/development/sprockets/13d999d14a434a925372c43c3633f355 +0 -0
  142. data/spec/dummy_app/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  143. data/spec/dummy_app/tmp/cache/assets/development/sprockets/14805e3ed08782f4b821fe6cfd03d911 +0 -0
  144. data/spec/dummy_app/tmp/cache/assets/development/sprockets/15cc819db1fd73a5d6ccd95fba030668 +0 -0
  145. data/spec/dummy_app/tmp/cache/assets/development/sprockets/1607bba44953c4434330d20d0cd747f4 +0 -0
  146. data/spec/dummy_app/tmp/cache/assets/development/sprockets/16b9e0f8dc1fdd8bea7b606f065d205d +0 -0
  147. data/spec/dummy_app/tmp/cache/assets/development/sprockets/1a780b90bf4d532e88e6943e93f18320 +0 -0
  148. data/spec/dummy_app/tmp/cache/assets/development/sprockets/1e445aefca5bc750ef4f584ec1dc0849 +0 -0
  149. data/spec/dummy_app/tmp/cache/assets/development/sprockets/1e9c5d8fa6de36416732b4eb490ceb6f +0 -0
  150. data/spec/dummy_app/tmp/cache/assets/development/sprockets/1ea633756c6cc95716a7887e44f88da7 +0 -0
  151. data/spec/dummy_app/tmp/cache/assets/development/sprockets/1ece2c45f188a29a36b208442154f8a2 +0 -0
  152. data/spec/dummy_app/tmp/cache/assets/development/sprockets/2172c90088dc36adff9ec10b3384286e +0 -0
  153. data/spec/dummy_app/tmp/cache/assets/development/sprockets/2489731b3ac988935fe92593f0f2edbf +0 -0
  154. data/spec/dummy_app/tmp/cache/assets/development/sprockets/27c712c397ece8a28de4ff2044a3f722 +0 -0
  155. data/spec/dummy_app/tmp/cache/assets/development/sprockets/28eefd9e9c7ea2e1414cd10a6d184ae5 +0 -0
  156. data/spec/dummy_app/tmp/cache/assets/development/sprockets/2a013e71f11699ea897968c03d3f4355 +0 -0
  157. data/spec/dummy_app/tmp/cache/assets/development/sprockets/2c4f283baa7b297e503fe2d75f959b06 +0 -0
  158. data/spec/dummy_app/tmp/cache/assets/development/sprockets/2cf86cf22c1bd9a69271904cb4a1c131 +0 -0
  159. data/spec/dummy_app/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  160. data/spec/dummy_app/tmp/cache/assets/development/sprockets/2fa38257718e8b4641d97f10b43d1ac7 +0 -0
  161. data/spec/dummy_app/tmp/cache/assets/development/sprockets/2fd038eaf9bbdb2d1f4fe4afd3aeb654 +0 -0
  162. data/spec/dummy_app/tmp/cache/assets/development/sprockets/303d5268aec48d5bd29ea616e15ea1cd +0 -0
  163. data/spec/dummy_app/tmp/cache/assets/development/sprockets/309e5bc3a9891c7dfcb01887b7c973a5 +0 -0
  164. data/spec/dummy_app/tmp/cache/assets/development/sprockets/30f138394dc8bad04a7ad6c19f3ee922 +0 -0
  165. data/spec/dummy_app/tmp/cache/assets/development/sprockets/31036ef469da85883b40b6b4ee37e61e +0 -0
  166. data/spec/dummy_app/tmp/cache/assets/development/sprockets/31a9b7e7b828d0633af58b75c59273de +0 -0
  167. data/spec/dummy_app/tmp/cache/assets/development/sprockets/332ad2cb8debd7079dda31bd72d43806 +0 -0
  168. data/spec/dummy_app/tmp/cache/assets/development/sprockets/344185411a898184d8eaa3f96536e50f +0 -0
  169. data/spec/dummy_app/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  170. data/spec/dummy_app/tmp/cache/assets/development/sprockets/364e7109a425ab206d5f8881b5d37cfc +0 -0
  171. data/spec/dummy_app/tmp/cache/assets/development/sprockets/37dd73a179070963cb766a24703a58a1 +0 -0
  172. data/spec/dummy_app/tmp/cache/assets/development/sprockets/39c9026282a865c56fac8e234419eb61 +0 -0
  173. data/spec/dummy_app/tmp/cache/assets/development/sprockets/3a592f975983e33afd63283ecac1de80 +0 -0
  174. data/spec/dummy_app/tmp/cache/assets/development/sprockets/3a7a7c1950ba3ca0968d0c8ffc9b8635 +0 -0
  175. data/spec/dummy_app/tmp/cache/assets/development/sprockets/3ab09536f24f9fbe56a56a012bf266d7 +0 -0
  176. data/spec/dummy_app/tmp/cache/assets/development/sprockets/3b22caac59de2c2af20c0e8bf86cf015 +0 -0
  177. data/spec/dummy_app/tmp/cache/assets/development/sprockets/3dbf5c413607e86fa3ff1f931887217e +0 -0
  178. data/spec/dummy_app/tmp/cache/assets/development/sprockets/4063ac4ee22e83471de121940c9a9689 +0 -0
  179. data/spec/dummy_app/tmp/cache/assets/development/sprockets/425aa438199f939cf930519e27539355 +0 -0
  180. data/spec/dummy_app/tmp/cache/assets/development/sprockets/43485146d4435be69b94512f4871b48a +0 -0
  181. data/spec/dummy_app/tmp/cache/assets/development/sprockets/43c3c0bfd40d48fa470d6369b70c4ed5 +0 -0
  182. data/spec/dummy_app/tmp/cache/assets/development/sprockets/44290e987cc9e134606381c2ed4c3e19 +0 -0
  183. data/spec/dummy_app/tmp/cache/assets/development/sprockets/450d1a68e0d88f6f859522ccf0e7fa75 +0 -0
  184. data/spec/dummy_app/tmp/cache/assets/development/sprockets/46ff8eb0f50fc17b55b2e65a1a9a1832 +0 -0
  185. data/spec/dummy_app/tmp/cache/assets/development/sprockets/498d1a8d06e7b8bd347f41609dfe7dbc +0 -0
  186. data/spec/dummy_app/tmp/cache/assets/development/sprockets/4da7d8ac21ee8ee7cbdde2edd894cc4e +0 -0
  187. data/spec/dummy_app/tmp/cache/assets/development/sprockets/505027f29aa1c70c5425d19ea9fb77ce +0 -0
  188. data/spec/dummy_app/tmp/cache/assets/development/sprockets/5073b1f44a8a2ee95c4368fb2610360d +0 -0
  189. data/spec/dummy_app/tmp/cache/assets/development/sprockets/50b1ef23635589d50f9b31642903f67c +0 -0
  190. data/spec/dummy_app/tmp/cache/assets/development/sprockets/51663175018a723eb6432251c4ff2e2a +0 -0
  191. data/spec/dummy_app/tmp/cache/assets/development/sprockets/5287e92c354e3bafe071e5853eb65ced +0 -0
  192. data/spec/dummy_app/tmp/cache/assets/development/sprockets/52955fb6b1313a736917570386d038f7 +0 -0
  193. data/spec/dummy_app/tmp/cache/assets/development/sprockets/54603322364591c06b6250b0584ab27e +0 -0
  194. data/spec/dummy_app/tmp/cache/assets/development/sprockets/55d364519e6304a1d512d881ced67211 +0 -0
  195. data/spec/dummy_app/tmp/cache/assets/development/sprockets/56d487b917bb9ff84706849c66fee0c7 +0 -0
  196. data/spec/dummy_app/tmp/cache/assets/development/sprockets/59f72211dfd90317c1bc78a481ae189d +0 -0
  197. data/spec/dummy_app/tmp/cache/assets/development/sprockets/5c6b037458b3843da5366697c858985e +0 -0
  198. data/spec/dummy_app/tmp/cache/assets/development/sprockets/5e8f4ca85fe26be682d2e563f23f1f9e +0 -0
  199. data/spec/dummy_app/tmp/cache/assets/development/sprockets/5f6cb8d54ddfd855f5fbfb72a4aac107 +0 -0
  200. data/spec/dummy_app/tmp/cache/assets/development/sprockets/6016aac84581a1ff8e9503adf790f0eb +0 -0
  201. data/spec/dummy_app/tmp/cache/assets/development/sprockets/604f08938cbe197b663267d4ac623b3c +0 -0
  202. data/spec/dummy_app/tmp/cache/assets/development/sprockets/63703decf049effbdea24cb40c7d8feb +0 -0
  203. data/spec/dummy_app/tmp/cache/assets/development/sprockets/65a64732023d6edc64645f6d67ab6376 +0 -0
  204. data/spec/dummy_app/tmp/cache/assets/development/sprockets/67e64bdc647ff62357f616466875cc05 +0 -0
  205. data/spec/dummy_app/tmp/cache/assets/development/sprockets/685130c66086333bc60a3e13426e637d +0 -0
  206. data/spec/dummy_app/tmp/cache/assets/development/sprockets/68bc948f8a4f37f1b96c1ccef3501603 +0 -0
  207. data/spec/dummy_app/tmp/cache/assets/development/sprockets/68df326b958b409f9811f1aa1ae3df75 +0 -0
  208. data/spec/dummy_app/tmp/cache/assets/development/sprockets/693bc2b458236fe0f3db96348cb0d0dc +0 -0
  209. data/spec/dummy_app/tmp/cache/assets/development/sprockets/699daefc627fb5fde880b9a0791933b6 +0 -0
  210. data/spec/dummy_app/tmp/cache/assets/development/sprockets/6aba4f56935b86463d039d0849f8a4b4 +0 -0
  211. data/spec/dummy_app/tmp/cache/assets/development/sprockets/6ff566ad21a9b0caa51f55b63848d1d5 +0 -0
  212. data/spec/dummy_app/tmp/cache/assets/development/sprockets/729d2237d10c9e2170d23785478ca63f +0 -0
  213. data/spec/dummy_app/tmp/cache/assets/development/sprockets/76a8cd7f52d42a76574338632a5356d6 +0 -0
  214. data/spec/dummy_app/tmp/cache/assets/development/sprockets/779d045bffa46a9da91572f71bb4f33a +0 -0
  215. data/spec/dummy_app/tmp/cache/assets/development/sprockets/78762c001b9b200fa9963eee922b41d0 +0 -0
  216. data/spec/dummy_app/tmp/cache/assets/development/sprockets/7991e04eb66b191a868dbb38c761d2da +0 -0
  217. data/spec/dummy_app/tmp/cache/assets/development/sprockets/7af26b28f05d60534b847b073340b9d0 +0 -0
  218. data/spec/dummy_app/tmp/cache/assets/development/sprockets/7c3ec870c8e901cb6ca171c7345618c2 +0 -0
  219. data/spec/dummy_app/tmp/cache/assets/development/sprockets/7d5d91f945b7415354d7f6d3653e7d80 +0 -0
  220. data/spec/dummy_app/tmp/cache/assets/development/sprockets/7eecec59a10631fead107d7e8c265910 +0 -0
  221. data/spec/dummy_app/tmp/cache/assets/development/sprockets/8497b02b98b9d3a6e78388d6c1bab1f1 +0 -0
  222. data/spec/dummy_app/tmp/cache/assets/development/sprockets/858868dacf187de97fe2580f31d09dbe +0 -0
  223. data/spec/dummy_app/tmp/cache/assets/development/sprockets/859c3817c6f5b6d64e457ccd9a33d5a2 +0 -0
  224. data/spec/dummy_app/tmp/cache/assets/development/sprockets/86f13c507e9e995021b05371d252c33c +0 -0
  225. data/spec/dummy_app/tmp/cache/assets/development/sprockets/8717579ef5b551df9b2635f59120a0e1 +0 -0
  226. data/spec/dummy_app/tmp/cache/assets/development/sprockets/888dd6c485e0655b1ca9bfde716acdda +0 -0
  227. data/spec/dummy_app/tmp/cache/assets/development/sprockets/88b7acf651a9d0e1c9b3c8e6db719467 +0 -0
  228. data/spec/dummy_app/tmp/cache/assets/development/sprockets/88f65fc30613c8283f186e248253c020 +0 -0
  229. data/spec/dummy_app/tmp/cache/assets/development/sprockets/8a6aebb20a64dd2680834fa0d28bf832 +0 -0
  230. data/spec/dummy_app/tmp/cache/assets/development/sprockets/8a7d0e83eaa7cfb2826796e2c1a81a65 +0 -0
  231. data/spec/dummy_app/tmp/cache/assets/development/sprockets/902a894fafabac558abf12953428d975 +0 -0
  232. data/spec/dummy_app/tmp/cache/assets/development/sprockets/90c19158b0d4f03b467216c6f9b61af2 +0 -0
  233. data/spec/dummy_app/tmp/cache/assets/development/sprockets/91da1a8fa92fc4acdb6f8fb1658eff85 +0 -0
  234. data/spec/dummy_app/tmp/cache/assets/development/sprockets/958c546e8b56eecbfd2357ee9984f986 +0 -0
  235. data/spec/dummy_app/tmp/cache/assets/development/sprockets/977fe9c1da3ce7cbef3ec54cd7681b57 +0 -0
  236. data/spec/dummy_app/tmp/cache/assets/development/sprockets/98048e0cb396b79d4352a7d10737bc22 +0 -0
  237. data/spec/dummy_app/tmp/cache/assets/development/sprockets/9828e6214ad484fda452904b4591a6ba +0 -0
  238. data/spec/dummy_app/tmp/cache/assets/development/sprockets/9915a7d7fc327736e2852c02cf683916 +0 -0
  239. data/spec/dummy_app/tmp/cache/assets/development/sprockets/99dd18a65861aff71f60940f3f904dc4 +0 -0
  240. data/spec/dummy_app/tmp/cache/assets/development/sprockets/9b8b02558a49e17f6230fd1a84af03ac +0 -0
  241. data/spec/dummy_app/tmp/cache/assets/development/sprockets/9daf110b844179988cda473c3702cd36 +0 -0
  242. data/spec/dummy_app/tmp/cache/assets/development/sprockets/9e98d3ede9a4ae58ad176c09aac8784c +0 -0
  243. data/spec/dummy_app/tmp/cache/assets/development/sprockets/9f2acc37eeea8b15228a38ecbcfe12ec +0 -0
  244. data/spec/dummy_app/tmp/cache/assets/development/sprockets/9f304eccc018ffb73d8dbdea67ff4c45 +0 -0
  245. data/spec/dummy_app/tmp/cache/assets/development/sprockets/a0ac3dab292e1eb99d5e8a524e6dfded +0 -0
  246. data/spec/dummy_app/tmp/cache/assets/development/sprockets/a19531c0b551d0e8aaa386a2cba28621 +0 -0
  247. data/spec/dummy_app/tmp/cache/assets/development/sprockets/a1b5928996636a64ed28d5c815722fc0 +0 -0
  248. data/spec/dummy_app/tmp/cache/assets/development/sprockets/a2c39932df9ec8c9bcd8e1f4a84240dd +0 -0
  249. data/spec/dummy_app/tmp/cache/assets/development/sprockets/a2e4e33192daa77f118bde803b5f469e +0 -0
  250. data/spec/dummy_app/tmp/cache/assets/development/sprockets/a43272bdd86ec2506b047bc1e4ce8876 +0 -0
  251. data/spec/dummy_app/tmp/cache/assets/development/sprockets/a7e1c04200e6e4bda31455a74405ff27 +0 -0
  252. data/spec/dummy_app/tmp/cache/assets/development/sprockets/a971e4dcd80c8771557c6770de027db9 +0 -0
  253. data/spec/dummy_app/tmp/cache/assets/development/sprockets/aa295fd96f916013ffee63976fc76a95 +0 -0
  254. data/spec/dummy_app/tmp/cache/assets/development/sprockets/aa5ab09e4efff43a501273bba49aff5a +0 -0
  255. data/spec/dummy_app/tmp/cache/assets/development/sprockets/ab7de79e9f45ea0210ca722448a61ee6 +0 -0
  256. data/spec/dummy_app/tmp/cache/assets/development/sprockets/abc033045fbf49313622395790a41449 +0 -0
  257. data/spec/dummy_app/tmp/cache/assets/development/sprockets/ac5ba64ea91a44c78d859322e8007b51 +0 -0
  258. data/spec/dummy_app/tmp/cache/assets/development/sprockets/ae56fc628b3fcbc09e9d6bc9cfcfa47f +0 -0
  259. data/spec/dummy_app/tmp/cache/assets/development/sprockets/af312b037fcda8a7c4d4314bbb1294d6 +0 -0
  260. data/spec/dummy_app/tmp/cache/assets/development/sprockets/b0a443220285aa4214c99886f304be36 +0 -0
  261. data/spec/dummy_app/tmp/cache/assets/development/sprockets/b12fd4d4c75c5d4ecedeb33e9015d240 +0 -0
  262. data/spec/dummy_app/tmp/cache/assets/development/sprockets/b24f7fb90e26a052f58af7aec2887f99 +0 -0
  263. data/spec/dummy_app/tmp/cache/assets/development/sprockets/b31281285c049738a71f17d3bce0cb07 +0 -0
  264. data/spec/dummy_app/tmp/cache/assets/development/sprockets/b3ebffc5d529a910f098e186052959ec +0 -0
  265. data/spec/dummy_app/tmp/cache/assets/development/sprockets/b6767aa65b283214e52c1b488053348a +0 -0
  266. data/spec/dummy_app/tmp/cache/assets/development/sprockets/b76e4c022c5b8441b34d7fd884f01591 +0 -0
  267. data/spec/dummy_app/tmp/cache/assets/development/sprockets/b7832ccf4cb727dbb1db2fa906ba58ce +0 -0
  268. data/spec/dummy_app/tmp/cache/assets/development/sprockets/b7fda322633dec2bac36ebd075fca86b +0 -0
  269. data/spec/dummy_app/tmp/cache/assets/development/sprockets/b993ae256cdd45c1f983da2d611049a3 +0 -0
  270. data/spec/dummy_app/tmp/cache/assets/development/sprockets/badb668711397918483b38b6452a19ce +0 -0
  271. data/spec/dummy_app/tmp/cache/assets/development/sprockets/bc96c4fb801c05f926e1bc3fa935418b +0 -0
  272. data/spec/dummy_app/tmp/cache/assets/development/sprockets/bd574a8c5be676a00338f53b536d16c7 +0 -0
  273. data/spec/dummy_app/tmp/cache/assets/development/sprockets/bdff1b5babecc1dd5f99a5878c240298 +0 -0
  274. data/spec/dummy_app/tmp/cache/assets/development/sprockets/beebf50fccb9786a6b9c15060939e196 +0 -0
  275. data/spec/dummy_app/tmp/cache/assets/development/sprockets/c0ecb07d07862572d3e52a8b48245757 +0 -0
  276. data/spec/dummy_app/tmp/cache/assets/development/sprockets/c1d57e1af37bb3d7fec10b83b501c561 +0 -0
  277. data/spec/dummy_app/tmp/cache/assets/development/sprockets/c32f36794c5f61e47ff16beed6cd32ee +0 -0
  278. data/spec/dummy_app/tmp/cache/assets/development/sprockets/c546515632c00eb37eb345e92d604abc +0 -0
  279. data/spec/dummy_app/tmp/cache/assets/development/sprockets/c7383cde7ee415f0a343bfe658885afc +0 -0
  280. data/spec/dummy_app/tmp/cache/assets/development/sprockets/c93eebdbd34ccde24867d33a75ba23bb +0 -0
  281. data/spec/dummy_app/tmp/cache/assets/development/sprockets/cc343c6575f3d88e77e5d0c54208f131 +0 -0
  282. data/spec/dummy_app/tmp/cache/assets/development/sprockets/cc66ba8f2c55f0e0201e9c5d3fb9756a +0 -0
  283. data/spec/dummy_app/tmp/cache/assets/development/sprockets/cd0ab14140d01fee32d8cd011f558895 +0 -0
  284. data/spec/dummy_app/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  285. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d0182afb2a6b3793c9b793d174a32c52 +0 -0
  286. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d0ff728fdab90faf6864895c4388b9a3 +0 -0
  287. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d22147d54feb1d5083b1858b3f0ca9d4 +0 -0
  288. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d281f19fc3b6a6755f669021ba1f1e6c +0 -0
  289. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d383bce808d440db9243b6a766172489 +0 -0
  290. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d3bc3752c772eeb2e0b3c2918cc863a6 +0 -0
  291. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  292. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d7fb14951075b1ec677cc130302a26b2 +0 -0
  293. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d893535a31ef07ab97ed6965cb3f0fb5 +0 -0
  294. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d8e009b8040122f415eeab5ea2b48e58 +0 -0
  295. data/spec/dummy_app/tmp/cache/assets/development/sprockets/d99ca00bff5f10b356270d8c956f4012 +0 -0
  296. data/spec/dummy_app/tmp/cache/assets/development/sprockets/db193f817e5de1268f9e9397829aa188 +0 -0
  297. data/spec/dummy_app/tmp/cache/assets/development/sprockets/dd22a990e8e9fc359a59039954abc0c3 +0 -0
  298. data/spec/dummy_app/tmp/cache/assets/development/sprockets/dddcb7f44b3421803102a90cef903b2a +0 -0
  299. data/spec/dummy_app/tmp/cache/assets/development/sprockets/de89d996da9e70756b13c808c1db5251 +0 -0
  300. data/spec/dummy_app/tmp/cache/assets/development/sprockets/dea7e9cb07d7e5890a38c24eba35e55e +0 -0
  301. data/spec/dummy_app/tmp/cache/assets/development/sprockets/df2e404f81bab3f3b50423d7aa652844 +0 -0
  302. data/spec/dummy_app/tmp/cache/assets/development/sprockets/e076be05d795e33011e9165ce3565719 +0 -0
  303. data/spec/dummy_app/tmp/cache/assets/development/sprockets/e16add15b2c7174bd21c0d70d318f4fc +0 -0
  304. data/spec/dummy_app/tmp/cache/assets/development/sprockets/e2158064cf90553ca96435e06073bb60 +0 -0
  305. data/spec/dummy_app/tmp/cache/assets/development/sprockets/e4cef9cfcc9f94843f54b52b318f593c +0 -0
  306. data/spec/dummy_app/tmp/cache/assets/development/sprockets/e54d18d8cbe7b6ab25445a607c15674c +0 -0
  307. data/spec/dummy_app/tmp/cache/assets/development/sprockets/e5f6b1c85d1d4ec5a26284694ab8d660 +0 -0
  308. data/spec/dummy_app/tmp/cache/assets/development/sprockets/e7cc7fb019fd86a28d82c7f63d749ebe +0 -0
  309. data/spec/dummy_app/tmp/cache/assets/development/sprockets/e8b94e5699ca066cbff81d9ed6727dbf +0 -0
  310. data/spec/dummy_app/tmp/cache/assets/development/sprockets/e901ea625274dfd094b70154e09d58b2 +0 -0
  311. data/spec/dummy_app/tmp/cache/assets/development/sprockets/eb794751bdec36ee921a2fbebfb6c7e6 +0 -0
  312. data/spec/dummy_app/tmp/cache/assets/development/sprockets/eccc72c3ec8522b88d235892cd8f45f2 +0 -0
  313. data/spec/dummy_app/tmp/cache/assets/development/sprockets/f1365895382790389d013528129a140a +0 -0
  314. data/spec/dummy_app/tmp/cache/assets/development/sprockets/f27b5dad4fdaec1c4ede5f174b64de32 +0 -0
  315. data/spec/dummy_app/tmp/cache/assets/development/sprockets/f2c23c8157dd64d926ee77c4b955f6b6 +0 -0
  316. data/spec/dummy_app/tmp/cache/assets/development/sprockets/f3e483f413d3151c5849cbd83476ce0a +0 -0
  317. data/spec/dummy_app/tmp/cache/assets/development/sprockets/f76fdcf47a0b7ee91ca690326d152bee +0 -0
  318. data/spec/dummy_app/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  319. data/spec/dummy_app/tmp/cache/assets/development/sprockets/f903a7ee38dcd742dca81df64e11733e +0 -0
  320. data/spec/dummy_app/tmp/cache/assets/development/sprockets/f9295b3b0f4d6dc11fdffaa7e0d02f72 +0 -0
  321. data/spec/dummy_app/tmp/cache/assets/development/sprockets/fa12d1dad434ff516a64628a635c07c8 +0 -0
  322. data/spec/dummy_app/tmp/cache/assets/development/sprockets/fae07930e81fdd4084871f66e4634e8a +0 -0
  323. data/spec/dummy_app/tmp/cache/assets/development/sprockets/fc182fc9375dd4ba9b0e0039d71f0944 +0 -0
  324. data/spec/dummy_app/tmp/cache/assets/development/sprockets/fd5d00a09369cb7c59b53d72ca896828 +0 -0
  325. data/spec/dummy_app/tmp/cache/assets/development/sprockets/fdf1d8b5d1d7b6c5fe5e2f5b467812a3 +0 -0
  326. data/spec/dummy_app/tmp/cache/assets/development/sprockets/fef1622202b16661f9ae083c25eaa0cd +0 -0
  327. data/spec/dummy_app/tmp/cache/assets/development/sprockets/ff5a0e8ee643dae44f31640f626ce94a +0 -0
  328. metadata +726 -0
@@ -0,0 +1,26 @@
1
+ .sortable_tree{
2
+ &.expandable{
3
+ h4{
4
+ margin-left: 50px;
5
+ }
6
+ }
7
+
8
+ .expand{
9
+ float: left;
10
+ cursor: pointer;
11
+
12
+ border: 1px solid lightgray;
13
+ color: lightgray;
14
+
15
+ font-size: 13px;
16
+ font-weight: normal;
17
+ line-height: 13px;
18
+ text-align: center;
19
+
20
+ width: 13px;
21
+ height: 13px;
22
+ margin: 3px 10px 0 0;
23
+
24
+ &.empty{ display:none !important; }
25
+ }
26
+ }
@@ -0,0 +1,25 @@
1
+ .nested_options{
2
+ padding: 3px;
3
+ font-size: 18px;
4
+ font-family: Arial;
5
+ border: 1px solid gray;
6
+
7
+ option{
8
+ color: black; padding: 3px;
9
+ &.selected{ font-weight: bold; color: red; }
10
+ }
11
+
12
+ @for $i from 1 through 2{
13
+ .l_#{$i}{
14
+ padding-left: #{($i - 1)*15}px;
15
+ font-size: #{(100 - $i * 10) + '%'};
16
+ }
17
+ }
18
+
19
+ @for $i from 3 through 10{
20
+ .l_#{$i}{
21
+ padding-left: #{($i - 1)*15}px;
22
+ font-size: 70%;
23
+ }
24
+ }
25
+ }
@@ -0,0 +1,108 @@
1
+ .sortable_tree{
2
+ margin: 0; padding: 0;
3
+ *{ margin: 0; padding: 0; }
4
+
5
+ ol{
6
+ margin: 0 0 0 13px;
7
+ padding: 0 0 0 15px;
8
+ border-left: 1px dashed gray;
9
+ list-style: none outside none;
10
+ }
11
+
12
+ li{
13
+ margin-bottom:5px;
14
+ position: relative;
15
+ list-style: none outside none;
16
+ }
17
+
18
+ a{
19
+ color:#000;
20
+ font-size:10pt;
21
+ font-weight:normal;
22
+ text-decoration:none;
23
+ line-height: 150%;
24
+ margin-left:30px;
25
+ margin-right:120px;
26
+ display:block;
27
+ &:hover{ text-decoration: underline; }
28
+ }
29
+
30
+ h4{
31
+ margin-left: 30px;
32
+
33
+ a{
34
+ color: #333;
35
+ font-size: 14px;
36
+ margin-left: 0;
37
+ &:hover{ background: #eee; }
38
+ }
39
+ }
40
+
41
+ p{
42
+ margin-right: 75px;
43
+ padding: 5px;
44
+ }
45
+
46
+ .handle{
47
+ background: transparent image-url("iconza/icons/move.png");
48
+ background-position: center center;
49
+
50
+ width: 16px;
51
+ height: 16px;
52
+ margin: 3px 10px 0 0;
53
+ float: left;
54
+ cursor: move;
55
+
56
+ &:hover{ background: transparent image-url("iconza/icons/red_move.png"); }
57
+ }
58
+
59
+ .item{
60
+ padding: 5px;
61
+ background: #f7f7f7;
62
+ border-radius: 3px;
63
+ margin-bottom: 5px;
64
+ &:hover{ background: #eee; }
65
+ }
66
+
67
+ .placeholder {
68
+ background-color: #EEF;
69
+ border: 1px dashed blue;
70
+ }
71
+
72
+ .ui-nestedSortable-error {
73
+ background: #FAA;
74
+ color: #8a1f11;
75
+ }
76
+
77
+ .controls{
78
+ position: absolute;
79
+ top: 1px; right: 10px;
80
+
81
+ a{
82
+ width: 20px;
83
+ height: 20px;
84
+ display: block;
85
+
86
+ float: left;
87
+ padding: 5px;
88
+ cursor: pointer;
89
+ position: relative;
90
+
91
+ margin: 0 0 5px 5px;
92
+ overflow: hidden; zoom: 1;
93
+
94
+ &.new{
95
+ background: transparent image-url("iconza/icons/add.png") no-repeat scroll center center;
96
+ &:hover{ background: transparent image-url("iconza/icons/red_add.png") no-repeat scroll center center; }
97
+ }
98
+ &.edit{
99
+ background: transparent image-url("iconza/icons/edit.png") no-repeat scroll center center;
100
+ &:hover{ background: transparent image-url("iconza/icons/red_edit.png") no-repeat scroll center center; }
101
+ }
102
+ &.delete{
103
+ background: transparent image-url("iconza/icons/delete.png") no-repeat scroll center center;
104
+ &:hover{ background: transparent image-url("iconza/icons/red_delete.png") no-repeat scroll center center; }
105
+ }
106
+ }
107
+ }
108
+ }
@@ -0,0 +1,35 @@
1
+ .tree{
2
+ margin:0; padding:0;
3
+ *{ margin: 0; padding: 0; }
4
+
5
+ ol{
6
+ margin: 0 0 0 13px;
7
+ padding: 0 0 0 15px;
8
+ border-left: 1px dashed gray;
9
+ list-style: none outside none;
10
+ }
11
+
12
+ li{
13
+ margin-bottom:5px;
14
+ position: relative;
15
+ list-style: none outside none;
16
+ }
17
+
18
+ a{
19
+ color: black;
20
+ font-size: 14px;
21
+
22
+ &:hover {
23
+ color: black;
24
+ background: #ddd;
25
+ }
26
+ }
27
+
28
+ .item{
29
+ padding: 5px;
30
+ background: #eee;
31
+ margin-bottom: 5px;
32
+ border-radius: 3px;
33
+ &:hover{ background: #ddd; }
34
+ }
35
+ }
@@ -0,0 +1,93 @@
1
+ module JquerySortableTreeController
2
+ module DefineVariablesMethod
3
+ def sortable_model
4
+ @sortable_model ||= self.class.to_s.split(':').last.sub(/Controller/, '').singularize.constantize
5
+ end
6
+
7
+ def sortable_collection
8
+ @sortable_collection ||= self.class.to_s.split(':').last.sub(/Controller/,'').underscore.downcase
9
+ end
10
+
11
+ def the_define_common_variables
12
+ ["@#{sortable_collection.singularize}", sortable_collection, sortable_model]
13
+ end
14
+
15
+ def id
16
+ @id ||= params[:id].to_i
17
+ end
18
+
19
+ def parent_id
20
+ @parent_id ||= params[:parent_id].to_i
21
+ end
22
+
23
+ def sort
24
+ @sort ||= params[:tree_sort] == 'reversed' ? 'reversed_nested_set' : 'nested_set'
25
+ end
26
+
27
+ def prev_id
28
+ @prev_id ||= params[:prev_id].to_i
29
+ end
30
+
31
+ def next_id
32
+ @next_id ||= params[:next_id].to_i
33
+ end
34
+
35
+ def move_to_prev
36
+ @move_to_prev ||= params[:tree_sort] == 'reversed' ? :move_to_left_of : :move_to_right_of
37
+ end
38
+
39
+ def move_to_next
40
+ @move_to_next ||= params[:tree_sort] == 'reversed' ? :move_to_right_of : :move_to_left_of
41
+ end
42
+
43
+ def move_to_parent
44
+ :move_to_child_of
45
+ end
46
+
47
+ def object_to_rebuild
48
+ self.sortable_model.find(id)
49
+ end
50
+
51
+ def move_to_nowhere?
52
+ parent_id.zero? && prev_id.zero? && next_id.zero?
53
+ end
54
+
55
+ def prev_next_parent
56
+ return 'prev' unless prev_id.zero?
57
+ return 'next' unless next_id.zero?
58
+ return 'parent' unless parent_id.zero?
59
+ end
60
+
61
+ def move_to
62
+ send("move_to_#{prev_next_parent}")
63
+ end
64
+
65
+ def node_id
66
+ send("#{prev_next_parent}_id")
67
+ end
68
+
69
+ def node
70
+ sortable_model.find(node_id)
71
+ end
72
+ end
73
+
74
+ module ExpandNode
75
+ include DefineVariablesMethod
76
+
77
+ def expand_node
78
+ @children = object_to_rebuild.children.send(sort) if id && sort
79
+ return render(nothing: true, status: :no_content) if !@children || @children.count.zero?
80
+ render layout: false, template: "#{sortable_collection}/expand_node"
81
+ end
82
+ end
83
+
84
+ module Rebuild
85
+ include DefineVariablesMethod
86
+
87
+ def rebuild
88
+ return render(nothing: true, status: :no_content) if move_to_nowhere?
89
+ object_to_rebuild.send(move_to, node)
90
+ render(nothing: true, status: :ok)
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,27 @@
1
+ # DOC:
2
+ # We use Helper Methods for tree building,
3
+ # because it's faster than View Templates and Partials
4
+
5
+ # SECURITY note
6
+ # Prepare your data on server side for rendering
7
+ # or use h.html_escape(node.content)
8
+ # for escape potentially dangerous content
9
+ module JquerySortableTreeHelper
10
+ module RenderExpandableTreeHelper
11
+ class Render < JquerySortableTreeHelper::RenderSortableTreeHelper::Render
12
+ attr_accessor :h, :options
13
+
14
+ def initialize(h, options)
15
+ @h, @options = h, options
16
+ end
17
+
18
+ def div_item
19
+ h.content_tag(:div, handle + expand_button + edit_link + controls, class: :item)
20
+ end
21
+
22
+ def expand_button
23
+ h.content_tag(:b, '+', class: 'expand plus')
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,37 @@
1
+ module JquerySortableTreeHelper
2
+ module RenderIndentedOptionsHelper
3
+ class Render
4
+ attr_accessor :h, :options
5
+
6
+ def initialize(h, options)
7
+ @h, @options = h, options
8
+ end
9
+
10
+ def render_node
11
+ h.content_tag(:option, title, tag_options) + children
12
+ end
13
+
14
+ def title
15
+ "\u202f" * (@options[:spacing] || 3).to_i * (@options[:level]-1) + node.send(@options[:title])
16
+ end
17
+
18
+ def tag_options
19
+ html_options = { value: node.id }
20
+
21
+ if options[:selected] == node
22
+ html_options[:selected] = 'selected'
23
+ html_options[:class] = 'selected'
24
+ end
25
+ html_options
26
+ end
27
+
28
+ def node
29
+ @options[:node]
30
+ end
31
+
32
+ def children
33
+ @options[:children].html_safe
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,29 @@
1
+ module JquerySortableTreeHelper
2
+ module RenderNestedOptionsHelper
3
+ class Render
4
+ attr_accessor :h, :options
5
+
6
+ def initialize(h, options)
7
+ @h, @options = h, options
8
+ end
9
+
10
+ def render_node
11
+ @h.content_tag(:option, options[:node].send(options[:title]), tag_options) + children
12
+ end
13
+
14
+ def children
15
+ @options[:children].html_safe
16
+ end
17
+
18
+ def tag_options
19
+ opts = { class: "l_#{@options[:level]}", value: @options[:node][:id] }
20
+
21
+ if @options[:selected] == @options[:node]
22
+ opts[:class] += ' selected'
23
+ opts[:selected] = :selected
24
+ end
25
+ opts
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,65 @@
1
+ # DOC:
2
+ # We use Helper Methods for tree building,
3
+ # because it's faster than View Templates and Partials
4
+
5
+ # SECURITY note
6
+ # Prepare your data on server side for rendering
7
+ # or use h.html_escape(node.content)
8
+ # for escape potentially dangerous content
9
+ module JquerySortableTreeHelper
10
+ module RenderSortableTreeHelper
11
+ class Render
12
+ attr_accessor :h, :options
13
+
14
+ def initialize(h, options)
15
+ @h, @options = h, options
16
+ end
17
+
18
+ def render_node
19
+ return h.content_tag(:li, div_item + children,
20
+ class: :node,
21
+ data: { node_id: options[:node].id }
22
+ )
23
+ end
24
+
25
+ def div_item
26
+ h.content_tag(:div, handle + edit_link + controls, class: :item)
27
+ end
28
+
29
+ def handle
30
+ h.content_tag(:i, '', class: :handle)
31
+ end
32
+
33
+ def edit_link
34
+ h.content_tag(:h4, h.link_to(options[:node].send(options[:title]), show_path, class: :edit))
35
+ end
36
+
37
+ def show_link
38
+ h.content_tag(:h4,
39
+ h.link_to(options[:node].send(options[:title]),
40
+ h.url_for(options[:namespace] + [options[:node]]))
41
+ )
42
+ end
43
+
44
+ def controls
45
+ link_options = {
46
+ class: :delete,
47
+ method: :delete,
48
+ data: {
49
+ confirm: I18n.t('are_you_sure', default: 'Are you sure?'),
50
+ remote: true
51
+ }
52
+ }
53
+ h.content_tag(:div, h.link_to('', show_path, link_options), class: :controls)
54
+ end
55
+
56
+ def children
57
+ h.content_tag(:ol, options[:children].html_safe, class: :nested_set) unless options[:children].blank?
58
+ end
59
+
60
+ def show_path
61
+ h.url_for(controller: (options[:controller] || (options[:klass] && options[:klass].pluralize)), action: :show, id: options[:node].id, format: :json)
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,23 @@
1
+ # DOC:
2
+ # We use Helper Methods for tree building,
3
+ # because it's faster than View Templates and Partials
4
+
5
+ # SECURITY note
6
+ # Prepare your data on server side for rendering
7
+ # or use h.html_escape(node.content)
8
+ # for escape potentially dangerous content
9
+ module JquerySortableTreeHelper
10
+ module RenderTreeHelper
11
+ class Render < JquerySortableTreeHelper::RenderSortableTreeHelper::Render
12
+ attr_accessor :h, :options
13
+
14
+ def initialize(h, options)
15
+ @h, @options = h, options
16
+ end
17
+
18
+ def div_item
19
+ h.content_tag(:div, show_link, class: :item)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,142 @@
1
+ module JquerySortableTreeHelper
2
+ # Ilya Zykin, zykin-ilya@ya.ru, Russia [Ivanovo, Saint Petersburg] 2009-2014
3
+ # github.com/the-teacher
4
+ TREE_RENDERERS = {
5
+ tree: RenderTreeHelper,
6
+ sortable: RenderSortableTreeHelper,
7
+ expandable: RenderExpandableTreeHelper,
8
+ nested_options: RenderNestedOptionsHelper,
9
+ indented_options: RenderIndentedOptionsHelper
10
+ }.freeze
11
+
12
+ ###############################################
13
+ # Common Base Methods
14
+ ###############################################
15
+
16
+ def define_class_of_elements_of tree
17
+ case
18
+ when tree.is_a?(ActiveRecord::Relation) then tree.name.to_s.underscore.downcase
19
+ when tree.empty? then nil
20
+ else tree.first.class.to_s.underscore.downcase
21
+ end
22
+ end
23
+
24
+ def build_tree_html context, render_module, options = {}
25
+ render_module::Render.new(context, options).render_node
26
+ end
27
+
28
+ ###############################################
29
+ # Shortcuts
30
+ ###############################################
31
+
32
+ def just_tree(tree, options = {})
33
+ build_server_tree(tree, { type: :tree }.merge!(options))
34
+ end
35
+
36
+ def base_data
37
+ {
38
+ model: params[:controller].singularize,
39
+ title: 'title',
40
+ max_levels: 5,
41
+ parent_id: params[:parent_id],
42
+ rebuild_url: send("rebuild_#{params[:controller]}_url"),
43
+ url: url_for(controller: params[:controller], action: :show, id: ':id', format: :json)
44
+ }
45
+ end
46
+
47
+ def space(height)
48
+ content_tag(:div, '&nbsp;'.html_safe, style: "height: #{height}px;")
49
+ end
50
+
51
+ def fake_node(options)
52
+ OpenStruct.new(options[:title] => '', id: ':id', children: nil)
53
+ end
54
+
55
+ def sortable_tree(tree, options = {})
56
+ space(20) +
57
+ add_new_node_form(base_data.merge(options)) +
58
+ content_tag(:ol, build_tree_html(self, TREE_RENDERERS[:sortable], base_options.merge(options).merge({ node: fake_node(options) })), class: 'fake-node hidden', style: 'display: none;') +
59
+ content_tag(:ol, build_server_tree(tree, { type: :sortable }.merge!(options)),
60
+ class: 'sortable_tree',
61
+ data: base_data.merge(options.slice(:parent_id, :model, :rebuild_url, :title, :max_levels))
62
+ )
63
+ end
64
+
65
+ def form_for_options(options)
66
+ {
67
+ html: { id: "new-#{options[:model]}-form" },
68
+ url: send("#{options[:model].pluralize}_path", format: :json),
69
+ method: :post,
70
+ remote: true
71
+ }
72
+ end
73
+
74
+ def add_new_node_form(options)
75
+ capture do
76
+ form_for(options[:model].to_sym, form_for_options(options)) do |f|
77
+ title_field = f.text_field options[:title].to_sym, required: true, class: 'form-control', placeholder: I18n.t('sortable_tree.title_of_new_node', default: "The #{options[:title]} of new #{options[:model]}")
78
+ concat content_tag(:div, title_field, class: 'form-group')
79
+ concat f.hidden_field :parent_id, value: options[:parent_id]
80
+ end
81
+ end
82
+ end
83
+
84
+ def nested_options(tree, options = {})
85
+ build_server_tree(tree, { type: :nested_options }.merge!(options))
86
+ end
87
+
88
+ def indented_options(tree, options = {})
89
+ build_server_tree(tree, { type: :indented_options }.merge!(options))
90
+ end
91
+
92
+ def expandable_tree(tree, options = {})
93
+ build_server_tree(tree, { type: :expandable }.merge!(options))
94
+ end
95
+
96
+ ###############################################
97
+ # Server Side Render Tree Helper
98
+ ###############################################
99
+
100
+ def base_options
101
+ {
102
+ id: :id,
103
+ title: :title,
104
+ node: nil,
105
+ type: :tree,
106
+ root: false,
107
+ level: 0,
108
+ namespace: [],
109
+ controller: params[:controller]
110
+ }
111
+ end
112
+
113
+ def build_children(tree, opts)
114
+ children = (opts[:boost][opts[:node].id.to_i] || [])
115
+ children.reduce('') { |r, elem| r + build_server_tree(tree, opts.merge(node: elem, root: false, level: opts[:level].next)) }
116
+ end
117
+
118
+ def roots(tree)
119
+ min_parent_id = tree.map(&:parent_id).compact.min
120
+ tree.select { |e| e.parent_id == min_parent_id }
121
+ end
122
+
123
+ def merge_base_options(tree, options)
124
+ opts = base_options.merge(options)
125
+ opts[:namespace] = [*opts[:namespace]]
126
+ opts[:render_module] ||= TREE_RENDERERS[opts[:type]]
127
+ opts[:klass] ||= define_class_of_elements_of(tree)
128
+ opts[:boost] ||= tree.group_by { |item| item.parent_id.to_i }
129
+ opts
130
+ end
131
+
132
+ def build_server_tree(tree, options = {})
133
+ tree = [*tree]
134
+ opts = merge_base_options(tree, options)
135
+
136
+ if opts[:node]
137
+ raw build_tree_html(self, opts[:render_module], opts.merge(children: build_children(tree, opts)))
138
+ else
139
+ raw (roots(tree) || []).reduce('') { |r, root| r + build_server_tree(tree, opts.merge(node: root, root: true, level: opts[:level].next)) }
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,12 @@
1
+ class IndentedCollectionSelectInput < SimpleForm::Inputs::CollectionSelectInput
2
+ def input
3
+ label_method, value_method = detect_collection_methods
4
+ collection.map! do |o|
5
+ depth_method = options[:depth_method] || :depth
6
+ spacing = (options[:spacing] || 3).to_i
7
+ label = "\u202f" * spacing * o.send(depth_method) + o.send(label_method)
8
+ [label, o.send(value_method)]
9
+ end
10
+ super
11
+ end
12
+ end
data/lib/fake.example ADDED
@@ -0,0 +1,44 @@
1
+ book = {
2
+ 'Programs' => {
3
+ 'Lexical Structure' => [
4
+ 'Comments',
5
+ 'Documentation',
6
+ 'Whitespace',
7
+ 'Literals',
8
+ 'Identifiers'
9
+ ]
10
+ }
11
+ }
12
+
13
+ def create_hub user, title
14
+ obj = user.send(:hubs).new
15
+ obj.title = title
16
+ obj.hub_type = :book
17
+ obj.state = :published
18
+ obj.save!
19
+ obj
20
+ end
21
+
22
+ def build_page_tree user, book, parent_obj = nil
23
+ book.each_pair do |key, value|
24
+ obj = create_hub(user, key)
25
+ obj.move_to_child_of(parent_obj) if parent_obj
26
+ parent_obj = obj
27
+
28
+ if value.is_a? Hash
29
+ build_page_tree(user, value, parent_obj)
30
+ end
31
+
32
+ if value.is_a? Array
33
+ value.each do |key|
34
+ obj = create_hub(user, key)
35
+ obj.move_to_child_of(parent_obj)
36
+ end
37
+ end
38
+
39
+ end
40
+ end
41
+
42
+ build_page_tree(User.first, book)
43
+
44
+ Hub.roots.of_(:book).last.self_and_descendants