#-- # Copyright (c) 2012+ Damjan Rems # # Permission is hereby granted, free of charge, to any person obtaining # a copy of this software and associated documentation files (the # "Software"), to deal in the Software without restriction, including # without limitation the rights to use, copy, modify, merge, publish, # distribute, sublicense, and/or sell copies of the Software, and to # permit persons to whom the Software is furnished to do so, subject to # the following conditions: # # The above copyright notice and this permission notice shall be # included in all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #++ ########################################################################### # # CmseditHelper module defines helper methods used by cmsedit actions. Output is controlled by # data found in 3 major sections of DRG CMS form: index, result_set and form sections. # ########################################################################### module CmsIndexHelper ############################################################################ # Creates action div for cmsedit index action. ############################################################################ def dc_actions_for_index @js = @form['script'] || @form['js'] || '' @css = @form['css'] || '' return '' if @form['index'].nil? actions = @form['index']['actions'] return '' if actions.blank? std_actions = {2 => 'new', 3 => 'sort', 4 => 'filter' } std_actions.delete(2) if @form['readonly'] if actions.class == String actions = dc_define_standard_actions(actions, std_actions) elsif actions['standard'] actions.merge!(std_actions) actions['standard'] = nil end # start div with hidden spinner image html = %(
#{fa_icon('spinner lg spin')}
' html.html_safe end ############################################################################ # Creates filter div for cmsedit index/filter action. ############################################################################ def dc_div_filter choices = [] filter = (@form['index'] and @form['index']['filter']) ? @form['index']['filter'] + ',' : '' filter << 'id as text_field' # filter id is added by default filter.split(',').each do |f| f.strip! name = f.match(' as ') ? f.split(' ').first : f # like another field on the form if f.match(' like ') a = f.split(' ') name = a.first f = a.last end choices << [ t("helpers.label.#{@form['table']}.#{name}", name), f ] end choices4_operators = t('drgcms.choices4_filter_operators').chomp.split(',').inject([]) {|r,v| r << (v.match(':') ? v.split(':') : v )} # currently selected options if session[@form['table']] and session[@form['table']][:filter] field_name, operators_value, dummy = session[@form['table']][:filter].split("\t") else field_name, operators_value = nil, nil end #{ form_tag :table => @form['table'], filter: :on, filter_input: 1, action: :index, method: :post } url = url_for(table: @form['table'],form_name: params['form_name'], filter: :on, filter_input: 1, action: :index, controller: :cmsedit) html =<

#{t('drgcms.filter_set')}

