effective_datatables 2.0.1 → 2.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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee.erb +19 -5
- data/app/controllers/effective/datatables_controller.rb +1 -1
- data/app/helpers/effective_datatables_helper.rb +7 -2
- data/app/models/effective/active_record_datatable_tool.rb +16 -0
- data/app/models/effective/effective_datatable/ajax.rb +5 -6
- data/app/models/effective/effective_datatable/options.rb +40 -13
- data/app/models/effective/effective_datatable/rendering.rb +10 -16
- data/lib/effective_datatables/version.rb +1 -1
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: eb195f3890afb3faee956495d534e0a1bb09013e
         | 
| 4 | 
            +
              data.tar.gz: 8acf1b7ec6a347a3157718504f6830a001d0360c
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: d8cb8fc4dbb8f209bd2a5259e5c0f1594a5c1bb0a8dc763cbd0ae55b63b8194bb5ca96649fd0fbf5b4b97b6bec8cbc06fa8da7144e04d67aeb1c49fce52accfa
         | 
| 7 | 
            +
              data.tar.gz: 4d9addc52f7eac6742137e29a967aa465a69bd2c4baadcbebbb248b6dcedf6eab3457819e8002447aaf729a59d1a631232ea646ec484bd4fbabd63ae9acd63e3
         | 
| @@ -20,18 +20,30 @@ initializeDataTables = -> | |
| 20 20 | 
             
                      { sortable: false, targets: datatable.data('non-sortable') }
         | 
| 21 21 | 
             
                    ].concat(datatable.data('column-classes') || []).concat(datatable.data('column-names') || [])
         | 
| 22 22 | 
             
                    order: datatable.data('default-order')
         | 
| 23 | 
            +
                    serverParams: (params) ->
         | 
| 24 | 
            +
                      table = this.DataTable()
         | 
| 25 | 
            +
                      table.columns().flatten().each (index) =>  # Pass which columns are visible back to server
         | 
| 26 | 
            +
                        params['columns'][index]['visible'] =  table.column(index).visible()
         | 
| 23 27 | 
             
                    colVis:
         | 
| 24 28 | 
             
                      showAll: 'Show all'
         | 
| 25 29 | 
             
                      restore: 'Show default'
         | 
| 26 30 | 
             
                      activate: 'click'
         | 
| 27 31 | 
             
                      align: 'right'
         | 
| 28 32 | 
             
                      label: (index, title, th) -> $(th).prop('title')
         | 
| 33 | 
            +
                      stateChange: (iCol, bVisible) ->
         | 
| 34 | 
            +
                        timeout = $(this.dom.button).data('timeout')
         | 
| 35 | 
            +
                        clearTimeout(timeout) if timeout
         | 
| 36 | 
            +
                        timeout = setTimeout(
         | 
| 37 | 
            +
                          =>
         | 
| 38 | 
            +
                            $(this.dom.button).closest('.dataTables_wrapper').find('table').first().DataTable().draw()
         | 
| 39 | 
            +
                            $.event.trigger('page:change')
         | 
| 40 | 
            +
                        , 1000)
         | 
| 41 | 
            +
                        $(this.dom.button).data('timeout', timeout)
         | 
| 29 42 | 
             
                    tableTools:
         | 
| 30 43 | 
             
                      sSwfPath: "<%= asset_path('effective_datatables/copy_csv_xls_pdf.swf') %>",
         | 
| 31 44 | 
             
                      aButtons: ['csv', {'sExtends': 'xls', 'sButtonText': 'Excel'}, 'print']
         | 
| 32 45 |  | 
| 33 | 
            -
                   | 
| 34 | 
            -
                  if simple
         | 
| 46 | 
            +
                  if datatable.data('effective-datatables-table') == 'simple'
         | 
| 35 47 | 
             
                    init_options['lengthMenu'] = [-1] # Show all results
         | 
| 36 48 | 
             
                    init_options['dom'] = "<'row'r>t" # Just show the table
         | 
| 37 49 |  | 
| @@ -46,12 +58,14 @@ initializeDataTables = -> | |
| 46 58 | 
             
                    table.DataTable().column("#{obj.data('column-name')}:name").search(obj.val()).draw()
         | 
