drg_cms 0.6.1.9 → 0.7.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) 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 +69 -32
  6. data/app/assets/javascripts/drg_cms_application.js +0 -2
  7. data/app/assets/javascripts/drg_cms_cms.js +2 -3
  8. data/app/assets/stylesheets/drg_cms/drg_cms.css +89 -26
  9. data/app/assets/stylesheets/drg_cms/jstree.css +32 -27
  10. data/app/assets/stylesheets/drg_cms/select-multiple.css +4 -2
  11. data/app/controllers/cmsedit_controller.rb +9 -111
  12. data/app/controllers/dc_application_controller.rb +100 -23
  13. data/app/controllers/dc_common_controller.rb +10 -24
  14. data/app/controls/browse_models_control.rb +3 -1
  15. data/app/controls/cmsedit_control.rb +5 -1
  16. data/app/controls/dc_category_control.rb +61 -0
  17. data/app/controls/dc_report.rb +1 -1
  18. data/app/forms/all_options.yml +2 -0
  19. data/app/forms/cms_menu.yml +3 -2
  20. data/app/forms/dc_browse_models.yml +24 -2
  21. data/app/forms/dc_category.yml +17 -8
  22. data/app/forms/dc_category_as_tree.yml +31 -0
  23. data/app/forms/dc_steps_template.yml +51 -0
  24. data/app/forms/help/dc_category_as_tree.en +4 -0
  25. data/app/forms/help/dc_category_as_tree.sl +5 -0
  26. data/app/helpers/cms_common_helper.rb +66 -1
  27. data/app/helpers/cms_edit_helper.rb +230 -121
  28. data/app/helpers/cms_helper.rb +74 -17
  29. data/app/helpers/cms_index_helper.rb +40 -37
  30. data/app/helpers/dc_application_helper.rb +37 -76
  31. data/app/helpers/dc_category_helper.rb +129 -0
  32. data/app/models/dc_category.rb +50 -24
  33. data/app/models/dc_journal.rb +2 -2
  34. data/app/models/dc_json_ld.rb +18 -41
  35. data/app/models/drgcms_form_fields/date_picker.rb +10 -12
  36. data/app/models/drgcms_form_fields/datetime_picker.rb +10 -11
  37. data/app/models/drgcms_form_fields/drgcms_field.rb +46 -4
  38. data/app/models/drgcms_form_fields/readonly.rb +1 -1
  39. data/app/models/drgcms_form_fields/select.rb +2 -2
  40. data/app/models/drgcms_form_fields/text_autocomplete.rb +2 -2
  41. data/app/models/drgcms_form_fields/text_with_select.rb +1 -0
  42. data/app/models/drgcms_form_fields/tree_select.rb +20 -19
  43. data/app/renderers/dc_common_renderer.rb +20 -3
  44. data/app/views/cmsedit/_form.html.erb +19 -12
  45. data/app/views/cmsedit/edit.html.erb +10 -6
  46. data/app/views/cmsedit/index.html.erb +5 -3
  47. data/app/views/cmsedit/new.html.erb +9 -5
  48. data/app/views/dc_common/_help.html.erb +1 -0
  49. data/app/views/layouts/content.html.erb +1 -1
  50. data/config/locales/drgcms_en.yml +7 -0
  51. data/config/locales/drgcms_sl.yml +7 -0
  52. data/drg_cms.gemspec +3 -3
  53. data/lib/drg_cms/version.rb +1 -1
  54. data/lib/tasks/dc_cleanup.rake +20 -42
  55. metadata +18 -12
  56. data/History.log +0 -109
@@ -137,13 +137,13 @@ def dc_actions_for_form(position)
137
137
  actions.delete('standard')
138
138
  actions = actions.to_a.sort { |x, y| x[0] <=> y[0] }
139
139
  # Add spinner to the beginning