#{ select(nil, 'filter_field1', options_for_select(choices, field_name), { include_blank: true }) } #{ select(nil, 'filter_oper', options_for_select(choices4_operators, operators_value)) }
EOT html.html_safe end ############################################################################ # Creates popup div for setting filter on result set header. ############################################################################ def dc_filter_popup html = %Q[" html.html_safe end ############################################################################ # Will return title based on @form['title'] ############################################################################ def dc_form_title return t("helpers.label.#{@form['table']}.tabletitle", @form['table']) if @form['title'].nil? return t(@form['title'], @form['title']) if @form['title'].class == String # Hash dc_process_eval(@form['title']['eval'], [@form['title']['caption'] || @form['title']['text'], params]) end ############################################################################ # Creates title div for index action. Title div also includes paging options # and help link ############################################################################ def dc_title_for_index(result = nil) dc_table_title(dc_form_title(), result) end ############################################################################ # Determines actions and width of actions column ############################################################################ def dc_actions_column actions = @form['result_set']['actions'] return [{}, 0] if actions.nil? || dc_dont?(actions) # standard actions actions = {'standard' => true} if actions.class == String && actions == 'standard' std_actions = { 2 => 'edit', 5 => 'delete' } if actions['standard'] actions.merge!(std_actions) actions.delete('standard') end width = @form['result_set']['actions_width'] || 18*actions.size [actions, width] end ############################################################################ # Calculates (blank) space required for actions when @record_footer is rendered ############################################################################ def dc_actions_column_for_footer return '' unless @form['result_set']['actions'] ignore, width = dc_actions_column %Q[
].html_safe end ############################################################################ # Creates actions that could be performed on single row of result set. ############################################################################ def dc_actions_for_result(document) actions = @form['result_set']['actions'] return '' if actions.nil? || @form['readonly'] actions, width = dc_actions_column() html = %Q[' html.html_safe end ############################################################################ # Creates header div for result set. ############################################################################ def dc_header_for_result html = '
' if @form['result_set']['actions'] and !@form['readonly'] ignore, width = dc_actions_column() if width > 0 && @form['result_set']['actions'][0].to_s == 'check' check_all = fa_icon('check-square-o', class: 'dc-check-all') end html << %Q[
#{check_all}
] end # preparation for sort icon sort_field, sort_direction = nil, nil if session[@form['table']] sort_field, sort_direction = session[@form['table']][:sort].to_s.split(' ') end if (columns = @form['result_set']['columns']) columns.sort.each do |k, v| session[:form_processing] = "result_set:columns: #{k}=#{v}" next if v['width'].to_s.match(/hidden|none/i) th = %Q[
#{dc_link_to(label, icon, sort: v['name'], table: params[:table], form_name: params[:form_name], action: :index, icon_pos: :last )}
" else th << ">#{label}
" end html << "
" + th end end (html << '').html_safe end ############################################################################ # Creates link for single or double click on result column ############################################################################ def dc_clicks_for_result(document) html = '' if @form['result_set']['dblclick'] yaml = @form['result_set']['dblclick'] opts = {} opts[:controller] = yaml['controller'] || 'cmsedit' opts[:action] = yaml['action'] opts[:table] = yaml['table'] opts[:form_name] = yaml['form_name'] opts[:method] = yaml['method'] || 'get' opts[:id] = document['id'] opts[:readonly] = yaml['readonly'] if yaml['readonly'] opts[:window_close] = yaml['window_close'] if yaml['window_close'] html << ' data-dblclick=' + url_for(opts) else html << (' data-dblclick=' + url_for(action: 'show', controller: 'cmsedit', id: document.id, ids: params[:ids], readonly: (params[:readonly] ? 2 : 1), table: params[:table], form_name: params[:form_name]) ) if @form['form'] end html end ############################################################################ # Formats value according to format supplied or data type. There is lots of things missing here. ############################################################################ def dc_format_value(value, format=nil) return '' if value.nil? klass = value.class.to_s return CmsCommonHelper.dc_format_date_time(value, format) if klass.match(/time|date/i) format = format.to_s.upcase if format[0] == 'N' return '' if value == 0 && format.match('Z') format.gsub!('Z', '') dec = format[1].blank? ? nil : format[1].to_i sep = format[2].blank? ? nil : format[2] del = format[3].blank? ? nil : format[3] cur = format[4].blank? ? nil : format[4] dc_format_number(value, dec, sep, del, cur) else value.to_s end end ############################################################################ # Creates tr code for each row of result set. ############################################################################ def dc_row_for_result(document) clas = "dc-#{cycle('odd','even')} " + dc_style_or_class(nil, @form['result_set']['tr_class'], nil, document) style = dc_style_or_class('style', @form['result_set']['tr_style'], nil, document) "
".html_safe end ############################################################################ # Creates column for each field of result set document. ############################################################################ def dc_columns_for_result(document) return '' unless @form['result_set']['columns'] html = '' @form['result_set']['columns'].sort.each do |k,v| session[:form_processing] = "result_set:columns: #{k}=#{v}" next if v['width'].to_s.match(/hidden|none/i) # convert shortcut to hash v = {'name' => v} if v.class == String begin # eval value = if v['eval'] dc_process_column_eval(v, document) # as field elsif document.respond_to?(v['name']) dc_format_value(document.send( v['name'] ), v['format']) # as hash (dc_memory) elsif document.class == Hash dc_format_value(document[ v['name'] ], v['format']) # error else "??? #{v['name']}" end rescue Exception => e dc_log_exception(e, 'dc_columns_for_result') value = '!!!Error' end html << '
' # set class clas = dc_style_or_class(nil, v['td_class'], value, document) # set width and align an additional style style = dc_style_or_class(nil, v['td_style'] || v['style'], value, document) flex_align = v['align'].to_s == 'right' ? 'flex-direction:row-reverse;' : '' width_align = %Q[width:#{v['width'] || '15%'};#{flex_align}] style = "style=\"#{width_align}#{style}\" " html << "
#{value}
" end html.html_safe end ############################################################################ # Split eval expression to array by parameters. # Ex. Will split dc_name4_value(one ,"two") => ['dc_name4_value', 'one', 'two'] ############################################################################ def dc_eval_to_array(expression) expression.split(/\ |\,|\(|\)/).delete_if {|e| e.blank? }.map {|e| e.gsub(/\'|\"/,'').strip } end private ############################################################################ # Process eval. Breaks eval option and calls with send method. # Parameters: # evaluate : String : Expression to be evaluated # parameters : Array : array of parameters which will be send to method ############################################################################ def dc_process_eval(evaluate, parameters) # evaluate by calling send method clas, method = evaluate.split('.') if method.nil? send(clas, *parameters) else klass = clas.camelize.constantize klass.send(method, *parameters) end end ############################################################################ # Process eval option for field value. # Used for processing single field column on result_set or form head. ############################################################################ def dc_process_column_eval(yaml, document) # dc_name_for_id if yaml['eval'].match(/dc_name4_id|dc_name_for_id/) parms = dc_eval_to_array(yaml['eval']) if parms.size == 3 dc_name_for_id(parms[1], parms[2], nil, document[ yaml['name'] ]) else dc_name_for_id(parms[1], parms[2], parms[3], document[ yaml['name'] ]) end # dc_name_for_value from locale definition elsif yaml['eval'].match(/dc_name4_value|dc_name_for_value/) parms = dc_eval_to_array(yaml['eval']) if parms.size == 1 dc_name_for_value( @form['table'], yaml['name'], document[ yaml['name'] ] ) else dc_name_for_value( parms[1], parms[2], document[ yaml['name'] ] ) end # defined in helpers. For example dc_icon_for_boolean elsif respond_to?(yaml['eval']) send(yaml['eval'], document[yaml['name']]) # defined in model elsif document.respond_to?(yaml['eval']) document.send(yaml['eval']) # special eval elsif yaml['eval'].match('eval ') # TO DO evaluate with specified parameters # eval with params else parms = {} if yaml['params'].class == String parms = dc_value_for_parameter(yaml['params'], document) elsif yaml['params'].class == Hash yaml['params'].each { |k, v| parms[k] = dc_value_for_parameter(v) } else parms = document[ yaml['name'] ] end dc_process_eval(yaml['eval'], parms) end end ############################################################################ # Defines style or class for row (tr) or column (td) ############################################################################ def dc_style_or_class(selector, yaml, value, record) return '' if yaml.nil? # alias record and value so both names can be used in eval field, document = value, record html = selector ? "#{selector}=\"" : '' begin html << if yaml.class == String yaml # direct evaluate expression elsif yaml['eval'] eval(yaml['eval']) elsif yaml['method'] dc_process_eval(yaml['method'], record) end rescue Exception => e dc_log_exception(e, 'dc_style_or_class') end html << '"' if selector html end ############################################################################ # Get standard actions when actions directive contains single line. # Subroutine of dc_actions_for_index # # Allows for actions: new, filter, standard syntax ############################################################################ def dc_define_standard_actions(actions_params, standard) actions = {} actions_params.split(',').each do |an_action| an_action.strip! if an_action == 'standard' actions.merge!(standard) else standard.each do |index, action| (actions[index] = action; break) if action == an_action end end end actions end end