| 47 59 |  | 
| 48 60 | 
             
                  # For every existing Input, Set up the search events
         | 
| 49 | 
            -
                   | 
| 61 | 
            +
                  search_inputs = datatable.find('thead').first().find('input,select')
         | 
| 62 | 
            +
             | 
| 63 | 
            +
                  search_inputs.each (index, input) ->
         | 
| 50 64 | 
             
                    $input = $(input)
         | 
| 51 65 |  | 
| 52 66 | 
             
                    if $input.data('column-name')
         | 
| 53 | 
            -
                      $input.on 'click', (event) -> false # Dont order columns when you click inside the input
         | 
| 54 | 
            -
                      $input.on 'mousedown', (event) -> event.stopPropagation() # Dont order columns when you click inside the input
         | 
| 67 | 
            +
                      $input.parent().on 'click', (event) -> false # Dont order columns when you click inside the input
         | 
| 68 | 
            +
                      $input.parent().on 'mousedown', (event) -> event.stopPropagation() # Dont order columns when you click inside the input
         | 
| 55 69 |  | 
| 56 70 | 
             
                      if $input.is('select')
         | 
| 57 71 | 
             
                        $input.on 'change', (event) -> dataTableSearch(event)
         | 
| @@ -31,8 +31,13 @@ module EffectiveDatatablesHelper | |
| 31 31 | 
             
                    end
         | 
| 32 32 | 
             
                  end
         | 
| 33 33 |  | 
| 34 | 
            -
                  form.input name, label: false, required: false, | 
| 35 | 
            -
                     | 
| 34 | 
            +
                  form.input name, label: false, required: false,
         | 
| 35 | 
            +
                    as: (defined?(EffectiveFormInputs) ? :effective_select : :select),
         | 
| 36 | 
            +
                    collection: opts[:filter][:values],
         | 
| 37 | 
            +
                    multiple: opts[:filter][:multiple] == true,
         | 
| 38 | 
            +
                    include_blank: (opts[:label] || name.titleize),
         | 
| 39 | 
            +
                    input_html: { name: nil, autocomplete: 'off', data: {'column-name' => opts[:name], 'column-index' => opts[:index]} },
         | 
| 40 | 
            +
                    input_js: { placeholder: (opts[:label] || name.titleize) }
         | 
| 36 41 | 
             
                else
         | 
| 37 42 | 
             
                  content_tag(:p, opts[:label] || name)
         | 
| 38 43 | 
             
                end
         | 
| @@ -46,6 +46,22 @@ module Effective | |
| 46 46 | 
             
                    else
         | 
| 47 47 | 
             
                      collection.where("#{column} ILIKE :term", term: "%#{term}%")
         | 
| 48 48 | 
             
                    end
         | 
| 49 | 
            +
                  when :has_many
         | 
| 50 | 
            +
                    inverse_ids = term.split(',').map { |term| (term = term.to_i) == 0 ? nil : term }.compact
         | 
| 51 | 
            +
                    return collection unless inverse_ids.present?
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                    reflection = collection.klass.reflect_on_association(table_column[:name].to_sym)
         | 
| 54 | 
            +
                    raise "unable to find #{collection.klass.name} :has_many :#{table_column[:name]} association" unless reflection
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                    obj = reflection.build_association({}) # Clinic
         | 
| 57 | 
            +
                    klass = obj.class
         | 
| 58 | 
            +
             | 
| 59 | 
            +
                    inverse = klass.reflect_on_association(collection.table_name) || obj.class.reflect_on_association(collection.table_name.singularize)
         | 
| 60 | 
            +
                    raise "unable to find #{klass.name} has_many :#{collection.table_name} or belongs_to :#{collection.table_name.singularize} associations" unless inverse
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    ids = klass.where(id: inverse_ids).joins(inverse.name).pluck(inverse.foreign_key)
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                    collection.where(id: ids)
         | 
| 49 65 | 
             
                  when :datetime, :date
         | 
| 50 66 | 
             
                    begin
         | 