140
- html = %Q[<span class="dc-spinner">#{fa_icon('settings-o spin')}</span><ul class="dc-menu #{position}">]
140
+ html = %(<span class="dc-spinner">#{mi_icon('settings-o spin')}</span><ul class="dc-menu #{position}">)
141
141
 
142
142
  actions.each do |key, options|
143
143
  session[:form_processing] = "form:actions: #{key} #{options}"
144
144
  next if options.nil? # yes it happens
145
145
 
146
- parms = @parms.clone
146
+ parms = @form_params.clone
147
147
  if options.class == String
148
148
  next if @form['readonly'] and !options.match(/back|close/)
149
149
 
@@ -211,7 +211,7 @@ def dc_actions_for_form(position)
211
211
  dc_submit_tag(caption, icon, { data: parameters, title: options['title'] }) +
212
212
  '</li>'
213
213
  else
214
- %(<li><div class="dc-link-no">#{fa_icon(icon)} #{caption}</div></li>)
214
+ %(<li><div class="dc-link-no">#{mi_icon(icon)} #{caption}</div></li>)
215
215
  end
216
216
 
217
217
  # delete with some sugar added
@@ -279,127 +279,26 @@ def dc_check_and_default(value, default, values=nil) #:nodoc:
279
279
  end
280
280
 
281
281
  ############################################################################
282
- # Creates input fields for one tab. Subroutine of dc_fields_for_form.
283
- ############################################################################
284
- def dc_fields_for_tab(fields_on_tab) #:nodoc:
285
- html = '<div class="dc-form">'
286
- labels_pos = dc_check_and_default(@form['form']['labels_pos'], 'right', ['top', 'left', 'right'])
287
- hidden_fields, odd_even = '', nil
288
- group_option, group_count = 0, 0
289
- reset_cycle()
290
- # Select form fields and sort them by key
291
- form_fields = fields_on_tab.select {|field| field.class == Integer }
292
- form_fields.to_a.sort.each do |number, options|
293
- session[:form_processing] = "form:fields: #{number}=#{options}"
294
- # ignore if edit_only singe field is required
295
- next if params[:edit_only] and params[:edit_only] != options['name']
296
- # hidden_fields. Add them at the end
297
- if options['type'] == 'hidden_field'
298
- hidden_fields << DrgcmsFormFields::HiddenField.new(self, @record, options).render
299
- next
300
- end
301
- # label
302
- field_html,label,help = dc_field_label_help(options)
303
- # Line separator
304
- html << dc_top_bottom_line(:top, options)
305
- # Beginning of new row
306
- if group_count == 0
307
- html << '<div class="row-div">'
308
- odd_even = cycle('odd','even')
309
- group_count = options['group'] || 1
310
- group_option = options['group'] || 1
311
- end
312
-
313
- html << if labels_pos == 'top'
314
- %(
315
- <div class="dc-form-label-top dc-color-#{odd_even} dc-align-left" title="#{help}">
316
- <label for="record_#{options['name']}">#{label} </label>
317
- <div id="td_record_#{options['name']}">#{field_html}</div>
318
- </div> )
319
- else
320
- # no label
321
- if dc_dont?(options['caption'])
322
- label = ''
323
- label_width = 0
324
- data_width = 100
325
- elsif group_option > 1
326
- label_width = group_option != group_count ? 10 : 14
327
- data_width = 21
328
- else
329
- label_width = 14
330
- data_width = 85
331
- end
332
- help.gsub!('<br>',"\n") if help.present?
333
- %(
334
- <div class="dc-form-label dc-color-#{odd_even} dc-align-#{labels_pos} dc-width-#{label_width}" title="#{help}">
335
- <label for="record_#{options['name']}">#{label} </label>
336
- </div>
337
- <div id="td_record_#{options['name']}" class="dc-form-field dc-color-#{odd_even} dc-width-#{data_width}">#{field_html}</div>
338
- )
339
- end
340
- # check if group end
341
- if (group_count -= 1) == 0
342
- html << '</div>'
343
- # insert dummy div when only two fields in group
344
- html << '<div></div>' if group_option == 2
345
- end
346
-
347
- html << dc_top_bottom_line(:bottom, options)
348
- end
349
- html << '</div>' << hidden_fields
350
- end
351
-
352
- ############################################################################
353
- # Creates edit form from fields or tabs options
282
+ # Creates input fields defined in form options
354
283
  ############################################################################
355
284
  def dc_fields_for_form
356
- html, tabs, tab_data = '',[], ''
285
+ html = "<div id='data_fields' " + (@form['form']['height'] ? "style=\"height: #{@form['form']['height']}px;\">" : '>')
357
286
  @js ||= ''
358
287
  @css ||= ''
359
- # Only fields defined
288
+ # fields
360
289
  if (form_fields = @form['form']['fields'])
361
- html << "<div id='data_fields' " + (@form['form']['height'] ? "style=\"height: #{@form['form']['height']}px;\">" : '>')
362
- html << dc_fields_for_tab(form_fields) + '</div>'
363
- else
364
- # there are multiple tabs on form
365
- first = true # first tab
366
- @form['form']['tabs'].keys.sort.each do |tab_name|
367
- next if tab_name.match('actions')
368
- # Tricky when editing single field. If field is not present on the tab skip to next tab
369
- if params[:edit_only]
370
- is_on_tab = false
371
- @form['form']['tabs'][tab_name].each { |k, v| is_on_tab = true if params[:edit_only] == v['name'] }
372
- next unless is_on_tab
373
- end
374
- # first div is displayed, all others are hidden
375
- tab_data << "<div id=\"data_#{tab_name.delete("\s\n")}\""
376
- tab_data << ' class="div-hidden"' unless first
377
- tab_data << " style=\"height: #{@form['form']['height']}px;\"" if @form['form']['height']
378
- tab_data << ">#{dc_fields_for_tab(@form['form']['tabs'][tab_name])}</div>"
379
-
380
- tab_label, tab_title = dc_tab_label_help(tab_name)
381
- tabs << [tab_name, tab_label, tab_title]
382
- first = false
383
- end
384
- # make it all work together
385
- html << '<ul class="dc-form-ul" >'
386
- first = true # first tab must be selected
387
- tabs.each do |tab_name, tab_label, tab_title|
388
- html << %(<li id="li_#{tab_name}" data-div="#{tab_name.delete("\s\n")}" title="#{tab_title}" class="dc-form-li)
389
- html << ' dc-form-li-selected' if first
390
- html << "\">#{tab_label}</li>"
391
- first = false
392
- end
393
- html << '</ul>'
394
- html << tab_data
290
+ html << dc_input_form_create(form_fields) + '</div>'
291
+ # tabs
292
+ elsif @form['form']['tabs']
293
+ html = dc_tabs_form_create()
395
294
  end
396
295
  # add last_updated_at hidden field so controller can check if record was updated in db during editing
397
296
  html << hidden_field(nil, :last_updated_at, value: @record.updated_at.to_i) if @record.respond_to?(:updated_at)
398
297
  # add form time stamp to prevent double form submit
399
298
  html << hidden_field(nil, :form_time_stamp, value: Time.now.to_i)
400
299
  # add javascript code if defined by form
401
- @js << "\n#{@form['script']}"
402
- @css << "\n#{@form['css']}"
300
+ @js << "\n#{@form['script']} #{@form['js']}"
301
+ @css << "\n#{@form['css']}\n#{@form['form']['css']}"
403
302
  html.html_safe
404
303
  end
405
304
 
@@ -426,7 +325,7 @@ def dc_head_for_form
426
325
  label = if caption.blank?
427
326
  ''
428
327
  elsif options['name'] == caption
429
- t_name(options['name'], options['name'].capitalize.gsub('_',' ') )
328
+ t_label_for_field(options['name'], options['name'].capitalize.gsub('_',' ') )
430
329
  else
431
330
  t(caption, caption)
432
331
  end
@@ -444,13 +343,13 @@ def dc_head_for_form
444
343
  #
445
344
  klass = dc_style_or_class(nil, options['class'], field, @record)
446
345
  style = dc_style_or_class(nil, options['style'], field, @record)
447
- html << %Q[<div class="dc-column #{klass}" style="width:#{percent*span}%;#{style}">
346
+ html << %(<div class="dc-column #{klass}" style="width:#{percent*span}%;#{style}">
448
347
  #{label.blank? ? '' : "<span class=\"label\">#{label}</span>"}
449
348
  <span id="head-#{options['name']}" class="field">#{field}</span>
450
- </div>]
349
+ </div>)
451
350
  current += span
452
351
  if current == split
453
- html << %Q[</div>\n<div class="dc-row">]
352
+ html << %(</div>\n<div class="dc-row">)
454
353
  current = 0
455
354
  end
456
355
  end
@@ -488,18 +387,44 @@ def dc_document_statistics
488
387
  parms[:controller] = 'dc_common'
489
388
  parms[:action] = 'copy_clipboard'
490
389
  url = url_for(parms.permit!)
390
+ html << '<div>'
491
391
  html << fa_icon('content_copy-o md-18', class: 'dc-link-img dc-link-ajax',
492
392
  'data-url' => url, 'data-request' => 'get', title: t('drgcms.doc_copy_clipboard') )
493
393
 
494
- url = url_for(controller: 'cmsedit', action: :index, table: 'dc_journal', filter: 'on',
394
+ url = url_for(controller: :cmsedit, action: :run, table: 'dc_journal', control: 'cmsedit.filter_on',
495
395
  filter_oper: 'eq', filter_field: 'doc_id', filter_value: @record.id)
396
+
496
397
  html << fa_icon('history md-18', class: 'dc-link-img dc-window-open',
497
398
  'data-url' => url, title: t('helpers.label.dc_journal.tabletitle') )
498
- html << %(<span>ID: </span><span id="record-id" class="hover" onclick="dc_copy_to_clipboard('record-id');" title="Copy document ID to clipboard">#{@record.id}</span>)
399
+ html << %(<span>ID: </span>
400
+ <span id="record-id" class="hover" onclick="dc_copy_to_clipboard('record-id');" title="Copy document ID to clipboard">#{@record.id}
401
+ </span>)
402
+
403
+ (html << '</div></div>').html_safe
404
+ end
405
+
406
+ ############################################################################
407
+ # Updates form prior to processing form
408
+ ############################################################################
409
+ def dc_form_update
410
+ # update form for steps options
411
+ if @form.dig('form', 'steps')
412
+ dc_form_update_steps
413
+ end
414
+ end
415
+
416
+ ############################################################################
417
+ # If form is divided into two parts, this method gathers html to be painted
418
+ # on right side of the form pane.
419
+ ############################################################################
420
+ def dc_form_left
421
+ yaml = @form.dig('form', 'form_left')
422
+ return '' unless yaml
499
423
 
500
- #dc_copy_to_clipboard
424
+ html = ''
425
+ html << dc_process_eval(yaml['eval'], self) if yaml['eval']
501
426
 
502
- (html << '</div>').html_safe
427
+ html.html_safe
503
428
  end
504
429
 
505
430
  private
@@ -520,4 +445,188 @@ def dc_top_bottom_line(location, options)
520
445
  end
521
446
  end
522
447
 
448
+ ############################################################################
449
+ # Creates input fields for one tab. Subroutine of dc_fields_for_form.
450
+ ############################################################################
451
+ def dc_input_form_create(fields_on_tab) #:nodoc:
452
+ html = '<div class="dc-form">'
453
+ labels_pos = dc_check_and_default(@form['form']['labels_pos'], 'right', %w[top left right])
454
+ hidden_fields, odd_even = '', nil
455
+ group_option, group_count = 0, 0
456
+ reset_cycle()
457
+ # Select form fields and sort them by key
458
+ form_fields = fields_on_tab.select {|field| field.class == Integer }
459
+ form_fields.to_a.sort.each do |number, options|
460
+ session[:form_processing] = "form:fields: #{number}=#{options}"
461
+ # ignore if edit_only singe field is required
462
+ next if params[:edit_only] and params[:edit_only] != options['name']
463
+ next if options.nil?
464
+
465
+ # hidden_fields. Add them at the end
466
+ if options['type'] == 'hidden_field'
467
+ hidden_fields << DrgcmsFormFields::HiddenField.new(self, @record, options).render
468
+ next
469
+ end
470
+ # label
471
+ field_html,label,help = dc_field_label_help(options)
472
+ # Line separator
473
+ html << dc_top_bottom_line(:top, options)
474
+ # Beginning of new row
475
+ if group_count == 0
476
+ html << '<div class="row-div">'
477
+ odd_even = cycle('odd','even')
478
+ group_count = options['group'] || 1
479
+ group_option = options['group'] || 1
480
+ end
481
+
482
+ html << if labels_pos == 'top'
483
+ %(
484
+ <div class="dc-form-label-top dc-color-#{odd_even} dc-align-left" title="#{help}">
485
+ <label for="record_#{options['name']}">#{label} </label>
486
+ <div id="td_record_#{options['name']}">#{field_html}</div>
487
+ </div> )
488
+ else
489
+ # no label
490
+ if dc_dont?(options['caption'])
491
+ label = ''
492
+ label_width = 0
493
+ data_width = 100
494
+ elsif group_option > 1
495
+ label_width = group_option != group_count ? 10 : 14
496
+ data_width = 21
497
+ else
498
+ label_width = 14
499
+ data_width = 85
500
+ end
501
+ help.gsub!('<br>',"\n") if help.present?
502
+ %(
503
+ <div class="dc-form-label dc-color-#{odd_even} dc-align-#{labels_pos} dc-width-#{label_width}" title="#{help}">
504
+ <label for="record_#{options['name']}">#{label} </label>
505
+ </div>
506
+ <div id="td_record_#{options['name']}" class="dc-form-field dc-color-#{odd_even} dc-width-#{data_width}">#{field_html}</div>
507
+ )
508
+ end
509
+ # check if group end
510
+ if (group_count -= 1) == 0
511
+ html << '</div>'
512
+ # insert dummy div when only two fields in group
513
+ html << '<div></div>' if group_option == 2
514
+ end
515
+
516
+ html << dc_top_bottom_line(:bottom, options)
517
+ end
518
+ html << '</div>' << hidden_fields
519
+ end
520
+
521
+ ############################################################################
522
+ # Will create html code required for input form with steps defined
523
+ ############################################################################
524
+ def dc_steps_one_element(element, tab_name = nil)
525
+ def add_one_step(key, tab_name, key_number)
526
+ fields = tab_name ? @form['form']['tabs'][tab_name] : @form['form']['fields']
527
+ { key_number => fields[key] }
528
+ end
529
+
530
+ key_number, fields = 0, {}
531
+ element.to_s.split(',').each do |particle|
532
+ if particle.match('-')
533
+ tabs_fields = tab_name ? @form['form']['tabs'][tab_name] : @form['form']['fields']
534
+ next if tabs_fields.nil?
535
+
536
+ start, to_end = particle.split('-').map(&:to_i)
537
+ tabs_fields.each { |key, data| fields.merge!(add_one_step(key, tab_name, key_number += 10)) if (start..to_end).include?(key) }
538
+ else
539
+ fields.merge!(add_one_step(particle.to_i, tab_name, key_number += 10))
540
+ end
541
+ end
542
+ fields
543
+ end
544
+
545
+ ############################################################################
546
+ # Will create html code required for input form with steps defined and update
547
+ # actions.
548
+ ############################################################################
549
+ def dc_form_update_steps
550
+ def add_step_to_form(index, step, next_step)
551
+ @form['form']['actions'][index]['params']['step'] = step
552
+ @form['form']['actions'][index]['params']['next_step'] = next_step
553
+ end
554
+
555
+ form = {}
556
+ step = params[:step].to_i
557
+ step_data = @form['form']['steps'].to_a[step - 1]
558
+
559
+ step_data.last.each do |element|
560
+ if element.first == 'fields'
561
+ form.merge!(dc_steps_one_element(element.second))
562
+ elsif element.first == 'tabs'
563
+ element.last.each do |tab_name, data|
564
+ form.merge!(dc_steps_one_element(data, tab_name))
565
+ end
566
+ end
567
+ end
568
+ # fraction updates of newly created form
569
+ form.deep_merge!(step_data.last['update']) if step_data.last['update']
570
+ # update steps data on form
571
+ add_step_to_form(10, step, step - 1)
572
+ add_step_to_form(20, step, step + 1)
573
+ add_step_to_form(100, step, step + 1)
574
+ # remove not needed steps
575
+ if step < 2
576
+ @form['form']['actions'].delete(10)
577
+ elsif step == @form['form']['steps'].size
578
+ @form['form']['actions'].delete(20)
579
+ end
580
+ @form['form']['actions'].delete(100) unless step == @form['form']['steps'].size
581
+ # update form_name and control name if defined
582
+ %w[1 10 20 100].each do |i|
583
+ next unless @form['form']['actions'][i.to_i]
584
+
585
+ @form['form']['actions'][i.to_i]['form_name'] = CmsHelper.form_param(params)
586
+ control = @form['control'] ? @form['control'] : @form['table']
587
+ @form['form']['actions'][i.to_i]['control'].sub!('x.', "#{control}.")
588
+ end
589
+
590
+ @form['form']['form_left'] ||= { 'eval' => 'dc_steps_menu_get'}
591
+ @form['form']['fields'] = form
592
+ end
593
+
594
+ ############################################################################
595
+ # Will create html code required for input form with tabs
596
+ ############################################################################
597
+ def dc_tabs_form_create
598
+ html, tabs, tab_data = '', [], ''
599
+ # there are multiple tabs on form
600
+ first = true # first tab
601
+ @form['form']['tabs'].keys.sort.each do |tab_name|
602
+ next if tab_name.match('actions')
603
+ # Tricky when editing single field. If field is not present on the tab skip to next tab
604
+ if params[:edit_only]
605
+ is_on_tab = false
606
+ @form['form']['tabs'][tab_name].each { |k, v| is_on_tab = true if params[:edit_only] == v['name'] }
607
+ next unless is_on_tab
608
+ end
609
+ # first div is displayed, all others are hidden
610
+ tab_data << "<div id=\"data_#{tab_name.delete("\s\n")}\""
611
+ tab_data << ' class="div-hidden"' unless first
612
+ tab_data << " style=\"height: #{@form['form']['height']}px;\"" if @form['form']['height']
613
+ tab_data << ">#{dc_input_form_create(@form['form']['tabs'][tab_name])}</div>"
614
+
615
+ tab_label, tab_title = dc_tab_label_help(tab_name)
616
+ tabs << [tab_name, tab_label, tab_title]
617
+ first = false
618
+ end
619
+ # make it all work together
620
+ html << '<ul class="dc-form-ul" >'
621
+ first = true # first tab must be selected
622
+ tabs.each do |tab_name, tab_label, tab_title|
623
+ html << %(<li id="li_#{tab_name}" data-div="#{tab_name.delete("\s\n")}" title="#{tab_title}" class="dc-form-li)
624
+ html << ' dc-form-li-selected' if first
625
+ html << "\">#{tab_label}</li>"
626
+ first = false
627
+ end
628
+ html << '</ul>'
629
+ html << tab_data
630
+ end
631
+
523
632
  end
@@ -35,8 +35,16 @@ module CmsHelper
35
35
  ############################################################################
36
36
  def dc_script_action(yaml)
37
37
  icon = dc_icon_for_link yaml['icon']
38
- data = %(data-request="script" data-script="#{yaml['js'] || yaml['script']}" data-url="script")
39
- %(<li><div class="dc-link-ajax" #{data}>#{icon} #{ t(yaml['caption'],yaml['caption']) }</div></li>)
38
+ yaml['html'] ||= {}
39
+ yaml['html']['data-url'] = 'script'
40
+ yaml['html']['data-request'] = 'script'
41
+ yaml['html']['data-script'] = "#{yaml['js'] || yaml['script']}"
42
+ yaml['html']['class'] ||= 'dc-link-ajax'
43
+ attributes = yaml['html'].inject('') { |r, e| r << "#{e.first}=\"#{e.last}\"" }
44
+
45
+ # data = %(data-request="script" data-script="#{yaml['js'] || yaml['script']}" data-url="script")
46
+ #%(<li><div class="dc-link-ajax" #{data}>#{icon} #{ t(yaml['caption'], yaml['caption']) }</div></li>)
47
+ %(<li><div #{attributes}>#{icon} #{ t(yaml['caption'], yaml['caption']) }</div></li>)
40
48
  end
41
49
 
42
50
  ############################################################################
@@ -105,11 +113,13 @@ def dc_label_help(options)
105
113
  return [nil, nil] if %w(comment action).include?(options['type'])
106
114
 
107
115
  label = options['caption'] || options['text'] || options['label']
108
- label = if label.blank?
109
- t_name(options['name'], options['name'].capitalize.gsub('_',' ') )
110
- elsif options['name']
111
- t(label, label)
112
- end
116
+ if options['name']
117
+ label = if label.blank?
118
+ t_label_for_field(options['name'], options['name'].capitalize.gsub('_',' ') )
119
+ elsif options['name']
120
+ t(label, label)
121
+ end
122
+ end
113
123
  # help text can be defined in form or in translations starting with helpers. or as helpers.help.collection.field
114
124
  help = options['help']
115
125
  help ||= "helpers.help.#{@form['table']}.#{options['name']}" if options['name']
@@ -128,11 +138,11 @@ end
128
138
  # help : String : Help text
129
139
  ############################################################################
130
140
  def dc_tab_label_help(tab_name)
131
- label = @form['form']['tabs'][tab_name]['caption'] || tab_name
132
- label = t(label, t_name(label, label))
141
+ label = @form.dig('form', 'tabs', tab_name, 'caption') || tab_name
142
+ label = t(label, t_label_for_field(label, label))
133
143
 
134
- help = @form['form']['tabs'][tab_name]['help'] || "helpers.help.#{@form['table']}.#{tab_name}"
135
- help = t(help, t_name(help, help))
144
+ help = @form.dig('form', 'tabs', tab_name, 'help') || "helpers.help.#{@form['table']}.#{tab_name}"
145
+ help = t(help, t_label_for_field(help, help))
136
146
  help = nil if help.match('helpers.') # help not found in translation
137
147
 
138
148
  [label, help]
@@ -197,12 +207,14 @@ def dc_link_ajax_window_submit_action(yaml, record = nil, action_active = true)
197
207
  unless dc_is_action_active?(yaml)
198
208
  return %(<li><div class="dc-link-no">#{icon} #{caption}</div></li>)
199
209
  end
200
- # set data-confirm when confirm
210
+ # set data-confirm when confirm shortcut present
201
211
  yaml['html'] ||= {}
202
- confirm = yaml['html']['data-confirm'] || yaml['confirm']
203
- yaml['html']['data-confirm'] = t(confirm) if confirm.present?
204
- yaml['html']['title'] ||= yaml['title']
205
- yaml['html']['title'] = t(yaml['title']) if yaml['title'].present?
212
+ text = yaml['html']['data-confirm'] || yaml['confirm']
213
+ yaml['html']['data-confirm'] = t(text) if text.present?
214
+
215
+ text = yaml['html']['title'] || yaml['title']
216
+ yaml['html']['title'] = t(text) if text.present?
217
+
206
218
  yaml['html']['target'] ||= yaml['target']
207
219
  # direct url
208
220
  if yaml['url']
@@ -282,11 +294,18 @@ end
282
294
  ############################################################################
283
295
  def dc_log_exception(exception, where = '')
284
296
  log = exception ? "\n*** Error:#{where + ':'} #{exception.message}\n#{exception.backtrace.first.inspect}\n" : ''
285
- log << "DRG Form processing line: #{session[:form_processing]}\n"
297
+ log << "DRG Form: #{CmsHelper.form_param(params)}, line: #{session[:form_processing]}\n"
286
298
 
287
299
  logger.error log
288
300
  end
289
301
 
302
+ ############################################################################
303
+ # Will return form id, to be used on each form for simpler css selecting.
304
+ ############################################################################
305
+ def dc_form_id
306
+ %( id=#{CmsHelper.form_param(params) || CmsHelper.table_param(params)} )
307
+ end
308
+
290
309
  ############################################################################
291
310
  # Will return form_name from parameter regardless if set as form_name or just f.
292
311
  ############################################################################
@@ -301,4 +320,42 @@ def self.table_param(params)
301
320
  params[:table] || params[:t]
302
321
  end
303
322
 
323
+ ########################################################################
324
+ # Searches forms path for file_name and returns full file name or nil if not found.
325
+ #
326
+ # @param [String] Form file name. File name can be passed as gem_name.filename. This can
327
+ # be useful when you are extending form but want to retain same name as original form
328
+ # For example. You are extending dc_user form from drg_cms gem and want to
329
+ # retain same dc_user name. This can be done by setting drg_cms.dc_user as extend option.
330
+ #
331
+ # @return [String] Form file name including path or nil if not found.
332
+ ########################################################################
333
+ def self.form_file_find(form_file)
334
+ form_path = nil
335
+ form_path, form_file = form_file.split(/\.|\//) if form_file.match(/\.|\//)
336
+
337
+ DrgCms.paths(:forms).reverse.each do |path|
338
+ f = "#{path}/#{form_file}.yml"
339
+ return f if File.exist?(f) && (form_path.nil? || path.to_s.match(/\/#{form_path}(-|\/)/i))
340
+ end
341
+ raise "Exception: Form file '#{form_file}' not found!"
342
+ end
343
+
344
+ ########################################################################
345
+ # Merges two forms when current form extends other form. Subroutine of dc_form_read.
346
+ # With a little help of https://www.ruby-forum.com/topic/142809
347
+ ########################################################################
348
+ def self.forms_merge(hash1, hash2)
349
+ target = hash1.dup
350
+ hash2.keys.each do |key|
351
+ if hash2[key].is_a?(Hash) && hash1[key].is_a?(Hash)
352
+ target[key] = CmsHelper.forms_merge(hash1[key], hash2[key])
353
+ next
354
+ end
355
+ target[key] = hash2[key] == '/' ? nil : hash2[key]
356
+ end
357
+ # delete keys with nil value
358
+ target.delete_if { |k, v| v.nil? }
359
+ end
360
+
304
361
  end