drg_cms 0.6.0.3 → 0.6.0.6
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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/drg_cms/drg_cms.js +259 -102
- data/app/assets/javascripts/drg_cms_cms.js +1 -1
- data/app/assets/stylesheets/drg_cms/drg_cms.css +314 -142
- data/app/assets/stylesheets/drg_cms/select-multiple.css +11 -2
- data/app/controllers/cmsedit_controller.rb +313 -236
- data/app/controllers/dc_application_controller.rb +29 -4
- data/app/controllers/dc_common_controller.rb +19 -16
- data/app/{controllers → controls}/browse_models_control.rb +0 -0
- data/app/{controllers → controls}/dc_page_control.rb +24 -8
- data/app/controls/dc_poll_result_control.rb +88 -0
- data/app/{controllers → controls}/design_element_settings_control.rb +0 -0
- data/app/forms/all_options.yml +11 -3
- data/app/forms/cms_menu.yml +22 -18
- data/app/forms/dc_design.yml +6 -3
- data/app/forms/dc_filter.yml +3 -6
- data/app/forms/dc_poll_result.yml +74 -0
- data/app/forms/dc_poll_result_export.yml +35 -0
- data/app/helpers/cmsedit_edit_helper.rb +471 -0
- data/app/helpers/cmsedit_helper.rb +151 -821
- data/app/helpers/cmsedit_index_helper.rb +567 -0
- data/app/helpers/dc_application_helper.rb +48 -31
- data/app/models/{dc_dummy.rb → __dc_dummy.rb} +0 -0
- data/app/models/dc_filter.rb +12 -5
- data/app/models/dc_memory.rb +8 -1
- data/app/models/dc_poll.rb +38 -19
- data/app/models/dc_poll_result.rb +44 -0
- data/app/models/dc_temp.rb +137 -0
- data/app/models/drgcms_form_fields/action.rb +61 -0
- data/app/models/drgcms_form_fields/comment.rb +8 -4
- data/app/models/drgcms_form_fields/date_picker.rb +7 -6
- data/app/models/drgcms_form_fields/date_select.rb +1 -1
- data/app/models/drgcms_form_fields/datetime_picker.rb +8 -7
- data/app/models/drgcms_form_fields/datetime_select.rb +1 -1
- data/app/models/drgcms_form_fields/drgcms_field.rb +39 -7
- data/app/models/drgcms_form_fields/embedded.rb +7 -2
- data/app/models/drgcms_form_fields/file_field.rb +52 -0
- data/app/models/drgcms_form_fields/html_field.rb +1 -1
- data/app/models/drgcms_form_fields/multitext_autocomplete.rb +7 -4
- data/app/models/drgcms_form_fields/number_field.rb +15 -6
- data/app/models/drgcms_form_fields/radio.rb +91 -0
- data/app/models/drgcms_form_fields/readonly.rb +1 -1
- data/app/models/drgcms_form_fields/select.rb +14 -2
- data/app/models/drgcms_form_fields/text_area.rb +1 -1
- data/app/models/drgcms_form_fields/text_autocomplete.rb +1 -1
- data/app/models/drgcms_form_fields/text_field.rb +1 -1
- data/app/models/drgcms_form_fields/text_with_select.rb +6 -3
- data/app/models/drgcms_form_fields/tree_select.rb +11 -3
- data/app/renderers/dc_poll_renderer.rb +29 -11
- data/app/views/cmsedit/{remove_edit_stuff.js.erb → __remove_edit_stuff.js.erb} +0 -0
- data/app/views/cmsedit/{show.html.erb → __show.html.erb} +0 -0
- data/app/views/cmsedit/_edit_stuff.html.erb +2 -4
- data/app/views/cmsedit/_form.html.erb +4 -3
- data/app/views/cmsedit/_result.html.erb +2 -3
- data/app/views/cmsedit/edit.html.erb +2 -1
- data/app/views/cmsedit/index.html.erb +6 -1
- data/app/views/cmsedit/new.html.erb +1 -1
- data/config/locales/drgcms_en.yml +7 -0
- data/config/locales/drgcms_sl.yml +8 -1
- data/config/locales/models_en.yml +13 -4
- data/config/locales/models_sl.yml +13 -2
- data/drg_cms.gemspec +1 -1
- data/lib/drg_cms.rb +1 -0
- data/lib/drg_cms/version.rb +1 -1
- data/lib/generators/new_drg_form/new_drg_form_generator.rb +7 -2
- metadata +20 -13
- data/app/assets/stylesheets/drg_cms/__jquery-ui.css +0 -339
- data/test/fixtures/drg_cms_test_data.rb +0 -87
@@ -0,0 +1,567 @@
|
|
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
|
+
|
24
|
+
###########################################################################
|
25
|
+
#
|
26
|
+
# CmseditHelper module defines helper methods used by cmsedit actions. Output is controlled by
|
27
|
+
# data found in 3 major sections of DRG CMS form: index, result_set and form sections.
|
28
|
+
#
|
29
|
+
###########################################################################
|
30
|
+
module CmseditIndexHelper
|
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
|
+
############################################################################
|
54
|
+
# Creates action div for cmsedit index action.
|
55
|
+
############################################################################
|
56
|
+
def dc_actions_for_index()
|
57
|
+
@js = @form['script'] || @form['js'] || ''
|
58
|
+
@css = @form['css'] || ''
|
59
|
+
return '' if @form['index'].nil? or @form['readonly']
|
60
|
+
actions = @form['index']['actions']
|
61
|
+
return '' if actions.blank?
|
62
|
+
|
63
|
+
std_actions = {2 => 'new', 3 => 'sort', 4 => 'filter' }
|
64
|
+
if actions.class == String
|
65
|
+
actions = define_standard_actions(actions, std_actions)
|
66
|
+
elsif actions['standard']
|
67
|
+
actions.merge!(std_actions)
|
68
|
+
actions['standard'] = nil
|
69
|
+
end
|
70
|
+
|
71
|
+
# start div with hidden spinner image
|
72
|
+
html = <<EOT
|
73
|
+
<form id="dc-action-menu">
|
74
|
+
<span class="dc-spinner">#{fa_icon('spinner lg spin')}</span>
|
75
|
+
<ul class="dc-action-menu">
|
76
|
+
EOT
|
77
|
+
# Remove actions settings and sort
|
78
|
+
only_actions = []
|
79
|
+
actions.each { |key, value| only_actions << [key, value] if key.class == Integer }
|
80
|
+
only_actions.sort_by!(&:first)
|
81
|
+
only_actions.each do |key, options|
|
82
|
+
session[:form_processing] = "index:actions: #{key}=#{options}"
|
83
|
+
next if options.nil? # must be
|
84
|
+
url = @parms.clone
|
85
|
+
yaml = options.class == String ? {'type' => options} : options # if single definition simulate type parameter
|
86
|
+
action = yaml['type'].to_s.downcase
|
87
|
+
if action == 'url'
|
88
|
+
dc_deprecate "action: url will be deprecated. Use action: link in index: actions! Form #{params['form_name']}"
|
89
|
+
action = 'link'
|
90
|
+
end
|
91
|
+
# if return_to is present link directly to URL
|
92
|
+
if action == 'link' and yaml['url']
|
93
|
+
url = yaml['url']
|
94
|
+
else
|
95
|
+
url['controller'] = yaml['controller'] if yaml['controller']
|
96
|
+
url['action'] = yaml['action'] || action
|
97
|
+
url['table'] = yaml['table'] if yaml['table']
|
98
|
+
url['form_name'] = yaml['form_name'] if yaml['form_name']
|
99
|
+
url['control'] = yaml['control'] if yaml['control']
|
100
|
+
end
|
101
|
+
# html link options
|
102
|
+
yhtml = yaml['html'] || {}
|
103
|
+
yhtml['title'] = yaml['title'] if yaml['title']
|
104
|
+
code = case
|
105
|
+
# sort
|
106
|
+
when action == 'sort' then
|
107
|
+
choices = [['id','id']]
|
108
|
+
if @form['index']['sort']
|
109
|
+
@form['index']['sort'].split(',').each do |s|
|
110
|
+
s.strip!
|
111
|
+
choices << [ t("helpers.label.#{@form['table']}.#{s}"), s ]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
fa_icon('sort-alpha-asc') + ' ' + t('drgcms.sort') + ' ' +
|
115
|
+
select('sort', 'sort', choices, { include_blank: true },
|
116
|
+
{ class: 'drgcms_sort', 'data-table' => @form['table']} )
|
117
|
+
# filter
|
118
|
+
when action == 'filter' then
|
119
|
+
caption = t('drgcms.filter')
|
120
|
+
caption << ' ' + fa_icon('caret-down lg') + DcFilter.menu_filter(self)
|
121
|
+
# add filter OFF link
|
122
|
+
sess = session[@form['table']]
|
123
|
+
if sess and sess[:filter]
|
124
|
+
caption << ' ' + dc_link_to(nil,'remove lg', {controller: 'cmsedit',
|
125
|
+
filter: 'off', table: @form['table']}, { title: DcFilter.title4_filter_off(sess[:filter]) })
|
126
|
+
end
|
127
|
+
caption
|
128
|
+
# new
|
129
|
+
when action == 'new' then
|
130
|
+
caption = yaml['caption'] || 'drgcms.new'
|
131
|
+
dc_link_to(caption,'plus', url, yhtml )
|
132
|
+
# menu
|
133
|
+
when action == 'menu' then
|
134
|
+
caption = t(options['caption'], options['caption']) + ' ' + fa_icon('caret-down lg')
|
135
|
+
caption + eval(options['eval'])
|
136
|
+
=begin
|
137
|
+
# reorder
|
138
|
+
when action == 'reorder' then
|
139
|
+
caption = t('drgcms.reorder')
|
140
|
+
parms = @parms.clone
|
141
|
+
parms['operation'] = v
|
142
|
+
parms['id'] = params[:ids]
|
143
|
+
parms['table'] = @form['table']
|
144
|
+
dc_link_to( caption, 'reorder', parms, method: :delete )
|
145
|
+
=end
|
146
|
+
when action == 'script'
|
147
|
+
html << dc_script_action(options)
|
148
|
+
next
|
149
|
+
when action == 'field'
|
150
|
+
html << dc_field_action(yaml)
|
151
|
+
next
|
152
|
+
when %w(ajax link window submit).include?(action)
|
153
|
+
html << dc_link_ajax_window_submit_action(options, nil)
|
154
|
+
next
|
155
|
+
else
|
156
|
+
caption = yaml['caption'] || yaml['text']
|
157
|
+
icon = yaml['icon'] ? yaml['icon'] : action
|
158
|
+
dc_link_to(caption, icon, url, yhtml)
|
159
|
+
end
|
160
|
+
html << "<li class=\"dc-link dc-animate\">#{code}</li>"
|
161
|
+
html << DcFilter.get_filter_field(self) if action == 'filter'
|
162
|
+
end
|
163
|
+
html << '</ul>'
|
164
|
+
html << '</form>'
|
165
|
+
html.html_safe
|
166
|
+
end
|
167
|
+
|
168
|
+
############################################################################
|
169
|
+
# Creates filter div for cmsedit index/filter action.
|
170
|
+
############################################################################
|
171
|
+
def dc_div_filter()
|
172
|
+
choices = []
|
173
|
+
filter = (@form['index'] and @form['index']['filter']) ? @form['index']['filter'] + ',' : ''
|
174
|
+
filter << 'id as text_field' # filter id is added by default
|
175
|
+
filter.split(',').each do |f|
|
176
|
+
f.strip!
|
177
|
+
name = f.match(' as ') ? f.split(' ').first : f
|
178
|
+
# like another field on the form
|
179
|
+
if f.match(' like ')
|
180
|
+
a = f.split(' ')
|
181
|
+
name = a.first
|
182
|
+
f = a.last
|
183
|
+
end
|
184
|
+
choices << [ t("helpers.label.#{@form['table']}.#{name}", name), f ]
|
185
|
+
end
|
186
|
+
choices4_operators = t('drgcms.choices4_filter_operators').chomp.split(',').inject([]) {|r,v| r << (v.match(':') ? v.split(':') : v )}
|
187
|
+
# currently selected options
|
188
|
+
if session[@form['table']] and session[@form['table']][:filter]
|
189
|
+
field_name, operators_value, dummy = session[@form['table']][:filter].split("\t")
|
190
|
+
else
|
191
|
+
field_name, operators_value = nil, nil
|
192
|
+
end
|
193
|
+
#{ form_tag :table => @form['table'], filter: :on, filter_input: 1, action: :index, method: :post }
|
194
|
+
url = url_for(table: @form['table'],form_name: params['form_name'], filter: :on, filter_input: 1, action: :index, controller: :cmsedit)
|
195
|
+
html =<<EOT
|
196
|
+
<div id="drgcms_filter" class="div-hidden">
|
197
|
+
<h1>#{t('drgcms.filter_set')}</h1>
|
198
|
+
|
199
|
+
#{ select(nil, 'filter_field1', options_for_select(choices, field_name), { include_blank: true }) }
|
200
|
+
#{ select(nil, 'filter_oper', options_for_select(choices4_operators, operators_value)) }
|
201
|
+
<div class="dc-menu">
|
202
|
+
<div class="dc-link dc-animate drgcms_popup_submit" data-url="#{url}">#{fa_icon('check-square-o')} #{t('drgcms.filter_on')}</div>
|
203
|
+
<div class="dc-link dc-animate">#{dc_link_to('drgcms.filter_off','close', {action: :index, filter: 'off', table: @form['table'], form_name: params['form_name']}) }</div>
|
204
|
+
</div>
|
205
|
+
</div>
|
206
|
+
EOT
|
207
|
+
html.html_safe
|
208
|
+
end
|
209
|
+
|
210
|
+
############################################################################
|
211
|
+
# Creates popup div for setting filter on result set header.
|
212
|
+
############################################################################
|
213
|
+
def dc_filter_popup()
|
214
|
+
html = %Q[<div class="filter-popup" style="display: none;">
|
215
|
+
<div>#{t('drgcms.filter_set')}</div>
|
216
|
+
<ul>]
|
217
|
+
url = url_for(table: @form['table'],form_name: params['form_name'], filter: :on, filter_input: 1, action: :index, controller: :cmsedit)
|
218
|
+
t('drgcms.choices4_filter_operators').chomp.split(',').each do |operator_choice|
|
219
|
+
caption,choice = operator_choice.split(':')
|
220
|
+
html << %Q[<li data-operator="#{choice}" data-url="#{url}">#{caption}</li>]
|
221
|
+
end
|
222
|
+
html << "</ul></div>"
|
223
|
+
html.html_safe
|
224
|
+
end
|
225
|
+
|
226
|
+
############################################################################
|
227
|
+
# Creates title div for cmsedit index result set records. Title div also includes paging
|
228
|
+
# options.
|
229
|
+
############################################################################
|
230
|
+
def dc_table_title_for_result(result=nil)
|
231
|
+
title = if @form['title'] # form has title section
|
232
|
+
t(@form['title'], @form['title'])
|
233
|
+
else # get name from translations
|
234
|
+
t("helpers.label.#{@form['table']}.tabletitle", @form['table'])
|
235
|
+
end
|
236
|
+
dc_table_title(title, result)
|
237
|
+
end
|
238
|
+
|
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
|
+
############################################################################
|
259
|
+
# Determines actions and width of actions column
|
260
|
+
############################################################################
|
261
|
+
def dc_actions_column()
|
262
|
+
actions = @form['result_set']['actions']
|
263
|
+
return [{},0] if actions.nil? or dc_dont?(actions)
|
264
|
+
# standard actions
|
265
|
+
actions = {'standard' => true} if actions.class == String && actions == 'standard'
|
266
|
+
std_actions = {' 2' => 'edit', ' 3' => 'delete'}
|
267
|
+
if actions['standard']
|
268
|
+
actions.merge!(std_actions)
|
269
|
+
actions.delete('standard')
|
270
|
+
end
|
271
|
+
#
|
272
|
+
width = @form['result_set']['actions_width'] || 18*actions.size
|
273
|
+
[ actions, width ]
|
274
|
+
end
|
275
|
+
|
276
|
+
############################################################################
|
277
|
+
# Calculates (blank) space required for actions when @record_footer is rendered
|
278
|
+
############################################################################
|
279
|
+
def dc_actions_column_for_footer()
|
280
|
+
return '' unless @form['result_set']['actions']
|
281
|
+
ignore, width = dc_actions_column
|
282
|
+
%Q[<div class="actions" style="width: #{width}px;"></div>].html_safe
|
283
|
+
end
|
284
|
+
|
285
|
+
|
286
|
+
############################################################################
|
287
|
+
# Creates actions that could be performed on single row of result set.
|
288
|
+
############################################################################
|
289
|
+
def dc_actions_for_result(document)
|
290
|
+
actions = @form['result_set']['actions']
|
291
|
+
return '' if actions.nil? or @form['readonly']
|
292
|
+
#
|
293
|
+
actions, width = dc_actions_column()
|
294
|
+
html = %Q[<ul class="actions" style="width: #{width}px;">]
|
295
|
+
actions.each do |k,v|
|
296
|
+
session[:form_processing] = "result_set:actions: #{k}=#{v}"
|
297
|
+
next if k == 'standard' # ignore standard definition
|
298
|
+
parms = @parms.clone
|
299
|
+
# if single definition simulate type parameter
|
300
|
+
yaml = v.class == String ? {'type' => v} : v
|
301
|
+
# code already includes li tag
|
302
|
+
if %w(ajax link window submit).include?(yaml['type']) then
|
303
|
+
@record = document # otherwise document fields can't be used as parameters
|
304
|
+
html << dc_link_ajax_window_submit_action(yaml,document)
|
305
|
+
else
|
306
|
+
html << '<li class="dc-link">'
|
307
|
+
html << case
|
308
|
+
when yaml['type'] == 'edit' then
|
309
|
+
parms['action'] = 'edit'
|
310
|
+
parms['id'] = document.id
|
311
|
+
dc_link_to( nil, 'pencil lg', parms )
|
312
|
+
when yaml['type'] == 'duplicate' then
|
313
|
+
parms['id'] = document.id
|
314
|
+
# duplicate string will be added to these fields.
|
315
|
+
parms['dup_fields'] = yaml['dup_fields']
|
316
|
+
parms['action'] = 'create'
|
317
|
+
dc_link_to( nil, 'copy lg', parms, data: { confirm: t('drgcms.confirm_dup') }, method: :post )
|
318
|
+
when yaml['type'] == 'delete' then
|
319
|
+
parms['action'] = 'destroy'
|
320
|
+
parms['id'] = document.id
|
321
|
+
parms['return_to'] = request.url
|
322
|
+
dc_link_to( nil, 'remove lg', parms, data: { confirm: t('drgcms.confirm_delete') }, method: :delete )
|
323
|
+
# undocumented so far
|
324
|
+
when yaml['type'] == 'edit_embedded'
|
325
|
+
parms['controller'] = 'cmsedit'
|
326
|
+
parms['table'] += ";#{yaml['table']}"
|
327
|
+
parms['ids'] ||= ''
|
328
|
+
parms['ids'] += "#{document.id};"
|
329
|
+
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
|
345
|
+
else # error.
|
346
|
+
yaml['type'].to_s
|
347
|
+
end
|
348
|
+
html << '</li>'
|
349
|
+
end
|
350
|
+
end
|
351
|
+
html << '</ul>'
|
352
|
+
html.html_safe
|
353
|
+
end
|
354
|
+
|
355
|
+
############################################################################
|
356
|
+
# Creates header div for result set.
|
357
|
+
############################################################################
|
358
|
+
def dc_header_for_result()
|
359
|
+
html = '<div class="dc-result-header">'
|
360
|
+
if @form['result_set']['actions'] and !@form['readonly']
|
361
|
+
ignore, width = dc_actions_column()
|
362
|
+
html << %Q[<div class="actions" style="width: #{width}px;"></div>]
|
363
|
+
end
|
364
|
+
# preparation for sort icon
|
365
|
+
sort_field, sort_direction = nil, nil
|
366
|
+
if session[@form['table']]
|
367
|
+
sort_field, sort_direction = session[@form['table']][:sort].to_s.split(' ')
|
368
|
+
end
|
369
|
+
#
|
370
|
+
if (columns = @form['result_set']['columns'])
|
371
|
+
columns.sort.each do |k,v|
|
372
|
+
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
|
378
|
+
# no sorting when embedded documents or custom filter is active
|
379
|
+
sort_ok = @form['result_set'].nil? || (@form['result_set'] && @form['result_set']['filter'].nil?)
|
380
|
+
sort_ok = sort_ok || (@form['index'] && @form['index']['sort'])
|
381
|
+
if @tables.size == 1 and sort_ok
|
382
|
+
icon = 'sort lg'
|
383
|
+
if v['name'] == sort_field
|
384
|
+
icon = sort_direction == '1' ? 'sort-alpha-asc lg' : 'sort-alpha-desc lg'
|
385
|
+
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>"
|
387
|
+
else
|
388
|
+
th << ">#{caption}</div>"
|
389
|
+
end
|
390
|
+
html << "<div class=\"spacer\"></div>" + th
|
391
|
+
end
|
392
|
+
end
|
393
|
+
(html << '</div>').html_safe
|
394
|
+
end
|
395
|
+
|
396
|
+
############################################################################
|
397
|
+
# Creates link for single or double click on result column
|
398
|
+
############################################################################
|
399
|
+
def dc_clicks_for_result(document)
|
400
|
+
html = ''
|
401
|
+
if @form['result_set']['dblclick']
|
402
|
+
yaml = @form['result_set']['dblclick']
|
403
|
+
opts = {}
|
404
|
+
opts[:controller] = yaml['controller'] || 'cmsedit'
|
405
|
+
opts[:action] = yaml['action']
|
406
|
+
opts[:table] = yaml['table']
|
407
|
+
opts[:form_name] = yaml['form_name']
|
408
|
+
opts[:method] = yaml['method'] || 'get'
|
409
|
+
opts[:id] = document['id']
|
410
|
+
html << ' data-dblclick=' + url_for(opts)
|
411
|
+
else
|
412
|
+
html << (' data-dblclick=' +
|
413
|
+
url_for(action: 'show', controller: 'cmsedit', id: document.id,
|
414
|
+
readonly: (params[:readonly] ? 2 : 1), table: params[:table],
|
415
|
+
form_name: params[:form_name], ids: params[:ids]) ) if @form['form']
|
416
|
+
end
|
417
|
+
html
|
418
|
+
end
|
419
|
+
|
420
|
+
############################################################################
|
421
|
+
# Formats value according to format supplied or data type. There is lots of things missing here.
|
422
|
+
############################################################################
|
423
|
+
def dc_format_value(value, format=nil)
|
424
|
+
return '' if value.nil?
|
425
|
+
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
|
433
|
+
dec = format[1].blank? ? nil : format[1].to_i
|
434
|
+
sep = format[2].blank? ? nil : format[2]
|
435
|
+
del = format[3].blank? ? nil : format[3]
|
436
|
+
cur = format[4].blank? ? nil : format[4]
|
437
|
+
dc_format_number(value, dec, sep, del, cur)
|
438
|
+
else
|
439
|
+
value.to_s
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
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
|
+
############################################################################
|
464
|
+
# Creates tr code for each row of result set.
|
465
|
+
############################################################################
|
466
|
+
def dc_row_for_result(document)
|
467
|
+
clas = "dc-#{cycle('odd','even')} " + dc_style_or_class(nil, @form['result_set']['tr_class'], nil, document)
|
468
|
+
style = dc_style_or_class('style', @form['result_set']['tr_style'], nil, document)
|
469
|
+
"<div id=\"#{document.id}\" class=\"dc-result-data #{clas}\" #{dc_clicks_for_result(document)} #{style}>".html_safe
|
470
|
+
end
|
471
|
+
|
472
|
+
############################################################################
|
473
|
+
# Process eval. Breaks eval option and calls with send method.
|
474
|
+
# Parameters:
|
475
|
+
# evaluate : String : Expression to be evaluated
|
476
|
+
# parameters : Array : array of parameters which will be send to method
|
477
|
+
############################################################################
|
478
|
+
def dc_process_eval(evaluate, parameters)
|
479
|
+
# evaluate by calling send method
|
480
|
+
clas, method = evaluate.split('.')
|
481
|
+
if method.nil?
|
482
|
+
send(clas, *parameters)
|
483
|
+
else
|
484
|
+
klass = clas.camelize.constantize
|
485
|
+
klass.send(method, *parameters)
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
############################################################################
|
490
|
+
# Process eval option for field value.
|
491
|
+
# Used for processing single field column on result_set or form head.
|
492
|
+
############################################################################
|
493
|
+
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'] ])
|
499
|
+
else
|
500
|
+
dc_name4_id(a[1], a[2], a[3], document[ yaml['name'] ])
|
501
|
+
end
|
502
|
+
# dc_name4_value
|
503
|
+
elsif yaml['eval'].match('dc_name4_value')
|
504
|
+
dc_name4_value( @form['table'], yaml['name'], document[ yaml['name'] ] )
|
505
|
+
elsif yaml['eval'].match('eval ')
|
506
|
+
# TO DO evaluate with specified parameters
|
507
|
+
else
|
508
|
+
parameters = if yaml['params']
|
509
|
+
# pass document as parameter
|
510
|
+
if yaml['params'] == 'document' or yaml['params'] == 'record'
|
511
|
+
document
|
512
|
+
else
|
513
|
+
yaml['params'].chomp.split(',').inject([]) do |result,e|
|
514
|
+
result << document[e.strip]
|
515
|
+
end
|
516
|
+
end
|
517
|
+
else
|
518
|
+
document[ yaml['name'] ]
|
519
|
+
end
|
520
|
+
# evaluate by calling send method
|
521
|
+
dc_process_eval(yaml['eval'], parameters)
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
############################################################################
|
526
|
+
# Creates column for each field of result set document.
|
527
|
+
############################################################################
|
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']}"
|
548
|
+
end
|
549
|
+
rescue Exception => e
|
550
|
+
dc_log_exception(e)
|
551
|
+
value = '!!!Error'
|
552
|
+
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
|
564
|
+
end
|
565
|
+
|
566
|
+
|
567
|
+
end
|