| 51 67 | 
             
                      digits = term.scan(/(\d+)/).flatten.map(&:to_i)
         | 
| @@ -8,12 +8,11 @@ module Effective | |
| 8 8 | 
             
                  # It sends us a list of columns that are different than our table_columns order
         | 
| 9 9 | 
             
                  # So this method just returns an array of column names, as per ColReorder
         | 
| 10 10 | 
             
                  def display_table_columns
         | 
| 11 | 
            -
                    if params[:columns]. | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
             | 
| 16 | 
            -
                      end
         | 
| 11 | 
            +
                    return nil if params[:columns].blank?
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    @display_table_columns ||= params[:columns].each_with_object({}) do |(_, column), retval|
         | 
| 14 | 
            +
                      retval[column[:name]] = table_columns[column[:name]] # Same order as ColReordernow
         | 
| 15 | 
            +
                      retval[column[:name]][:visible] = (column[:visible] == 'true') # As per ColVis
         | 
| 17 16 | 
             
                    end
         | 
| 18 17 | 
             
                  end
         | 
| 19 18 |  | 
| @@ -15,20 +15,22 @@ module Effective | |
| 15 15 |  | 
| 16 16 | 
             
                    # Here we identify all belongs_to associations and build up a Hash like:
         | 
| 17 17 | 
             
                    # {user: {foreign_key: 'user_id', klass: User}, order: {foreign_key: 'order_id', klass: Effective::Order}}
         | 
