# frozen_string_literal: true module DatatablesHelper # Generate a html table tag for supporting ajax datatables # # == Parameters: # # options:: # Options which will be simply passed to content_tag method # # block:: # Content for thead, which is required for ajax datatable # # == Usage: # # <%= dt id: 'entities-list', class: 'display', :'data-url' => info_articles_path(:format => :json), # :'data-sorting_column' => (if current_sys.selfdrive? then 4 else 5 end), :'data-sorting_dir' => 'desc' do %> # <%= dt_col(data: { m_data_prop: 'id', s_type: 'numeric', s_width: '50px' }){ InfoArticle.human_attribute_name :id } %> # ... # <%= dt_col(data: { m_data_prop: 'actions', s_width: '70px', b_sortable: 'false' }) { t 'actions' } %> # <% end %> # def datatable_tag(options) # User autoWidth to calculate width, and use scrollX to allow scroll table, it will cause some black on the right of table, so need to set 100% width # Pass in options params to add additional configs content_tag :table, { width: '100%' }.merge(options) do html = content_tag(:thead) { yield } || '' html << content_tag(:tbody) raw html end end alias dt datatable_tag # Similiar to @datatable_tag method but this will pass section as the block parameter, # means in the block, we have to render sections accordingly. # We support :thead, :tbody and :tfoot right now def datatable_tag_section(options) content_tag :table, options do html = content_tag(:thead) { yield(:thead) } || '' html << content_tag(:tbody) { yield(:tbody) } html << content_tag(:tfoot) do content_tag(:tr) { yield(:tfoot) } end raw html end end alias dts datatable_tag_section # Generate th html tag for building up ajax datatable html tag # # == Parameters: # # options:: # Options which will be passed to content_tag method. To be awared, an node named "data" will be treated as # an hash, and it will be used to build HTML options with pattern like "data-*" # # == Usage: # To render a datatable column with data property id: # dt_col(data: { m_data_prop: 'id', s_type: 'numeric', s_width: '50px' }){ InfoArticle.human_attribute_name :id } # This will render: # 编号 # # To render a datatable column with data property actions, with sorting feature disabled: # dt_col(data: { m_data_prop: 'actions', s_width: '70px', b_sortable: 'false' }) { t 'actions' } # This will render: # 操作 # def datatable_col_tag(name = nil, options = {}) options = name if block_given? data_options = options.delete :data # Build up data options data = {} data_options.each { |k, v| data["data-#{k}"] = v } if data if block_given? content_tag(:th, options.merge(data)) { yield } else content_tag(:th, name, options.merge(data)) end end alias dt_col datatable_col_tag # Shortcut method for datatable_col_tag for those columns with needs for only data attributes # # == Parameters: # col_title:: # Column title # data_options:: # Hash represent data attributes # # == Usage: # <%= d_col InfoArticle.human_attribute_name(:info_column_id ), m_data_prop: 'info_column_name', s_width: '60px' %> def datatable_col_tag_dataonly(col_title, data_options) datatable_col_tag(data: data_options) { col_title } end alias d_col datatable_col_tag_dataonly # A short function to wrap actions group for table rows with edit, delete buttons and others. # # == Parameters: # edit_target:: # Link target for editing # del_target:: # Link target for deleting # other_target:: # Link targets for other actions # opts:: # Options to be passed to the buttons, :edit for edit button and :del for delete button as well as others # # == Usage: # edit_and_del(edit_route_path(row), route_path(row), [], {edit: {data:{id: 1}, class: ''}, del: {data:{id: 1}, class: ''}}) # def render_edit_and_del_actions(edit_target, del_target, other_actions = [], opts = {}) actions = [{ target: edit_target, link_text: '编辑', options: opts.delete(:edit) }, { target: del_target, link_text: '删除', options: { method: :delete }.merge(opts.delete(:delete)) }] if other_actions.any? other_actions.each do |action| key = action.keys.first actions << { target: action[key][:target], link_text: action[key][:link_text], options: { method: action[key][:method] }.merge(opts.delete(key)) } end end row_actions actions end alias edit_and_del render_edit_and_del_actions # Generate HTML codes for array of buttons for each row in a html grid. # # == Parameters: # buttons:: # An array contains buttons information to be included in HTML table row, which normally will be the last col. # Ruby link_to function will be used for each button in the array, each button of the array will be an hash, # it should contained following information: # :target: Link target # :link_text: Text to include between begin and end tag of an A ancor # :button_style: Button style class, if this has been indicated, this function won't apply it's default class # :options: Extra options to be assigned to the link_to function, except the :class key, it will be combinted # with some default css classes # == Returns: # HTML codes to be inserted into html table row cell, to present actions in each table row. # # == Usage: # row_actions [ # { target: edit_route_path(row), link_text: icon(:edit), options: data {data: id} }, # { # target: route_path(row, :format => :json), link_text: icon(:'trash-o'), button_style: :'btn-danger', # options: { :remote => true, :method => :delete, :data => { :confirm => tv('delete_row_confirm') } } # } # ] # def render_table_row_actions(buttons) actions = "
".dup buttons.each do |b| b[:options] ||= {} actions << link_to(raw(b[:link_text]), b[:target], b[:options]) end actions << '
' end alias row_actions render_table_row_actions def render_multi_values(items) actions = ''.dup items.each do |item| actions << "#{item || '/'}
" end actions.chomp('
') << '
' end alias multi_values render_multi_values # Helper to be used in jbuilder for rendering datatable json response # # == Usages: # datatable_json_response do # json.foo 'bar' # end # # @return Datatable json response def datatable_json_response(json, &block) json.draw params['draw'] || 0 json.recordsTotal @total_rows if @total_rows json.recordsFiltered @total_rows_filtered || @total_rows if @total_rows || @total_rows if defined?(@error) json.error @error else json.data(&block) end end def sort_opt(model, column) { model: model, column: column }.to_json end end