drg_cms 0.7.0.8 → 0.7.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/drg_cms/drg_cms.js +50 -20
- data/app/assets/stylesheets/drg_cms/drg_cms.css +89 -31
- data/app/assets/stylesheets/drg_cms/select-multiple.css +5 -6
- data/app/controllers/cmsedit_controller.rb +57 -24
- data/app/controllers/dc_application_controller.rb +18 -21
- data/app/controls/dc_poll_result_control.rb +36 -36
- data/app/controls/dc_setup_control.rb +53 -0
- data/app/forms/all_options.yml +3 -3
- data/app/forms/cms_menu.yml +7 -0
- data/app/forms/dc_image_search.yml +2 -2
- data/app/forms/dc_poll.yml +2 -1
- data/app/forms/dc_poll_result.yml +10 -7
- data/app/forms/dc_setup.yml +45 -0
- data/app/forms/dc_steps_template.yml +4 -1
- data/app/helpers/cms_common_helper.rb +14 -10
- data/app/helpers/cms_helper.rb +8 -7
- data/app/helpers/cms_index_helper.rb +56 -42
- data/app/helpers/dc_application_helper.rb +46 -16
- data/app/helpers/dc_image_helper.rb +2 -2
- data/app/models/concerns/dc_user_concern.rb +1 -1
- data/app/models/dc_big_table.rb +1 -1
- data/app/models/dc_filter.rb +5 -9
- data/app/models/dc_image.rb +1 -1
- data/app/models/dc_memory.rb +2 -2
- data/app/models/dc_setup.rb +111 -0
- data/app/models/drgcms_form_fields/datetime_picker.rb +1 -1
- data/app/models/drgcms_form_fields/embedded.rb +17 -9
- data/app/models/drgcms_form_fields/multitext_autocomplete.rb +44 -36
- data/app/models/drgcms_form_fields/select.rb +21 -5
- data/app/renderers/dc_big_menu_renderer.rb +18 -20
- data/app/renderers/dc_menu_renderer.rb +21 -58
- data/app/renderers/dc_simple_menu_renderer.rb +1 -1
- data/app/views/cmsedit/_edit_stuff.html.erb +3 -0
- data/config/locales/drgcms_en.yml +8 -0
- data/config/locales/drgcms_sl.yml +12 -4
- data/config/locales/models_en.yml +17 -1
- data/config/locales/models_sl.yml +17 -1
- data/lib/drg_cms/version.rb +1 -1
- data/lib/drg_cms.rb +22 -23
- data/lib/generators/new_drg_form/new_drg_form_generator.rb +32 -14
- metadata +5 -2
@@ -855,10 +855,10 @@ def dc_user_can_view(ctrl, policy_id)
|
|
855
855
|
policies = if site.inherit_policy.blank?
|
856
856
|
site.dc_policies
|
857
857
|
else
|
858
|
-
|
858
|
+
Mongo::QueryCache.cache { DcSite.find(site.inherit_policy) }.dc_policies
|
859
859
|
end
|
860
860
|
# permission defined by default policy
|
861
|
-
default_policy =
|
861
|
+
default_policy = Mongo::QueryCache.cache { policies.find_by(is_default: true) }
|
862
862
|
return cache_add(policy_id, false, 'Default access policy not found for the site!') unless default_policy
|
863
863
|
|
864
864
|
permissions = {}
|
@@ -866,14 +866,14 @@ def dc_user_can_view(ctrl, policy_id)
|
|
866
866
|
# update permissions with defined policy
|
867
867
|
part_policy = nil
|
868
868
|
if policy_id
|
869
|
-
part_policy =
|
869
|
+
part_policy = Mongo::QueryCache.cache { policies.find(policy_id) }
|
870
870
|
return cache_add(policy_id, false, 'Access policy not found for part!') unless part_policy
|
871
871
|
|
872
872
|
part_policy.dc_policy_rules.to_a.each { |v| permissions[v.dc_policy_role_id] = v.permission }
|
873
873
|
end
|
874
874
|
# apply guest role if no roles defined
|
875
875
|
if ctrl.session[:user_roles].nil?
|
876
|
-
role =
|
876
|
+
role = Mongo::QueryCache.cache { DcPolicyRole.find_by(system_name: 'guest', active: true) }
|
877
877
|
return cache_add(policy_id, false, 'System guest role not defined!') unless role
|
878
878
|
|
879
879
|
ctrl.session[:user_roles] = [role.id]
|
@@ -999,7 +999,15 @@ def dc_big_table(key)
|
|
999
999
|
desc = v.value if desc.blank? # still blank. Use value as description
|
1000
1000
|
ret << [desc, v.value]
|
1001
1001
|
end
|
1002
|
-
ret
|
1002
|
+
ret.sort_alphabetical_by(&:first)
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
########################################################################
|
1006
|
+
# Will return name for value defined in dc_big_table
|
1007
|
+
########################################################################
|
1008
|
+
def dc_big_table_name_for_value(key, value)
|
1009
|
+
dc_big_table(key).each { |k, val| return k if val.to_s == value.to_s}
|
1010
|
+
'???'
|
1003
1011
|
end
|
1004
1012
|
|
1005
1013
|
########################################################################
|
@@ -1110,12 +1118,12 @@ end
|
|
1110
1118
|
# Returns:
|
1111
1119
|
# HTML data to be embedded into page header
|
1112
1120
|
#######################################################################
|
1113
|
-
def dc_get_json_ld
|
1114
|
-
return '' if @json_ld.
|
1121
|
+
def dc_get_json_ld
|
1122
|
+
return '' if @json_ld.blank?
|
1115
1123
|
|
1116
1124
|
%(
|
1117
1125
|
<script type="application/ld+json">
|
1118
|
-
#{JSON.pretty_generate({'@context' => 'http://schema.org', '@graph' => @json_ld})}
|
1126
|
+
#{JSON.pretty_generate({ '@context' => 'http://schema.org', '@graph' => @json_ld })}
|
1119
1127
|
</script>).html_safe
|
1120
1128
|
end
|
1121
1129
|
|
@@ -1135,21 +1143,40 @@ def dc_add_json_ld(element)
|
|
1135
1143
|
end
|
1136
1144
|
|
1137
1145
|
########################################################################
|
1138
|
-
# Will return meta data for SEO optimizations
|
1146
|
+
# Will return meta data for SEO optimizations.
|
1147
|
+
# It will also create special link rel="canonical" tag if defined in meta tags or page document.
|
1139
1148
|
#
|
1140
1149
|
# Returns:
|
1141
1150
|
# HTML data to be embedded into page header
|
1142
1151
|
#######################################################################
|
1143
1152
|
def dc_get_seo_meta_tags
|
1144
1153
|
html = ''
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
|
1154
|
+
has_canonical = false
|
1155
|
+
html << @meta_tags.inject('') do |r, tag|
|
1156
|
+
r << if tag.first.match('canonical')
|
1157
|
+
has_canonical = true
|
1158
|
+
dc_get_link_canonical_tag(tag.last)
|
1159
|
+
else
|
1160
|
+
%(<meta #{tag.first} content="#{tag.last}">\n )
|
1161
|
+
end
|
1149
1162
|
end if @meta_tags
|
1163
|
+
html << dc_get_link_canonical_tag(@page&.canonical_link) unless has_canonical
|
1150
1164
|
html.html_safe
|
1151
1165
|
end
|
1152
1166
|
|
1167
|
+
########################################################################
|
1168
|
+
# helper for setting canonical link on the page
|
1169
|
+
#######################################################################
|
1170
|
+
def dc_get_link_canonical_tag(href = nil)
|
1171
|
+
return %(<link rel="canonical" href="#{request.url}">\n) if href.blank?
|
1172
|
+
|
1173
|
+
unless href.match(/^http/i)
|
1174
|
+
uri = URI.parse(request.url)
|
1175
|
+
href = "#{uri.scheme}://#{uri.host}/#{href.delete_prefix('/')}"
|
1176
|
+
end
|
1177
|
+
%(<link rel="canonical" href="#{href}">\n)
|
1178
|
+
end
|
1179
|
+
|
1153
1180
|
########################################################################
|
1154
1181
|
# Will add a meta tag to internal hash structure. If meta tag already exists it
|
1155
1182
|
# will be overwritten.
|
@@ -1178,7 +1205,7 @@ end
|
|
1178
1205
|
# Returns:
|
1179
1206
|
# [String] alt="image-tag"
|
1180
1207
|
#######################################################################
|
1181
|
-
def dc_img_alt_tag(file_name, text=nil)
|
1208
|
+
def dc_img_alt_tag(file_name, text = nil)
|
1182
1209
|
%( alt="#{dc_img_alt(file_name, text)}" ).html_safe
|
1183
1210
|
end
|
1184
1211
|
|
@@ -1194,7 +1221,7 @@ end
|
|
1194
1221
|
# Returns:
|
1195
1222
|
# [String] alt_image_name
|
1196
1223
|
#######################################################################
|
1197
|
-
def dc_img_alt(file_name, text=nil)
|
1224
|
+
def dc_img_alt(file_name, text = nil)
|
1198
1225
|
return text if text.present?
|
1199
1226
|
|
1200
1227
|
name = File.basename(file_name.to_s)
|
@@ -1203,7 +1230,10 @@ end
|
|
1203
1230
|
|
1204
1231
|
private
|
1205
1232
|
|
1206
|
-
|
1233
|
+
########################################################################
|
1234
|
+
# To cache localy dc_user_can_view response for a single call. It has large gains on sites
|
1235
|
+
# with large menus.
|
1236
|
+
########################################################################
|
1207
1237
|
def cache_add(id, can_view, msg)
|
1208
1238
|
@can_view_cache[id] = [can_view, msg]
|
1209
1239
|
end
|
@@ -71,7 +71,7 @@ end
|
|
71
71
|
############################################################################
|
72
72
|
# Will return code for previewing image on top of dc_image entry form
|
73
73
|
############################################################################
|
74
|
-
def
|
74
|
+
def first_dc_image(document, *parms)
|
75
75
|
src = "/#{dc_get_site.params.dig('dc_image', 'location')}/#{document.first_available_image}"
|
76
76
|
%(<span class="dc-image-preview"><img src="#{src}"></img></span><span id="dc-image-preview">).html_safe
|
77
77
|
end
|
@@ -79,7 +79,7 @@ end
|
|
79
79
|
######################################################################
|
80
80
|
# Will format qry result as html code for selecting image
|
81
81
|
######################################################################
|
82
|
-
def
|
82
|
+
def select_links_for_dc_image(doc, *parms)
|
83
83
|
%w[o s m l].inject('') { | r,size| r << dc_image_link_for_select(doc, size) }.html_safe
|
84
84
|
end
|
85
85
|
|
@@ -149,7 +149,7 @@ end
|
|
149
149
|
# Will return list of available groups
|
150
150
|
##########################################################################
|
151
151
|
def self.groups_for_select
|
152
|
-
where(group: true, active: true).order_by(name: 1).
|
152
|
+
where(group: true, active: true).order_by(name: 1).map { [_1.name, _1.id] }
|
153
153
|
end
|
154
154
|
|
155
155
|
private
|
data/app/models/dc_big_table.rb
CHANGED
data/app/models/dc_filter.rb
CHANGED
@@ -114,7 +114,7 @@ def self.get_filter_field(parent)
|
|
114
114
|
return '' if filter.nil?
|
115
115
|
|
116
116
|
filter = YAML.load(filter) rescue nil
|
117
|
-
return '' if filter.nil?
|
117
|
+
return '' if filter.nil? || filter['operation'].to_s == 'eval'
|
118
118
|
|
119
119
|
field = get_field_form_definition(filter['field'], parent)
|
120
120
|
return '' if field.nil? && filter['input'].nil?
|
@@ -186,14 +186,10 @@ def self.menu_filter(parent)
|
|
186
186
|
# only single defined. Convert to array.
|
187
187
|
filters = [filters] if filters.class == Hash
|
188
188
|
filters.each do |filter|
|
189
|
-
url = parent.
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
filter_oper: filter['operation'],
|
194
|
-
filter_value: filter['value'])
|
195
|
-
|
196
|
-
url = parent.url_for(controller: 'cmsedit', action: :run, t: table, f: CmsHelper.form_param(parent.params),
|
189
|
+
url = parent.url_for(controller: :cmsedit,
|
190
|
+
action: :run,
|
191
|
+
table: table,
|
192
|
+
form_name: CmsHelper.form_param(parent.params),
|
197
193
|
control: 'cmsedit.filter_on',
|
198
194
|
filter_field: filter['field'],
|
199
195
|
filter_oper: filter['operation'],
|
data/app/models/dc_image.rb
CHANGED
data/app/models/dc_memory.rb
CHANGED
@@ -63,8 +63,8 @@
|
|
63
63
|
# As result report.pdf file will be opened in new browser window.
|
64
64
|
########################################################################
|
65
65
|
class DcMemory
|
66
|
-
|
67
|
-
|
66
|
+
include Mongoid::Document
|
67
|
+
|
68
68
|
########################################################################
|
69
69
|
# Initilize object
|
70
70
|
########################################################################
|
@@ -0,0 +1,111 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2024+ 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
|
+
# DcSetup collection is used for settings, that are specific to the application,
|
26
|
+
# or part of application (gem). It consists of data dafinitions and form for editing data.
|
27
|
+
# Data is saved internaly in YAML format.
|
28
|
+
#
|
29
|
+
# When editing, admin can see and edit form definition (adding new data to application setup), while user
|
30
|
+
# sees only data entry form.
|
31
|
+
#
|
32
|
+
# Usage:
|
33
|
+
# my_app_settings = DcSetup.find_by(name: 'my_app')
|
34
|
+
# my_app_settings = DcSetup.get('my_app')
|
35
|
+
# company = my_app_settings.company_name
|
36
|
+
# company, ceo = my_app_settings[:company_name, 'ceo_name']
|
37
|
+
#
|
38
|
+
##############################################################################
|
39
|
+
class DcSetup
|
40
|
+
include Mongoid::Document
|
41
|
+
include Mongoid::Timestamps
|
42
|
+
|
43
|
+
attr_reader :my_data
|
44
|
+
attr_reader :my_fields
|
45
|
+
|
46
|
+
field :name, type: String, default: ''
|
47
|
+
field :data, type: String, default: ''
|
48
|
+
field :form, type: String, default: ''
|
49
|
+
field :editors, type: Array, default: []
|
50
|
+
|
51
|
+
field :created_by, type: BSON::ObjectId
|
52
|
+
field :updated_by, type: BSON::ObjectId
|
53
|
+
|
54
|
+
index name: 1
|
55
|
+
|
56
|
+
validates_length_of :name, minimum: 3
|
57
|
+
|
58
|
+
before_save do
|
59
|
+
self.data = my_data.to_yaml
|
60
|
+
end
|
61
|
+
|
62
|
+
##############################################################################
|
63
|
+
# Will return settings record for specified application.
|
64
|
+
#
|
65
|
+
# @param [String] app_name The name of the application
|
66
|
+
# @return [Object, nil] The settings record if found, nil otherwise
|
67
|
+
##############################################################################
|
68
|
+
def self.get(app_name)
|
69
|
+
DcSetup.find_by(name: app_name.to_s)
|
70
|
+
end
|
71
|
+
|
72
|
+
##############################################################################
|
73
|
+
# Will return value for single setting if called as method.
|
74
|
+
##############################################################################
|
75
|
+
def method_missing(m, *args, &block)
|
76
|
+
m = m.to_s
|
77
|
+
if m.match('=')
|
78
|
+
m.chomp!('=')
|
79
|
+
my_data[m] = args.first
|
80
|
+
else
|
81
|
+
my_data[m]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
##############################################################################
|
86
|
+
# Will return value for single setting. Called as parameter in square brackets.
|
87
|
+
# If more then one parameter is passed it will return them as array.
|
88
|
+
##############################################################################
|
89
|
+
def [](*keys)
|
90
|
+
return my_data[keys.first.to_s] if keys.size == 1
|
91
|
+
|
92
|
+
keys.inject([]) { |r, k| r << my_data[k.to_s] }
|
93
|
+
end
|
94
|
+
|
95
|
+
##############################################################################
|
96
|
+
# Will return true if setting is defined on the form
|
97
|
+
##############################################################################
|
98
|
+
def respond_to?(field_name)
|
99
|
+
return true #if my_fields[field_name.to_s]
|
100
|
+
|
101
|
+
super.respond_to?(field_name)
|
102
|
+
end
|
103
|
+
|
104
|
+
##############################################################################
|
105
|
+
#
|
106
|
+
##############################################################################
|
107
|
+
def my_data
|
108
|
+
@my_data ||= (YAML.unsafe_load(data)) || {}
|
109
|
+
end
|
110
|
+
|
111
|
+
end
|
@@ -81,7 +81,7 @@ end
|
|
81
81
|
###########################################################################
|
82
82
|
def self.get_data(params, name)
|
83
83
|
t = params['record'][name] ? params['record'][name].to_datetime : nil
|
84
|
-
t ? Time.
|
84
|
+
t ? Time.new(t.year, t.month, t.day, t.hour, t.min) : nil
|
85
85
|
end
|
86
86
|
|
87
87
|
end
|
@@ -53,19 +53,26 @@ def render
|
|
53
53
|
# HTML defaults. Some must be set
|
54
54
|
@yaml['html'] ||= {}
|
55
55
|
@yaml['html']['width'] ||= '99%'
|
56
|
+
# message when new record
|
57
|
+
if @record.new_record?
|
58
|
+
@yaml['html']['srcdoc'] = %(
|
59
|
+
<div style='font-family: helvetica; font-size: 1.7rem; font-weight: bold; color: #ddd; padding: 1rem'>
|
60
|
+
#{I18n.t('drgcms.iframe_save_to_view')}
|
61
|
+
</div>)
|
62
|
+
end
|
56
63
|
html = @yaml['html'].inject('') { |r, val| r << "#{val.first}=\"#{val.last}\" " }
|
57
64
|
|
58
65
|
@yaml['action'] ||= 'index'
|
59
66
|
# defaults both way
|
60
|
-
@yaml['table'] ||= @yaml['form_name']
|
61
|
-
@yaml['form_name'] ||= @yaml['table']
|
67
|
+
@yaml['table'] ||= @yaml['form_name']
|
68
|
+
@yaml['form_name'] ||= @yaml['table']
|
62
69
|
|
63
|
-
if @yaml['name'] == @yaml['table']
|
70
|
+
if @yaml['name'] == @yaml['table'] || @yaml['table'] == 'dc_memory'
|
64
71
|
tables = @yaml['table']
|
65
72
|
ids = @record.id
|
66
73
|
else
|
67
|
-
tables = @parent.tables.
|
68
|
-
ids = @parent.ids
|
74
|
+
tables = (@parent.tables.map(&:first) + [@yaml['table']]).join(';')
|
75
|
+
ids = (@parent.ids + [@record.id]).join(';')
|
69
76
|
end
|
70
77
|
# edit enabled embedded form on a readonly form
|
71
78
|
readonly = @yaml['readonly'].class == FalseClass ? nil : @readonly
|
@@ -73,11 +80,12 @@ def render
|
|
73
80
|
ids: ids, table: tables, form_name: @yaml['form_name'],
|
74
81
|
field_name: @yaml['name'], iframe: "if_#{@yaml['name']}", readonly: readonly }
|
75
82
|
# additional parameters if specified
|
76
|
-
@yaml['params'].each { |k,v| opts[k] = @parent.dc_value_for_parameter(v) } if @yaml['params']
|
77
|
-
|
83
|
+
@yaml['params'].each { |k, v| opts[k] = @parent.dc_value_for_parameter(v) } if @yaml['params']
|
84
|
+
|
78
85
|
@html << "<iframe class='iframe_embedded' id='if_#{@yaml['name']}' name='if_#{@yaml['name']}' #{html}></iframe>"
|
79
|
-
|
80
|
-
|
86
|
+
if @record.new_record?
|
87
|
+
else
|
88
|
+
url = @parent.url_for(opts)
|
81
89
|
attributes = case
|
82
90
|
when @yaml['load'].nil? || @yaml['load'].match('default')
|
83
91
|
"'src', '#{url}'"
|
@@ -55,16 +55,13 @@ class MultitextAutocomplete < DrgcmsField
|
|
55
55
|
# Returns value for readonly field
|
56
56
|
###########################################################################
|
57
57
|
def ro_standard(table, search)
|
58
|
-
|
58
|
+
current_values = @record.send(@yaml['name'])
|
59
|
+
return self if current_values.blank?
|
59
60
|
|
60
|
-
result = ''
|
61
61
|
table = table.classify.constantize
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
result << table.find(element)[search] + '<br>'
|
66
|
-
end
|
67
|
-
super(result)
|
62
|
+
search = search.split(/\.|\,/).first if search.match(/\.|\,/)
|
63
|
+
html = current_values.inject('') { |r, element| r << table.find(element)[search] + '<br>' }
|
64
|
+
super(html)
|
68
65
|
end
|
69
66
|
|
70
67
|
###########################################################################
|
@@ -73,11 +70,11 @@ end
|
|
73
70
|
def render
|
74
71
|
# get field name
|
75
72
|
if @yaml['search'].class == Hash
|
76
|
-
table
|
73
|
+
table = @yaml['search']['table']
|
77
74
|
field_name = @yaml['search']['field']
|
78
|
-
method
|
79
|
-
search
|
80
|
-
elsif @yaml['search'].to_s.match(
|
75
|
+
method = @yaml['search']['method']
|
76
|
+
search = method.nil? ? field_name : "#{field_name}.#{method}"
|
77
|
+
elsif @yaml['search'].to_s.match(/\.|\,/)
|
81
78
|
table, field_name, method = @yaml['search'].split(/\.|\,/).map(&:strip)
|
82
79
|
search = method.nil? ? field_name : "#{field_name}.#{method}"
|
83
80
|
else # search and table name are separated
|
@@ -101,60 +98,71 @@ def render
|
|
101
98
|
return self
|
102
99
|
end
|
103
100
|
|
104
|
-
#
|
105
|
-
collection = table.classify.constantize
|
101
|
+
# does collection exists
|
102
|
+
collection = table.classify.constantize rescue nil
|
103
|
+
if collection.nil?
|
104
|
+
@html << "Invalid table name: #{table}"
|
105
|
+
return self
|
106
|
+
end
|
107
|
+
|
108
|
+
# does field exists
|
106
109
|
unless @record.respond_to?(@yaml['name'])
|
107
110
|
@html << "Invalid field name: #{@yaml['name']}"
|
108
111
|
return self
|
109
112
|
end
|
110
|
-
|
113
|
+
|
114
|
+
# search data entry
|
111
115
|
@yaml['html'] ||= {}
|
112
116
|
@yaml['html']['value'] = '' # must be. Otherwise it will look into record and return error
|
113
117
|
@yaml['html']['placeholder'] = t('drgcms.search_placeholder')
|
114
118
|
_name = '_' + @yaml['name']
|
115
119
|
@html << '<div class="ui-autocomplete-border">'
|
116
|
-
@html << @parent.link_to(@parent.
|
120
|
+
@html << @parent.link_to(@parent.mi_icon('plus-square-o green'), '#', onclick: 'return false;') # dummy add. But it is usefull.
|
117
121
|
|
122
|
+
# text_field for autocomplete
|
118
123
|
record = record_text_for(@yaml['name'])
|
119
|
-
# text field for autocomplete
|
120
124
|
@html << '<span class="dc-text-autocomplete">' << @parent.text_field(record, _name, @yaml['html']) << '<span></span></span>'
|
121
|
-
|
125
|
+
|
126
|
+
# link for adding new documents to searched collection
|
122
127
|
if @yaml['with_new'] && !@readonly
|
123
128
|
@html << ' ' +
|
124
|
-
@parent.
|
129
|
+
@parent.mi_icon('plus-square-o', class: 'in-edit-add', title: t('drgcms.new'),
|
125
130
|
style: "vertical-align: top;", 'data-table' => @yaml['with_new'] )
|
126
131
|
end
|
132
|
+
|
127
133
|
# div to list active selections
|
128
134
|
@html << "<div id =\"#{record}#{@yaml['name']}\">"
|
129
|
-
#
|
130
|
-
|
131
|
-
|
135
|
+
# fill with current values
|
136
|
+
current_values = @record.send(@yaml['name'])
|
137
|
+
unless current_values.nil?
|
138
|
+
current_values.each do |element|
|
132
139
|
# this is quick and dirty trick. We have model dc_big_table which can be used for retrive
|
133
140
|
# more complicated options
|
134
141
|
# TODO retrieve choices from big_table
|
135
142
|
rec = if table == 'dc_big_table'
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
143
|
+
collection.find(@yaml['name'], @parent.session)
|
144
|
+
else
|
145
|
+
collection.find(element)
|
146
|
+
end
|
147
|
+
|
141
148
|
@html << if rec
|
142
|
-
link = @parent.link_to(@parent.
|
143
|
-
onclick: %($('##{rec.id}').hide();
|
144
|
-
link = @parent.
|
149
|
+
link = @parent.link_to(@parent.mi_icon('remove_circle red'), '#',
|
150
|
+
onclick: %($('##{rec.id}').hide(); let v = $('##{record}_#{@yaml['name']}_#{rec.id}'); v.val("-" + v.val());return false;))
|
151
|
+
link = @parent.mi_icon('check green') if @readonly
|
145
152
|
field = @parent.hidden_field(record, "#{@yaml['name']}_#{rec.id}", value: element)
|
146
153
|
%(<div id="#{rec.id}" style="padding:4px;">#{link} #{rec.send(field_name)}<br>#{field}</div>)
|
147
154
|
else
|
148
|
-
'** error **'
|
155
|
+
'** error **' # Related data is missing. It happends.
|
149
156
|
end
|
150
157
|
end
|
151
158
|
end
|
152
159
|
@html << "</div></div>"
|
160
|
+
|
153
161
|
# Create text for div to be added when new category is selected
|
154
|
-
link = @parent.link_to(@parent.
|
155
|
-
onclick:
|
162
|
+
link = @parent.link_to(@parent.mi_icon('remove_circle red'), '#',
|
163
|
+
onclick: %($('#rec_id').hide(); let v = $('##{record}_#{@yaml['name']}_rec_id'); v.val("-" + v.val());return false;"))
|
156
164
|
field = @parent.hidden_field(record, "#{@yaml['name']}_rec_id", value: 'rec_id')
|
157
|
-
one_div =
|
165
|
+
one_div = %(<div id="rec_id" style="padding:4px;">#{link} rec_search<br>#{field}</div>)
|
158
166
|
|
159
167
|
# JS stuff
|
160
168
|
@js << <<EOJS
|
@@ -174,7 +182,7 @@ $(document).ready(function() {
|
|
174
182
|
});
|
175
183
|
},
|
176
184
|
change: function (event, ui) {
|
177
|
-
|
185
|
+
let div = '#{one_div}';
|
178
186
|
if (ui.item != null) {
|
179
187
|
div = div.replace(/rec_id/g, ui.item.id)
|
180
188
|
div = div.replace('rec_search', ui.item.value)
|
@@ -197,7 +205,7 @@ end
|
|
197
205
|
###########################################################################
|
198
206
|
def self.get_data(params, name)
|
199
207
|
r = []
|
200
|
-
params['record'].each do |k, v|
|
208
|
+
params['record'].each do |k, v| # inject does not work on params
|
201
209
|
# if it starts with - then it was removed
|
202
210
|
r << BSON::ObjectId.from_string(v) if k.starts_with?("#{name}_") && v[0] != '-'
|
203
211
|
end
|
@@ -47,7 +47,9 @@ module DrgcmsFormFields
|
|
47
47
|
# * +depend:+ Select options may depend on a value in some other field. If depend option is specified
|
48
48
|
# then chices must be provided by class method and defined in eval option.
|
49
49
|
# * +html:+ html options which apply to select field (optional)
|
50
|
-
#
|
50
|
+
# * +with_new:+ model_name.form_name will invoke view dialog for selected option
|
51
|
+
# * +with_edit:+ model_name.form_name will invoke edit dialog for selected option
|
52
|
+
#
|
51
53
|
# Form example:
|
52
54
|
# 30:
|
53
55
|
# name: type
|
@@ -150,9 +152,21 @@ end
|
|
150
152
|
def add_view_code
|
151
153
|
return '' if (data = @record.send(@yaml['name'])).blank?
|
152
154
|
|
153
|
-
table, form_name = @yaml['
|
155
|
+
table, form_name = @yaml['with_view'].split(/\ |\,/).delete_if(&:blank)
|
154
156
|
url = @parent.url_for(controller: 'cmsedit', id: data, action: :edit, table: table, form_name: form_name, readonly: true, window_close: 1 )
|
155
|
-
icon = @parent.mi_icon('
|
157
|
+
icon = @parent.mi_icon('visibility-o md-18')
|
158
|
+
%(<span class="dc-window-open" data-url="#{url}"> #{icon}</span>)
|
159
|
+
end
|
160
|
+
|
161
|
+
###########################################################################
|
162
|
+
# Will add code to view more data about selected option in a window
|
163
|
+
###########################################################################
|
164
|
+
def add_edit_code
|
165
|
+
return '' if (data = @record.send(@yaml['name'])).blank?
|
166
|
+
|
167
|
+
table, form_name = @yaml['view'].split(/\ |\,/).delete_if(&:blank)
|
168
|
+
url = @parent.url_for(controller: 'cmsedit', id: data, action: :edit, table: table, form_name: form_name, window_close: 1 )
|
169
|
+
icon = @parent.mi_icon('edit-o md-18')
|
156
170
|
%(<span class="dc-window-open" data-url="#{url}"> #{icon}</span>)
|
157
171
|
end
|
158
172
|
|
@@ -182,7 +196,7 @@ def ro_standard
|
|
182
196
|
(html = choice; break) if choice.to_s == value.to_s
|
183
197
|
end
|
184
198
|
end
|
185
|
-
html << add_view_code if @yaml['
|
199
|
+
html << add_view_code if @yaml['with_view']
|
186
200
|
end
|
187
201
|
super(html)
|
188
202
|
end
|
@@ -202,12 +216,14 @@ def render
|
|
202
216
|
|
203
217
|
record = record_text_for(@yaml['name'])
|
204
218
|
if @yaml['html'][:multiple]
|
219
|
+
@yaml['html']['class'] = "#{@yaml['html']['class']} select-multiple"
|
205
220
|
@html << @parent.select(record, @yaml['name'], get_choices, options_part, @yaml['html'])
|
206
221
|
@js << "$('##{record}_#{@yaml['name']}').selectMultiple();"
|
207
222
|
else
|
208
223
|
@html << @parent.select(record, @yaml['name'], get_choices, options_part, @yaml['html'])
|
209
224
|
# add code for view more data
|
210
|
-
@html <<
|
225
|
+
@html << view_code_add() if @yaml['with_view']
|
226
|
+
@html << edit_code_add() if @yaml['with_edit'] && !@readonly
|
211
227
|
end
|
212
228
|
self
|
213
229
|
end
|