module Datatable module Helper def datatable "#{datatable_html} #{datatable_javascript}".html_safe end def datatable_html if Datatable::Base.config.jquery_ui datatable_base_html else datatable_html_with_wrapper end end def datatable_javascript raise "No @datatable assign" unless @datatable # TODO: this will escape ampersands # ERB::Util.h('http://www.foo.com/ab/asdflkj?asdf=asdf&asdf=alsdf') => "http://www.foo.com/ab/asdflkj?asdf=asdf&asdf=alsdf" "".html_safe end def javascript_include_datatable "".tap do |javascripts| if Datatable::Base.config.jquery_ui javascripts << (javascript_include_tag '/datatable/js/jquery-ui-1.8.14.custom.min.js') end javascripts << (javascript_include_tag '/datatable/js/jquery.dataTables.min.js') if Datatable::Base.config.table_tools == true javascripts << (javascript_include_tag '/datatable/js/TableTools.min.js') end end.html_safe end private def javascript_options defaults = { 'oLanguage' => { 'sInfoFiltered' => '', 'sProcessing' => Datatable::Base.config.spinner || 'Loading' }, 'sAjaxSource' => h(request.path), 'sDom' => '<"H"lfr>t<"F"ip>', 'iDisplayLength' => 25, 'bProcessing' => true, 'bServerSide' => true, 'sPaginationType' => "full_numbers", 'aoColumns' => "aocolumns_place_holder" } if Datatable::Base.config.table_tools == true defaults['oTableTools'] = { 'sSwfPath' => 'flash/copy_cvs_xls_pdf.swf' } end defaults['bJQueryUI'] = Datatable::Base.config.jquery_ui ? true : false # Could use !! but less clear defaults.merge(@datatable.javascript_options) end def datatable_html_with_wrapper <<-CONTENT.gsub(/^\s{6}/,"").html_safe
#{datatable_base_html}
CONTENT end def datatable_base_html <<-CONTENT.gsub(/^\s{6}/,"").html_safe #{headings} #{individual_column_searching if @datatable.javascript_options['individual_column_searching']}
CONTENT end def headings @datatable.columns.map do |key, value| "#{value[:heading] || humanize_column(key)}" end.join end def humanize_column(name) columns = name.split('.') [columns[0].singularize, columns[1]].compact.map(&:humanize).map(&:titleize).join(" ") end # returns a ruby hash of def ruby_aocolumns result = [] column_def_keys = %w[ asSorting bSearchable bSortable bUseRendered bVisible fnRender iDataSort mDataProp sClass sDefaultContent sName sSortDataType sTitle sType sWidth link_to ] index = 0 @datatable.columns.each_value do |column_hash| column_result = {} column_hash.each do |key,value| if column_def_keys.include?(key.to_s) column_result[key.to_s] = value end end # rewrite any link_to values as fnRender functions if column_result.include?('link_to') column_result['fnRender'] = %Q|function(oObj) { return replace('#{column_result['link_to']}', oObj.aData);}| column_result.delete('link_to') end if column_result.empty? result << nil else result << column_result end end result end def aocolumns_text outer = [] ruby_aocolumns.each do |column| if column inner = [] column.each do |key, value| inner << case key when 'fnRender' "\"#{key.to_s}\": #{value.to_json[1..-2]}" else "\"#{key.to_s}\": #{value.to_json}" end end outer << "{" + inner.join(", ") + "}" else outer << "null" end end '[' + outer.join(', ') + ']' end def individual_column_searching # TODO: placeholders only supported in HTML5 @datatable.columns.map do |key, value| if @datatable.columns[key][:bSearchable] == false %Q{ } else %Q{ } end end.join end end end