trellis 0.0.1 → 0.0.2

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.
Files changed (205) hide show
  1. data/History.txt +7 -0
  2. data/Manifest.txt +6 -181
  3. data/examples/crud_components/source/crud_components.rb +0 -1
  4. data/examples/examples.txt +32 -30
  5. data/examples/flickr/source/flickr.rb +0 -4
  6. data/examples/hangman/source/hangman.rb +1 -2
  7. data/examples/hilo/html/guess.xhtml +2 -2
  8. data/examples/hilo/source/hilo.rb +6 -6
  9. data/examples/routing/source/routing.rb +50 -0
  10. data/examples/stateful_counters/source/stateful_counters.rb +9 -4
  11. data/lib/trellis/{core_components.rb → component_library/core_components.rb} +48 -398
  12. data/lib/trellis/component_library/grid.rb +311 -0
  13. data/lib/trellis/{jquery.rb → component_library/jquery.rb} +0 -0
  14. data/lib/trellis/component_library/object_editor.rb +110 -0
  15. data/lib/trellis/trellis.rb +162 -52
  16. data/lib/trellis/utils.rb +9 -3
  17. data/lib/trellis/version.rb +1 -1
  18. data/tasks/rspec.rake +2 -1
  19. data/test/application_spec.rb +55 -30
  20. data/test/component_spec.rb +95 -81
  21. data/test/core_extensions_spec.rb +34 -2
  22. data/test/default_router_spec.rb +91 -0
  23. data/test/fixtures/application_spec_applications.rb +91 -3
  24. data/test/page_spec.rb +18 -8
  25. data/test/router_spec.rb +49 -49
  26. metadata +8 -185
  27. data/.git/COMMIT_EDITMSG +0 -1
  28. data/.git/HEAD +0 -1
  29. data/.git/config +0 -9
  30. data/.git/description +0 -1
  31. data/.git/hooks/applypatch-msg.sample +0 -15
  32. data/.git/hooks/commit-msg.sample +0 -24
  33. data/.git/hooks/post-commit.sample +0 -8
  34. data/.git/hooks/post-receive.sample +0 -15
  35. data/.git/hooks/post-update.sample +0 -8
  36. data/.git/hooks/pre-applypatch.sample +0 -14
  37. data/.git/hooks/pre-commit.sample +0 -18
  38. data/.git/hooks/pre-rebase.sample +0 -169
  39. data/.git/hooks/prepare-commit-msg.sample +0 -36
  40. data/.git/hooks/update.sample +0 -107
  41. data/.git/index +0 -0
  42. data/.git/info/exclude +0 -6
  43. data/.git/logs/HEAD +0 -1
  44. data/.git/logs/refs/heads/master +0 -1
  45. data/.git/logs/refs/remotes/origin/master +0 -1
  46. data/.git/objects/01/2368d4dd3162ed570e6c1423ecb07a6a35f8c0 +0 -0
  47. data/.git/objects/02/238c88c522b88e71529495460cc5c2c8abe110 +0 -0
  48. data/.git/objects/07/03d3b123189f1da72d3889d9340e681841c96d +0 -0
  49. data/.git/objects/0b/3935fdbf3ce8d37e6cb2a6ec94edaccb1c58dc +0 -0
  50. data/.git/objects/0f/ecd1ad35f280c874ce070b7a97a4c1f86ace54 +0 -0
  51. data/.git/objects/12/61911b063b7e6883c5e9db7ab4396183f6f2b5 +0 -0
  52. data/.git/objects/13/0b7e2d214ec198d07aeed5b462597670ce85ad +0 -0
  53. data/.git/objects/13/214d40f02b63f1233fd7881b1df9bb75d9c0a7 +0 -0
  54. data/.git/objects/14/7522bdc96af0b578935d81c1a7347b40573940 +0 -0
  55. data/.git/objects/16/a7fde706fe92b3548254d29722f5ca311ce63b +0 -2
  56. data/.git/objects/16/fe580663cc29d141bf416dff5bf21bf4ea42a3 +0 -0
  57. data/.git/objects/17/2d55806918bafb4e701515edb27147a4ef6498 +0 -0
  58. data/.git/objects/17/686ef1882ed6c3c07b781fab18739b1c5e48bd +0 -0
  59. data/.git/objects/17/824053c41a2cb523303e20cac42f66f9ca2134 +0 -0
  60. data/.git/objects/18/68448c5f88bc73b2fef6b8f3aa75b663013a3a +0 -1
  61. data/.git/objects/1a/6d9051dc4c7db10bdcf5e17c5cb717b072d30a +0 -0
  62. data/.git/objects/1a/8bdb445fb5668dcd1309cb9de5dedf846c822f +0 -0
  63. data/.git/objects/1b/6fa67b70358fdb82eabcd7ef3bc46d518d0426 +0 -0
  64. data/.git/objects/1c/f6510ed08a274fb3292d40557cebb3e7090767 +0 -0
  65. data/.git/objects/1d/e661ce11d5335e5dd7968ef5698e2eb164eb52 +0 -0
  66. data/.git/objects/1e/301ee672d6040e734af6d0a5491185129d7b67 +0 -0
  67. data/.git/objects/21/2201d46200f13d23d8199bd4a7ecc9165205b3 +0 -0
  68. data/.git/objects/22/f687370babdf38d224d2a9ff039707e8d0aac1 +0 -0
  69. data/.git/objects/24/202d2de95dc31f5f1802e629a16ad45b723267 +0 -0
  70. data/.git/objects/25/4c5b6b8d211d8b9f07310fd342fd7b078a81af +0 -0
  71. data/.git/objects/25/5832653fde9e9748855347fe7bce013aa0a6c7 +0 -0
  72. data/.git/objects/25/806945c89b4b5adb8c8676c308e4653361109c +0 -5
  73. data/.git/objects/26/cb8deaca28bf275769cbb71b88e53a44adb9ca +0 -0
  74. data/.git/objects/2e/1c13fb5f154f89cccd4c645540a2ec8ee0f57a +0 -0
  75. data/.git/objects/2f/437425b2c085bb529379e409d6b4bc7f9f9fba +0 -0
  76. data/.git/objects/2f/7cf4a25937b71f3de52e70c7a47cb2f7da07ea +0 -0
  77. data/.git/objects/31/31bdbbac6e6e7e24fd6ea84332461f67e6e5b6 +0 -0
  78. data/.git/objects/32/02e02de478263912b729283eabc7cdab8a8037 +0 -0
  79. data/.git/objects/32/839ed9baa8c800d9033655d1ee995499825fb5 +0 -0
  80. data/.git/objects/34/2e479c61796125b0e025b483401ec12f3c5824 +0 -2
  81. data/.git/objects/36/7acb017aebab3f627a5208c25885c21fa7fdbb +0 -0
  82. data/.git/objects/38/12910d2e2a8e6eeb79a399d20751675d3fbe77 +0 -0
  83. data/.git/objects/38/3fe1e1a07537db6e0f39c6005b7b4e40fa5ccd +0 -0
  84. data/.git/objects/39/5ef328bc94df9191f4d80a77503a5be9f1f673 +0 -0
  85. data/.git/objects/39/dc76dc096fdf737e9f4f7062b78cbf4ab9628f +0 -0
  86. data/.git/objects/3b/09eb196140b471556ed4c3987c0bc739733617 +0 -0
  87. data/.git/objects/3b/9f97f1bf55834832a92bab1ab900918dc49570 +0 -0
  88. data/.git/objects/40/5ffd3925b39dd905638ec24640dd8efa27cc1b +0 -0
  89. data/.git/objects/42/4a5f37c6fe3a7cac54b0f85688c1cce7da9cdf +0 -0
  90. data/.git/objects/44/9e23363d4e20da6a67be7ab78fc610b4e9852a +0 -0
  91. data/.git/objects/48/90bb5d241cecaa30b28148c920b833056c7508 +0 -0
  92. data/.git/objects/4c/558c43676410a2c0a7d5c7b94fca18923a9af1 +0 -0
  93. data/.git/objects/4f/bf572175dd5245104679ff8f676f6a34466c29 +0 -0
  94. data/.git/objects/53/8583edf00c9f656b32149a0e69e030371737c5 +0 -0
  95. data/.git/objects/5b/8a2c4bf7bb56ae199414096dbda21fd4b8cd63 +0 -0
  96. data/.git/objects/5c/9fe8ff998d56dc076657ef88ee9f784ec160f9 +0 -0
  97. data/.git/objects/5f/8441f9d3507587940f31af04dd9fd5911d2812 +0 -0
  98. data/.git/objects/61/4f2752550e63b793e31dcf98b5ea26c32eb0be +0 -0
  99. data/.git/objects/65/801b0fabdfd673861dbb2ac134d438ab2cc5e4 +0 -3
  100. data/.git/objects/66/2746dffaddbcd311f4ac070b5b9bddcd8894a7 +0 -0
  101. data/.git/objects/69/1ed3b65603a0d0dabfb66720e7163664be78f5 +0 -0
  102. data/.git/objects/69/3dc3b6037df8c1c8dfda916d649e7975481124 +0 -0
  103. data/.git/objects/69/67538427b3a371b33c01c72726ac7e67a04c39 +0 -0
  104. data/.git/objects/69/6cd6c3508e2adcc68829497884ff3d4b774dc2 +0 -0
  105. data/.git/objects/69/6ee93917040308ccd0bfc245d63c1cbeb23dae +0 -0
  106. data/.git/objects/6a/3ac317746a8a2cfc88f3580bbd2b03dc0d50b5 +0 -0
  107. data/.git/objects/6d/6ba435839a65b96cb3f7584a40dd3767a0990f +0 -0
  108. data/.git/objects/6f/32c190a651a82caeefeb55eb797fc5daf05426 +0 -0
  109. data/.git/objects/71/fecbce1bec36eaf4de655763d4bb7ceffc991d +0 -0
  110. data/.git/objects/72/01d78a9e90347fd2f7790f9e8665587791d853 +0 -0
  111. data/.git/objects/73/6c97d6a551363ba4a4956408ba228fcab7f91f +0 -0
  112. data/.git/objects/75/3264271e935e18f4eada49aa1818c6fb9e6abb +0 -0
  113. data/.git/objects/75/cc7d390b4a565495cbdc5a08d4479e7e8dbfeb +0 -0
  114. data/.git/objects/76/7c0c96f68b9ccec34ae538045a63bbe4f97d3e +0 -0
  115. data/.git/objects/7b/47fe9b1ab9f2692b9706054de706430089ecd4 +0 -0
  116. data/.git/objects/7c/73144ef6847d1bc2315aee0925c0e5cf5c09d1 +0 -0
  117. data/.git/objects/7d/9c177c155386606aa1024d5cb020a097eea64a +0 -0
  118. data/.git/objects/7d/e9a3296007c09ba9b7bc1802e1c5d9ad1d5dbb +0 -0
  119. data/.git/objects/7e/b73d408147c8d84881109189a9724292abcb8d +0 -0
  120. data/.git/objects/82/0e3bf5449a8f6b8eb637a653dcb2dc387b393c +0 -0
  121. data/.git/objects/83/a10ce96763cb30d0b81425e9372f89c52f4c9f +0 -0
  122. data/.git/objects/83/bdb801e78444d59225f83cf2f336f114cd23cf +0 -0
  123. data/.git/objects/85/24e583e822abc18b1ffdd0aa356c9c079b5548 +0 -0
  124. data/.git/objects/88/b46cc8de5237897d4ba5023d3efdc83fec4f7c +0 -0
  125. data/.git/objects/89/5eea66474f48a2cbf643ad0ef266fd26f9d2a3 +0 -0
  126. data/.git/objects/8a/539c5fc35d5b770d67241d2ccb6c6855df6a43 +0 -0
  127. data/.git/objects/8a/82cdbfb20cc58fdffe4e13b70b55977deb92c6 +0 -0
  128. data/.git/objects/8b/2b537442e4ac8719ffa71b3ae0c707133df06f +0 -0
  129. data/.git/objects/8c/2a45f0c81284a081f8d7980e9a54210a9dd52c +0 -0
  130. data/.git/objects/8e/10355b4ab312450031966107ef6a65b13833ee +0 -0
  131. data/.git/objects/90/f6c76767ae725f15fa6790dcb6afd1719fa0e2 +0 -0
  132. data/.git/objects/92/92b696aba9840c089241c68d4c6ca14be38a64 +0 -2
  133. data/.git/objects/93/e03faa6906892434fa9f2ad230c4ececc64055 +0 -0
  134. data/.git/objects/93/eca2e28d80fda45d327fdfc6c39ae690af41cd +0 -0
  135. data/.git/objects/95/92fe63bd5403654730cdec76cbf116ef83bbff +0 -0
  136. data/.git/objects/96/bc6dd471c1c188a2eb4308bcc3ca4e6c8faac8 +0 -0
  137. data/.git/objects/96/d855221a9ff4fba57d2b70680b57bd5115cfde +0 -0
  138. data/.git/objects/97/4ec92b2b9eb01a73fb57dc78d463cafdda69a7 +0 -0
  139. data/.git/objects/97/b7ec01ebe089832a0972d20b0a40d54456985c +0 -2
  140. data/.git/objects/97/fa6aaae4cfc7654feb39971e7aee5c41ed1679 +0 -1
  141. data/.git/objects/98/18351c6685a1df5d23686e6346d11d261cc6f0 +0 -0
  142. data/.git/objects/98/3d3b7e55cbbce2f2a52c6e6d830a5dca7b4d42 +0 -0
  143. data/.git/objects/a2/e551049a5388112c21e7f3a4a720bf720601fa +0 -0
  144. data/.git/objects/a3/7066bea4fae90d34761a3ebb3f8a348d94eba1 +0 -0
  145. data/.git/objects/a6/c99619145d1b9b75aa15ca04fbe4db0b2ee79b +0 -0
  146. data/.git/objects/aa/e2234d0a8c1485096c7a7de039eceb4e019e13 +0 -0
  147. data/.git/objects/b0/3b52f4269c9719e02ecd6caabd8aff5adf3aac +0 -0
  148. data/.git/objects/b1/50dbbd89f825302a9e82d8fdd66f238b8e6fc4 +0 -0
  149. data/.git/objects/b4/545fbe393aaa18f1c48de4d9f68f64ebf09ddc +0 -0
  150. data/.git/objects/b6/8691404e088692929d40b988b993f815d76756 +0 -0
  151. data/.git/objects/b7/daa3d844ef5f5cd917084e48edd82e67f8f476 +0 -0
  152. data/.git/objects/bf/4232281dba5a0f17e8b5c16b9cbd0f52274fa8 +0 -0
  153. data/.git/objects/bf/9b84d10f19188beffe5ee99e6f5af035ba77d3 +0 -2
  154. data/.git/objects/c0/06e664b306145de804f74ab27550d62a92f58a +0 -1
  155. data/.git/objects/c2/2806b16775f66453012d085d21fb8698521ea9 +0 -0
  156. data/.git/objects/c2/7f6559350f7adb19d43742b55b2f91d07b6550 +0 -0
  157. data/.git/objects/c3/833df21ed674a77374fd40ed931f900134d38b +0 -0
  158. data/.git/objects/c3/b9da021eb76abad0b17ad6c4be75595e41a7e6 +0 -0
  159. data/.git/objects/c5/ca6b7e3561ea88aba1712aabb984d1167787f1 +0 -0
  160. data/.git/objects/c6/39f65e1f43c75b7f57c5ab28623d295dfb2afd +0 -0
  161. data/.git/objects/c8/6f05fa5539f8e69e94850d1cd917919ff581be +0 -0
  162. data/.git/objects/cb/5e499c8dcc6f2901014a08e74f04b7a4bd6596 +0 -0
  163. data/.git/objects/cc/1289d25eeee6ba31b4e406372cb9abf969fc6f +0 -0
  164. data/.git/objects/cc/784e1b49111c42fa7eae10ad0e788186e672d1 +0 -0
  165. data/.git/objects/cc/bcae254dad515d7ef01a461980544e4483c41e +0 -0
  166. data/.git/objects/ce/bfadad3a7c17148998e04275e6d0d1cf1b2e1e +0 -0
  167. data/.git/objects/ce/f3335522abdc47a2c94be70455dcfaa9a51a27 +0 -0
  168. data/.git/objects/cf/6add7ea568d3d90d6a1f8afb0898b0119b14ff +0 -0
  169. data/.git/objects/d0/719abd196033fec0e4cbe2af68a26ca435389c +0 -0
  170. data/.git/objects/d1/ce63ff0eaec4dba419e5547f99195dfb9b5b20 +0 -0
  171. data/.git/objects/d2/c3feb3c74b892cca0049c0aced6ce786a784c8 +0 -0
  172. data/.git/objects/d7/8a91da13413419da71b539a3c6c7df4d8a2458 +0 -0
  173. data/.git/objects/d8/c7bed2b1357d54b6935536a8a51a3c73d535b4 +0 -0
  174. data/.git/objects/da/c3a1277ccb4806011e33eb32c5609cc45c46f2 +0 -0
  175. data/.git/objects/dc/3f920f4b937d0e2ac512f0bb31d477624c46d5 +0 -0
  176. data/.git/objects/dc/6c389abf5bd0d7b9be2a6bb6af90738a410e59 +0 -0
  177. data/.git/objects/df/07c423309f39c4d5570b0fad65dff23af654ae +0 -0
  178. data/.git/objects/e2/93a5c9e2257b9f3fcb8fa5d5c8147a2f07ba1b +0 -0
  179. data/.git/objects/e4/8464df56bf487e96e21ea99487330266dae3c9 +0 -0
  180. data/.git/objects/e6/9de29bb2d1d6434b8b29ae775ad8c2e48c5391 +0 -0
  181. data/.git/objects/e8/0c13a1d1f62756fb9f1e4fb9f7512e5b8c5816 +0 -0
  182. data/.git/objects/e9/b8ade2125b2615ddc4c8043940c40ed36215c9 +0 -0
  183. data/.git/objects/ed/59a7599a81ef7ea7c230c3332345a3484febf8 +0 -0
  184. data/.git/objects/f0/d2a74226877e9a28af814d0d3727e4a3487439 +0 -0
  185. data/.git/objects/f0/f3ba7264f1d8e60eb93a907092af98fdc248e4 +0 -0
  186. data/.git/objects/f1/cdcc7ff2dc6298318523b2c4e425f515a58bf7 +0 -3
  187. data/.git/objects/f4/45c96f406f4d2f9839b3fe2fe8bc7f943ab469 +0 -0
  188. data/.git/objects/f7/eef7ce0a650d6f0c85dc4982f481da7bd44362 +0 -0
  189. data/.git/objects/f9/0abf96c5059ce1ba115f73bc9cf33e4663b3e1 +0 -0
  190. data/.git/objects/f9/cf7ae572eaebbd63f809f16a5ef14b9c679790 +0 -0
  191. data/.git/objects/fc/300df53fe2c9467210e2fd4c2f34e1c9c7c89a +0 -0
  192. data/.git/objects/fc/45546596ab8debc4c9f49a7abc7fc14a7bcc7f +0 -4
  193. data/.git/objects/fc/68d89167f69614eda17bd56dfccb4355d818e6 +0 -0
  194. data/.git/objects/fc/e4c02bb132e73b3cb957da182db7b75a47c242 +0 -0
  195. data/.git/objects/fe/be283da7f326344013f1fc847c12c8f29ab6ef +0 -0
  196. data/.git/refs/heads/master +0 -1
  197. data/.git/refs/remotes/origin/master +0 -1
  198. data/.gitignore +0 -5
  199. data/README.txt +0 -156
  200. data/examples/simplest/html/start.xhtml +0 -0
  201. data/website/index.html +0 -124
  202. data/website/index.txt +0 -119
  203. data/website/javascripts/rounded_corners_lite.inc.js +0 -285
  204. data/website/stylesheets/screen.css +0 -138
  205. data/website/template.html.erb +0 -48
