drg_cms 0.4.39

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 (204) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +39 -0
  5. data/app/assets/images/drg_cms/add.png +0 -0
  6. data/app/assets/images/drg_cms/arrow_in.png +0 -0
  7. data/app/assets/images/drg_cms/arrow_out.png +0 -0
  8. data/app/assets/images/drg_cms/checkbox-checked.png +0 -0
  9. data/app/assets/images/drg_cms/checkbox-unchecked.png +0 -0
  10. data/app/assets/images/drg_cms/cols.png +0 -0
  11. data/app/assets/images/drg_cms/copy.png +0 -0
  12. data/app/assets/images/drg_cms/edit.png +0 -0
  13. data/app/assets/images/drg_cms/edit_design.png +0 -0
  14. data/app/assets/images/drg_cms/edit_page.png +0 -0
  15. data/app/assets/images/drg_cms/edit_site.png +0 -0
  16. data/app/assets/images/drg_cms/html.png +0 -0
  17. data/app/assets/images/drg_cms/pin.png +0 -0
  18. data/app/assets/images/drg_cms/printer.png +0 -0
  19. data/app/assets/images/drg_cms/reload.png +0 -0
  20. data/app/assets/images/drg_cms/search_16.png +0 -0
  21. data/app/assets/images/drg_cms/spinner.gif +0 -0
  22. data/app/assets/images/drg_cms/view_tile.png +0 -0
  23. data/app/assets/images/drg_cms/x.png +0 -0
  24. data/app/assets/javascripts/drg_cms/drg_cms.js +449 -0
  25. data/app/assets/javascripts/drg_cms/jquery-migrate.js +511 -0
  26. data/app/assets/javascripts/drg_cms/jquery.datetimepicker.js +1353 -0
  27. data/app/assets/javascripts/drg_cms/some_scripts.js +33 -0
  28. data/app/assets/javascripts/drg_cms_application.js +11 -0
  29. data/app/assets/javascripts/drg_cms_cms.js +28 -0
  30. data/app/assets/stylesheets/drg_cms/drg_cms.css +632 -0
  31. data/app/assets/stylesheets/drg_cms/jquery-ui.css +339 -0
  32. data/app/assets/stylesheets/drg_cms/jquery.datetimepicker.css +304 -0
  33. data/app/assets/stylesheets/drg_cms/th-bg.png +0 -0
  34. data/app/assets/stylesheets/drg_cms/theme.css +49 -0
  35. data/app/assets/stylesheets/drg_cms_application.css +12 -0
  36. data/app/assets/stylesheets/drg_cms_cms.css +26 -0
  37. data/app/controllers/cmsedit_controller.rb +673 -0
  38. data/app/controllers/dc_application_controller.rb +385 -0
  39. data/app/controllers/dc_at_the_beginning_controller.rb +120 -0
  40. data/app/controllers/dc_common_controller.rb +314 -0
  41. data/app/controllers/dc_mail_controller.rb +89 -0
  42. data/app/controllers/dc_main_controller.rb +40 -0
  43. data/app/controllers/drgcms_controls/dc_page_controls.rb +40 -0
  44. data/app/forms/all_options.yml +176 -0
  45. data/app/forms/cms_forms.yml +93 -0
  46. data/app/forms/cms_menu.yml +142 -0
  47. data/app/forms/dc_ad.yml +130 -0
  48. data/app/forms/dc_big_table.yml +59 -0
  49. data/app/forms/dc_big_table_locale.yml +41 -0
  50. data/app/forms/dc_big_table_value.yml +47 -0
  51. data/app/forms/dc_category.yml +57 -0
  52. data/app/forms/dc_design.yml +68 -0
  53. data/app/forms/dc_folder_permission.yml +49 -0
  54. data/app/forms/dc_forum_cat.yml +54 -0
  55. data/app/forms/dc_forum_forum.yml +53 -0
  56. data/app/forms/dc_forum_msg.yml +124 -0
  57. data/app/forms/dc_forum_privmsg.yml +125 -0
  58. data/app/forms/dc_forum_topic.yml +131 -0
  59. data/app/forms/dc_journal.yml +85 -0
  60. data/app/forms/dc_link.yml +55 -0
  61. data/app/forms/dc_mail.yml +88 -0
  62. data/app/forms/dc_mail_address.yml +56 -0
  63. data/app/forms/dc_mail_list.yml +44 -0
  64. data/app/forms/dc_mail_list_member.yml +42 -0
  65. data/app/forms/dc_menu.yml +62 -0
  66. data/app/forms/dc_menu_item.yml +81 -0
  67. data/app/forms/dc_page.yml +145 -0
  68. data/app/forms/dc_part.yml +102 -0
  69. data/app/forms/dc_permission.yml +50 -0
  70. data/app/forms/dc_piece.yml +105 -0
  71. data/app/forms/dc_policy.yml +57 -0
  72. data/app/forms/dc_policy_role.yml +42 -0
  73. data/app/forms/dc_policy_rule.yml +38 -0
  74. data/app/forms/dc_policy_rule_nocms.yml +38 -0
  75. data/app/forms/dc_poll.yml +113 -0
  76. data/app/forms/dc_poll_item.yml +76 -0
  77. data/app/forms/dc_simple_menu.yml +64 -0
  78. data/app/forms/dc_simple_menu_item.yml +80 -0
  79. data/app/forms/dc_site.yml +149 -0
  80. data/app/forms/dc_user.yml +142 -0
  81. data/app/forms/dc_user_role.yml +54 -0
  82. data/app/forms/drgcms_cms.yml +28 -0
  83. data/app/helpers/cmsedit_helper.rb +698 -0
  84. data/app/helpers/dc_ad_renderer.rb +206 -0
  85. data/app/helpers/dc_application_helper.rb +704 -0
  86. data/app/helpers/dc_big_menu_renderer.rb +180 -0
  87. data/app/helpers/dc_captcha_renderer.rb +100 -0
  88. data/app/helpers/dc_common_renderer.rb +132 -0
  89. data/app/helpers/dc_mail_renderer.rb +76 -0
  90. data/app/helpers/dc_menu_renderer.rb +143 -0
  91. data/app/helpers/dc_page_renderer.rb +80 -0
  92. data/app/helpers/dc_part_renderer.rb +162 -0
  93. data/app/helpers/dc_piece_renderer.rb +124 -0
  94. data/app/helpers/dc_poll_renderer.rb +219 -0
  95. data/app/helpers/dc_renderer.rb +56 -0
  96. data/app/helpers/dc_simple_menu_renderer.rb +244 -0
  97. data/app/helpers/drgcms_form_field.rb +863 -0
  98. data/app/models/__dc_global_data.rb +44 -0
  99. data/app/models/dc_ad.rb +52 -0
  100. data/app/models/dc_ad_stat.rb +34 -0
  101. data/app/models/dc_big_menu.rb +89 -0
  102. data/app/models/dc_big_table.rb +63 -0
  103. data/app/models/dc_big_table_locale.rb +35 -0
  104. data/app/models/dc_big_table_value.rb +38 -0
  105. data/app/models/dc_category.rb +48 -0
  106. data/app/models/dc_design.rb +48 -0
  107. data/app/models/dc_dummy.rb +30 -0
  108. data/app/models/dc_folder_permission.rb +43 -0
  109. data/app/models/dc_global_data.rb +44 -0
  110. data/app/models/dc_journal.rb +39 -0
  111. data/app/models/dc_key_value_store.rb +90 -0
  112. data/app/models/dc_link.rb +39 -0
  113. data/app/models/dc_mail.rb +64 -0
  114. data/app/models/dc_mail_address.rb +69 -0
  115. data/app/models/dc_mail_list.rb +48 -0
  116. data/app/models/dc_mail_list_member.rb +34 -0
  117. data/app/models/dc_menu.rb +59 -0
  118. data/app/models/dc_menu_item.rb +40 -0
  119. data/app/models/dc_page.rb +123 -0
  120. data/app/models/dc_part.rb +28 -0
  121. data/app/models/dc_permission.rb +58 -0
  122. data/app/models/dc_piece.rb +57 -0
  123. data/app/models/dc_policy.rb +94 -0
  124. data/app/models/dc_policy_role.rb +47 -0
  125. data/app/models/dc_policy_rule.rb +65 -0
  126. data/app/models/dc_poll.rb +46 -0
  127. data/app/models/dc_poll_item.rb +40 -0
  128. data/app/models/dc_sendmail.rb +48 -0
  129. data/app/models/dc_simple_menu.rb +58 -0
  130. data/app/models/dc_simple_menu_item.rb +39 -0
  131. data/app/models/dc_site.rb +92 -0
  132. data/app/models/dc_stat.rb +36 -0
  133. data/app/models/dc_user.rb +91 -0
  134. data/app/models/dc_user_role.rb +36 -0
  135. data/app/models/dc_visit.rb +35 -0
  136. data/app/views/cmsedit/_edit_stuff.html.erb +59 -0
  137. data/app/views/cmsedit/_edit_stuff.js.erb +6 -0
  138. data/app/views/cmsedit/_form.html.erb +21 -0
  139. data/app/views/cmsedit/_result.html.erb +20 -0
  140. data/app/views/cmsedit/edit.html.erb +6 -0
  141. data/app/views/cmsedit/error.html.erb +2 -0
  142. data/app/views/cmsedit/index.html.erb +6 -0
  143. data/app/views/cmsedit/new.html.erb +5 -0
  144. data/app/views/cmsedit/show.html.erb +21 -0
  145. data/app/views/dc_at_the_beginning/create.html.erb +9 -0
  146. data/app/views/dc_at_the_beginning/index.html.erb +19 -0
  147. data/app/views/dc_common/paste_clipboard.html.erb +17 -0
  148. data/app/views/dc_mail/subscribe.html.erb +7 -0
  149. data/app/views/dc_mail/unsubscribe.html.erb +19 -0
  150. data/app/views/layouts/cms.html.erb +17 -0
  151. data/app/views/layouts/cmsedit.html.erb +16 -0
  152. data/app/views/layouts/content.html.erb +16 -0
  153. data/config/initializers/kaminari_patch.rb +36 -0
  154. data/config/locales/datetimepicker.yml +13 -0
  155. data/config/locales/drgcms_en.yml +96 -0
  156. data/config/locales/drgcms_sl.yml +97 -0
  157. data/config/locales/en.yml +7 -0
  158. data/config/locales/kaminari.yml +26 -0
  159. data/config/locales/models_en.yml +790 -0
  160. data/config/locales/models_sl.yml +805 -0
  161. data/config/locales/mongoid_sl.yml +60 -0
  162. data/config/locales/sl.yml +211 -0
  163. data/config/routes.rb +2 -0
  164. data/drg_cms.gemspec +28 -0
  165. data/lib/drg_cms.rb +45 -0
  166. data/lib/drg_cms/engine.rb +30 -0
  167. data/lib/drg_cms/version.rb +3 -0
  168. data/lib/tasks/at_the_beginning.yml +26 -0
  169. data/lib/tasks/dc_cleanup.rake +94 -0
  170. data/lib/tasks/drg_cms_tasks.rake +118 -0
  171. data/lib/tasks/send_mail.rake +253 -0
  172. data/lib/tasks/site_statistics.rake +80 -0
  173. data/test/drg_cms_test.rb +7 -0
  174. data/test/dummy/README.rdoc +261 -0
  175. data/test/dummy/Rakefile +7 -0
  176. data/test/dummy/app/assets/javascripts/application.js +15 -0
  177. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  178. data/test/dummy/app/controllers/application_controller.rb +3 -0
  179. data/test/dummy/app/helpers/application_helper.rb +2 -0
  180. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  181. data/test/dummy/config.ru +4 -0
  182. data/test/dummy/config/application.rb +59 -0
  183. data/test/dummy/config/boot.rb +10 -0
  184. data/test/dummy/config/database.yml +25 -0
  185. data/test/dummy/config/environment.rb +5 -0
  186. data/test/dummy/config/environments/development.rb +37 -0
  187. data/test/dummy/config/environments/production.rb +67 -0
  188. data/test/dummy/config/environments/test.rb +37 -0
  189. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  190. data/test/dummy/config/initializers/inflections.rb +15 -0
  191. data/test/dummy/config/initializers/mime_types.rb +5 -0
  192. data/test/dummy/config/initializers/secret_token.rb +7 -0
  193. data/test/dummy/config/initializers/session_store.rb +8 -0
  194. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  195. data/test/dummy/config/locales/en.yml +5 -0
  196. data/test/dummy/config/routes.rb +58 -0
  197. data/test/dummy/public/404.html +26 -0
  198. data/test/dummy/public/422.html +26 -0
  199. data/test/dummy/public/500.html +25 -0
  200. data/test/dummy/public/favicon.ico +0 -0
  201. data/test/dummy/script/rails +6 -0
  202. data/test/integration/navigation_test.rb +10 -0
  203. data/test/test_helper.rb +15 -0
  204. metadata +375 -0
