drg_cms 0.6.1.11 → 0.7.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +260 -0
  3. data/MIT-LICENSE +1 -1
  4. data/README.md +9 -5
  5. data/app/assets/javascripts/drg_cms/drg_cms.js +95 -34
  6. data/app/assets/javascripts/drg_cms/jquery.bpopup.js +372 -0
  7. data/app/assets/javascripts/drg_cms_application.js +1 -3
  8. data/app/assets/javascripts/drg_cms_cms.js +3 -4
  9. data/app/assets/stylesheets/drg_cms/drg_cms.css +37 -5
  10. data/app/assets/stylesheets/drg_cms/jstree.css +32 -27
  11. data/app/assets/stylesheets/drg_cms/select-multiple.css +6 -4
  12. data/app/controllers/cmsedit_controller.rb +22 -24
  13. data/app/controllers/dc_application_controller.rb +10 -9
  14. data/app/controllers/dc_common_controller.rb +14 -11
  15. data/app/controllers/dc_main_controller.rb +0 -1
  16. data/app/controls/dc_gallery_control.rb +46 -0
  17. data/app/controls/dc_image_control.rb +180 -0
  18. data/app/controls/dc_page_control.rb +3 -3
  19. data/app/controls/dc_poll_result_control.rb +7 -8
  20. data/app/controls/dc_report.rb +9 -4
  21. data/app/controls/design_element_settings_control.rb +88 -37
  22. data/app/forms/all_options.yml +18 -7
  23. data/app/forms/cms_menu.yml +10 -4
  24. data/app/forms/dc_category.yml +17 -8
  25. data/app/forms/dc_category_as_tree.yml +31 -0
  26. data/app/forms/dc_gallery.yml +1 -1
  27. data/app/forms/dc_image.yml +122 -0
  28. data/app/forms/dc_image_search.yml +72 -0
  29. data/app/forms/dc_page.yml +11 -8
  30. data/app/forms/dc_steps_template.yml +2 -1
  31. data/app/forms/help/dc_category_as_tree.en +4 -0
  32. data/app/forms/help/dc_category_as_tree.sl +5 -0
  33. data/app/helpers/cms_common_helper.rb +24 -16
  34. data/app/helpers/cms_edit_helper.rb +28 -35
  35. data/app/helpers/cms_helper.rb +21 -5
  36. data/app/helpers/cms_index_helper.rb +53 -38
  37. data/app/helpers/dc_application_helper.rb +95 -121
  38. data/app/helpers/dc_category_helper.rb +129 -0
  39. data/app/helpers/dc_image_helper.rb +127 -0
  40. data/app/models/concerns/dc_policy_rule_concern.rb +1 -1
  41. data/app/models/concerns/dc_user_concern.rb +12 -4
  42. data/app/models/dc_category.rb +62 -24
  43. data/app/models/dc_design.rb +5 -4
  44. data/app/models/dc_filter.rb +19 -18
  45. data/app/models/dc_image.rb +237 -0
  46. data/app/models/dc_internals.rb +5 -9
  47. data/app/models/dc_policy_role.rb +8 -8
  48. data/app/models/drgcms_form_fields/date_picker.rb +10 -12
  49. data/app/models/drgcms_form_fields/datetime_picker.rb +10 -11
  50. data/app/models/drgcms_form_fields/drgcms_field.rb +55 -30
  51. data/app/models/drgcms_form_fields/embedded.rb +11 -8
  52. data/app/models/drgcms_form_fields/journal_diff.rb +2 -2
  53. data/app/models/drgcms_form_fields/multitext_autocomplete.rb +51 -47
  54. data/app/models/drgcms_form_fields/select.rb +20 -14
  55. data/app/models/drgcms_form_fields/text_with_select.rb +5 -9
  56. data/app/models/drgcms_form_fields/tree_select.rb +20 -19
  57. data/app/renderers/dc_gallery_renderer.rb +10 -4
  58. data/app/renderers/dc_page_renderer.rb +7 -7
  59. data/app/renderers/dc_poll_renderer.rb +13 -12
  60. data/app/views/cmsedit/_edit_stuff.html.erb +1 -1
  61. data/app/views/cmsedit/edit.html.erb +1 -1
  62. data/app/views/cmsedit/index.html.erb +1 -1
  63. data/app/views/cmsedit/new.html.erb +1 -0
  64. data/app/views/layouts/content.html.erb +1 -1
  65. data/config/locales/drgcms_en.yml +16 -2
  66. data/config/locales/drgcms_sl.yml +15 -2
  67. data/config/locales/models_en.yml +33 -0
  68. data/config/locales/models_sl.yml +44 -1
  69. data/drg_cms.gemspec +3 -3
  70. data/lib/drg_cms/version.rb +1 -1
  71. data/lib/drg_cms.rb +19 -5
  72. data/lib/generators/convert_to_ar/USAGE +8 -0
  73. data/lib/generators/convert_to_ar/convert_to_ar_generator.rb +158 -0
  74. data/lib/tasks/dc_cleanup.rake +20 -42
  75. metadata +25 -14
  76. data/History.log +0 -109
  77. data/app/assets/javascripts/drg_cms/jquery.bpopup.min.js +0 -7
  78. data/app/views/layouts/__cmsedit.html.erb +0 -16
