drg_cms 0.6.0.1 → 0.6.1.1.1
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 +454 -145
- data/app/assets/javascripts/drg_cms_application.js +1 -1
- data/app/assets/stylesheets/drg_cms/drg_cms.css +635 -244
- data/app/assets/stylesheets/drg_cms/select-multiple.css +18 -12
- data/app/assets/stylesheets/drg_cms_cms.css +1 -1
- data/app/controllers/cmsedit_controller.rb +515 -335
- data/app/controllers/dc_application_controller.rb +378 -111
- data/app/controllers/dc_common_controller.rb +105 -14
- data/app/{controllers → controls}/browse_models_control.rb +0 -0
- data/app/controls/dc_help_control.rb +126 -0
- data/app/{controllers → controls}/dc_page_control.rb +24 -8
- data/app/controls/dc_poll_result_control.rb +88 -0
- data/app/controls/dc_report.rb +223 -0
- data/app/{controllers → controls}/design_element_settings_control.rb +0 -0
- data/app/forms/all_options.yml +44 -9
- data/app/forms/cms_menu.yml +28 -18
- data/app/forms/dc_ad.yml +11 -22
- data/app/forms/dc_big_table.yml +1 -0
- data/app/forms/dc_big_table_value.yml +1 -0
- data/app/forms/dc_category.yml +2 -1
- data/app/forms/dc_design.yml +20 -16
- data/app/forms/dc_filter.yml +3 -6
- data/app/forms/dc_help_1.yml +109 -0
- data/app/forms/dc_journal.yml +3 -1
- data/app/forms/dc_json_ld.yml +59 -0
- data/app/forms/dc_key_value.yml +32 -0
- data/app/forms/dc_link.yml +1 -1
- data/app/forms/dc_menu.yml +2 -0
- data/app/forms/dc_menu_item.yml +2 -0
- data/app/forms/dc_page.yml +3 -5
- data/app/forms/dc_part.yml +1 -0
- data/app/forms/dc_piece.yml +1 -0
- data/app/forms/dc_poll.yml +15 -5
- data/app/forms/dc_poll_item.yml +2 -1
- data/app/forms/dc_poll_result.yml +83 -0
- data/app/forms/dc_poll_result_export.yml +35 -0
- data/app/forms/dc_seo.yml +33 -0
- data/app/forms/dc_simple_menu.yml +2 -0
- data/app/forms/dc_site.yml +4 -12
- data/app/forms/dc_user.yml +27 -11
- data/app/forms/dc_user_role.yml +3 -0
- data/app/forms/json_ld_schema.yml +168 -0
- data/app/helpers/cms_common_helper.rb +375 -0
- data/app/helpers/cms_edit_helper.rb +506 -0
- data/app/helpers/cms_helper.rb +268 -0
- data/app/helpers/cms_index_helper.rb +580 -0
- data/app/helpers/dc_application_helper.rb +218 -306
- data/app/models/concerns/dc_page_concern.rb +40 -6
- data/app/models/concerns/dc_policy_rule_concern.rb +20 -8
- data/app/models/concerns/dc_seo_concern.rb +66 -0
- data/app/models/concerns/dc_site_concern.rb +67 -44
- data/app/models/concerns/dc_user_concern.rb +57 -18
- data/app/models/dc_design.rb +30 -18
- data/app/models/dc_filter.rb +22 -13
- data/app/models/dc_json_ld.rb +152 -0
- data/app/models/dc_key_value.rb +48 -0
- data/app/models/dc_key_value_store.rb +1 -0
- data/app/models/dc_memory.rb +8 -1
- data/app/models/dc_page.rb +0 -1
- data/app/models/dc_permission.rb +49 -9
- data/app/models/dc_policy.rb +25 -14
- data/app/models/dc_policy_role.rb +22 -11
- data/app/models/dc_poll.rb +39 -19
- data/app/models/dc_poll_result.rb +46 -0
- data/app/models/dc_temp.rb +140 -0
- data/app/models/dc_user_role.rb +2 -2
- data/app/models/drgcms_form_fields.rb +12 -1
- 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 +11 -9
- data/app/models/drgcms_form_fields/date_select.rb +1 -1
- data/app/models/drgcms_form_fields/datetime_picker.rb +12 -10
- data/app/models/drgcms_form_fields/datetime_select.rb +1 -1
- data/app/models/drgcms_form_fields/drgcms_field.rb +55 -9
- data/app/models/drgcms_form_fields/embedded.rb +26 -16
- data/app/models/drgcms_form_fields/file_field.rb +52 -0
- data/app/models/drgcms_form_fields/file_select.rb +2 -2
- data/app/models/drgcms_form_fields/hash_field.rb +90 -0
- data/app/models/drgcms_form_fields/hidden_field.rb +1 -1
- data/app/models/drgcms_form_fields/html_field.rb +1 -1
- data/app/models/drgcms_form_fields/link_to.rb +2 -2
- data/app/models/drgcms_form_fields/method.rb +66 -0
- data/app/models/drgcms_form_fields/multitext_autocomplete.rb +23 -14
- data/app/models/drgcms_form_fields/number_field.rb +15 -6
- data/app/models/drgcms_form_fields/radio.rb +96 -0
- data/app/models/drgcms_form_fields/readonly.rb +2 -2
- data/app/models/drgcms_form_fields/select.rb +92 -29
- data/app/models/drgcms_form_fields/text_area.rb +1 -1
- data/app/models/drgcms_form_fields/text_autocomplete.rb +31 -17
- 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 +15 -4
- data/app/{helpers → renderers}/dc_ad_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_big_menu_renderer.rb +1 -0
- data/app/{helpers → renderers}/dc_captcha_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_common_renderer.rb +0 -0
- data/app/{helpers → renderers}/dc_gallery_renderer.rb +1 -0
- data/app/{helpers → renderers}/dc_menu_renderer.rb +11 -4
- data/app/{helpers → renderers}/dc_page_renderer.rb +1 -0
- data/app/{helpers → renderers}/dc_part_renderer.rb +5 -4
- data/app/{helpers → renderers}/dc_piece_renderer.rb +1 -1
- data/app/{helpers → renderers}/dc_poll_renderer.rb +91 -64
- data/app/{helpers → renderers}/dc_renderer.rb +1 -0
- data/app/{helpers → renderers}/dc_simple_menu_renderer.rb +1 -0
- 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 +4 -25
- 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 +4 -1
- data/app/views/cmsedit/index.html.erb +7 -1
- data/app/views/cmsedit/new.html.erb +3 -1
- data/app/views/dc_common/_help.html.erb +17 -0
- data/app/views/layouts/models.html.erb +2 -1
- data/config/locales/drgcms_en.yml +27 -3
- data/config/locales/drgcms_sl.yml +32 -5
- data/config/locales/models_en.yml +65 -17
- data/config/locales/models_sl.yml +69 -18
- data/drg_cms.gemspec +1 -1
- data/lib/drg_cms.rb +61 -1
- data/lib/drg_cms/version.rb +1 -1
- data/lib/generators/new_drg_form/new_drg_form_generator.rb +9 -2
- data/lib/tasks/database.rake +6 -56
- metadata +73 -54
- data/app/assets/stylesheets/drg_cms/__jquery-ui.css +0 -339
- data/app/helpers/application_helper.rb +0 -2
- data/app/helpers/cmsedit_helper.rb +0 -888
- data/app/models/dc_dummy.rb +0 -102
- data/test/fixtures/drg_cms_test_data.rb +0 -87
|
@@ -0,0 +1,268 @@
|
|
|
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 common methods used for DRGCMS forms.
|
|
27
|
+
#
|
|
28
|
+
###########################################################################
|
|
29
|
+
module CmsHelper
|
|
30
|
+
# javascript part created by form helpers
|
|
31
|
+
attr_reader :js
|
|
32
|
+
|
|
33
|
+
############################################################################
|
|
34
|
+
# Creates code for script action type.
|
|
35
|
+
############################################################################
|
|
36
|
+
def dc_script_action(yaml)
|
|
37
|
+
# data = {'request' => 'script', 'script' => yaml['js'] || yaml['script'] }
|
|
38
|
+
# %Q[<li class="dc-link-ajax with-link dc-animate">#{ dc_link_to(yaml['caption'], yaml['icon'], '#', data: data ) }</li>]
|
|
39
|
+
icon = dc_icon_for_link yaml['icon']
|
|
40
|
+
data = %Q[data-request="script" data-script="#{yaml['js'] || yaml['script']}"]
|
|
41
|
+
%Q[<li class="dc-link-ajax dc-animate" #{data}>#{icon} #{ t(yaml['caption'],yaml['caption']) }</li>]
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
############################################################################
|
|
45
|
+
# Will return field form definition if field is defined on form.
|
|
46
|
+
# Field definition will be used for input field on the form.
|
|
47
|
+
############################################################################
|
|
48
|
+
def dc_get_field_form_definition(name) #:nodoc:
|
|
49
|
+
return if @form['form'].nil?
|
|
50
|
+
|
|
51
|
+
@form['form']['tabs'].each do |tab|
|
|
52
|
+
# Array with 2 elements. First is tabname, second is data
|
|
53
|
+
my_fields = tab.last
|
|
54
|
+
my_fields.each {|k,v| return v if (k.class == Integer and v['name'] == name) }
|
|
55
|
+
end if @form['form']['tabs'] # I know. But nice.
|
|
56
|
+
#
|
|
57
|
+
@form['form']['fields'].each do |field|
|
|
58
|
+
next unless field.first.class == Integer # options
|
|
59
|
+
return field.last if field.last['name'] == name
|
|
60
|
+
end if @form['form']['fields']
|
|
61
|
+
nil
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
############################################################################
|
|
65
|
+
# Return field code, label and help text for a field defined on a DRG Form.
|
|
66
|
+
#
|
|
67
|
+
# Parameters:
|
|
68
|
+
# options : Hash : Field definition
|
|
69
|
+
#
|
|
70
|
+
# Returns: Array[3]
|
|
71
|
+
# field_html : String : HTML code for field definition
|
|
72
|
+
# label : String : Label text
|
|
73
|
+
# help : String : Help text
|
|
74
|
+
############################################################################
|
|
75
|
+
def dc_field_label_help(options)
|
|
76
|
+
label, help = dc_label_help(options)
|
|
77
|
+
# create field object from type and call its render method
|
|
78
|
+
if options['type'].present?
|
|
79
|
+
klass_string = options['type'].camelize
|
|
80
|
+
field_html = if DrgcmsFormFields.const_defined?(klass_string) # when field type defined
|
|
81
|
+
klass = DrgcmsFormFields.const_get(klass_string)
|
|
82
|
+
field = klass.new(self, @record, options).render
|
|
83
|
+
@js << field.js
|
|
84
|
+
@css << field.css
|
|
85
|
+
field.html
|
|
86
|
+
else
|
|
87
|
+
"Error: Field type #{options['type']} not defined!"
|
|
88
|
+
end
|
|
89
|
+
else
|
|
90
|
+
"Error: Field type missing!"
|
|
91
|
+
end
|
|
92
|
+
[field_html, label, help]
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
############################################################################
|
|
96
|
+
# Return label and help text for a field defined on Form.
|
|
97
|
+
#
|
|
98
|
+
# Parameters:
|
|
99
|
+
# options : Hash : Field definition
|
|
100
|
+
#
|
|
101
|
+
# Returns:
|
|
102
|
+
# label : String : Label text
|
|
103
|
+
# help : String : Help text
|
|
104
|
+
############################################################################
|
|
105
|
+
def dc_label_help(options)
|
|
106
|
+
# no label or help in comments
|
|
107
|
+
return [nil, nil] if %w(comment action).include?(options['type'])
|
|
108
|
+
|
|
109
|
+
label = options['caption'] || options['text'] || options['label']
|
|
110
|
+
label = if label.blank?
|
|
111
|
+
t_name(options['name'], options['name'].capitalize.gsub('_',' ') )
|
|
112
|
+
elsif options['name']
|
|
113
|
+
t(label, label)
|
|
114
|
+
end
|
|
115
|
+
# help text can be defined in form or in translations starting with helpers. or as helpers.help.collection.field
|
|
116
|
+
help = options['help']
|
|
117
|
+
help ||= "helpers.help.#{@form['table']}.#{options['name']}" if options['name']
|
|
118
|
+
help = t(help, ' ') if help.to_s.match(/helpers\./)
|
|
119
|
+
[label, help]
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
############################################################################
|
|
123
|
+
# Return label and help for tab on Form.
|
|
124
|
+
#
|
|
125
|
+
# Parameters:
|
|
126
|
+
# options : String : Tab name on form
|
|
127
|
+
#
|
|
128
|
+
# Returns:
|
|
129
|
+
# label : String : Label text
|
|
130
|
+
# help : String : Help text
|
|
131
|
+
############################################################################
|
|
132
|
+
def dc_tab_label_help(tab_name)
|
|
133
|
+
label = @form['form']['tabs'][tab_name]['caption'] || tab_name
|
|
134
|
+
label = t(label, t_name(label, label))
|
|
135
|
+
|
|
136
|
+
help = @form['form']['tabs'][tab_name]['help'] || "helpers.help.#{@form['table']}.#{tab_name}"
|
|
137
|
+
help = t(help, t_name(help, help))
|
|
138
|
+
help = nil if help.match('helpers.') # help not found in translation
|
|
139
|
+
|
|
140
|
+
[label, help]
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
############################################################################
|
|
144
|
+
# Creates code for including data entry field in index actions.
|
|
145
|
+
############################################################################
|
|
146
|
+
def dc_field_action(yaml)
|
|
147
|
+
# assign value if value found in parameters
|
|
148
|
+
if params['record']
|
|
149
|
+
value = params['record'][yaml['name']]
|
|
150
|
+
params["p_#{yaml['name']}"] = value
|
|
151
|
+
end
|
|
152
|
+
# find field definition on form
|
|
153
|
+
if ( field_definition = dc_get_field_form_definition(yaml['name']) )
|
|
154
|
+
# some options may be redefined
|
|
155
|
+
field_definition['size'] = yaml['size'] if yaml['size']
|
|
156
|
+
field, label, help = dc_field_label_help(field_definition)
|
|
157
|
+
else
|
|
158
|
+
yaml['type'] = yaml['field_type']
|
|
159
|
+
field, label, help = dc_field_label_help(yaml)
|
|
160
|
+
end
|
|
161
|
+
# input field will have label as placeholder
|
|
162
|
+
field = field.sub('input',"input placeholder=\"#{label}\"")
|
|
163
|
+
%Q[<li class="no-background">#{field}</li>]
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
############################################################################
|
|
167
|
+
# Create ex. class="my-class" html code from html options for action
|
|
168
|
+
############################################################################
|
|
169
|
+
def dc_html_data(yaml)
|
|
170
|
+
return '' if yaml.blank?
|
|
171
|
+
yaml.inject(' ') {|result, e| result = e.last.nil? ? result : result << "#{e.first}=\"#{e.last}\" "}
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
############################################################################
|
|
175
|
+
# Creates code for link, ajax or windows action for index or form actions.
|
|
176
|
+
#
|
|
177
|
+
# Parameters:
|
|
178
|
+
# yaml: Hash : Action definition
|
|
179
|
+
# record : Object : Currently selected record if available
|
|
180
|
+
# action_active : Boolean : Is action active or disabled
|
|
181
|
+
#
|
|
182
|
+
# Returns:
|
|
183
|
+
# String : HTML code for action
|
|
184
|
+
############################################################################
|
|
185
|
+
def dc_link_ajax_window_submit_action(yaml, record=nil, action_active=true)
|
|
186
|
+
parms = {}
|
|
187
|
+
caption = yaml['caption'] || yaml['text']
|
|
188
|
+
caption = caption ? t("#{caption.downcase}", caption) : nil
|
|
189
|
+
icon = yaml['icon'] ? "#{fa_icon(yaml['icon'])}" : ''
|
|
190
|
+
# action is not active
|
|
191
|
+
unless dc_is_action_active?(yaml)
|
|
192
|
+
return "<li class=\"dc-link-no\">#{icon} #{caption}</li>"
|
|
193
|
+
end
|
|
194
|
+
# set data-confirm when confirm
|
|
195
|
+
yaml['html'] ||= {}
|
|
196
|
+
confirm = yaml['html']['data-confirm'] || yaml['confirm']
|
|
197
|
+
yaml['html']['data-confirm'] = t(confirm) if confirm.present?
|
|
198
|
+
yaml['html']['title'] ||= yaml['title']
|
|
199
|
+
yaml['html']['title'] = t(yaml['title']) if yaml['title'].present?
|
|
200
|
+
yaml['html']['target'] ||= yaml['target']
|
|
201
|
+
# direct url
|
|
202
|
+
if yaml['url']
|
|
203
|
+
parms['url'] = yaml['url']
|
|
204
|
+
parms['idr'] = dc_document_path(record) if record
|
|
205
|
+
# make url from action controller
|
|
206
|
+
else
|
|
207
|
+
parms['controller'] = yaml['controller'] || 'cmsedit'
|
|
208
|
+
parms['action'] = yaml['action']
|
|
209
|
+
parms['table'] = yaml['table'] || @form['table']
|
|
210
|
+
parms['form_name'] = yaml['form_name']
|
|
211
|
+
parms['control'] = yaml['control'] if yaml['control']
|
|
212
|
+
parms['id'] = record.id if record
|
|
213
|
+
end
|
|
214
|
+
# add current id to parameters
|
|
215
|
+
parms['id'] = dc_document_path(record) if record
|
|
216
|
+
# overwrite with or add additional parameters from environment or record
|
|
217
|
+
yaml['params'].each { |k, v| parms[k] = dc_value_for_parameter(v, record) } if yaml['params']
|
|
218
|
+
|
|
219
|
+
parms['table'] = parms['table'].underscore if parms['table'] # might be CamelCase
|
|
220
|
+
# error if controller parameter is missing
|
|
221
|
+
if parms['controller'].nil? && parms['url'].nil?
|
|
222
|
+
"<li>#{'Controller not defined'}</li>"
|
|
223
|
+
else
|
|
224
|
+
#yaml['caption'] ||= yaml['text']
|
|
225
|
+
html_data = dc_html_data(yaml['html'])
|
|
226
|
+
url = url_for(parms) rescue 'URL error'
|
|
227
|
+
url = nil if parms['url'] == '#'
|
|
228
|
+
|
|
229
|
+
request = yaml['request'] || yaml['method'] || 'get'
|
|
230
|
+
if yaml['type'] == 'ajax' # ajax button
|
|
231
|
+
clas = "dc-link-ajax dc-animate"
|
|
232
|
+
%Q[<li class="#{clas}" data-url="#{action_active ? url : ''}" #{html_data}
|
|
233
|
+
data-request="#{request}" title="#{yaml['title']}">#{icon}#{caption}</li>]
|
|
234
|
+
|
|
235
|
+
elsif yaml['type'] == 'submit' # submit button
|
|
236
|
+
# It's dirty hack, but will prevent not authorized message and render index action correctly
|
|
237
|
+
parms[:filter] = 'on'
|
|
238
|
+
url = url_for(parms) rescue 'URL error'
|
|
239
|
+
clas = "dc-action-submit"
|
|
240
|
+
%Q[<li class="#{clas}" data-url="#{action_active ? url : ''}" #{html_data}
|
|
241
|
+
data-request="#{request}" title="#{yaml['title']}">#{icon}#{caption}</li>]
|
|
242
|
+
|
|
243
|
+
elsif yaml['type'] == 'link' # link button
|
|
244
|
+
clas = "dc-link dc-animate"
|
|
245
|
+
link = dc_link_to(caption, yaml['icon'], parms, yaml['html'] )
|
|
246
|
+
%Q[<li class="#{clas}">#{action_active ? link : caption}</li>]
|
|
247
|
+
|
|
248
|
+
elsif yaml['type'] == 'window'
|
|
249
|
+
clas = "dc-link dc-animate dc-window-open"
|
|
250
|
+
%Q[<li class="#{clas}" data-url="#{action_active ? url : ''}" #{html_data}>#{icon}#{caption}</li>]
|
|
251
|
+
|
|
252
|
+
else
|
|
253
|
+
'<li>Action Type error</li>'
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
############################################################################
|
|
259
|
+
# Log exception to rails log. Usefull for debugging eval errors.
|
|
260
|
+
############################################################################
|
|
261
|
+
def dc_log_exception(exception, where = '')
|
|
262
|
+
log = exception ? "\n*** Error:#{where + ':'} #{exception.message}\n#{exception.backtrace.first.inspect}\n" : ''
|
|
263
|
+
log << "DRG Form processing line: #{session[:form_processing]}\n"
|
|
264
|
+
|
|
265
|
+
logger.error log
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
end
|
|
@@ -0,0 +1,580 @@
|
|
|
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 CmsIndexHelper
|
|
31
|
+
|
|
32
|
+
############################################################################
|
|
33
|
+
# Creates action div for cmsedit index action.
|
|
34
|
+
############################################################################
|
|
35
|
+
def dc_actions_for_index()
|
|
36
|
+
@js = @form['script'] || @form['js'] || ''
|
|
37
|
+
@css = @form['css'] || ''
|
|
38
|
+
return '' if @form['index'].nil? or @form['readonly']
|
|
39
|
+
actions = @form['index']['actions']
|
|
40
|
+
return '' if actions.blank?
|
|
41
|
+
|
|
42
|
+
std_actions = {2 => 'new', 3 => 'sort', 4 => 'filter' }
|
|
43
|
+
if actions.class == String
|
|
44
|
+
actions = dc_define_standard_actions(actions, std_actions)
|
|
45
|
+
elsif actions['standard']
|
|
46
|
+
actions.merge!(std_actions)
|
|
47
|
+
actions['standard'] = nil
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# start div with hidden spinner image
|
|
51
|
+
html = %(
|
|
52
|
+
<form id="dc-action-menu">
|
|
53
|
+
<span class="dc-spinner">#{fa_icon('spinner lg spin')}</span>
|
|
54
|
+
<ul class="dc-action-menu">)
|
|
55
|
+
|
|
56
|
+
# Remove actions settings and sort
|
|
57
|
+
only_actions = []
|
|
58
|
+
actions.each { |key, value| only_actions << [key, value] if key.class == Integer }
|
|
59
|
+
only_actions.sort_by!(&:first)
|
|
60
|
+
only_actions.each do |key, options|
|
|
61
|
+
session[:form_processing] = "index:actions: #{key}=#{options}"
|
|
62
|
+
next if options.nil? # must be
|
|
63
|
+
url = @parms.clone
|
|
64
|
+
yaml = options.class == String ? {'type' => options} : options # if single definition simulate type parameter
|
|
65
|
+
action = yaml['type'].to_s.downcase
|
|
66
|
+
if action == 'url'
|
|
67
|
+
dc_deprecate "action: url will be deprecated. Use action: link in index: actions! Form #{params['form_name']}"
|
|
68
|
+
action = 'link'
|
|
69
|
+
end
|
|
70
|
+
# if return_to is present link directly to URL
|
|
71
|
+
if action == 'link' and yaml['url']
|
|
72
|
+
url = yaml['url']
|
|
73
|
+
else
|
|
74
|
+
url['controller'] = yaml['controller'] if yaml['controller']
|
|
75
|
+
url['action'] = yaml['action'] || action
|
|
76
|
+
url['table'] = yaml['table'] if yaml['table']
|
|
77
|
+
url['form_name'] = yaml['form_name'] if yaml['form_name']
|
|
78
|
+
url['control'] = yaml['control'] if yaml['control']
|
|
79
|
+
end
|
|
80
|
+
# html link options
|
|
81
|
+
yhtml = yaml['html'] || {}
|
|
82
|
+
yhtml['title'] = yaml['title'] if yaml['title']
|
|
83
|
+
|
|
84
|
+
code = case
|
|
85
|
+
# sort
|
|
86
|
+
when action == 'sort' then
|
|
87
|
+
choices = [['id','id']]
|
|
88
|
+
if @form['index']['sort']
|
|
89
|
+
@form['index']['sort'].split(',').each do |s|
|
|
90
|
+
s.strip!
|
|
91
|
+
choices << [ t("helpers.label.#{@form['table']}.#{s}"), s ]
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
fa_icon('sort-alpha-asc') + ' ' + t('drgcms.sort') + ' ' +
|
|
95
|
+
select('sort', 'sort', choices, { include_blank: true },
|
|
96
|
+
{ class: 'drgcms_sort', 'data-table' => @form['table'], 'data-form' => params['form_name']} )
|
|
97
|
+
|
|
98
|
+
# filter
|
|
99
|
+
when action == 'filter' then
|
|
100
|
+
caption = t('drgcms.filter')
|
|
101
|
+
caption << ' ' + fa_icon('caret-down lg') + DcFilter.menu_filter(self)
|
|
102
|
+
# add filter OFF link
|
|
103
|
+
sess = session[@form['table']]
|
|
104
|
+
if sess and sess[:filter]
|
|
105
|
+
caption << ' ' + dc_link_to(nil,'remove lg',
|
|
106
|
+
{ controller: 'cmsedit', filter: 'off', table: @form['table'], form_name: params['form_name'] },
|
|
107
|
+
{ title: DcFilter.title4_filter_off(sess[:filter]) })
|
|
108
|
+
end
|
|
109
|
+
caption
|
|
110
|
+
|
|
111
|
+
# new
|
|
112
|
+
when action == 'new' then
|
|
113
|
+
caption = yaml['caption'] || 'drgcms.new'
|
|
114
|
+
dc_link_to(caption,'plus', url, yhtml )
|
|
115
|
+
|
|
116
|
+
# menu
|
|
117
|
+
when action == 'menu' then
|
|
118
|
+
caption = t(options['caption'], options['caption']) + ' ' + fa_icon('caret-down lg')
|
|
119
|
+
caption + eval(options['eval'])
|
|
120
|
+
=begin
|
|
121
|
+
# reorder
|
|
122
|
+
when action == 'reorder' then
|
|
123
|
+
caption = t('drgcms.reorder')
|
|
124
|
+
parms = @parms.clone
|
|
125
|
+
parms['operation'] = v
|
|
126
|
+
parms['id'] = params[:ids]
|
|
127
|
+
parms['table'] = @form['table']
|
|
128
|
+
dc_link_to( caption, 'reorder', parms, method: :delete )
|
|
129
|
+
=end
|
|
130
|
+
when action == 'script'
|
|
131
|
+
html << dc_script_action(options)
|
|
132
|
+
next
|
|
133
|
+
|
|
134
|
+
when action == 'field'
|
|
135
|
+
html << dc_field_action(yaml)
|
|
136
|
+
next
|
|
137
|
+
|
|
138
|
+
when %w(ajax link window submit).include?(action)
|
|
139
|
+
html << dc_link_ajax_window_submit_action(options, nil)
|
|
140
|
+
next
|
|
141
|
+
|
|
142
|
+
else
|
|
143
|
+
caption = yaml['caption'] || yaml['text']
|
|
144
|
+
icon = yaml['icon'] ? yaml['icon'] : action
|
|
145
|
+
dc_link_to(caption, icon, url, yhtml)
|
|
146
|
+
end
|
|
147
|
+
html << "<li class=\"dc-link dc-animate\">#{code}</li>"
|
|
148
|
+
html << DcFilter.get_filter_field(self) if action == 'filter'
|
|
149
|
+
end
|
|
150
|
+
html << '</ul></form>'
|
|
151
|
+
html.html_safe
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
############################################################################
|
|
155
|
+
# Creates filter div for cmsedit index/filter action.
|
|
156
|
+
############################################################################
|
|
157
|
+
def dc_div_filter
|
|
158
|
+
choices = []
|
|
159
|
+
filter = (@form['index'] and @form['index']['filter']) ? @form['index']['filter'] + ',' : ''
|
|
160
|
+
filter << 'id as text_field' # filter id is added by default
|
|
161
|
+
filter.split(',').each do |f|
|
|
162
|
+
f.strip!
|
|
163
|
+
name = f.match(' as ') ? f.split(' ').first : f
|
|
164
|
+
# like another field on the form
|
|
165
|
+
if f.match(' like ')
|
|
166
|
+
a = f.split(' ')
|
|
167
|
+
name = a.first
|
|
168
|
+
f = a.last
|
|
169
|
+
end
|
|
170
|
+
choices << [ t("helpers.label.#{@form['table']}.#{name}", name), f ]
|
|
171
|
+
end
|
|
172
|
+
choices4_operators = t('drgcms.choices4_filter_operators').chomp.split(',').inject([]) {|r,v| r << (v.match(':') ? v.split(':') : v )}
|
|
173
|
+
# currently selected options
|
|
174
|
+
if session[@form['table']] and session[@form['table']][:filter]
|
|
175
|
+
field_name, operators_value, dummy = session[@form['table']][:filter].split("\t")
|
|
176
|
+
else
|
|
177
|
+
field_name, operators_value = nil, nil
|
|
178
|
+
end
|
|
179
|
+
#{ form_tag :table => @form['table'], filter: :on, filter_input: 1, action: :index, method: :post }
|
|
180
|
+
url = url_for(table: @form['table'],form_name: params['form_name'], filter: :on, filter_input: 1, action: :index, controller: :cmsedit)
|
|
181
|
+
html =<<EOT
|
|
182
|
+
<div id="drgcms_filter" class="div-hidden">
|
|
183
|
+
<h1>#{t('drgcms.filter_set')}</h1>
|
|
184
|
+
|
|
185
|
+
#{ select(nil, 'filter_field1', options_for_select(choices, field_name), { include_blank: true }) }
|
|
186
|
+
#{ select(nil, 'filter_oper', options_for_select(choices4_operators, operators_value)) }
|
|
187
|
+
<div class="dc-menu">
|
|
188
|
+
<div class="dc-link dc-animate drgcms_popup_submit" data-url="#{url}">#{fa_icon('check-square-o')} #{t('drgcms.filter_on')}</div>
|
|
189
|
+
<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>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
EOT
|
|
193
|
+
html.html_safe
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
############################################################################
|
|
197
|
+
# Creates popup div for setting filter on result set header.
|
|
198
|
+
############################################################################
|
|
199
|
+
def dc_filter_popup
|
|
200
|
+
html = %Q[<div class="filter-popup" style="display: none;">
|
|
201
|
+
<div>#{t('drgcms.filter_set')}</div>
|
|
202
|
+
<ul>]
|
|
203
|
+
url = url_for(table: @form['table'],form_name: params['form_name'], filter: :on, filter_input: 1, action: :index, controller: :cmsedit)
|
|
204
|
+
t('drgcms.choices4_filter_operators').chomp.split(',').each do |operator_choice|
|
|
205
|
+
caption,choice = operator_choice.split(':')
|
|
206
|
+
html << %Q[<li data-operator="#{choice}" data-url="#{url}">#{caption}</li>]
|
|
207
|
+
end
|
|
208
|
+
html << "</ul></div>"
|
|
209
|
+
html.html_safe
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
############################################################################
|
|
213
|
+
# Will return title based on @form['title']
|
|
214
|
+
############################################################################
|
|
215
|
+
def dc_form_title
|
|
216
|
+
return t("helpers.label.#{@form['table']}.tabletitle", @form['table']) if @form['title'].nil?
|
|
217
|
+
return t(@form['title'], @form['title']) if @form['title'].class == String
|
|
218
|
+
|
|
219
|
+
# Hash
|
|
220
|
+
dc_process_eval(@form['title']['eval'], [@form['title']['caption'] || @form['title']['text'], params])
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
############################################################################
|
|
224
|
+
# Creates title div for index action. Title div also includes paging options
|
|
225
|
+
# and help link
|
|
226
|
+
############################################################################
|
|
227
|
+
def dc_title_for_index(result = nil)
|
|
228
|
+
dc_table_title(dc_form_title(), result)
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
############################################################################
|
|
232
|
+
# Determines actions and width of actions column
|
|
233
|
+
############################################################################
|
|
234
|
+
def dc_actions_column
|
|
235
|
+
actions = @form['result_set']['actions']
|
|
236
|
+
return [{}, 0] if actions.nil? || dc_dont?(actions)
|
|
237
|
+
|
|
238
|
+
# standard actions
|
|
239
|
+
actions = {'standard' => true} if actions.class == String && actions == 'standard'
|
|
240
|
+
std_actions = { 2 => 'edit', 5 => 'delete' }
|
|
241
|
+
if actions['standard']
|
|
242
|
+
actions.merge!(std_actions)
|
|
243
|
+
actions.delete('standard')
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
width = @form['result_set']['actions_width'] || 18*actions.size
|
|
247
|
+
[actions, width]
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
############################################################################
|
|
251
|
+
# Calculates (blank) space required for actions when @record_footer is rendered
|
|
252
|
+
############################################################################
|
|
253
|
+
def dc_actions_column_for_footer
|
|
254
|
+
return '' unless @form['result_set']['actions']
|
|
255
|
+
|
|
256
|
+
ignore, width = dc_actions_column
|
|
257
|
+
%Q[<div class="actions" style="width: #{width}px;"></div>].html_safe
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
############################################################################
|
|
261
|
+
# Creates actions that could be performed on single row of result set.
|
|
262
|
+
############################################################################
|
|
263
|
+
def dc_actions_for_result(document)
|
|
264
|
+
actions = @form['result_set']['actions']
|
|
265
|
+
return '' if actions.nil? or @form['readonly']
|
|
266
|
+
|
|
267
|
+
actions, width = dc_actions_column()
|
|
268
|
+
html = %Q[<ul class="actions" style="width: #{width}px;">]
|
|
269
|
+
actions.sort_by(&:first).each do |k, v|
|
|
270
|
+
session[:form_processing] = "result_set:actions: #{k}=#{v}"
|
|
271
|
+
parms = @parms.clone
|
|
272
|
+
# if single definition simulate type parameter
|
|
273
|
+
yaml = v.class == String ? { 'type' => v } : v
|
|
274
|
+
# code already includes li tag
|
|
275
|
+
if %w(ajax link window submit).include?(yaml['type'])
|
|
276
|
+
@record = document # otherwise document fields can't be used as parameters
|
|
277
|
+
html << dc_link_ajax_window_submit_action(yaml, document)
|
|
278
|
+
else
|
|
279
|
+
html << '<li class="dc-link">'
|
|
280
|
+
html << case
|
|
281
|
+
when yaml['type'] == 'edit' then
|
|
282
|
+
parms['action'] = 'edit'
|
|
283
|
+
parms['id'] = document.id
|
|
284
|
+
dc_link_to( nil, 'pencil lg', parms )
|
|
285
|
+
when yaml['type'] == 'duplicate' then
|
|
286
|
+
parms['id'] = document.id
|
|
287
|
+
# duplicate string will be added to these fields.
|
|
288
|
+
parms['dup_fields'] = yaml['dup_fields']
|
|
289
|
+
parms['action'] = 'create'
|
|
290
|
+
dc_link_to( nil, 'copy lg', parms, data: { confirm: t('drgcms.confirm_dup') }, method: :post )
|
|
291
|
+
when yaml['type'] == 'delete' then
|
|
292
|
+
parms['action'] = 'destroy'
|
|
293
|
+
parms['id'] = document.id
|
|
294
|
+
#parms['return_to'] = request.url
|
|
295
|
+
dc_link_to( nil, 'remove lg', parms, data: { confirm: t('drgcms.confirm_delete') }, method: :delete )
|
|
296
|
+
# undocumented so far
|
|
297
|
+
when yaml['type'] == 'edit_embedded'
|
|
298
|
+
parms['controller'] = 'cmsedit'
|
|
299
|
+
parms['table'] += ";#{yaml['table']}"
|
|
300
|
+
parms['ids'] ||= ''
|
|
301
|
+
parms['ids'] += "#{document.id};"
|
|
302
|
+
dc_link_to( nil, 'table lg', parms, method: :get )
|
|
303
|
+
|
|
304
|
+
else # error.
|
|
305
|
+
yaml['type'].to_s
|
|
306
|
+
end
|
|
307
|
+
html << '</li>'
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
html << '</ul>'
|
|
311
|
+
html.html_safe
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
############################################################################
|
|
315
|
+
# Creates header div for result set.
|
|
316
|
+
############################################################################
|
|
317
|
+
def dc_header_for_result()
|
|
318
|
+
html = '<div class="dc-result-header">'
|
|
319
|
+
if @form['result_set']['actions'] and !@form['readonly']
|
|
320
|
+
ignore, width = dc_actions_column()
|
|
321
|
+
html << %Q[<div class="actions" style="width:#{width}px;"></div>]
|
|
322
|
+
end
|
|
323
|
+
# preparation for sort icon
|
|
324
|
+
sort_field, sort_direction = nil, nil
|
|
325
|
+
if session[@form['table']]
|
|
326
|
+
sort_field, sort_direction = session[@form['table']][:sort].to_s.split(' ')
|
|
327
|
+
end
|
|
328
|
+
|
|
329
|
+
if (columns = @form['result_set']['columns'])
|
|
330
|
+
columns.sort.each do |k, v|
|
|
331
|
+
session[:form_processing] = "result_set:columns: #{k}=#{v}"
|
|
332
|
+
next if v['width'].to_s.match(/hidden|none/i)
|
|
333
|
+
|
|
334
|
+
th = %Q[<div class="th" style="width:#{v['width'] || '15%'};text-align:#{v['align'] || 'left'};" data-name="#{v['name']}"]
|
|
335
|
+
label = v['caption'] || v['label']
|
|
336
|
+
label = (v['name'] ? "helpers.label.#{@form['table']}.#{v['name']}" : '') if label.nil?
|
|
337
|
+
label = t(label) if label.match(/\./)
|
|
338
|
+
# no sorting when embedded documents or custom filter is active
|
|
339
|
+
sort_ok = @form['result_set'].nil? || (@form['result_set'] && @form['result_set']['filter'].nil?)
|
|
340
|
+
sort_ok = sort_ok || (@form['index'] && @form['index']['sort'])
|
|
341
|
+
sort_ok = sort_ok && !dc_dont?(v['sort'], false)
|
|
342
|
+
if @tables.size == 1 and sort_ok
|
|
343
|
+
icon = 'sort lg'
|
|
344
|
+
if v['name'] == sort_field
|
|
345
|
+
icon = sort_direction == '1' ? 'sort-alpha-asc lg' : 'sort-alpha-desc lg'
|
|
346
|
+
end
|
|
347
|
+
th << ">#{dc_link_to(label, icon, sort: v['name'], table: params[:table], form_name: params[:form_name], action: :index, icon_pos: :last )}</div>"
|
|
348
|
+
else
|
|
349
|
+
th << ">#{label}</div>"
|
|
350
|
+
end
|
|
351
|
+
html << "<div class=\"spacer\"></div>" + th
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
(html << '</div>').html_safe
|
|
355
|
+
end
|
|
356
|
+
|
|
357
|
+
############################################################################
|
|
358
|
+
# Creates link for single or double click on result column
|
|
359
|
+
############################################################################
|
|
360
|
+
def dc_clicks_for_result(document)
|
|
361
|
+
html = ''
|
|
362
|
+
if @form['result_set']['dblclick']
|
|
363
|
+
yaml = @form['result_set']['dblclick']
|
|
364
|
+
opts = {}
|
|
365
|
+
opts[:controller] = yaml['controller'] || 'cmsedit'
|
|
366
|
+
opts[:action] = yaml['action']
|
|
367
|
+
opts[:table] = yaml['table']
|
|
368
|
+
opts[:form_name] = yaml['form_name']
|
|
369
|
+
opts[:method] = yaml['method'] || 'get'
|
|
370
|
+
opts[:id] = document['id']
|
|
371
|
+
opts[:readonly] = yaml['readonly'] if yaml['readonly']
|
|
372
|
+
opts[:window_close] = yaml['window_close'] if yaml['window_close']
|
|
373
|
+
html << ' data-dblclick=' + url_for(opts)
|
|
374
|
+
else
|
|
375
|
+
html << (' data-dblclick=' +
|
|
376
|
+
url_for(action: 'show', controller: 'cmsedit', id: document.id, ids: params[:ids],
|
|
377
|
+
readonly: (params[:readonly] ? 2 : 1), table: params[:table],
|
|
378
|
+
form_name: params[:form_name]) ) if @form['form']
|
|
379
|
+
end
|
|
380
|
+
html
|
|
381
|
+
end
|
|
382
|
+
|
|
383
|
+
############################################################################
|
|
384
|
+
# Formats value according to format supplied or data type. There is lots of things missing here.
|
|
385
|
+
############################################################################
|
|
386
|
+
def dc_format_value(value, format=nil)
|
|
387
|
+
return '' if value.nil?
|
|
388
|
+
|
|
389
|
+
klass = value.class.to_s
|
|
390
|
+
if klass.match(/time|date/i)
|
|
391
|
+
CmsCommonHelper.dc_format_date_time(value, format)
|
|
392
|
+
elsif format.to_s[0] == 'N'
|
|
393
|
+
return '' if value == 0 and format.match('z')
|
|
394
|
+
|
|
395
|
+
dec = format[1].blank? ? nil : format[1].to_i
|
|
396
|
+
sep = format[2].blank? ? nil : format[2]
|
|
397
|
+
del = format[3].blank? ? nil : format[3]
|
|
398
|
+
cur = format[4].blank? ? nil : format[4]
|
|
399
|
+
dc_format_number(value, dec, sep, del, cur)
|
|
400
|
+
else
|
|
401
|
+
value.to_s
|
|
402
|
+
end
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
############################################################################
|
|
406
|
+
# Creates tr code for each row of result set.
|
|
407
|
+
############################################################################
|
|
408
|
+
def dc_row_for_result(document)
|
|
409
|
+
clas = "dc-#{cycle('odd','even')} " + dc_style_or_class(nil, @form['result_set']['tr_class'], nil, document)
|
|
410
|
+
style = dc_style_or_class('style', @form['result_set']['tr_style'], nil, document)
|
|
411
|
+
"<div id=\"#{document.id}\" class=\"dc-result-data #{clas}\" #{dc_clicks_for_result(document)} #{style}>".html_safe
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
############################################################################
|
|
415
|
+
# Creates column for each field of result set document.
|
|
416
|
+
############################################################################
|
|
417
|
+
def dc_columns_for_result(document)
|
|
418
|
+
return '' unless @form['result_set']['columns']
|
|
419
|
+
html = ''
|
|
420
|
+
@form['result_set']['columns'].sort.each do |k,v|
|
|
421
|
+
session[:form_processing] = "result_set:columns: #{k}=#{v}"
|
|
422
|
+
next if v['width'].to_s.match(/hidden|none/i)
|
|
423
|
+
|
|
424
|
+
# convert shortcut to hash
|
|
425
|
+
v = {'name' => v} if v.class == String
|
|
426
|
+
begin
|
|
427
|
+
# eval
|
|
428
|
+
value = if v['eval']
|
|
429
|
+
dc_process_column_eval(v, document)
|
|
430
|
+
# as field
|
|
431
|
+
elsif document.respond_to?(v['name'])
|
|
432
|
+
dc_format_value(document.send( v['name'] ), v['format'])
|
|
433
|
+
# as hash (dc_memory)
|
|
434
|
+
elsif document.class == Hash
|
|
435
|
+
dc_format_value(document[ v['name'] ], v['format'])
|
|
436
|
+
# error
|
|
437
|
+
else
|
|
438
|
+
"??? #{v['name']}"
|
|
439
|
+
end
|
|
440
|
+
rescue Exception => e
|
|
441
|
+
dc_log_exception(e, 'dc_columns_for_result')
|
|
442
|
+
value = '!!!Error'
|
|
443
|
+
end
|
|
444
|
+
html << '<div class="spacer"></div>'
|
|
445
|
+
# set class
|
|
446
|
+
clas = dc_style_or_class(nil, v['td_class'], value, document)
|
|
447
|
+
# set width and align an additional style
|
|
448
|
+
style = dc_style_or_class(nil, v['td_style'] || v['style'], value, document)
|
|
449
|
+
flex_align = v['align'].to_s == 'right' ? 'flex-direction:row-reverse;' : ''
|
|
450
|
+
width_align = %Q[width:#{v['width'] || '15%'};#{flex_align}]
|
|
451
|
+
style = "style=\"#{width_align}#{style}\" "
|
|
452
|
+
|
|
453
|
+
html << "<div class=\"td #{clas}\" #{style}>#{value}</div>"
|
|
454
|
+
end
|
|
455
|
+
html.html_safe
|
|
456
|
+
end
|
|
457
|
+
|
|
458
|
+
private
|
|
459
|
+
|
|
460
|
+
############################################################################
|
|
461
|
+
# Process eval. Breaks eval option and calls with send method.
|
|
462
|
+
# Parameters:
|
|
463
|
+
# evaluate : String : Expression to be evaluated
|
|
464
|
+
# parameters : Array : array of parameters which will be send to method
|
|
465
|
+
############################################################################
|
|
466
|
+
def dc_process_eval(evaluate, parameters)
|
|
467
|
+
# evaluate by calling send method
|
|
468
|
+
clas, method = evaluate.split('.')
|
|
469
|
+
if method.nil?
|
|
470
|
+
send(clas, *parameters)
|
|
471
|
+
else
|
|
472
|
+
klass = clas.camelize.constantize
|
|
473
|
+
klass.send(method, *parameters)
|
|
474
|
+
end
|
|
475
|
+
end
|
|
476
|
+
|
|
477
|
+
############################################################################
|
|
478
|
+
# Split eval expression to array by parameters.
|
|
479
|
+
# Will split dc_name4_value(one ,"two") => ['dc_name4_value', 'one', 'two']
|
|
480
|
+
############################################################################
|
|
481
|
+
def dc_eval_to_array(expression)
|
|
482
|
+
expression.split(/\ |\,|\(|\)/).delete_if {|e| e.blank? }.map {|e| e.gsub(/\'|\"/,'').strip }
|
|
483
|
+
end
|
|
484
|
+
|
|
485
|
+
############################################################################
|
|
486
|
+
# Process eval option for field value.
|
|
487
|
+
# Used for processing single field column on result_set or form head.
|
|
488
|
+
############################################################################
|
|
489
|
+
def dc_process_column_eval(yaml, document)
|
|
490
|
+
# dc_name_for_id
|
|
491
|
+
if yaml['eval'].match(/dc_name4_id|dc_name_for_id/)
|
|
492
|
+
parms = dc_eval_to_array(yaml['eval'])
|
|
493
|
+
if parms.size == 3
|
|
494
|
+
dc_name_for_id(parms[1], parms[2], nil, document[ yaml['name'] ])
|
|
495
|
+
else
|
|
496
|
+
dc_name_for_id(parms[1], parms[2], parms[3], document[ yaml['name'] ])
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
# dc_name_for_value from locale definition
|
|
500
|
+
elsif yaml['eval'].match(/dc_name4_value|dc_name_for_value/)
|
|
501
|
+
parms = dc_eval_to_array(yaml['eval'])
|
|
502
|
+
if parms.size == 1
|
|
503
|
+
dc_name_for_value( @form['table'], yaml['name'], document[ yaml['name'] ] )
|
|
504
|
+
else
|
|
505
|
+
dc_name_for_value( parms[1], parms[2], document[ yaml['name'] ] )
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
# defined in helpers. For example dc_icon_for_boolean
|
|
509
|
+
elsif respond_to?(yaml['eval'])
|
|
510
|
+
send(yaml['eval'], document[yaml['name']])
|
|
511
|
+
|
|
512
|
+
# defined in model
|
|
513
|
+
elsif document.respond_to?(yaml['eval'])
|
|
514
|
+
document.send(yaml['eval'])
|
|
515
|
+
|
|
516
|
+
# special eval
|
|
517
|
+
elsif yaml['eval'].match('eval ')
|
|
518
|
+
# TO DO evaluate with specified parameters
|
|
519
|
+
|
|
520
|
+
# eval with params
|
|
521
|
+
else
|
|
522
|
+
parms = {}
|
|
523
|
+
if yaml['params'].class == String
|
|
524
|
+
parms = dc_value_for_parameter(yaml['params'], document)
|
|
525
|
+
elsif yaml['params'].class == Hash
|
|
526
|
+
yaml['params'].each { |k, v| parms[k] = dc_value_for_parameter(v) }
|
|
527
|
+
else
|
|
528
|
+
parms = document[ yaml['name'] ]
|
|
529
|
+
end
|
|
530
|
+
dc_process_eval(yaml['eval'], parms)
|
|
531
|
+
end
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
############################################################################
|
|
535
|
+
# Defines style or class for row (tr) or column (td)
|
|
536
|
+
############################################################################
|
|
537
|
+
def dc_style_or_class(selector, yaml, value, record)
|
|
538
|
+
return '' if yaml.nil?
|
|
539
|
+
|
|
540
|
+
# alias record and value so both names can be used in eval
|
|
541
|
+
field, document = value, record
|
|
542
|
+
html = selector ? "#{selector}=\"" : ''
|
|
543
|
+
begin
|
|
544
|
+
html << if yaml.class == String
|
|
545
|
+
yaml
|
|
546
|
+
# direct evaluate expression
|
|
547
|
+
elsif yaml['eval']
|
|
548
|
+
eval(yaml['eval'])
|
|
549
|
+
elsif yaml['method']
|
|
550
|
+
dc_process_eval(yaml['method'], record)
|
|
551
|
+
end
|
|
552
|
+
rescue Exception => e
|
|
553
|
+
dc_log_exception(e, 'dc_style_or_class')
|
|
554
|
+
end
|
|
555
|
+
html << '"' if selector
|
|
556
|
+
html
|
|
557
|
+
end
|
|
558
|
+
|
|
559
|
+
############################################################################
|
|
560
|
+
# Get standard actions when actions directive contains single line.
|
|
561
|
+
# Subroutine of dc_actions_for_index
|
|
562
|
+
#
|
|
563
|
+
# Allows for actions: new, filter, standard syntax
|
|
564
|
+
############################################################################
|
|
565
|
+
def dc_define_standard_actions(actions_params, standard)
|
|
566
|
+
actions = {}
|
|
567
|
+
actions_params.split(',').each do |an_action|
|
|
568
|
+
an_action.strip!
|
|
569
|
+
if an_action == 'standard'
|
|
570
|
+
actions.merge!(standard)
|
|
571
|
+
else
|
|
572
|
+
standard.each do |index, action|
|
|
573
|
+
(actions[index] = action; break) if action == an_action
|
|
574
|
+
end
|
|
575
|
+
end
|
|
576
|
+
end
|
|
577
|
+
actions
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
end
|