drg_cms 0.6.0.6 → 0.6.0.8

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/drg_cms/drg_cms.js +92 -36
  3. data/app/assets/stylesheets/drg_cms/drg_cms.css +141 -101
  4. data/app/assets/stylesheets/drg_cms/select-multiple.css +9 -12
  5. data/app/assets/stylesheets/drg_cms_cms.css +1 -1
  6. data/app/controllers/cmsedit_controller.rb +100 -32
  7. data/app/controllers/dc_application_controller.rb +71 -12
  8. data/app/controls/dc_report.rb +227 -0
  9. data/app/forms/all_options.yml +24 -5
  10. data/app/forms/dc_big_table.yml +1 -0
  11. data/app/forms/dc_big_table_value.yml +1 -0
  12. data/app/forms/dc_poll.yml +12 -5
  13. data/app/forms/dc_poll_item.yml +2 -1
  14. data/app/forms/dc_poll_result.yml +9 -0
  15. data/app/forms/dc_site.yml +2 -6
  16. data/app/helpers/cms_common_helper.rb +311 -0
  17. data/app/helpers/{cmsedit_edit_helper.rb → cms_edit_helper.rb} +52 -25
  18. data/app/helpers/{cmsedit_helper.rb → cms_helper.rb} +38 -31
  19. data/app/helpers/{cmsedit_index_helper.rb → cms_index_helper.rb} +152 -155
  20. data/app/helpers/dc_application_helper.rb +20 -234
  21. data/app/models/concerns/dc_site_concern.rb +12 -1
  22. data/app/models/dc_filter.rb +10 -8
  23. data/app/models/dc_permission.rb +30 -0
  24. data/app/models/dc_poll.rb +1 -0
  25. data/app/models/dc_poll_result.rb +4 -2
  26. data/app/models/dc_temp.rb +5 -2
  27. data/app/models/drgcms_form_fields.rb +12 -1
  28. data/app/models/drgcms_form_fields/date_picker.rb +4 -3
  29. data/app/models/drgcms_form_fields/datetime_picker.rb +4 -3
  30. data/app/models/drgcms_form_fields/drgcms_field.rb +18 -4
  31. data/app/models/drgcms_form_fields/embedded.rb +17 -9
  32. data/app/models/drgcms_form_fields/file_field.rb +1 -1
  33. data/app/models/drgcms_form_fields/hidden_field.rb +1 -1
  34. data/app/models/drgcms_form_fields/method.rb +65 -0
  35. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +17 -11
  36. data/app/models/drgcms_form_fields/radio.rb +10 -5
  37. data/app/models/drgcms_form_fields/readonly.rb +1 -1
  38. data/app/models/drgcms_form_fields/select.rb +49 -32
  39. data/app/models/drgcms_form_fields/text_autocomplete.rb +21 -21
  40. data/app/renderers/dc_big_menu_renderer.rb +1 -0
  41. data/app/renderers/dc_gallery_renderer.rb +1 -0
  42. data/app/renderers/dc_menu_renderer.rb +1 -0
  43. data/app/renderers/dc_page_renderer.rb +1 -0
  44. data/app/renderers/dc_part_renderer.rb +1 -0
  45. data/app/renderers/dc_piece_renderer.rb +1 -1
  46. data/app/renderers/dc_poll_renderer.rb +43 -38
  47. data/app/renderers/dc_renderer.rb +1 -0
  48. data/app/renderers/dc_simple_menu_renderer.rb +1 -0
  49. data/config/locales/drgcms_en.yml +3 -2
  50. data/config/locales/drgcms_sl.yml +5 -4
  51. data/config/locales/models_en.yml +9 -2
  52. data/config/locales/models_sl.yml +10 -3
  53. data/lib/drg_cms/version.rb +1 -1
  54. data/lib/generators/new_drg_form/new_drg_form_generator.rb +5 -3
  55. data/lib/tasks/database.rake +6 -56
  56. metadata +35 -33
  57. data/app/helpers/application_helper.rb +0 -2
@@ -27,7 +27,7 @@
27
27
  # data found in 3 major sections of DRG CMS form: index, result_set and form sections.
28
28
  #
29
29
  ###########################################################################
30
- module CmseditEditHelper
30
+ module CmsEditHelper
31
31
 
32
32
  ############################################################################
33
33
  # Will return value when internal or additional parameters are defined in action
@@ -61,7 +61,15 @@ def dc_is_action_active?(options)
61
61
  # usually only for test
62
62
  when option.class == TrueClass || option['eval'].class == TrueClass then true
63
63
  when option.class == String then
64
- (@record.new_record? && option == 'new_record') || (!@record.new_record? && option == 'not_new_record')
64
+ if option.match(/new_record/i)
65
+ (@record.new_record? && option == 'new_record') || (!@record.new_record? && option == 'not_new_record')
66
+ elsif option.match(/\./)
67
+ # shortcut for method and eval option
68
+ parms = @record ? @record : params
69
+ dc_process_eval(option,parms)
70
+ else
71
+ eval(option['eval'])
72
+ end
65
73
  # direct evaluate expression
66
74
  when option['eval'] then