@@ -0,0 +1,863 @@
1
+ #--
2
+ # Copyright (c) 2012+ Damjan Rems
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+ module DrgcmsFormField
24
+
25
+ ###########################################################################
26
+ #
27
+ ###########################################################################
28
+ class DrgcmsField
29
+ attr_reader :html, :js
30
+
31
+ def initialize( parent, record, yaml )
32
+ @parent = parent
33
+ @record = record
34
+ @yaml = yaml
35
+ @form = parent.form
36
+ @readonly = (@yaml and @yaml['readonly']) || (@form and @form['readonly'])
37
+ @html = ''
38
+ @js = ''
39
+ self
40
+ end
41
+
42
+ ####################################################################
43
+ # Wrapper for i18 t method, with some spice added
44
+ ####################################################################
45
+ def t(key, default='')
46
+ c = I18n.t(key)
47
+ if c.match( 'translation missing' )
48
+ c = I18n.t(key, locale: 'en')
49
+ # Still not found. Return default if set
50
+ c = default unless default.blank?
51
+ end
52
+ c
53
+ end
54
+
55
+ ####################################################################
56
+ # Standard code for return on readonly field
57
+ ####################################################################
58
+ def ro_standard(value=nil)
59
+ # @html << "<span class='dc-readonly'>#{@record[@yaml['name']]}</span>" if @record.respond_to?(@yaml['name'])
60
+ value = @record[@yaml['name']] if value.nil? and @record.respond_to?(@yaml['name'])
61
+ @html << "<table class='dc-readonly'><td>#{value}</td></table>"
62
+ self
63
+ end
64
+
65
+ ####################################################################
66
+ # Set value of the field when value is defined by params. Fields may be
67
+ # intialized by setting params with name of the field preceding by p_.
68
+ #
69
+ # Example: Form has field named picture. Field can be initialized by
70
+ # setting value of param p_picture.
71
+ ####################################################################
72
+ def set_initial_value(opt1='html', opt2='value')
73
+ @yaml['html'] ||= {}
74
+ value_send_as = 'p_' + @yaml['name']
75
+ @yaml[opt1][opt2] = @parent.params[value_send_as] if @parent.params[value_send_as]
76
+ end
77
+
78
+ ####################################################################
79
+ # Will return ruby hash formated as javascript hash which can be used
80
+ # for passing parameters in javascript code.
81
+ ####################################################################
82
+ def hash_to_options(hash)
83
+ options = hash.to_a.inject('') do |r,v|
84
+ r << "#{v[0]}: #{v[1]},"
85
+ end
86
+ options.chomp(',')
87
+ end
88
+
89
+ ###########################################################################
90
+ # Default get_data method for retrieving data from object on the form into
91
+ # record to be saved.
92
+ ###########################################################################
93
+ def self.get_data(params, name)
94
+ params['record'][name]
95
+ end
96
+
97
+ end
98
+
99
+ ###########################################################################
100
+ # Create form field for displaying difference between two fields in journal
101
+ ###########################################################################
102
+ class Readonly < DrgcmsField
103
+ def render
104
+ @html << @parent.hidden_field('record', @yaml['name']) # retain field as hidden field
105
+ @html << '<table class="dc-readonly"><td>'
106
+
107
+ @html << if @yaml['eval']
108
+ if @yaml['eval'].match('dc_name4_id')
109
+ a = @yaml['eval'].split(',')
110
+ @parent.dc_name4_id(a[1], a[2], @record[ @yaml['name'] ])
111
+ else
112
+ eval( "#{@yaml['eval']} '#{@record[ @yaml['name'] ]}'")
113
+ end
114
+ else
115
+ @parent.dc_format_value(@record[@yaml['name']],@yaml['format'])
116
+ end
117
+ @html << '</td></table>'
118
+ self
119
+ end
120
+ end
121
+
122
+ ###########################################################################
123
+ # Dummy HiddenField class so everything works as expected
124
+ ###########################################################################
125
+ class HiddenField < DrgcmsField
126
+ def render
127
+ set_initial_value
128
+ value = @yaml['html']['value'] ? @yaml['html']['value'] : @record[@yaml['name']]
129
+ @parent.hidden_field('record', @yaml['name'], value: value)
130
+ end
131
+ end
132
+
133
+ ###########################################################################
134
+ # Creates html required to paint embedded object on input form.
135
+ ###########################################################################
136
+ class Embedded < DrgcmsField
137
+
138
+ def render
139
+ return self if @record.new_record? # would be in error
140
+ # HTML defaults. Some must be set
141
+ @yaml['html'] ||= {}
142
+ @yaml['html']['height'] ||= 300
143
+ @yaml['html']['width'] ||= '99%'
144
+ # defaults both way
145
+ # p '**********************'
146
+ # p [@yaml['table'],@yaml['formname']]
147
+ @yaml['table'] ||= @yaml['formname'] if @yaml['formname']
148
+ @yaml['formname'] ||= @yaml['table'] if @yaml['table']
149
+ # p [@yaml['table'],@yaml['formname']]
150
+ html = ''
151
+ @yaml['html'].each {|k,v| html << "#{k}=\"#{v}\" "}
152
+ #
153
+ tables = @parent.tables.inject('') { |r,v| r << "#{v[1]};" } + @yaml['table']
154
+ ids = @parent.ids.inject('') { |r,v| r << "#{v};" } + @record._id
155
+ opts = { controller: 'cmsedit', action: 'index', ids: ids, table: tables, formname: @yaml['formname'],
156
+ iframe: "if_#{@yaml['name']}", readonly: @readonly }
157
+ @html << "<iframe class='iframe_embedded' id='if_#{@yaml['name']}' name='if_#{@yaml['name']}' #{html}></iframe>"
158
+ @js = <<EOJS
159
+ $(document).ready( function() {
160
+ $('#if_#{@yaml['name']}').attr('src', '#{@parent.url_for(opts)}');
161
+ });
162
+ EOJS
163
+ self
164
+ end
165
+
166
+ end
167
+
168
+ ###########################################################################
169
+ # Alias for Embedded. EmbeddedIframe will be deprecated.
170
+ ###########################################################################
171
+ class EmbeddedIframe < Embedded
172
+ end
173
+
174
+ ###########################################################################
175
+ # Create form field for displaying difference between two fields in journal
176
+ ###########################################################################
177
+ class JournalDiff < DrgcmsField
178
+ def render
179
+ @yaml['name'] = 'old' if @record[@yaml['name']].nil?
180
+ @html << '<table width="99%">'
181
+ JSON.parse(@record[@yaml['name']]).each do |k,v|
182
+ @html << "<tr><td style='background-color: #654ddd;'>#{@parent.check_box('select', k)} #{k}:</td></tr>
183
+ <tr><td style='background-color: #ffe;'>#{v[0]}</td></tr>
184
+ <tr><td style='background-color: #eff;'>#{v[1]}</td></tr>"
185
+ end
186
+ @html << '</table>'
187
+ self
188
+ end
189
+ end
190
+
191
+ ###########################################################################
192
+ # Create form field for multitext_autocomplete
193
+ ###########################################################################
194
+ class MultitextAutocomplete < DrgcmsField
195
+
196
+ ###########################################################################
197
+ # returns value for readonly field
198
+ ###########################################################################
199
+ def ro_standard(table, search)
200
+ result = ''
201
+ table = table.classify.constantize
202
+ return super('') if @record[@yaml['name']].nil?
203
+ @record[@yaml['name']].each do |element|
204
+ result << table.find(element)[search] + '<br>'
205
+ end
206
+ super(result)
207
+ end
208
+
209
+ ###########################################################################
210
+ #
211
+ ###########################################################################
212
+ def render
213
+ # search field name
214
+ if @yaml['search'].match(/\./)
215
+ table, search = @yaml['search'].split('.')
216
+ else
217
+ search = @yaml['search']
218
+ end
219
+ # determine table name
220
+ if @yaml['table']
221
+ table = if @yaml['table'].class == String
222
+ @yaml['table']
223
+ # eval(how_to_get_my_table_name)
224
+ elsif @yaml['table']['eval']
225
+ eval @yaml['table']['eval']
226
+ else
227
+ p "Field #{@yaml['name']}: Invalid table parameter!"
228
+ nil
229
+ end
230
+ end
231
+ return 'Table or search field not defined!' unless (table and search)
232
+ #
233
+ return ro_standard(table, search) if @readonly
234
+ # put field to enter search data on form
235
+ @yaml['html'] ||= {}
236
+ @yaml['html']['value'] = '' # must be. Otherwise it will look into record and return error
237
+ _name = '_' + @yaml['name']
238
+ @html << '<table class="ui-autocomplete-table"><td>'
239
+ @html << @parent.link_to(@parent.image_tag('drg_cms/add.png', class: 'dc-link-img'), '#',onclick: 'return false;') # dummy add. But it is usefull.
240
+ @html << ' ' << @parent.text_field('record', _name, @yaml['html']) # text field for autocomplete
241
+ @html << "<div id =\"record#{@yaml['name']}\">" # div to list active records
242
+ # TODO check if table exists
243
+ t = table.classify.constantize
244
+ # find value for each field inside categories
245
+ unless @record[@yaml['name']].nil?
246
+ @record[@yaml['name']].each do |element|
247
+ # this is quick and dirty trick. We have model dc_big_table which can be used for retrive
248
+ # more complicated options
249
+ # TODO retrieve choices from big_table
250
+ rec = if table == 'dc_big_table'
251
+ t.find(@yaml['name'], @parent.session)
252
+ else
253
+ t.find(element)
254
+ end
255
+ # Related data is missing. It happends.
256
+ @html << if rec
257
+ link = @parent.link_to(@parent.image_tag('drg_cms/x.png', class: 'dc-link-img'), '#',
258
+ onclick: "$('##{rec.id}').hide(); var v = $('#record_#{@yaml['name']}_#{rec.id}'); v.val(\"-\" + v.val());return false;")
259
+ field = @parent.hidden_field('record', "#{@yaml['name']}_#{rec.id}", value: element)
260
+ "<div id=\"#{rec.id}\">#{link} #{rec[search]}<br>#{field}</div>"
261
+ else
262
+ '** error **'
263
+ end
264
+ end
265
+ end
266
+ @html << "</div></td></table>"
267
+ # Create text for div to be added when new category is selected
268
+ link = @parent.link_to(@parent.image_tag('drg_cms/x.png', class: 'dc-link-img'), '#',
269
+ onclick: "$('#rec_id').hide(); var v = $('#record_#{@yaml['name']}_rec_id'); v.val(\"-\" + v.val());return false;")
270
+ field = @parent.hidden_field('record', "#{@yaml['name']}_rec_id", value: 'rec_id')
271
+ one_div = "<div id=\"rec_id\">#{link} rec_search<br>#{field}</div>"
272
+
273
+ # JS stuff
274
+ @js << <<EOJS
275
+ $(document).ready(function() {
276
+ $("#record_#{_name}").autocomplete( {
277
+ source: function(request, response) {
278
+ $.ajax({
279
+ url: "#{ @parent.url_for( controller: 'dc_common', action: 'autocomplete' )}",
280
+ type: "POST",
281
+ dataType: "json",
282
+ data: { input: request.term, table: "#{table}", search: "#{search}" #{(',id: "'+@yaml['id'] + '"') if @yaml['id']} },
283
+ success: function(data) {
284
+ /* alert(data); */
285
+ response( $.map( data, function(key) {
286
+ return key;
287
+ }));
288
+ }
289
+ });
290
+ },
291
+ change: function (event, ui) {
292
+ var div = '#{one_div}';
293
+ div = div.replace(/rec_id/g, ui.item.id)
294
+ div = div.replace('rec_search', ui.item.value)
295
+ $("#record#{@yaml['name']}").append(div);
296
+ $("#record_#{_name}").val('');
297
+ },
298
+ minLength: 2
299
+ });
300
+ });
301
+ EOJS
302
+
303
+ self
304
+ end
305
+
306
+ ###########################################################################
307
+ # Method for retrieving data from multitext_autocomplete form field.
308
+ ###########################################################################
309
+ def self.get_data(params, name)
310
+ r = []
311
+ params['record'].each do |k,v|
312
+ # if it starts with - then it was removed
313
+ r << BSON::ObjectId.from_string(v) if k.match("#{name}_") and v[0,1] != '-'
314
+ end
315
+ r.uniq!
316
+ r
317
+ end
318
+
319
+ end
320
+
321
+ ###########################################################################
322
+ # Create form field for select
323
+ ###########################################################################
324
+ class Select < DrgcmsField
325
+
326
+ ###########################################################################
327
+ # Return values, when choices options will be returned by avaluating expression
328
+ ###########################################################################
329
+ def do_eval(e)
330
+ e.strip!
331
+ method = e.split(/\ |\(/).first
332
+ return eval(e) if respond_to?(method) # id method defined here
333
+ return eval('@parent.'+e) if @parent.respond_to?(method) # is method defined in helpers
334
+ # eval whatever it is
335
+ eval e
336
+ end
337
+
338
+ ###########################################################################
339
+ # Return choices array for fields with choices
340
+ ###########################################################################
341
+ def get_choices
342
+ begin
343
+ choices = case
344
+ when @yaml['choices'] then @yaml['choices']
345
+ when @yaml['eval'] then
346
+ do_eval(@yaml['eval'])
347
+ else
348
+ c = t('helpers.label.' + @form['table'] + '.choices4_' + @yaml['name'] )
349
+ c = 'Error' if c.match( 'translation missing' )
350
+ c
351
+ end
352
+ # Convert string to Array
353
+ choices.class == String ?
354
+ choices.chomp.split(',').inject([]) {|r,v| r << (v.match(':') ? v.split(':') : v )} :
355
+ choices
356
+ rescue
357
+ [] # return empty array when error occures
358
+ end
359
+ end
360
+
361
+ ###########################################################################
362
+ # Return value only when readonly is required
363
+ ###########################################################################
364
+ def ro_standard
365
+ value = @record.respond_to?(@yaml['name']) ? @record[@yaml['name']] : nil
366
+ return super('') if value.nil?
367
+ #
368
+ get_choices.each do |choice|
369
+ if choice.class == Array
370
+ return super(choice.first) if choice.last == value
371
+ else
372
+ return super(choice) if choice == value
373
+ end
374
+ end
375
+ super('')
376
+ end
377
+
378
+ ###########################################################################
379
+ #
380
+ ###########################################################################
381
+ def render
382
+ return ro_standard if @readonly
383
+ set_initial_value('html','selected')
384
+ #
385
+ @yaml['html'].symbolize_keys!
386
+ @html << @parent.select('record', @yaml['name'], get_choices, @yaml['html'])
387
+ self
388
+ end
389
+
390
+ end
391
+
392
+ ###########################################################################
393
+ # Create form field for select
394
+ ###########################################################################
395
+ class CheckBox < DrgcmsField
396
+
397
+ ###########################################################################
398
+ #
399
+ ###########################################################################
400
+ def render
401
+ set_initial_value('html','default')
402
+ # checked flag must be set
403
+ @yaml['html']['checked'] = !@parent.dc_dont?(@yaml['html']['default']) if @yaml['html']['default']
404
+ # disable it if readonly
405
+ @yaml['html']['disabled'] = @readonly ? true : nil
406
+ # If choices are present split them to set checked and unchecked value
407
+ @yaml['checked_value'], @yaml['unchecked_value'] = @yaml['choices'].split(',') if @yaml['choices']
408
+ @yaml['html'].symbolize_keys!
409
+ @html << if @yaml['checked_value']
410
+ @parent.check_box('record', @yaml['name'], @yaml['html'], @yaml['checked_value'], @yaml['unchecked_value'] || '0')
411
+ else
412
+ @parent.check_box('record', @yaml['name'], @yaml['html'])
413
+ end
414
+ self
415
+ end
416
+ end
417
+
418
+ ###########################################################################
419
+ # Create comment form field
420
+ ###########################################################################
421
+ class Comment < DrgcmsField
422
+
423
+ ###########################################################################
424
+ #
425
+ ###########################################################################
426
+ def render
427
+ @html << @yaml['text']
428
+ self
429
+ end
430
+ end
431
+
432
+ ###########################################################################
433
+ # Create link_to form field
434
+ ###########################################################################
435
+ class LinkTo < DrgcmsField
436
+
437
+ ###########################################################################
438
+ #
439
+ ###########################################################################
440
+ def render
441
+ @yaml['html'] ||= {}
442
+ @yaml['html']['class'] ||= 'dc-submit'
443
+ @yaml['html'].symbolize_keys!
444
+ #
445
+ url = @yaml['url'] || "#{@yaml[:controller]}/#{@yaml[:action]}/#{@yaml[:id]}"
446
+ url.gsub!('//','/') # no action and id
447
+ url = '/' + @yaml['url'] unless url[0,1] == '/' # no leading /
448
+ url.chop if url[0,-1] == '/' # remove trailing /
449
+ #
450
+ @html << @parent.link_to(@yaml['text'], url, @yaml['html'])
451
+ self
452
+ end
453
+ end
454
+
455
+ ###########################################################################
456
+ # Create submit_tag form field
457
+ ###########################################################################
458
+ class SubmitTag < DrgcmsField
459
+
460
+ ###########################################################################
461
+ #
462
+ ###########################################################################
463
+ def render
464
+ @yaml['html'] ||= {}
465
+ @yaml['html']['class'] ||= 'dc-submit'
466
+ @yaml['html'].symbolize_keys!
467
+ text = @yaml['caption'] || @yaml['text']
468
+ text = t(@yaml['text']) if text.match(/\./)
469
+
470
+ @html << @parent.submit_tag(text, @yaml['html'])
471
+ self
472
+ end
473
+ end
474
+
475
+ ###########################################################################
476
+ # Create Password form field
477
+ ###########################################################################
478
+ class PasswordField < DrgcmsField
479
+
480
+ ###########################################################################
481
+ #
482
+ ###########################################################################
483
+ def render
484
+ return self if @readonly
485
+ @yaml['html'] ||= {}
486
+ @html << @parent.password_field('record', @yaml['name'], @yaml['html'])
487
+ self
488
+ end
489
+ end
490
+
491
+ ###########################################################################
492
+ # Create date_select form field
493
+ ###########################################################################
494
+ class DateSelect < DrgcmsField
495
+
496
+ ###########################################################################
497
+ #
498
+ ###########################################################################
499
+ def render
500
+ # return ro_standard if @readonly
501
+ return ro_standard( @parent.dc_format_value(@record[@yaml['name']])) if @readonly
502
+
503
+ #
504
+ @yaml['options'] ||= {}
505
+ set_initial_value('options','default')
506
+ @yaml['options'].symbolize_keys!
507
+ @yaml['html'].symbolize_keys!
508
+ @html << @parent.date_select('record', @yaml['name'], @yaml['options'], @yaml['html'])
509
+ self
510
+ end
511
+
512
+ ####################################################################
513
+ # Get data for DateTime field
514
+ # According to https://gist.github.com/315227
515
+ ####################################################################
516
+ def self.get_data(params, name)
517
+ attrs = params['record'].collect do |key, value|
518
+ if key =~ /^#{Regexp.escape(name.to_s)}\((\d+)(\w)\)$/
519
+ [$1.to_i, value.send("to_#$2")]
520
+ end
521
+ end.compact.sort_by(&:first).map(&:last)
522
+ # Return nil if error
523
+ begin
524
+ Time.zone.local(*attrs) unless attrs.empty?
525
+ rescue
526
+ nil
527
+ end
528
+ end
529
+
530
+ end
531
+
532
+ ###########################################################################
533
+ # Create date_select form field
534
+ ###########################################################################
535
+ class DatetimeSelect < DrgcmsField
536
+
537
+ ###########################################################################
538
+ #
539
+ ###########################################################################
540
+ def render
541
+ return ro_standard( @parent.dc_format_value(@record[@yaml['name']])) if @readonly
542
+ #
543
+ @yaml['options'] ||= {}
544
+ set_initial_value('options','default')
545
+ @yaml['options'].symbolize_keys!
546
+ @yaml['html'].symbolize_keys!
547
+ #
548
+ @html << @parent.datetime_select('record', @yaml['name'], @yaml['options'], @yaml['html'])
549
+ self
550
+ end
551
+
552
+ ###########################################################################
553
+ #
554
+ ###########################################################################
555
+ def self.get_data(params, name)
556
+ DateSelect.get_data(params, name)
557
+ end
558
+
559
+ end
560
+
561
+ ###########################################################################
562
+ # Create datetime_picker form field
563
+ ###########################################################################
564
+ class DatePicker < DrgcmsField
565
+
566
+ ###########################################################################
567
+ #
568
+ ###########################################################################
569
+ def render
570
+ # return ro_standard if @readonly
571
+ return ro_standard( @parent.dc_format_value(@record[@yaml['name']])) if @readonly
572
+ #
573
+ @yaml['options'] ||= {}
574
+ set_initial_value
575
+ @yaml['html']['size'] ||= 10
576
+ @yaml['html']['value'] = I18n.localize(@record[@yaml['name']].localtime.to_date) if @record[@yaml['name']]
577
+ #
578
+ @yaml['options']['lang'] ||= "'#{I18n.locale}'"
579
+ @yaml['options']['format'] ||= "'#{t('datetimepicker.formats.date')}'"
580
+ @yaml['options']['timepicker'] = false
581
+ #
582
+ @html << @parent.text_field('record', @yaml['name'], @yaml['html'])
583
+ @js << <<EOJS
584
+ $(document).ready(function() {
585
+ $("#record_#{@yaml['name']}").datetimepicker( {
586
+ #{hash_to_options(@yaml['options'])}
587
+ });
588
+ });
589
+ EOJS
590
+
591
+ self
592
+ end
593
+
594
+ ###########################################################################
595
+ #
596
+ ###########################################################################
597
+ def self.get_data(params, name)
598
+ t = params['record'][name].to_datetime
599
+ t ? Time.zone.local(t.year, t.month, t.day) : nil
600
+ end
601
+
602
+ end
603
+ ###########################################################################
604
+ # Create datetime_picker form field
605
+ ###########################################################################
606
+ class DatetimePicker < DrgcmsField
607
+
608
+ ###########################################################################
609
+ #
610
+ ###########################################################################
611
+ def render
612
+ # return ro_standard if @readonly
613
+ return ro_standard( @parent.dc_format_value(@record[@yaml['name']])) if @readonly
614
+ #
615
+ @yaml['options'] ||= {}
616
+ set_initial_value
617
+ @yaml['html']['size'] ||= 12
618
+ @yaml['html']['value'] = I18n.localize(@record[@yaml['name']].localtime) if @record[@yaml['name']]
619
+ #
620
+ @yaml['options']['lang'] ||= "'#{I18n.locale}'"
621
+ @yaml['options']['format'] ||= "'#{t('datetimepicker.formats.datetime')}'"
622
+ #
623
+ @html << @parent.text_field('record', @yaml['name'], @yaml['html'])
624
+ @js << <<EOJS
625
+ $(document).ready(function() {
626
+ $("#record_#{@yaml['name']}").datetimepicker( {
627
+ #{hash_to_options(@yaml['options'])}
628
+ });
629
+ });
630
+ EOJS
631
+
632
+ self
633
+ end
634
+
635
+ ###########################################################################
636
+ #
637
+ ###########################################################################
638
+ def self.get_data(params, name)
639
+ t = params['record'][name].to_datetime
640
+ t ? Time.zone.local(t.year, t.month, t.day, t.hour, t.min) : nil
641
+ end
642
+
643
+ end
644
+
645
+ ###########################################################################
646
+ # Create text_autocomplete form field
647
+ ###########################################################################
648
+ class TextAutocomplete < DrgcmsField
649
+
650
+ ###########################################################################
651
+ #
652
+ ###########################################################################
653
+ def render
654
+ # Return descriptive text and put it into input field
655
+ # search field name
656
+ if @yaml['search'].class == Hash
657
+ table = @yaml['search']['table']
658
+ ret_name = @yaml['search']['field'] || @yaml['search']['search']
659
+ p 'search:search keyword is replaced with field keyword and will be depricated!' if @yaml['search']['search']
660
+ method = @yaml['search']['method']
661
+ elsif @yaml['search'].match(/\./)
662
+ table, ret_name, method = @yaml['search'].split('.')
663
+ else
664
+ ret_name = @yaml['search']
665
+ end
666
+ # determine table name
667
+ if @yaml['table']
668
+ table = if @yaml['table'].class == String
669
+ @yaml['table']
670
+ # eval(how_to_get_my_table_name)
671
+ elsif @yaml['table']['eval']
672
+ eval @yaml['table']['eval']
673
+ else
674
+ p "Field #{@yaml['name']}: Invalid table parameter!"
675
+ nil
676
+ end
677
+ end
678
+ return 'Table or field keyword not defined!' unless (table and ret_name)
679
+ # TODO check if table exists
680
+ t = table.classify.constantize
681
+ # find record and return value of field
682
+ value_send_as = 'p_' + @yaml['name']
683
+ value = if @parent.params[value_send_as]
684
+ @parent.params[value_send_as]
685
+ elsif @record and @record[@yaml['name']]
686
+ @record[@yaml['name']]
687
+ end
688
+ # Found value to be written in field
689
+ if value
690
+ record = t.find(value)
691
+ value_displayed = record[ret_name] if record
692
+ end
693
+ # return if readonly
694
+ return ro_standard(value_displayed) if @readonly
695
+ # Add method back, so autocomplete will know that it must search for method inside class
696
+ ret_name = "#{ret_name}.#{method}" if method
697
+ @yaml['html'] ||= {}
698
+ @yaml['html']['value'] = value_displayed
699
+ #
700
+ _name = '_' + @yaml['name']
701
+ @html << @parent.text_field('record', _name, @yaml['html'])
702
+ if @yaml['with_new']
703
+ @html << @parent.image_tag('drg_cms/add.png', class: 'in-edit-add', title: t('drgcms.new'),
704
+ style: "vertical-align: top;", 'data-table' => @yaml['with_new'] )
705
+ end
706
+ @html << @parent.hidden_field('record', @yaml['name'], value: value) # actual value will be in hidden field
707
+ # JS stuff
708
+ @js << <<EOJS
709
+ $(document).ready(function() {
710
+ $("#record_#{_name}").autocomplete( {
711
+ source: function(request, response) {
712
+ $.ajax({
713
+ url: '/dc_common/autocomplete',
714
+ type: "POST",
715
+ dataType: "json",
716
+ data: { input: request.term, table: "#{table}", search: "#{ret_name}" #{(',id: "'+@yaml['id'] + '"') if @yaml['id']} },
717
+ success: function(data) {
718
+ //alert(data);
719
+ response( $.map( data, function(key) {
720
+ return key;
721
+ }));
722
+ }
723
+ });
724
+ },
725
+ change: function (event, ui) {
726
+ $("#record_#{@yaml['name']}").val(ui.item.id);
727
+ },
728
+ minLength: 2
729
+ });
730
+ });
731
+ EOJS
732
+
733
+ self
734
+ end
735
+ end
736
+
737
+ ###########################################################################
738
+ # Create text_area form field
739
+ ###########################################################################
740
+ class TextArea < DrgcmsField
741
+
742
+ ###########################################################################
743
+ #
744
+ ###########################################################################
745
+ def render
746
+ return ro_standard if @readonly
747
+ #
748
+ @yaml['html'] ||= {}
749
+ value_send_as = 'p_' + @yaml['name']
750
+ @yaml['html']['value'] = @parent.params[value_send_as] if @parent.params[value_send_as]
751
+ @html << @parent.text_area('record', @yaml['name'], @yaml['html'])
752
+ self
753
+ end
754
+ end
755
+
756
+ ###########################################################################
757
+ # Create text_field form field
758
+ ###########################################################################
759
+ class TextField < DrgcmsField
760
+
761
+ ###########################################################################
762
+ #
763
+ ###########################################################################
764
+ def render
765
+ return ro_standard if @readonly
766
+ set_initial_value
767
+ #
768
+ @html << @parent.text_field('record', @yaml['name'], @yaml['html'])
769
+ self
770
+ end
771
+ end
772
+
773
+ ###########################################################################
774
+ # Create text_field plus select with optional values for the field
775
+ ###########################################################################
776
+ class TextWithSelect < Select
777
+
778
+ ###########################################################################
779
+ #
780
+ ###########################################################################
781
+ def render
782
+ return ro_standard if @readonly
783
+ set_initial_value('html','value')
784
+
785
+ @html << @parent.text_field('record', @yaml['name'], @yaml['html'])
786
+ @yaml['html']['class'] = 'text-with-select'
787
+ @yaml['html'].symbolize_keys!
788
+ @html << @parent.select( @yaml['name'] + '_', nil, get_choices, { include_blank: true }, { class: 'text-with-select' })
789
+
790
+ # javascript to update text field if new value is selected in select field
791
+ @js =<<EOJS
792
+ $(document).ready(function() {
793
+ $('##{@yaml['name']}_').change( function() {
794
+ if ($(this).val().toString().length > 0) {
795
+ $('#record_#{@yaml['name']}').val( $(this).val() );
796
+ }
797
+ $('#record_#{@yaml['name']}').focus();
798
+ });
799
+ });
800
+ EOJS
801
+ self
802
+ end
803
+ end
804
+
805
+ ###########################################################################
806
+ # Create html_field form field
807
+ #
808
+ # Class implements redirection for calling actual edit field code.
809
+ # This can be drg_default_html_editor's ckeditor or any other code defined
810
+ # by dc_site.settings html_editor setting.
811
+ ###########################################################################
812
+ class HtmlField < DrgcmsField
813
+
814
+ ###########################################################################
815
+ #
816
+ ###########################################################################
817
+ def render
818
+ return ro_standard if @readonly
819
+ # retrieve html editor from page settings
820
+ editor_string = @parent.dc_get_site.params['html_editor'] if @parent.dc_get_site
821
+ editor_string ||= 'ckeditor'
822
+ #
823
+ klas_string = editor_string.camelize
824
+ if DrgcmsFormField.const_defined?(klas_string)
825
+ klas = DrgcmsFormField::const_get(klas_string)
826
+ o = klas.new(@parent, @record, @yaml).render
827
+ @js << o.js
828
+ @html << o.html
829
+ else
830
+ @html << "HTML editor not defined. Check site.settings or include drgcms_default_html_editor gem."
831
+ end
832
+ self
833
+ end
834
+ end
835
+
836
+ ###########################################################################
837
+ # Create text_field plus select with optional values for the field
838
+ ###########################################################################
839
+ class FileSelect < DrgcmsField
840
+
841
+ ###########################################################################
842
+ #
843
+ ###########################################################################
844
+ def render
845
+ return ro_standard if @readonly
846
+ # retrieve html editor from page settings
847
+ selector_string = @parent.dc_get_site.params['file_select'] if @parent.dc_get_site
848
+ selector_string ||= 'elfinder'
849
+ #
850
+ klas_string = selector_string.camelize
851
+ if DrgcmsFormField.const_defined?(klas_string)
852
+ klas = DrgcmsFormField::const_get(klas_string)
853
+ o = klas.new(@parent, @record, @yaml).render
854
+ @js << o.js
855
+ @html << o.html
856
+ else
857
+ @html << "File select component not defined. Check site.settings or include drgcms_default_html_editor gem."
858
+ end
859
+ self
860
+ end
861
+ end
862
+
863
+ end