@@ -0,0 +1,311 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright &169;2001-2008 Integrallis Software, LLC.
5
+ # All Rights Reserved.
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining
8
+ # a copy of this software and associated documentation files (the
9
+ # "Software"), to deal in the Software without restriction, including
10
+ # without limitation the rights to use, copy, modify, merge, publish,
11
+ # distribute, sublicense, and/or sell copies of the Software, and to
12
+ # permit persons to whom the Software is furnished to do so, subject to
13
+ # the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be
16
+ # included in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ #++
26
+
27
+ require 'trellis/trellis'
28
+ require 'paginator'
29
+
30
+ module Trellis
31
+ module CoreLibrary
32
+
33
+ #
34
+ #
35
+ #
36
+ class Grid < Trellis::Component
37
+ is_stateful
38
+
39
+ tag_name "grid"
40
+
41
+ attr_accessor :source
42
+ field :page_position, :persistent => true
43
+ attr_reader :properties
44
+ attr_reader :commands
45
+ attr_reader :counter_method
46
+ attr_reader :counter_method_arguments
47
+ attr_reader :retrieve_block
48
+ attr_reader :sort_properties
49
+ field :sorted_by, :persistent => true
50
+ field :sort_direction, :persistent => true, :default_value => :ascending
51
+
52
+ def initialize
53
+ @properties = []
54
+ @sort_properties = []
55
+ @commands = []
56
+ end
57
+
58
+ # must be called before rendering
59
+ def columns(*syms)
60
+ syms.each do |sym|
61
+ @properties << sym
62
+ end
63
+ end
64
+
65
+ def add_command(options=[])
66
+ # extract options
67
+ name = options[:name] if options
68
+ page = options[:page] if options
69
+ context = options[:context] if options
70
+ image = options[:image] if options
71
+
72
+ @commands << lambda do |tag, object|
73
+ tid = tag.attr['tid']
74
+ value = object.send(context.to_sym)
75
+ url_root = tag.globals.page.class.url_root
76
+ page = tag.globals.page.class.name unless page
77
+ href = Trellis::DefaultRouter.to_uri(:url_root => url_root,
78
+ :page => page,
79
+ :event => name,
80
+ :source => tid,
81
+ :value => value)
82
+
83
+ %{
84
+ <a href="#{href}">
85
+ <img src='#{image}'/>
86
+ </a>
87
+ }
88
+ end
89
+ end
90
+
91
+ def sort_by_all_except(*syms)
92
+ @sort_properties = @properties.reject { |property| syms.includes?(property)}
93
+ end
94
+
95
+ def sort_by(*syms)
96
+ unless syms.first == :all
97
+ @sort_properties = syms
98
+ else
99
+ @sort_properties = @properties
100
+ end
101
+ end
102
+
103
+ def size_accessor(symbol, args)
104
+ @counter_method, @counter_method_arguments = symbol, args
105
+ end
106
+
107
+ def retrieve_method(&block)
108
+ @retrieve_block = block
109
+ end
110
+
111
+ # event handlers
112
+
113
+ def on_page(page)
114
+ @page_position = page.to_i # must use the cohersion built in capabilities
115
+ end
116
+
117
+ def on_sort(property)
118
+ to_sym = property.to_sym
119
+ if @sort_properties.include?(to_sym)
120
+ if @sorted_by != to_sym
121
+ @sorted_by = to_sym
122
+ else
123
+ @sort_direction = @sort_direction == :ascending ? :descending : :ascending
124
+ end
125
+ end
126
+ end
127
+
128
+ render do |tag|
129
+ url_root = tag.globals.page.class.url_root
130
+ # get the page object
131
+ page = tag.globals.page
132
+ # get the tag properties
133
+ tid = tag.attr['tid']
134
+ rows_per_page = tag.attr['rows_per_page'] || 3
135
+ # get the instance of the component from the page
136
+ grid = page.send("grid_#{tid}")
137
+ # get the properties or columns
138
+ properties = grid.properties
139
+ # get the sort properties
140
+ sort_properties = grid.sort_properties
141
+ # current page
142
+ current_page = grid.page_position || 1
143
+ # sort information
144
+ sorted_by = grid.sorted_by
145
+ sort_direction = grid.sort_direction
146
+ commands = grid.commands
147
+ # get the source from either the tag or the component instance itself
148
+ source = tag.attr['source'] || grid.source
149
+ # get the array or collection that we can iterate over
150
+ iterator = tag.globals.send(source.to_sym)
151
+
152
+ builder = Builder::XmlMarkup.new
153
+
154
+ # build the table
155
+ builder.div(:class => "t-data-grid") {
156
+
157
+ # configure pagination
158
+ #TODO need to implement page ranging
159
+ range = tag.attr['page_range'] || 5
160
+ available_rows = 0
161
+ unless grid.counter_method
162
+ available_rows = iterator.length
163
+ else
164
+ unless grid.counter_method_arguments
165
+ available_rows = iterator.send(grid.counter_method)
166
+ else
167
+ available_rows = iterator.send(grid.counter_method, grid.counter_method_arguments)
168
+ end
169
+ end
170
+
171
+ # configure the pager
172
+ pager = Paginator.new(available_rows, rows_per_page) do |offset, per_page|
173
+ rows = nil
174
+ unless grid.retrieve_method
175
+ if sorted_by
176
+ iterator = iterator.sort_by { |row| row.send(sorted_by) }
177
+ iterator.reverse! if sort_direction == :descending
178
+ end
179
+ rows = iterator[offset, per_page]
180
+ else
181
+ rows = grid.retrieve_method.call
182
+ end
183
+ rows
184
+ end
185
+
186
+ # get the current page from the pager
187
+ rows = pager.page(current_page)
188
+
189
+ # render the pager control if necessary
190
+ unless pager.number_of_pages < 2
191
+ builder.div(:class => "t-data-grid-pager") {
192
+ # loop over the pages
193
+ (1..pager.number_of_pages).each do |page_num|
194
+ if page_num == current_page
195
+ builder.span("#{page_num}", :class => "current")
196
+ else
197
+ href = Trellis::DefaultRouter.to_uri(:url_root => url_root,
198
+ :page => page.class.name,
199
+ :event => "page",
200
+ :source => "grid_#{tid}",
201
+ :value => "#{page_num}")
202
+ builder.a("#{page_num}", :href => href, :title => "Go to page #{page_num}")
203
+ end
204
+ end
205
+ }
206
+ end
207
+
208
+ # build the html
209
+ builder.table(:class => "t-data-grid") {
210
+ # header
211
+ builder.thead {
212
+ builder.tr {
213
+ properties.each_index { |index|
214
+ property = properties[index]
215
+ field_name = property.to_s.humanize
216
+
217
+ if properties.length == index + 1
218
+ css_class = "#{field_name} t-last"
219
+ elsif index == 0
220
+ css_class = "#{field_name} t-first"
221
+ else
222
+ css_class = "#{field_name}"
223
+ end
224
+
225
+ sort_image = 'sortable.png'
226
+ if property == sorted_by
227
+ if sort_direction == :ascending
228
+ sort_image = 'sort-desc.png'
229
+ elsif sort_direction == :descending
230
+ sort_image = 'sort-asc.png'
231
+ end
232
+ end
233
+
234
+ unless sort_properties.include?(property)
235
+ builder.th(field_name, :class => css_class)
236
+ else
237
+ builder.th(:class => css_class) {
238
+ href = Trellis::DefaultRouter.to_uri(:url_root => url_root,
239
+ :page => page.class.name,
240
+ :event => "sort",
241
+ :source => "grid_#{tid}",
242
+ :value => "#{property}")
243
+ builder.a(field_name, :href => href)
244
+ builder.a(:href => href) {
245
+ builder.img(:alt => "[Sortable]",
246
+ :class => "t-sort-icon",
247
+ :id => "#{property}:sort",
248
+ :src => "#{url_root}/images/#{sort_image}",
249
+ :name => "#{property}:sort")
250
+ }
251
+ }
252
+ end
253
+ }
254
+ # add columns for commands
255
+ if commands && !commands.empty?
256
+ (1..commands.size).each do
257
+ builder.th
258
+ end
259
+ end
260
+ }
261
+ }
262
+
263
+ # body
264
+ builder.tbody {
265
+ # data
266
+ index = 0
267
+ rows.each do |item|
268
+ if (rows.last_item_number - rows.first_item_number) == index + 1
269
+ css_class = "t-last"
270
+ elsif index == 0
271
+ css_class = "t-first"
272
+ else
273
+ css_class = nil
274
+ end
275
+ index = index + 1
276
+
277
+ if css_class
278
+ builder.tr(:class => css_class) {
279
+ properties.each { |property|
280
+ field_value = item.send(property)
281
+ builder.td("#{field_value}", :class => "#{property}")
282
+ }
283
+ # add columns for commands
284
+ if commands && !commands.empty?
285
+ commands.each { |command|
286
+ builder.td { |td| td << command.call(tag, item)}
287
+ }
288
+ end
289
+ }
290
+ else
291
+ builder.tr {
292
+ properties.each { |property|
293
+ field_value = item.send(property)
294
+ builder.td("#{field_value}", :class => "#{property}")
295
+ }
296
+ # add columns for commands
297
+ if commands && !commands.empty?
298
+ commands.each { |command|
299
+ builder.td { |td| td << command.call(tag, item)}
300
+ }
301
+ end
302
+ }
303
+ end
304
+ end if rows
305
+ }
306
+ }
307
+ }
308
+ end
309
+ end
310
+ end
311
+ end
@@ -0,0 +1,110 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright &169;2001-2008 Integrallis Software, LLC.
5
+ # All Rights Reserved.
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person obtaining
8
+ # a copy of this software and associated documentation files (the
9
+ # "Software"), to deal in the Software without restriction, including
10
+ # without limitation the rights to use, copy, modify, merge, publish,
11
+ # distribute, sublicense, and/or sell copies of the Software, and to
12
+ # permit persons to whom the Software is furnished to do so, subject to
13
+ # the following conditions:
14
+ #
15
+ # The above copyright notice and this permission notice shall be
16
+ # included in all copies or substantial portions of the Software.
17
+ #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25
+ #++
26
+
27
+ require 'trellis/trellis'
28
+ require 'paginator'
29
+
30
+ module Trellis
31
+ module CoreLibrary
32
+ #
33
+ #
34
+ #
35
+ class ObjectEditor < Trellis::Component
36
+ is_stateful
37
+
38
+ depends_on :form, :submit
39
+
40
+ field :model, :persistent => true
41
+ attr_reader :retrieve_block
42
+ attr_reader :properties
43
+ attr_accessor :submit_text
44
+ attr_reader :submit_block
45
+
46
+ def initialize
47
+ @properties = []
48
+ end
49
+
50
+ # must be called before rendering
51
+ def fields(*syms)
52
+ syms.each do |sym|
53
+ @properties << sym
54
+ end
55
+ end
56
+
57
+ def on_submit(&block)
58
+ # populate the object with values from the session
59
+ if page.params
60
+ properties.each do |property|
61
+ value = page.params[property.to_sym]
62
+ @model.instance_variable_set("@#{property}".to_sym, value)
63
+ end
64
+ end
65
+ if block_given?
66
+ @submit_block = block
67
+ else
68
+ @submit_block.call(@model)
69
+ end
70
+ end
71
+
72
+ render do |tag|
73
+ url_root = tag.globals.page.class.url_root
74
+ # get the page object
75
+ page = tag.globals.page
76
+ # get the tag properties
77
+ tid = tag.attr['tid']
78
+ # get the instance of the component from the page
79
+ editor = page.send("object_editor_#{tid}")
80
+ # get the properties or columns
81
+ properties = editor.properties
82
+ # get the source from either the tag or the component instance itself
83
+ source = tag.attr['model'] || editor.model
84
+ submit_text = tag.attr['submit_text'] || editor.submit_text || "Submit"
85
+
86
+ builder = Builder::XmlMarkup.new
87
+
88
+ # the editor encloses a form
89
+ form = tag.render("form", "tid" => "form_#{tid}", "method" => "post", "on_behalf" => "object_editor#{tid}") do
90
+ builder.div(:class => "t-beaneditor") {
91
+ properties.each { |property|
92
+ field_name = property.to_s.humanize
93
+ field_value = source.send(property)
94
+ builder.div(:class => "t-beaneditor-row") {
95
+ builder.label(field_name, :for => property, :id => "#{property}:label")
96
+ builder.input(:id => property, :name => property, :type => "text", :value => field_value)
97
+ builder.img(:alt => "[Error]", :class => "t-error-icon t-invisible", :id => "#{property}:icon", :src => "#{url_root}/images/field-error-marker.gif", :name => "#{property}:icon")
98
+ }
99
+ } if source
100
+ builder.div(:class => "t-beaneditor-row") {
101
+ builder << tag.render("submit", "tid" => "submit", "name" => "whats_the_name", "value" => submit_text)
102
+ }
103
+ }
104
+ end
105
+ form
106
+ end
107
+
108
+ end
109
+ end
110
+ end