67
75
  eval(option['eval'])
@@ -98,6 +106,7 @@ def dc_actions_for_form(position)
98
106
  actions = std_actions if actions.nil?
99
107
  # readonly
100
108
  actions = {1 => 'back'} if @form['readonly']
109
+ actions = {1 => 'close'} if params[:window_close]
101
110
  # Actions are strictly forbidden
102
111
  if @form['form']['actions'] and dc_dont?(@form['form']['actions'])
103
112
  actions = []
@@ -126,7 +135,7 @@ def dc_actions_for_form(position)
126
135
  next if options.nil? # yes it happends
127
136
  parms = @parms.clone
128
137
  if options.class == String
129
- next if params[:readonly] and !(options == 'back')
138
+ next if params[:readonly] and !options.match(/back|close/)
130
139
 
131
140
  html << '<li class="dc-link dc-animate">'
132
141
  html << case
@@ -162,6 +171,14 @@ def dc_actions_for_form(position)
162
171
 
163
172
  when options == 'refresh' then
164
173
  "<div onclick='window.location.href=window.location.href;'>#{fa_icon('refresh')} #{t('drgcms.refresh')}</div></li>"
174
+
175
+ when options == 'close' then
176
+ close = params[:window_close].to_i
177
+ if close < 2
178
+ "<div onclick='window.close();'>#{fa_icon('close')} #{t('drgcms.close')}</div></li>"
179
+ else
180
+ "<div onclick='history.back();'>#{fa_icon('close')} #{t('drgcms.close')}</div></li>"
181
+ end
165
182
  else
166
183
  "err1 #{key}=>#{options}"
167
184
  end
@@ -247,21 +264,13 @@ def dc_check_and_default(value, default, values=nil) #:nodoc:
247
264
  value
248
265
  end
249
266
 
250
- ############################################################################
251
- # Creates top or bottom horizontal line on form.
252
- ############################################################################
253
- def dc_top_bottom_line(options)
254
- '<div class="dc-separator"></div>'
255
- end
256
-
257
267
  ############################################################################
258
268
  # Creates input fields for one tab. Subroutine of dc_fields_for_form.
259
269
  ############################################################################
260
270
  def dc_fields_for_tab(fields_on_tab) #:nodoc:
261
- html = '<div class="dc-form">'
262
- labels_pos = dc_check_and_default(@form['form']['labels_pos'], 'right', ['top','left','right'])
263
- hidden_fields = ''
264
- odd_even = nil
271
+ html = '<div class="dc-form">'
272
+ labels_pos = dc_check_and_default(@form['form']['labels_pos'], 'right', ['top', 'left', 'right'])
273
+ hidden_fields, odd_even = '', nil
265
274
  group_option, group_count = 0, 0
266
275
  reset_cycle()
267
276
  # Select form fields and sort them by key
@@ -278,8 +287,8 @@ def dc_fields_for_tab(fields_on_tab) #:nodoc:
278
287
  # label
279
288
  field_html,label,help = dc_field_label_help(options)
280
289
  # Line separator
281
- html << dc_top_bottom_line(options['top-line']) if options['top-line']
282
- # Begining of new row
290
+ html << dc_top_bottom_line(:top, options)
291
+ # Beginning of new row
283
292
  if group_count == 0
284
293
  html << '<div class="row-div">'
285
294
  odd_even = cycle('odd','even')
@@ -320,7 +329,7 @@ def dc_fields_for_tab(fields_on_tab) #:nodoc:
320
329
  html << '<div></div>' if group_option == 2
321
330
  end
322
331
 
323
- html << dc_top_bottom_line(options['bottom-line']) if options['bottom-line']
332
+ html << dc_top_bottom_line(:bottom, options)
324
333
  end
325
334
  html << '</div>' << hidden_fields
326
335
  end
@@ -332,22 +341,22 @@ def dc_fields_for_form()
332
341
  html, tabs, tab_data = '',[], ''
333
342
  @js ||= ''
334
343
  @css ||= ''
335
- # Only fields defined
344
+ # Only fields defined
336
345
  if (form_fields = @form['form']['fields'])
337
346
  html << "<div id='data_fields' " + (@form['form']['height'] ? "style=\"height: #{@form['form']['height']}px;\">" : '>')
338
347
  html << dc_fields_for_tab(form_fields) + '</div>'
339
348
  else
340
- # there are multiple tabs on form
349
+ # there are multiple tabs on form
341
350
  first = true # first tab
342
351
  @form['form']['tabs'].keys.sort.each do |tab_name|
343
352
  next if tab_name.match('actions')
344
- # Tricky. If field name is not on the tab skip to next tab
353
+ # Tricky. If field name is not on the tab skip to next tab
345
354
  if params[:edit_only]
346
355
  is_on_tab = false
347
356
  @form['form']['tabs'][tab_name].each {|k,v| is_on_tab = true if params[:edit_only] == v['name'] }
348
357
  next unless is_on_tab
349
358
  end
350
- # first div is displayed, all others are hidden
359
+ # first div is displayed, all others are hidden
351
360
  tab_data << "<div id=\"data_#{tab_name.delete("\s\n")}\""