@@ -55,30 +55,30 @@ after_save :cache_clear
55
55
  after_destroy :cache_clear
56
56
 
57
57
  ####################################################################
58
- # Clear cache if cache is configured
58
+ # Clear cache when cache is configured
59
59
  ####################################################################
60
60
  def cache_clear
61
61
  DrgCms.cache_clear(:dc_permission)
62
62
  DrgCms.cache_clear(:dc_site)
63
+ DrgCms.cache_clear(:dc_policy_role)
63
64
  end
64
65
 
65
66
  ########################################################################
66
67
  # Return all defined roles as choices for use in select field.
67
68
  ########################################################################
68
69
  def self.choices4_roles
69
- where(active: true).order_by(name: 1).inject([]) { |r,role| r << [ role.name, role._id] }
70
+ where(active: true).order_by(name: 1).inject([]) { |r, role| r << [ role.name, role._id] }
70
71
  end
71
72
 
72
73
  ########################################################################
73
74
  # Search for role when role parameter is String.
74
75
  ########################################################################
75
76
  def self.get_role(role)
76
- if role.class == String
77
- rol = role
78
- role = find_by(name: rol) || find_by(system_name: rol)
79
- end
80
- role
81
- end
77
+ doc = DrgCms.cache_read(['dc_policy_role', role])
78
+ return doc if doc
82
79
 
80
+ doc = find_by(name: role) || find_by(system_name: role)
81
+ DrgCms.cache_write(['dc_policy_role', role], doc)
82
+ end
83
83
 
84
84
  end
@@ -66,30 +66,28 @@ class DatePicker < DrgcmsField
66
66
  ###########################################################################
67
67
  def render
68
68
  value = @record.try(@yaml['name']) ? I18n.localize(@record[@yaml['name']].to_date) : nil
69
- #return ro_standard( @parent.dc_format_value(value)) if @readonly
70
-
71
- @yaml['options'] ||= {}
72
69
  set_initial_value
73
70
  @yaml['html']['size'] ||= @yaml['size'] || 10
74
71
  @yaml['html']['value'] ||= value
75
72
  @yaml['html']['autocomplete'] ||= 'off'
76
73
  @yaml['html']['class'] = @yaml['html']['class'].to_s + ' date-picker'
77
74
 
78
- @yaml['options']['lang'] ||= "'#{I18n.locale}'"
79
- @yaml['options']['format'] ||= "'#{t('datetimepicker.formats.date')}'"
80
- @yaml['options']['timepicker'] = false
81
- @yaml['options']['scrollMonth'] ||= false
82
- @yaml['options']['scrollInput'] ||= false
75
+ options = options_to_hash(@yaml['options'])
76
+ options['lang'] ||= I18n.locale.to_s
77
+ options['format'] ||= t('datetimepicker.formats.date')
78
+ options['timepicker'] = false
79
+ options['scrollMonth'] ||= false
80
+ options['scrollInput'] ||= false
83
81
 