| 18 | 
            -
                    belong_tos = (collection. | 
| 19 | 
            -
                       | 
| 20 | 
            -
                        begin
         | 
| 21 | 
            -
                          klass = bt.klass || bt.foreign_type.sub('_type', '').classify.constantize
         | 
| 22 | 
            -
                        rescue => e
         | 
| 23 | 
            -
                          klass = nil
         | 
| 24 | 
            -
                        end
         | 
| 18 | 
            +
                    belong_tos = (collection.klass.reflect_on_all_associations(:belongs_to) rescue []).inject({}) do |retval, bt|
         | 
| 19 | 
            +
                      next if bt.options[:polymorphic]
         | 
| 25 20 |  | 
| 26 | 
            -
             | 
| 27 | 
            -
                       | 
| 21 | 
            +
                      klass = bt.klass || (bt.foreign_type.sub('_type', '').classify.constantize rescue nil)
         | 
| 22 | 
            +
                      retval[bt.name.to_s] = {foreign_key: bt.foreign_key, klass: klass} if bt.foreign_key.present? && klass.present?
         | 
| 28 23 |  | 
| 29 24 | 
             
                      retval
         | 
| 30 25 | 
             
                    end
         | 
| 31 26 |  | 
| 27 | 
            +
                    # has_manys
         | 
| 28 | 
            +
                    has_manys = (collection.klass.reflect_on_all_associations(:has_many) rescue []).inject({}) do |retval, hm|
         | 
| 29 | 
            +
                      klass = hm.klass || (hm.build_association({}).class)
         | 
| 30 | 
            +
                      retval[hm.name.to_s] = {klass: klass}
         | 
| 31 | 
            +
                      retval
         | 
| 32 | 
            +
                    end
         | 
| 33 | 
            +
             | 
| 32 34 | 
             
                    table_columns = cols.each_with_index do |(name, _), index|
         | 
| 33 35 | 
             
                      # If this is a belongs_to, add an :if clause specifying a collection scope if
         | 
| 34 36 | 
             
                      if belong_tos.key?(name)
         | 
| @@ -45,10 +47,29 @@ module Effective | |
| 45 47 | 
             
                      cols[name][:label] ||= name.titleize
         | 
| 46 48 | 
             
                      cols[name][:column] ||= (sql_table && sql_column) ? "\"#{sql_table.name}\".\"#{sql_column.name}\"" : name
         | 
| 47 49 | 
             
                      cols[name][:width] ||= nil
         | 
| 48 | 
            -
                      cols[name][:sortable] = true if cols[name][:sortable] | 
| 49 | 
            -
                      cols[name][: | 
| 50 | 
            +
                      cols[name][:sortable] = true if cols[name][:sortable].nil?
         | 
| 51 | 
            +
                      cols[name][:visible] = true if cols[name][:visible].nil?
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                      # Type
         | 
| 54 | 
            +
                      cols[name][:type] ||= (
         | 
| 55 | 
            +
                        if belong_tos.key?(name)
         | 
| 56 | 
            +
                          :belongs_to
         | 
| 57 | 
            +
                        elsif has_manys.key?(name)
         | 
| 58 | 
            +
                          :has_many
         | 
| 59 | 
            +
                        elsif sql_column.try(:type).present?
         | 
| 60 | 
            +
                          sql_column.type
         | 
| 61 | 
            +
                        else
         | 
| 62 | 
            +
                          :string # When in doubt
         | 
| 63 | 
            +
                        end
         | 
| 64 | 
            +
                      )
         | 
| 65 | 
            +
             | 
| 50 66 | 
             
                      cols[name][:class] = "col-#{cols[name][:type]} col-#{name} #{cols[name][:class]}".strip
         | 
| 51 67 |  | 
| 68 | 
            +
                      # HasMany
         | 
| 69 | 
            +
                      if cols[name][:type] == :has_many
         | 
| 70 | 
            +
                        cols[name][:sortable] = false
         | 
| 71 | 
            +
                      end
         | 
| 72 | 
            +
             | 
| 52 73 | 
             
                      # EffectiveObfuscation
         | 
| 53 74 | 
             
                      if name == 'id' && defined?(EffectiveObfuscation) && collection.respond_to?(:deobfuscate)
         | 
| 54 75 | 
             
                        cols[name][:sortable] = false
         | 
| @@ -66,7 +87,7 @@ module Effective | |
| 66 87 | 
             
                        cols[name][:sql_as_column] = true
         | 
| 67 88 | 
             
                      end
         | 
| 68 89 |  | 
| 69 | 
            -
                      cols[name][:filter] = initialize_table_column_filter(cols[name][:filter], cols[name][:type], belong_tos[name])
         | 
| 90 | 
            +
                      cols[name][:filter] = initialize_table_column_filter(cols[name][:filter], cols[name][:type], belong_tos[name], has_manys[name])
         | 
| 70 91 |  | 
| 71 92 | 
             
                      if cols[name][:partial]
         | 
| 72 93 | 
             
                        cols[name][:partial_local] ||= (sql_table.try(:name) || cols[name][:partial].split('/').last(2).first.presence || 'obj').singularize.to_sym
         | 
| @@ -81,7 +102,7 @@ module Effective | |
| 81 102 |  | 
| 82 103 | 
             
                  end
         | 
| 83 104 |  | 
| 84 | 
            -
                  def initialize_table_column_filter(filter, col_type, belongs_to)
         | 
| 105 | 
            +
                  def initialize_table_column_filter(filter, col_type, belongs_to, has_many)
         | 
| 85 106 | 
             
                    return {type: :null} if filter == false
         | 
| 86 107 |  | 
| 87 108 | 
             
                    filter = {type: filter.to_sym} if filter.kind_of?(String)
         | 
| @@ -96,6 +117,12 @@ module Effective | |
| 96 117 | 
             
                        type: :select,
         | 
| 97 118 | 
             
                        values: Proc.new { belongs_to[:klass].all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[1] <=> y[1] } }
         | 
| 98 119 | 
             
                      }
         | 
| 120 | 
            +
                    when :has_many
         | 
| 121 | 
            +
                      {
         | 
| 122 | 
            +
                        type: :select,
         | 
| 123 | 
            +
                        multiple: true,
         | 
| 124 | 
            +
                        values: Proc.new { has_many[:klass].all.map { |obj| [obj.to_s, obj.id] }.sort { |x, y| x[1] <=> y[1] } }
         | 
| 125 | 
            +
                      }
         | 
| 99 126 | 
             
                    when :effective_roles
         | 
| 100 127 | 
             
                      {type: :select, values: EffectiveRoles.roles}
         | 
| 101 128 | 
             
                    when :integer
         | 