352
361
  tab_data << ' class="div-hidden"' unless first
353
362
  tab_data << " style=\"height: #{@form['form']['height']}px;\"" if @form['form']['height']
@@ -356,13 +365,13 @@ def dc_fields_for_form()
356
365
  tabs << [tab_name, tab_label]
357
366
  first = false
358
367
  end
359
- # make it all work together
368
+ # make it all work together
360
369
  html << '<ul class="dc-form-ul" >'
361
370
  first = true # first tab must be selected
362
371
  tabs.each do |tab_name, tab_label|
363
372
  html << "<li id=\"li_#{tab_name}\" data-div=\"#{tab_name.delete("\s\n")}\" class=\"dc-form-li"
364
373
  html << ' dc-form-li-selected' if first
365
- html << "\">#{t(tab_label, t_name(tab_label,tab_label))}</li>"
374
+ html << "\">#{t(tab_label, t_name(tab_label, tab_label))}</li>"
366
375
  first = false
367
376
  end
368
377
  html << '</ul>'
@@ -378,9 +387,8 @@ def dc_fields_for_form()
378
387
  html.html_safe
379
388
  end
380
389
 
381
-
382
390
  ############################################################################
383
- # Creates head form div. Head form div is used to display header datausefull
391
+ # Creates head form div. Head form div is used to display header data usefull
384
392
  # to be seen even when tabs are switched.
385
393
  ############################################################################
386
394
  def dc_head_for_form()
@@ -468,4 +476,23 @@ def dc_document_statistics
468
476
  (html << '</div></div>').html_safe
469
477
  end
470
478
 
479
+ private
480
+
481
+ ############################################################################
482
+ # Creates top or bottom horizontal line on form.
483
+ #
484
+ # @param [String] location (top or bottom)
485
+ # @param [Object] options yaml field definition
486
+ #
487
+ # @return [String] html code for drawing a line
488
+ ############################################################################
489
+ def dc_top_bottom_line(location, options)
490
+ if options["#{location}-line"] || options['line'].to_s == location.to_s
491
+ '<div class="dc-separator"></div>'
492
+ else
493
+ ''
494
+ end
495
+ end
496
+
497
+
471
498
  end
@@ -26,7 +26,7 @@
26
26
  # CmseditHelper module defines common methods used for DRGCMS forms.
27
27
  #
28
28
  ###########################################################################
29
- module CmseditHelper
29
+ module CmsHelper
30
30
  # javascript part created by form helpers
31
31
  attr_reader :js
32
32
 
@@ -75,29 +75,33 @@ end
75
75
  def dc_field_label_help(options)
76
76
  # no label or help in comments
77
77
  unless %w(comment action).include?(options['type'])
78
- caption = options['caption'] || options['text']
79
- label = if caption.blank?
78
+ label = options['caption'] || options['text'] || options['label']
79
+ label = if label.blank?
80
80
  t_name(options['name'], options['name'].capitalize.gsub('_',' ') )
81
81
  elsif options['name']
82
- t(caption, caption)
82
+ t(label, label)
83
83
  end
84
84
  # help text can be defined in form or in translations starting with helpers. or as helpers.help.collection.field
85
- help = if options['help']
86
- options['help'].match('helpers.') ? t(options['help']) : options['help']
87
- end
88
- help ||= t('helpers.help.' + @form['table'] + '.' + options['name'],' ') if options['name']
85
+ help = options['help']
86
+ help ||= "helpers.help.#{@form['table']}.#{options['name']}" if options['name']
87
+ help = t(help, ' ') if help.to_s.match(/helpers\./)
89
88
  end
90
- # create field object from class and call its render method
91
- klass_string = options['type'].camelize
92
- field_html = if DrgcmsFormFields.const_defined?(klass_string) # when field type defined
93
- klass = DrgcmsFormFields.const_get(klass_string)
94
- field = klass.new(self, @record, options).render
95
- @js << field.js
96
- @css << field.css
97
- field.html
98
- else # litle error string
99
- "Error: Field type #{options['type']} not defined!"
89
+ # create field object from type option and call its render method
90
+ if options['type'].present?
91
+ klass_string = options['type'].camelize
92
+ field_html = if DrgcmsFormFields.const_defined?(klass_string) # when field type defined
93
+ klass = DrgcmsFormFields.const_get(klass_string)
94
+ field = klass.new(self, @record, options).render
95
+ @js << field.js
96
+ @css << field.css
97
+ field.html
98
+ else
99
+ "Error: Field type #{options['type']} not defined!"
100
+ end
101
+ else
102
+ "Error: Field type missing!"
100
103
  end
104
+
101
105
  [field_html, label, help]
102
106
  end
103
107
 
@@ -110,25 +114,26 @@ def dc_field_action(yaml)
110
114
  value = params['record'][yaml['name']]
111
115
  params["p_#{yaml['name']}"] = value
112
116
  end
113
- #
117
+ # find field definition on form
114
118
  if ( field_definition = dc_get_field_form_definition(yaml['name']) )