84
82
  record = record_text_for(@yaml['name'])
85
83
  @html << @parent.text_field(record, @yaml['name'], @yaml['html'])
86
- @js << %Q[
84
+ @js << %(
87
85
  $(document).ready(function() {
88
- $("##{record}_#{@yaml['name']}").datetimepicker( {
89
- #{hash_to_options(@yaml['options'])}
86
+ $("##{record}_#{@yaml['name']}").datetimepicker({
87
+ #{hash_to_options(options)}
90
88
  });
91
89
  });
92
- ] unless @readonly
90
+ ) unless @readonly
93
91
 
94
92
  self
95
93
  end
@@ -30,12 +30,12 @@ module DrgcmsFormFields
30
30
  # * +name:+ Field name (required)
31
31
  # * +options:+ options which apply to date_picker field. All options can be found here http://xdsoft.net/jqplugins/datetimepicker/ .
32
32
  # Options can be defined in single line like:
33
- # * options: 'step: 15,inline: true,lang: "sl"' or
33
+ # * options: 'step: 15,inline: true,lang: sl' or
34
34
  #
35
35
  # * options:
36
36
  # * step: 15
37
37
  # * inline: true
38
- # * lang: '"sl"'
38
+ # * lang: sl
39
39
  #
40
40
  # * +html:+ html options which apply to date_time_picker field (optional)
41
41
  #
@@ -52,27 +52,26 @@ class DatetimePicker < DrgcmsField
52
52
  ###########################################################################
53
53
  def render
54
54
  value = @record.try(@yaml['name']) ? I18n.localize(@record[@yaml['name']].localtime) : nil
55
- #return ro_standard( @parent.dc_format_value(value)) if @readonly
56
-
57
- @yaml['options'] ||= {}
58
55
  set_initial_value
56
+
59
57
  @yaml['html']['size'] ||= @yaml['size'] || 14
60
58
  @yaml['html']['value'] ||= value if @record[@yaml['name']]
61
59
  @yaml['html']['autocomplete'] ||= 'off'
62
60
  @yaml['html']['class'] = @yaml['html']['class'].to_s + ' date-picker'
63
61
 
64
- @yaml['options']['lang'] ||= "'#{I18n.locale}'"
65
- @yaml['options']['format'] ||= "'#{t('datetimepicker.formats.datetime')}'"
62
+ options = options_to_hash(@yaml['options'])
63
+ options['lang'] ||= I18n.locale.to_s
64
+ options['format'] ||= t('datetimepicker.formats.datetime')
66
65
 
67
66
  record = record_text_for(@yaml['name'])
68
67
  @html << @parent.text_field(record, @yaml['name'], @yaml['html'])
69
- @js << %Q[
68
+ @js << %(
70
69
  $(document).ready(function() {
71
- $("##{record}_#{@yaml['name']}").datetimepicker( {
72
- #{hash_to_options(@yaml['options'])}
70
+ $("##{record}_#{@yaml['name']}").datetimepicker({
71
+ #{hash_to_options(options)}
73
72
  });
74
73
  });
75
- ] unless @readonly
74
+ ) unless @readonly
76
75
 
77
76
  self
78
77
  end
@@ -114,11 +114,11 @@ end
114
114
  # Returns:
115
115
  # String. Translated text.
116
116
  ####################################################################
117
- def t(key, default='')
117
+ def t(key, default = '')
118
118
  c = I18n.t(key)
119
- if c.match( 'translation missing' )
119
+ if c.match(/translation missing/i)
120
120
  c = I18n.t(key, locale: 'en')
121
- # Still not found. Return default if set
121
+ # Still not found. Return default if set
122
122
  c = default unless default.blank?
123
123
  end
124
124
  c
@@ -127,15 +127,8 @@ end
127
127
  ####################################################################
128
128
  # Standard code for returning readonly field.
129
129
  ####################################################################
130
- def ro_standard(value=nil)
131
- if value.nil?
132
- value = if @yaml['html']['value']
133
- @yaml['html']['value']
134
- else
135
- @record.respond_to?(@yaml['name']) ? @record.send(@yaml['name']) : nil
136
- end
137
- end
138
- #@html << (value.blank? ? '' : "<div class='dc-readonly'>#{value}</div>")
130
+ def ro_standard(value = nil)
131
+ value ||= @yaml['html']['value'] || (@record.respond_to?(@yaml['name']) ? @record.send(@yaml['name']) : nil)
139
132
  @html << %(<div id="#{@yaml['name']}" class="dc-readonly">#{value}</div>)
140
133
  self
141
134
  end
@@ -157,8 +150,9 @@ def set_initial_value(opt1 = 'html', opt2 = 'value')
157
150
  value_send_as = 'p_' + @yaml['name']
158
151
  if @parent.params[value_send_as]
159
152
  @yaml[opt1][opt2] = @parent.params[value_send_as]
160
- elsif @parent.flash[:record] and @parent.flash[:record][@yaml['name']]
161
- @yaml[opt1][opt2] = @parent.flash[:record][@yaml['name']]
153
+ elsif @parent.flash[:record]
154
+ value = @parent.flash[:record][@yaml['name']] || @parent.flash[:record][@yaml['name'].to_sym]
155
+ @yaml[opt1][opt2] = value if value
162
156
  end
163
157
  set_default_value(opt1, opt2) if @yaml['default']
164
158
  end
@@ -217,24 +211,13 @@ def set_style()
217
211
  end
218
212
  end
219
213
 
220
- ####################################################################
221
- # DEPRECATED!
222
- #
223
- # Returns css code for the field if specified. It replaces all occurences of '# '
224
- # with field name id, as defined on form.
225
- ####################################################################
226
- def __css_code
227
- return '' if @css.blank?
228
- @css.gsub!('# ',"#td_record_#{@yaml['name']} ")
229
- "\n<style type=\"text/css\">#{@css}</style>"
230
- end
231
-
232
214
  ####################################################################
233
215
  # Sets css code for the field if specified. It replaces all occurences of '# '
234
216
  # with field name id, as defined on form.
235
217
  ####################################################################
236
218
  def set_css_code(css)
237
219
  return '' if css.blank?
220
+
238
221
  css.gsub!('# ',"#td_record_#{@yaml['name']} ") if css.match('# ')
239
222
  css
240
223
  end
@@ -250,16 +233,58 @@ end
250
233
  # options:
251
234
  # height: 400
252
235
  # width: 800
253
- # toolbar: "'basic'"
236
+ # toolbar: "basic"
254
237
  #
255
- # => "height:400, width:800, toolbar:'basic'"
238
+ # => "height:400, width:800, toolbar: 'basic'"
256
239
  #
257
240
  # Return:
258
241
  # String: Options formated as javascript options.
259
242
  #
260
243
  ####################################################################
261
- def hash_to_options(hash)
262
- hash.to_a.inject([]) {|r,v| r << "#{v[0]}: #{v[1]}" }.join(',')
244
+ def hash_to_options(options)
245
+ c = ''
246
+ options.each do |key, option|
247
+ c << "#{key} : "
248
+ c << case
249
+ when option.to_s.match(/function/i) then option
250
+ when option.class == String then "\"#{option}\""
251
+ else option.to_s
252
+ end
253
+ c << ",\n"
254
+ end
255
+ c
256
+ end
257
+
258
+ ####################################################################
259
+ # Options may be defined on form as hash or as string. This method will
260
+ # ensure conversion of options into hash.
261
+ #
262
+ # Parameters:
263
+ # [String or Hash] : Form options
264
+ #
265
+ # Form example: As used in forms
266
+ # options:
267
+ # height: 400
268
+ # width: 800
269
+ # toolbar: "'basic'"
270
+ # or
271
+ #
272
+ # options: "height:400, width:800, toolbar:'basic'"
273
+ #
274
+ # Return:
275
+ # Hash: Options as Hash
276
+ ####################################################################
277
+ def options_to_hash(options)
278
+ return {} if options.nil?
279
+ return options unless options.class == String
280
+
281
+ options.chomp.split(',').inject({}) do |r, e|
282
+ key, value = e.chomp.split(':')
283
+ value.strip!
284
+ value = value[1..value.size - 2] if value[0] =~ /\'|\"/
285
+ r[key.strip] = value
286
+ r
287
+ end
263
288
  end
264
289
 
265
290
  ####################################################################
@@ -78,15 +78,18 @@ def render
78
78
  @html << "<iframe class='iframe_embedded' id='if_#{@yaml['name']}' name='if_#{@yaml['name']}' #{html}></iframe>"
79
79
  unless @record.new_record?
80
80
  url = @parent.url_for(opts)
81
- data = if @yaml['load'].nil? || @yaml['load'].match('default')
82
- "src"
83
- else
84
- "data-src-#{@yaml['load']}"
85
- end
86
- @js << %Q[
81
+ attributes = case
82
+ when @yaml['load'].nil? || @yaml['load'].match('default')
83
+ "'src', '#{url}'"
84
+ when @yaml['load'].match('delay')
85
+ "'data-src-#{@yaml['load']}', '#{url}'"
86
+ when @yaml['load'].match('always')
87
+ "{'data-src-#{@yaml['load']}': '#{url}', src: '#{url}'}"
88
+ end
89
+ @js << %(
87
90
  $(document).ready( function() {
88
- $('#if_#{@yaml['name']}').attr('#{data}', '#{url}');
89
- });]
91
+ $('#if_#{@yaml['name']}').attr(#{attributes});
92
+ });)
90
93
  end
91
94
  self
92
95
  end
@@ -49,8 +49,8 @@ def render
49
49
  old_value = v.class == Array ? v[0] : v
50
50
  new_value = v.class == Array ? v[1] : v
51
51
  @html << "<div style='background-color: #eee;'>#{@parent.check_box('select', k)} #{k}</div>
52
- <div style='background-color: #fcc;'>-<br>#{old_value}</div>
53
- <div style='background-color: #cfc;'>+<br>#{new_value}</div><br>"
52
+ <div style='background-color: #fcc;'>-<br>#{old_value.to_s.gsub("\n", '<br>')}</div>
53
+ <div style='background-color: #cfc;'>+<br>#{new_value.to_s.gsub("\n", '<br>')}</div><br>"
54
54
  end
55
55
  @html << '</div>'
56
56
  self
@@ -24,12 +24,12 @@ module DrgcmsFormFields
24
24
 
25
25
  ###########################################################################
26
26
  # Implementation of multitext_autocomplete DRG Form field.
27
- #
27
+ #
28
28
  # multitext_autocomplete field is complex data entry field which uses autocomplete
29
29
  # function when selecting multiple values for MongoDB Array field. Array typically holds
30
- # id's of selected documents and control typically displays value of the field name
30
+ # id's of selected documents and control typically displays value of the field name
31
31
  # defined by search options.
32
- #
32
+ #
33
33
  # ===Form options:
34
34
  # * +name:+ field name (required)
35
35
  # * +type:+ multitext_autocomplete (required)
@@ -40,12 +40,12 @@ module DrgcmsFormFields
40
40
  # * collection_name.search_field_name.method_name; When searching is more complex custom search
41
41
  # method may be defined in CollectionName model which will provide result set for search.
42
42
  # * +with_new+ Will add an icon for shortcut to add new document to collection
43
- #
43
+ #
44
44
  # Form example:
45
45
  # 90:
46
46
  # name: kats
47
47
  # type: multitext_autocomplete
48
- # search: dc_category.name
48
+ # search: dc_category.name
49
49
  # with_new: model_name
50
50
  # size: 30
51
51
  ###########################################################################
@@ -55,10 +55,11 @@ class MultitextAutocomplete < DrgcmsField
55
55
  # Returns value for readonly field
56
56
  ###########################################################################
57
57
  def ro_standard(table, search)
58
- result = ''
59
- table = table.classify.constantize
60
58
  return self if @record[@yaml['name']].nil?
61
- # when field name and method are defined together
59
+
60
+ result = ''
61
+ table = table.classify.constantize
62
+ # when field name and method are defined together
62
63
  search = search.split('.').first if search.match('.')
63
64
  @record[@yaml['name']].each do |element|
64
65
  result << table.find(element)[search] + '<br>'
@@ -69,8 +70,8 @@ end
69
70
  ###########################################################################
70
71
  # Render multitext_autocomplete field html code
71
72
  ###########################################################################
72
- def render
73
- # search field name
73
+ def render
74
+ # get field name
74
75
  if @yaml['search'].class == Hash
75
76
  table = @yaml['search']['table']
76
77
  field_name = @yaml['search']['field']
@@ -82,27 +83,28 @@ def render
82
83
  else # search and table name are separated
83
84
  search = field_name = @yaml['search']
84
85
  end
85
- # determine table name
86
+ # get table name
86
87
  if @yaml['table']
87
88
  table = if @yaml['table'].class == String
88
- @yaml['table']
89
- # eval(how_to_get_my_table_name)
90
- elsif @yaml['table']['eval']
91
- eval @yaml['table']['eval']
92
- else
93
- @parent.logger.error "Field #{@yaml['name']}: Invalid table parameter!"
94
- nil
95
- end
89
+ @yaml['table']
90
+ # eval(how_to_get_my_table_name)
91
+ elsif @yaml['table']['eval']
92
+ eval @yaml['table']['eval']
93
+ else
94
+ Rails.logger.error "Field #{@yaml['name']}: Invalid table parameter!"
95
+ nil
96
+ end
96
97
  end
97
- unless (table and search)
98
- @html << 'Table or search field not defined!'
98
+
99
+ if table.blank? || search.blank?
100
+ @html << 'Table or search field not defined!'
99
101
  return self
100
102
  end
101
- #
102
- # TODO check if table exists
103
+
104
+ # TODO check if table exists
103
105
  collection = table.classify.constantize
104
106
  unless @record.respond_to?(@yaml['name'])
105
- @html << "Invalid field name: #{@yaml['name']}"
107
+ @html << "Invalid field name: #{@yaml['name']}"
106
108
  return self
107
109
  end
108
110
  # put field to enter search data on form
@@ -117,44 +119,44 @@ def render
117
119
  # text field for autocomplete
118
120
  @html << '<span class="dc-text-autocomplete">' << @parent.text_field(record, _name, @yaml['html']) << '<span></span></span>'
119
121
  # direct link for adding new documents to collection
120
- if @yaml['with_new'] and !@readonly
121
- @html << ' ' +
122
+ if @yaml['with_new'] && !@readonly
123
+ @html << ' ' +
122
124
  @parent.fa_icon('plus-square-o', class: 'in-edit-add', title: t('drgcms.new'),
123
- style: "vertical-align: top;", 'data-table' => @yaml['with_new'] )
125
+ style: "vertical-align: top;", 'data-table' => @yaml['with_new'] )
124
126
  end
125
127
  # div to list active selections
126
128
  @html << "<div id =\"#{record}#{@yaml['name']}\">"
127
- # find value for each field inside categories
129
+ # find value for each field inside categories
128
130
  unless @record[@yaml['name']].nil?
129
131
  @record[@yaml['name']].each do |element|
130
- # this is quick and dirty trick. We have model dc_big_table which can be used for retrive
131
- # more complicated options
132
+ # this is quick and dirty trick. We have model dc_big_table which can be used for retrive
133
+ # more complicated options
132
134
  # TODO retrieve choices from big_table
133
135
  rec = if table == 'dc_big_table'
134
136
  collection.find(@yaml['name'], @parent.session)
135
137
  else
136
138
  collection.find(element)
137
139
  end
138
- # Related data is missing. It happends.
140
+ # Related data is missing. It happends.
139
141
  @html << if rec
140
142
  link = @parent.link_to(@parent.fa_icon('remove_circle', class: 'dc-red'), '#',
141
- onclick: "$('##{rec.id}').hide(); var v = $('##{record}_#{@yaml['name']}_#{rec.id}'); v.val(\"-\" + v.val());return false;")
143
+ onclick: %($('##{rec.id}').hide(); var v = $('##{record}_#{@yaml['name']}_#{rec.id}'); v.val("-" + v.val());return false;))
142
144
  link = @parent.fa_icon('check', class: 'dc-green') if @readonly
143
145
  field = @parent.hidden_field(record, "#{@yaml['name']}_#{rec.id}", value: element)
144
- "<div id=\"#{rec.id}\" style=\"padding:4px;\">#{link} #{rec.send(field_name)}<br>#{field}</div>"
146
+ %(<div id="#{rec.id}" style="padding:4px;">#{link} #{rec.send(field_name)}<br>#{field}</div>)
145
147
  else
146
148
  '** error **'
147
149
  end
148
150
  end
149
151
  end
150
152
  @html << "</div></div>"
151
- # Create text for div to be added when new category is selected
153
+ # Create text for div to be added when new category is selected
152
154
  link = @parent.link_to(@parent.fa_icon('remove_circle', class: 'dc-red'), '#',
153
155
  onclick: "$('#rec_id').hide(); var v = $('##{record}_#{@yaml['name']}_rec_id'); v.val(\"-\" + v.val());return false;")
154
156
  field = @parent.hidden_field(record, "#{@yaml['name']}_rec_id", value: 'rec_id')
155
157
  one_div = "<div id=\"rec_id\" style=\"padding:4px;\">#{link} rec_search<br>#{field}</div>"
156
-
157
- # JS stuff
158
+
159
+ # JS stuff
158
160
  @js << <<EOJS
159
161
  $(document).ready(function() {
160
162
  $("##{record}_#{_name}").autocomplete( {
@@ -173,10 +175,12 @@ $(document).ready(function() {
173
175
  },
174
176
  change: function (event, ui) {
175
177
  var div = '#{one_div}';
176
- div = div.replace(/rec_id/g, ui.item.id)
177
- div = div.replace('rec_search', ui.item.value)
178
- $("##{record}#{@yaml['name']}").append(div);
179
- $("##{record}_#{_name}").val('');
178
+ if (ui.item != null) {
179
+ div = div.replace(/rec_id/g, ui.item.id)
180
+ div = div.replace('rec_search', ui.item.value)
181
+ $("##{record}#{@yaml['name']}").append(div);
182
+ $("##{record}_#{_name}").val('');
183
+ }
180
184
  $("##{record}_#{_name}").focus();
181
185
  },
182
186
  minLength: 2
@@ -184,20 +188,20 @@ $(document).ready(function() {
184
188
  });
185
189
  EOJS
186
190
 
187
- self
191
+ self
188
192
  end
189
193
 
190
194
  ###########################################################################
191
- # Class method for retrieving data from multitext_autocomplete form field.
195
+ # Class method for retrieving data from multitext_autocomplete form field. Values are sabed
196
+ # in parameters as name_id => id
192
197
  ###########################################################################
193
198
  def self.get_data(params, name)
194
199
  r = []
195
- params['record'].each do |k,v|
196
- # if it starts with - then it was removed
197
- r << BSON::ObjectId.from_string(v) if k.match("#{name}_") and v[0,1] != '-'
200
+ params['record'].each do |k, v|
201
+ # if it starts with - then it was removed
202
+ r << BSON::ObjectId.from_string(v) if k.starts_with?("#{name}_") && v[0] != '-'
198
203
  end
199
- r.uniq!
200
- r
204
+ r.uniq
201
205
  end
202
206
 
203
207
  end
@@ -80,9 +80,9 @@ class Select < DrgcmsField
80
80
  def choices_in_helper(helper = nil)
81
81
  helper ||= "helpers.label.#{@form['table']}.choices4_#{@yaml['name']}"
82
82
  c = t(helper)
83
- if c.match( 'translation missing' )
83
+ if c.match(/translation missing/i)
84
84
  helper = "choices_for_#{@form['table']}_#{@yaml['name']}"
85
- return "Error. #{helper} not defined" if c.match( 'translation missing' )
85
+ return "Error. #{helper} not defined" if c.match(/translation missing/i)
86
86
  end
87
87
  c
88
88
  end
@@ -95,21 +95,27 @@ def choices_in_eval(e)
95
95
  e.strip!
96
96
  if @yaml['depend'].nil?
97
97
  method = e.split(/\ |\(/).first
98
- return eval(e) if respond_to?(method) # id method defined here
99
- return eval('@parent.' + e) if @parent.respond_to?(method) # is method defined in helpers
98
+ return eval(e) if respond_to?(method) # is method defined here
99
+ return eval('@parent.' + e) if @parent.respond_to?(method) # is method defined in helper methods
100
100
  # eval whatever it is there
101
101
  eval e
102
102
  else
103
- # add event listener to depend field
104
- @js << %(
105
- $(document).ready(function() {
106
- $('#record_#{@yaml['depend']}').change( function(e) { update_select_depend('record_#{@yaml['name']}', 'record_#{@yaml['depend']}','#{e}');});
107
- $('#_record_#{@yaml['depend']}').change( function(e) { update_select_depend('record_#{@yaml['name']}', '_record_#{@yaml['depend']}','#{e}');});
108
- });
103
+ # add event listener to depend field(s)
104
+ depend_value = ''
105
+ @js << "\n$(document).ready(function() {\n"
106
+ @yaml['depend'].split(',') do |depend|
107
+ depend.strip!
108
+ depend_value << ',' if depend_value.present?
109
+ # depend field might be virtual field. It's value should be set in params
110
+ depend_value << (depend[0] == '_' ? @parent.params["p_#{depend}"] : @record[depend]).to_s
111
+ next if depend == @yaml['name'] # self may be sent, but don't listen to change event
112
+
113
+ @js << %(
114
+ $('#record_#{depend}').change( function(e) { update_select_depend('record_#{@yaml['name']}', '#{@yaml['depend']}', '#{e}');});
115
+ $('#_record_#{depend}').change( function(e) { update_select_depend('record_#{@yaml['name']}', '#{@yaml['depend']}', '#{e}');});
109
116
  )
110
- # depend field might be virtual field. It's value should be set in params
111
- depend_value = @yaml['depend'][0] == '_' ? @parent.params["p_#{@yaml['depend']}"] : @record[@yaml['depend']]
112
-
117
+ end
118
+ @js << + "});\n"
113
119
  e << " '#{depend_value}'"
114
120
  eval e
115
121
  end
@@ -132,7 +138,7 @@ def get_choices
132
138
 
133
139
  choices.chomp.split(',').map { |e| e.match(':') ? e.split(':') : e }
134
140
  rescue Exception => e
135
- Rails.logger.debug "\nError in select eval. #{e.message}\n"
141
+ Rails.logger.error "\nError in select eval. #{e.message}\n"
136
142
  Rails.logger.debug(e.backtrace.join($/)) if Rails.env.development?
137
143
  ['error'] # return empty array when error occures
138
144
  end
@@ -65,9 +65,7 @@ class TextWithSelect < Select
65
65
  # Render text_with_select field html code
66
66
  ###########################################################################
67
67
  def render
68
- #return ro_standard if @readonly
69
- set_initial_value('html','value')
70
-
68
+ set_initial_value
71
69
  record = record_text_for(@yaml['name'])
72
70
  @html << @parent.text_field( record, @yaml['name'], @yaml['html'])
73
71
  @yaml['html']['class'] ||= ''
@@ -80,13 +78,11 @@ def render
80
78
  # javascript to update text field if new value is selected in select field
81
79
  @js =<<EOJS
82
80
  $(document).ready(function() {
83
- $('##{@yaml['name']}_').change( function() {
84
- if ($(this).val().toString().length > 0) {
85
- $('##{record}_#{@yaml['name']}').val( $(this).val() );
81
+ $('##{@yaml['name']}_').on("click", function() {
82
+ $('##{record}_#{@yaml['name']}').val( $(this).val().toString() );
86
83
  $('##{record}_#{@yaml['name']}').trigger("change");
87
- }
88
- $('##{record}_#{@yaml['name']}').focus();
89
- });
84
+ $('##{record}_#{@yaml['name']}').focus();
85
+ });
90
86
  });
91
87
  EOJS
92
88
  self