| @@ -59,8 +59,8 @@ module Effective | |
| 59 59 |  | 
| 60 60 | 
             
                    # We want to use the render :collection for each column that renders partials
         | 
| 61 61 | 
             
                    rendered = {}
         | 
| 62 | 
            -
                    table_columns.each do |name, opts|
         | 
| 63 | 
            -
                      if opts[:partial]
         | 
| 62 | 
            +
                    (display_table_columns || table_columns).each do |name, opts|
         | 
| 63 | 
            +
                      if opts[:partial] && opts[:visible]
         | 
| 64 64 | 
             
                        locals = {
         | 
| 65 65 | 
             
                          datatable: self,
         | 
| 66 66 | 
             
                          table_column: table_columns[name],
         | 
| @@ -84,14 +84,19 @@ module Effective | |
| 84 84 |  | 
| 85 85 | 
             
                    collection.each_with_index.map do |obj, index|
         | 
| 86 86 | 
             
                      (display_table_columns || table_columns).map do |name, opts|
         | 
| 87 | 
            -
                         | 
| 87 | 
            +
                        if opts[:visible] == false
         | 
| 88 | 
            +
                          ''
         | 
| 89 | 
            +
                        elsif opts[:partial]
         | 
| 88 90 | 
             
                          rendered[name][index]
         | 
| 89 91 | 
             
                        elsif opts[:block]
         | 
| 90 92 | 
             
                          view.instance_exec(obj, collection, self, &opts[:block])
         | 
| 91 93 | 
             
                        elsif opts[:proc]
         | 
| 92 94 | 
             
                          view.instance_exec(obj, collection, self, &opts[:proc])
         | 
| 93 95 | 
             
                        elsif opts[:type] == :belongs_to
         | 
| 94 | 
            -
                           | 
| 96 | 
            +
                          (obj.send(name) rescue nil).to_s
         | 
| 97 | 
            +
                        elsif opts[:type] == :has_many
         | 
| 98 | 
            +
                          objs = (obj.send(name).map(&:to_s).sort rescue [])
         | 
| 99 | 
            +
                          objs.length == 1 ? objs.first : (opts[:sentence] ? objs.to_sentence : objs.join('<br>'))
         | 
| 95 100 | 
             
                        elsif opts[:type] == :obfuscated_id
         | 
| 96 101 | 
             
                          (obj.send(:to_param) rescue nil).to_s
         | 
| 97 102 | 
             
                        elsif opts[:type] == :effective_roles
         | 
| @@ -101,20 +106,9 @@ module Effective | |
| 101 106 | 
             
                        elsif opts[:type] == :date
         | 
| 102 107 | 
             
                          (obj.send(name).strftime(EffectiveDatatables.date_format) rescue nil)
         | 
| 103 108 | 
             
                        else
         | 
| 104 | 
            -
                           | 
| 105 | 
            -
                          val = (obj[opts[:array_index]] rescue nil) if val == nil
         | 
| 106 | 
            -
                          val
         | 
| 109 | 
            +
                          obj.send(name) rescue (obj[opts[:array_index]] rescue nil)
         | 
| 107 110 | 
             
                        end
         | 
| 108 111 |  | 
| 109 | 
            -
                        # Last minute formatting of dates
         | 
| 110 | 
            -
                        case value
         | 
| 111 | 
            -
                        when Date
         | 
| 112 | 
            -
                          value.strftime(EffectiveDatatables.date_format)
         | 
| 113 | 
            -
                        when Time, DateTime
         | 
| 114 | 
            -
                          value.strftime(EffectiveDatatables.datetime_format)
         | 
| 115 | 
            -
                        else
         | 
| 116 | 
            -
                          value.to_s
         | 
| 117 | 
            -
                        end
         | 
| 118 112 | 
             
                      end
         | 
| 119 113 | 
             
                    end
         | 
| 120 114 | 
             
                  end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: effective_datatables
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.0. | 
| 4 | 
            +
              version: 2.0.2
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Code and Effect
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015- | 
| 11 | 
            +
            date: 2015-08-04 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rails
         |