115
- field, label, help = dc_field_label_help(field_definition)
119
+ # some options may be redefined
120
+ field_definition['size'] = yaml['size'] if yaml['size']
121
+ field, label, help = dc_field_label_help(field_definition)
116
122
  else
117
123
  yaml['type'] = yaml['field_type']
118
124
  field, label, help = dc_field_label_help(yaml)
119
125
  end
120
- # input field will have label as placeholder
121
- field = field.sub('input',"input placeholder=\"#{label}\"")
122
- %Q[<li class="no-background">#{field}</li>]
123
-
126
+ # input field will have label as placeholder
127
+ field = field.sub('input',"input placeholder=\"#{label}\"")
128
+ %Q[<li class="no-background">#{field}</li>]
124
129
  end
125
130
 
126
131
  ############################################################################
127
- #
132
+ # Create ex. class="my-class" html code from html options for action
128
133
  ############################################################################
129
134
  def dc_html_data(yaml)
130
135
  return '' if yaml.blank?
131
- yaml.inject(' ') {|result, e| result << "#{e.first}=\"#{e.last}\" "}
136
+ yaml.inject(' ') {|result, e| result = e.last.nil? ? result : result << "#{e.first}=\"#{e.last}\" "}
132
137
  end
133
138
 
134
139
  ############################################################################
@@ -154,6 +159,9 @@ def dc_link_ajax_window_submit_action(yaml, record=nil, action_active=true)
154
159
  yaml['html'] ||= {}
155
160
  confirm = yaml['html']['data-confirm'] || yaml['confirm']
156
161
  yaml['html']['data-confirm'] = t(confirm) unless confirm.blank?
162
+ yaml['html']['title'] ||= yaml['title']
163
+ yaml['html']['title'] = t(yaml['title'])
164
+ yaml['html']['target'] ||= yaml['target']
157
165
  # direct url
158
166
  if yaml['url']
159
167
  parms['controller'] = yaml['url']
@@ -162,7 +170,7 @@ def dc_link_ajax_window_submit_action(yaml, record=nil, action_active=true)
162
170
  else
163
171
  parms['controller'] = yaml['controller'] || 'cmsedit'
164
172
  parms['action'] = yaml['action']
165
- parms['table'] = yaml['table']
173
+ parms['table'] = yaml['table'] || @form['table']
166
174
  parms['form_name'] = yaml['form_name']
167
175
  parms['control'] = yaml['control'] if yaml['control']
168
176
  parms['id'] = record.id if record
@@ -176,15 +184,14 @@ def dc_link_ajax_window_submit_action(yaml, record=nil, action_active=true)
176
184
  if parms['controller'].nil? && parms['url'].nil?
177
185
  "<li>#{'Controller not defined'}</li>"
178
186
  else
179
- yaml['caption'] ||= yaml['text']
180
-
187
+ yaml['caption'] ||= yaml['text']
181
188
  html_data = dc_html_data(yaml['html'])
182
189
  #
183
190
  url = url_for(parms) rescue 'URL error'
184
191
  request = yaml['request'] || yaml['method'] || 'get'
185
192
  if yaml['type'] == 'ajax' # ajax button
186
193
  clas = "dc-link-ajax dc-animate"
187
- %Q[<li class="#{clas}" data-url="#{action_active ? url : ''}" #{html_data}
194
+ %Q[<li class="#{clas}" data-url="#{action_active ? url : ''}" #{html_data}
188
195
  data-request="#{request}" title="#{yaml['title']}">#{icon}#{caption}</li>]
189
196
 
190
197
  elsif yaml['type'] == 'submit' # submit button
@@ -197,7 +204,7 @@ def dc_link_ajax_window_submit_action(yaml, record=nil, action_active=true)
197
204
 
198
205
  elsif yaml['type'] == 'link' # link button
199
206
  clas = "dc-link dc-animate"
200
- link = dc_link_to(yaml['caption'],yaml['icon'], parms, {target: yaml['target'], html: yaml['html']} )
207
+ link = dc_link_to(yaml['caption'], yaml['icon'], parms, html_data )
201
208
  %Q[<li class="#{clas}">#{action_active ? link : caption}</li>]
202
209
 
203
210
  elsif yaml['type'] == 'window'
@@ -27,29 +27,8 @@
27
27
  # data found in 3 major sections of DRG CMS form: index, result_set and form sections.
28
28
  #
29
29
  ###########################################################################
30
- module CmseditIndexHelper
30
+ module CmsIndexHelper
31
31
 
32
- ############################################################################
33
- # Get standard actions when actions directive contains single line.
34
- # Subroutine of dc_actions_for_index
35
- #
36
- # Allows for actions: new, filter, standard syntax
37
- ############################################################################
38
- def define_standard_actions(actions_params, standard)
39
- actions = {}
40
- actions_params.split(',').each do |an_action|
41
- an_action.strip!
42
- if an_action == 'standard'
43
- actions.merge!(standard)
44
- else
45
- standard.each do |index, action|
46
- (actions[index] = action; break) if action == an_action
47
- end
48
- end
49
- end
50
- actions
51
- end
52
-
53
32
  ############################################################################
54
33
  # Creates action div for cmsedit index action.
55
34
  ############################################################################
@@ -62,7 +41,7 @@ def dc_actions_for_index()
62
41
 
63
42
  std_actions = {2 => 'new', 3 => 'sort', 4 => 'filter' }
64
43
  if actions.class == String
65
- actions = define_standard_actions(actions, std_actions)
44
+ actions = dc_define_standard_actions(actions, std_actions)
66
45
  elsif actions['standard']
67
46
  actions.merge!(std_actions)
68
47
  actions['standard'] = nil
@@ -113,7 +92,7 @@ EOT
113
92
  end
114
93
  fa_icon('sort-alpha-asc') + ' ' + t('drgcms.sort') + ' ' +
115
94
  select('sort', 'sort', choices, { include_blank: true },
116
- { class: 'drgcms_sort', 'data-table' => @form['table']} )
95
+ { class: 'drgcms_sort', 'data-table' => @form['table'], 'data-form' => params['form_name']} )
117
96
  # filter
118
97
  when action == 'filter' then
119
98
  caption = t('drgcms.filter')
@@ -121,8 +100,9 @@ EOT
121
100
  # add filter OFF link
122
101
  sess = session[@form['table']]
123
102
  if sess and sess[:filter]
124
- caption << '&nbsp;&nbsp;' + dc_link_to(nil,'remove lg', {controller: 'cmsedit',
125
- filter: 'off', table: @form['table']}, { title: DcFilter.title4_filter_off(sess[:filter]) })
103
+ caption << '&nbsp;&nbsp;' + dc_link_to(nil,'remove lg',
104
+ { controller: 'cmsedit', filter: 'off', table: @form['table'], form_name: params['form_name'] },
105
+ { title: DcFilter.title4_filter_off(sess[:filter]) })
126
106
  end
127
107
  caption
128
108
  # new
@@ -229,79 +209,63 @@ end
229
209
  ############################################################################
230
210
  def dc_table_title_for_result(result=nil)
231
211
  title = if @form['title'] # form has title section
232
- t(@form['title'], @form['title'])
212
+ if @form['title'].class == Hash
213
+ dc_process_eval(@form['title']['eval'], [@form['title']['caption'] || @form['title']['text'], params])
214
+ else
215
+ t(@form['title'], @form['title'])
216
+ end
233
217
  else # get name from translations
234
218
  t("helpers.label.#{@form['table']}.tabletitle", @form['table'])
235
219
  end
236
220
  dc_table_title(title, result)
237
221
  end
238
222
 
239
- ############################################################################
240
- # Creates code for link or ajax action type. Subroutine of dc_actions_for_result.
241
- ############################################################################
242
- def __dc_link_or_ajax_action(yaml, parms) #:nodoc:
243
- rest = {}
244
- rest['method'] = yaml['method'] || yaml['request'] || 'get'
245
- rest['caption'] = yaml['caption'] || yaml['text']
246
- rest['class'] = 'dc-animate'
247
- rest['title'] = yaml['title']
248
-
249
- if yaml['type'] == 'link'
250
- dc_link_to(yaml['caption'], yaml['icon'], parms, rest )
251
- else
252
- rest['data-url'] = url_for(parms)
253
- rest['class'] << " fa fa-#{yaml['icon']}"
254
- fa_icon(yaml['icon'], rest )
255
- end
256
- end
257
-
258
223
  ############################################################################
259
224
  # Determines actions and width of actions column
260
225
  ############################################################################
261
- def dc_actions_column()
226
+ def dc_actions_column
262
227
  actions = @form['result_set']['actions']
263
- return [{},0] if actions.nil? or dc_dont?(actions)
228
+ return [{}, 0] if actions.nil? or dc_dont?(actions)
264
229
  # standard actions
265
230
  actions = {'standard' => true} if actions.class == String && actions == 'standard'
266
- std_actions = {' 2' => 'edit', ' 3' => 'delete'}
231
+ std_actions = { 2 => 'edit', 5 => 'delete' }
267
232
  if actions['standard']
268
233
  actions.merge!(std_actions)
269
234
  actions.delete('standard')
270
235
  end
271
236
  #
272
237
  width = @form['result_set']['actions_width'] || 18*actions.size
273
- [ actions, width ]
238
+ [actions, width]
274
239
  end
275
240
 
276
241
  ############################################################################
277
242
  # Calculates (blank) space required for actions when @record_footer is rendered
278
243
  ############################################################################
279
- def dc_actions_column_for_footer()
244
+ def dc_actions_column_for_footer
280
245
  return '' unless @form['result_set']['actions']
246
+
281
247
  ignore, width = dc_actions_column
282
248
  %Q[<div class="actions" style="width: #{width}px;"></div>].html_safe
283
249
  end
284
250
 
285
-
286
251
  ############################################################################
287
252
  # Creates actions that could be performed on single row of result set.
288
253
  ############################################################################
289
254
  def dc_actions_for_result(document)
290
255
  actions = @form['result_set']['actions']
291
256
  return '' if actions.nil? or @form['readonly']
292
- #
257
+
293
258
  actions, width = dc_actions_column()
294
259
  html = %Q[<ul class="actions" style="width: #{width}px;">]
295
- actions.each do |k,v|
260
+ actions.sort_by(&:first).each do |k, v|
296
261
  session[:form_processing] = "result_set:actions: #{k}=#{v}"
297
- next if k == 'standard' # ignore standard definition
298
- parms = @parms.clone
262
+ parms = @parms.clone
299
263
  # if single definition simulate type parameter
300
- yaml = v.class == String ? {'type' => v} : v
264
+ yaml = v.class == String ? { 'type' => v } : v
301
265
  # code already includes li tag
302
266
  if %w(ajax link window submit).include?(yaml['type']) then
303
267
  @record = document # otherwise document fields can't be used as parameters
304
- html << dc_link_ajax_window_submit_action(yaml,document)
268
+ html << dc_link_ajax_window_submit_action(yaml, document)
305
269
  else
306
270
  html << '<li class="dc-link">'
307
271
  html << case
@@ -327,21 +291,7 @@ def dc_actions_for_result(document)
327
291
  parms['ids'] ||= ''
328
292
  parms['ids'] += "#{document.id};"
329
293
  dc_link_to( nil, 'table lg', parms, method: :get )
330
- =begin
331
- when yaml['type'] == 'link' || yaml['type'] == 'ajax' then
332
- if yaml['url']
333
- parms['controller'] = yaml['url']
334
- parms['idr'] = document.id
335
- else
336
- parms['id'] = document.id
337
- end
338
- parms['controller'] = yaml['controller'] if yaml['controller']
339
- parms['action'] = yaml['action'] if yaml['action']
340
- parms['table'] = yaml['table'] if yaml['table']
341
- parms['form_name'] = yaml['form_name'] if yaml['form_name']
342
- parms['target'] = yaml['target'] if yaml['target']
343
- dc_link_or_ajax_action(yaml, parms)
344
- =end
294
+
345
295
  else # error.
346
296
  yaml['type'].to_s
347
297
  end
@@ -359,33 +309,35 @@ def dc_header_for_result()
359
309
  html = '<div class="dc-result-header">'
360
310
  if @form['result_set']['actions'] and !@form['readonly']
361
311
  ignore, width = dc_actions_column()
362
- html << %Q[<div class="actions" style="width: #{width}px;"></div>]
312
+ html << %Q[<div class="actions" style="width:#{width}px;"></div>]
363
313
  end
364
314
  # preparation for sort icon
365
315
  sort_field, sort_direction = nil, nil
366
316
  if session[@form['table']]
367
317
  sort_field, sort_direction = session[@form['table']][:sort].to_s.split(' ')
368
318
  end
369
- #
319
+
370
320
  if (columns = @form['result_set']['columns'])
371
- columns.sort.each do |k,v|
321
+ columns.sort.each do |k, v|
372
322
  session[:form_processing] = "result_set:columns: #{k}=#{v}"
373
- th = %Q[<div class="th" style="width: #{v['width'] || '15%'};text-align: #{v['align'] || 'left'};" data-name="#{v['name']}"]
374
- # when no caption or name is defined it might be just spacer
375
- if (caption = v['caption']).nil?
376
- caption = v['name'] ? t("helpers.label.#{@form['table']}.#{v['name']}") : ''
377
- end
323
+ next if v['width'].to_s.match(/hidden|none/i)
324
+
325
+ th = %Q[<div class="th" style="width:#{v['width'] || '15%'};text-align:#{v['align'] || 'left'};" data-name="#{v['name']}"]
326
+ label = v['caption'] || v['label']
327
+ label = (v['name'] ? "helpers.label.#{@form['table']}.#{v['name']}" : '') if label.nil?
328
+ label = t(label) if label.match(/helpers\./)
378
329
  # no sorting when embedded documents or custom filter is active
379
330
  sort_ok = @form['result_set'].nil? || (@form['result_set'] && @form['result_set']['filter'].nil?)
380
331
  sort_ok = sort_ok || (@form['index'] && @form['index']['sort'])
332
+ sort_ok = sort_ok && !dc_dont?(v['sort'], false)
381
333
  if @tables.size == 1 and sort_ok
382
334
  icon = 'sort lg'
383
335
  if v['name'] == sort_field
384
336
  icon = sort_direction == '1' ? 'sort-alpha-asc lg' : 'sort-alpha-desc lg'
385
337
  end
386
- th << ">#{dc_link_to(caption, icon, sort: v['name'], table: params[:table], form_name: params[:form_name], action: :index, icon_pos: :last )}</div>"
338
+ th << ">#{dc_link_to(label, icon, sort: v['name'], table: params[:table], form_name: params[:form_name], action: :index, icon_pos: :last )}</div>"
387
339
  else
388
- th << ">#{caption}</div>"
340
+ th << ">#{label}</div>"
389
341
  end
390
342
  html << "<div class=\"spacer\"></div>" + th
391
343
  end
@@ -407,6 +359,8 @@ def dc_clicks_for_result(document)
407
359
  opts[:form_name] = yaml['form_name']
408
360
  opts[:method] = yaml['method'] || 'get'
409
361
  opts[:id] = document['id']
362
+ opts[:readonly] = yaml['readonly'] if yaml['readonly']
363
+ opts[:window_close] = yaml['window_close'] if yaml['window_close']
410
364
  html << ' data-dblclick=' + url_for(opts)
411
365
  else
412
366
  html << (' data-dblclick=' +
@@ -422,14 +376,13 @@ end
422
376
  ############################################################################
423
377
  def dc_format_value(value, format=nil)
424
378
  return '' if value.nil?
379
+
425
380
  klass = value.class.to_s
426
- case when klass.match('Time') then
427
- format ||= t('time.formats.default')
428
- value.strftime(format)
429
- when klass.match('Date') then
430
- format ||= t('date.formats.default')
431
- value.strftime(format)
432
- when format.to_s[0] == 'N' then
381
+ if klass.match(/time|date/i)
382
+ CmsCommonHelper.dc_format_date_time(value, format)
383
+ elsif format.to_s[0] == 'N'
384
+ return '' if value == 0 and format.match('z')
385
+
433
386
  dec = format[1].blank? ? nil : format[1].to_i
434
387
  sep = format[2].blank? ? nil : format[2]
435
388
  del = format[3].blank? ? nil : format[3]
@@ -440,26 +393,6 @@ def dc_format_value(value, format=nil)
440
393
  end
441
394
  end
442
395
 
443
- ############################################################################
444
- # Defines style or class for row (tr) or column (td)
445
- ############################################################################
446
- def dc_style_or_class(selector, yaml, value, record)
447
- return '' if yaml.nil?
448
- # alias record and value so both names can be used in eval
449
- field, document = value, record
450
- html = selector ? "#{selector}=\"" : ''
451
- html << if yaml.class == String
452
- yaml
453
- # direct evaluate expression
454
- elsif yaml['eval']
455
- eval(yaml['eval']) rescue 'background-color:red;'
456
- elsif yaml['method']
457
- dc_process_eval(yaml['method'],record)
458
- end
459
- html << '"' if selector
460
- html
461
- end
462
-
463
396
  ############################################################################
464
397
  # Creates tr code for each row of result set.
465
398
  ############################################################################
@@ -469,6 +402,52 @@ def dc_row_for_result(document)
469
402
  "<div id=\"#{document.id}\" class=\"dc-result-data #{clas}\" #{dc_clicks_for_result(document)} #{style}>".html_safe
470
403
  end
471
404
 
405
+ ############################################################################
406
+ # Creates column for each field of result set document.
407
+ ############################################################################
408
+ def dc_columns_for_result(document)
409
+ return '' unless @form['result_set']['columns']
410
+ html = ''
411
+ @form['result_set']['columns'].sort.each do |k,v|
412
+ session[:form_processing] = "result_set:columns: #{k}=#{v}"
413
+ next if v['width'].to_s.match(/hidden|none/i)
414
+
415
+ # convert shortcut to hash
416
+ v = {'name' => v} if v.class == String
417
+ begin
418
+ # eval
419
+ value = if v['eval']
420
+ dc_process_column_eval(v, document)
421
+ # as field
422
+ elsif document.respond_to?(v['name'])
423
+ dc_format_value(document.send( v['name'] ), v['format'])
424
+ # as hash (dc_memory)
425
+ elsif document.class == Hash
426
+ dc_format_value(document[ v['name'] ], v['format'])
427
+ # error
428
+ else
429
+ "??? #{v['name']}"
430
+ end
431
+ rescue Exception => e
432
+ dc_log_exception(e)
433
+ value = '!!!Error'
434
+ end
435
+ html << '<div class="spacer"></div>'
436
+ # set class
437
+ clas = dc_style_or_class(nil, v['td_class'], value, document)
438
+ # set width and align an additional style
439
+ style = dc_style_or_class(nil, v['td_style'] || v['style'], value, document)
440
+ flex_align = v['align'].to_s == 'right' ? 'flex-direction:row-reverse;' : ''
441
+ width_align = %Q[width:#{v['width'] || '15%'};#{flex_align}]
442
+ style = "style=\"#{width_align}#{style}\" "
443
+
444
+ html << "<div class=\"td #{clas}\" #{style}>#{value}</div>"
445
+ end
446
+ html.html_safe
447
+ end
448
+
449
+ private
450
+
472
451
  ############################################################################
473
452
  # Process eval. Breaks eval option and calls with send method.
474
453
  # Parameters:
@@ -486,22 +465,41 @@ def dc_process_eval(evaluate, parameters)
486
465
  end
487
466
  end
488
467
 
468
+ ############################################################################
469
+ # Break eval expression to array by parameters.
470
+ # Will break dc_name4_value(one ,"two") => ['dc_name4_value', 'one', 'two']
471
+ ############################################################################
472
+ def dc_eval_to_array(expression)
473
+ expression.split(/\ |\,|\(|\)/).delete_if {|e| e.blank? }.map {|e| e.gsub(/\'|\"/,'').strip }
474
+ end
475
+
489
476
  ############################################################################
490
477
  # Process eval option for field value.
491
478
  # Used for processing single field column on result_set or form head.
492
479
  ############################################################################
493
480
  def dc_process_column_eval(yaml, document)
494
- # dc_name4_id
495
- if yaml['eval'].match('dc_name4_id')
496
- a = yaml['eval'].split(/\ |\,/)
497
- if a.size == 3
498
- dc_name4_id(a[1], a[2], nil, document[ yaml['name'] ])
481
+ # dc_name_for_id
482
+ if yaml['eval'].match('dc_name4_id') || yaml['eval'].match('dc_name_for_id')
483
+ prms = dc_eval_to_array(yaml['eval'])
484
+ if prms.size == 3
485
+ dc_name_for_id(prms[1], prms[2], nil, document[ yaml['name'] ])
499
486
  else
500
- dc_name4_id(a[1], a[2], a[3], document[ yaml['name'] ])
487
+ dc_name_for_id(prms[1], prms[2], prms[3], document[ yaml['name'] ])
501
488
  end
502
- # dc_name4_value
503
- elsif yaml['eval'].match('dc_name4_value')
504
- dc_name4_value( @form['table'], yaml['name'], document[ yaml['name'] ] )
489
+ # dc_name_for_value from this model
490
+ elsif yaml['eval'] == 'dc_name4_value' || yaml['eval'] == 'dc_name_for_value'
491
+ dc_name_for_value( @form['table'], yaml['name'], document[ yaml['name'] ] )
492
+ # dc_name_for_value from other model
493
+ elsif yaml['eval'].match('dc_name4_value') || yaml['eval'].match('dc_name_for_value')
494
+ prms = dc_eval_to_array(yaml['eval'])
495
+ dc_name_for_value( prms[1], prms[2], document[ yaml['name'] ] )
496
+ # for example dc_icon_for_boolean
497
+ elsif respond_to?(yaml['eval'])
498
+ send(yaml['eval'], document[ yaml['name'] ])
499
+ # defined in document
500
+ elsif document.respond_to?(yaml['eval'])
501
+ document.send(yaml['eval'])
502
+ # special eval
505
503
  elsif yaml['eval'].match('eval ')
506
504
  # TO DO evaluate with specified parameters
507
505
  else
@@ -523,45 +521,44 @@ def dc_process_column_eval(yaml, document)
523
521
  end
524
522
 
525
523
  ############################################################################
526
- # Creates column for each field of result set document.
524
+ # Defines style or class for row (tr) or column (td)
527
525
  ############################################################################
528
- def dc_columns_for_result(document)
529
- return '' unless @form['result_set']['columns']
530
- html = ''
531
- @form['result_set']['columns'].sort.each do |k,v|
532
- session[:form_processing] = "result_set:columns: #{k}=#{v}"
533
- # convert shortcut to hash
534
- v = {'name' => v} if v.class == String
535
- begin
536
- # eval
537
- value = if v['eval']
538
- dc_process_column_eval(v, document)
539
- # as field
540
- elsif document.respond_to?(v['name'])
541
- dc_format_value(document.send( v['name'] ), v['format'])
542
- # as hash (dc_memory)
543
- elsif document.class == Hash
544
- dc_format_value(document[ v['name'] ], v['format'])
545
- # error
546
- else
547
- "!!! #{v['name']}"
526
+ def dc_style_or_class(selector, yaml, value, record)
527
+ return '' if yaml.nil?
528
+ # alias record and value so both names can be used in eval
529
+ field, document = value, record
530
+ html = selector ? "#{selector}=\"" : ''
531
+ html << if yaml.class == String
532
+ yaml
533
+ # direct evaluate expression
534
+ elsif yaml['eval']
535
+ eval(yaml['eval']) rescue 'background-color:red;'
536
+ elsif yaml['method']
537
+ dc_process_eval(yaml['method'],record)
538
+ end
539
+ html << '"' if selector
540
+ html
541
+ end
542
+
543
+ ############################################################################
544
+ # Get standard actions when actions directive contains single line.
545
+ # Subroutine of dc_actions_for_index
546
+ #
547
+ # Allows for actions: new, filter, standard syntax
548
+ ############################################################################
549
+ def dc_define_standard_actions(actions_params, standard)
550
+ actions = {}
551
+ actions_params.split(',').each do |an_action|
552
+ an_action.strip!
553
+ if an_action == 'standard'
554
+ actions.merge!(standard)
555
+ else
556
+ standard.each do |index, action|
557
+ (actions[index] = action; break) if action == an_action
548
558
  end
549
- rescue Exception => e
550
- dc_log_exception(e)
551
- value = '!!!Error'
552
559
  end
553
- html << '<div class="spacer"></div>'
554
- # set class
555
- clas = dc_style_or_class(nil, v['td_class'], value, document)
556
- # set width and align an additional style
557
- style = dc_style_or_class(nil, v['td_style'] || v['style'], value, document)
558
- width_align = %Q[width: #{v['width'] || '15%'};text-align: #{v['align'] || 'left'};]
559
- style = "#{width_align}#{style}"
560
-
561
- html << "<div class=\"td #{clas}\" style=\"#{style}\">#{value}</div>"
562
- end
563
- html.html_safe
560
+ end
561
+ actions
564
562
  end
565
563
 
566
-
567
564
  end