effective_datatables 2.5.2 → 2.6.0
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/README.md +5 -1
- data/app/assets/javascripts/effective_datatables.js +1 -0
- data/app/assets/javascripts/effective_datatables/charts.js.coffee +13 -0
- data/app/assets/javascripts/effective_datatables/initialize.js.coffee +11 -9
- data/app/helpers/effective_datatables_helper.rb +39 -13
- data/app/models/effective/datatable.rb +31 -9
- data/app/models/effective/effective_datatable/charts.rb +20 -0
- data/app/models/effective/effective_datatable/dsl.rb +7 -82
- data/app/models/effective/effective_datatable/dsl/charts.rb +22 -0
- data/app/models/effective/effective_datatable/dsl/datatable.rb +78 -0
- data/app/models/effective/effective_datatable/dsl/scopes.rb +18 -0
- data/app/models/effective/effective_datatable/options.rb +19 -14
- data/app/views/effective/datatables/_chart.html.haml +1 -0
- data/app/views/effective/datatables/_datatable.html.haml +0 -1
- data/app/views/effective/datatables/_scopes.html.haml +1 -1
- data/lib/effective_datatables.rb +2 -0
- data/lib/effective_datatables/version.rb +1 -1
- data/lib/generators/templates/effective_datatables.rb +3 -0
- metadata +8 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 3c540b23d9f98ea45c144088577103ea0c495ea7
         | 
| 4 | 
            +
              data.tar.gz: a61e210447bb08fe4c40282a283c4c9881e8b5f9
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: a179b5653c8b9f07dd3b08fb2631da06e6d6d249241e17826b700e9b1ffca7efc5cf9b36f80dea09de4651934e69220f51404743ac05c228fb7077a994d43b4d
         | 
| 7 | 
            +
              data.tar.gz: 225185be2373c71dd8142791a7ccf059f4e2cf1f508d3edbdb1e57143832a286b9a28f7e410143990a5446523608d1eeb4459bb7f2bc19e0ef883c6227fb86c9
         | 
    
        data/README.md
    CHANGED
    
    | @@ -544,9 +544,13 @@ When declaring a scope, a form field will automatically be placed above the data | |
| 544 544 | 
             
            The value of the scope, its default value, will be available for use anywehre in your datatable via the `attributes` hash.
         | 
| 545 545 |  | 
| 546 546 | 
             
            ```ruby
         | 
| 547 | 
            -
             | 
| 547 | 
            +
            scopes do
         | 
| 548 | 
            +
              scope :start_date, Time.zone.now-3.months, filter: { input_html: { class: 'datepicker' } }
         | 
| 549 | 
            +
            end
         | 
| 548 550 | 
             
            ```
         | 
| 549 551 |  | 
| 552 | 
            +
            (scopes is declared outside of the `datatable do ... end` block)
         | 
| 553 | 
            +
             | 
| 550 554 | 
             
            and then in your collection, or any `table_column` block:
         | 
| 551 555 |  | 
| 552 556 | 
             
            ```ruby
         | 
| @@ -18,6 +18,7 @@ | |
| 18 18 | 
             
            //= require effective_datatables/bulk_actions
         | 
| 19 19 | 
             
            //= require effective_datatables/responsive
         | 
| 20 20 | 
             
            //= require effective_datatables/scopes
         | 
| 21 | 
            +
            //= require effective_datatables/charts
         | 
| 21 22 | 
             
            //= require effective_datatables/initialize
         | 
| 22 23 |  | 
| 23 24 | 
             
            $.extend( $.fn.dataTable.defaults, {
         | 
| @@ -0,0 +1,13 @@ | |
| 1 | 
            +
            initializeCharts = ->
         | 
| 2 | 
            +
              $('.effective-datatables-chart').each ->
         | 
| 3 | 
            +
                $chart = $(this)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                data = $chart.data('data') || []
         | 
| 6 | 
            +
                type = $chart.data('type') || 'BarChart'
         | 
| 7 | 
            +
                options = $chart.data('options') || {}
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                chart = new google.visualization[type](document.getElementById($chart.attr('id')))
         | 
| 10 | 
            +
                chart.draw(google.visualization.arrayToDataTable(data), options)
         | 
| 11 | 
            +
             | 
| 12 | 
            +
            $ -> initializeCharts()
         | 
| 13 | 
            +
            $(document).on 'page:change', -> initializeCharts()
         | 
| @@ -69,15 +69,18 @@ initializeDataTables = -> | |
| 69 69 | 
             
                  pagingType: 'simple_numbers'
         | 
| 70 70 | 
             
                  initComplete: (settings) ->
         | 
| 71 71 | 
             
                    initializeBulkActions(this.api())
         | 
| 72 | 
            -
                    initializeScopes(this.api())
         | 
| 73 72 | 
             
                    initializeFilters(this.api())
         | 
| 74 73 | 
             
                  drawCallback: (settings) ->
         | 
| 75 74 | 
             
                    $table = $(this.api().table().node())
         | 
| 76 75 | 
             
                    selected = $table.data('bulk-actions-restore-selected-values')
         | 
| 77 76 | 
             
                    completeBulkAction($table, selected) if selected && selected.length > 0
         | 
| 78 77 |  | 
| 79 | 
            -
                    if settings['json'] | 
| 80 | 
            -
                       | 
| 78 | 
            +
                    if settings['json']
         | 
| 79 | 
            +
                      if settings['json']['aggregates']
         | 
| 80 | 
            +
                        drawAggregates($table, settings['json']['aggregates'])
         | 
| 81 | 
            +
             | 
| 82 | 
            +
                      if settings['json']['charts']
         | 
| 83 | 
            +
                        drawCharts($table, settings['json']['charts'])
         | 
| 81 84 |  | 
| 82 85 | 
             
                # Copies the bulk actions html, stored in a data attribute on the table, into the buttons area
         | 
| 83 86 | 
             
                initializeBulkActions = (api) ->
         | 
| @@ -107,12 +110,11 @@ initializeDataTables = -> | |
| 107 110 | 
             
                    if $row
         | 
| 108 111 | 
             
                      $.each values, (col, value) => $row.children().eq(col).html(value)
         | 
| 109 112 |  | 
| 110 | 
            -
                 | 
| 111 | 
            -
             | 
| 112 | 
            -
             | 
| 113 | 
            -
             | 
| 114 | 
            -
             | 
| 115 | 
            -
                  $table.closest('.dataTables_wrapper').prepend(scopes['scopeHtml']) if scopes
         | 
| 113 | 
            +
                drawCharts = ($table, charts) ->
         | 
| 114 | 
            +
                  $.each charts, (name, data) =>
         | 
| 115 | 
            +
                    $(".effective-datatables-chart[data-name='#{name}']").each (_, obj) =>
         | 
| 116 | 
            +
                      chart = new google.visualization[data['type']](obj)
         | 
| 117 | 
            +
                      chart.draw(google.visualization.arrayToDataTable(data['data']), data['options'])
         | 
| 116 118 |  | 
| 117 119 | 
             
                # Appends the filter html, stored in the column definitions, into each column header
         | 
| 118 120 | 
             
                initializeFilters = (api) ->
         | 
| @@ -1,13 +1,50 @@ | |
| 1 1 | 
             
            module EffectiveDatatablesHelper
         | 
| 2 2 | 
             
              def render_datatable(datatable, input_js_options = nil)
         | 
| 3 | 
            -
                datatable. | 
| 3 | 
            +
                return unless datatable.present?
         | 
| 4 | 
            +
                datatable.view ||= self
         | 
| 5 | 
            +
             | 
| 4 6 | 
             
                render partial: 'effective/datatables/datatable',
         | 
| 5 7 | 
             
                  locals: { datatable: datatable, input_js_options: input_js_options.try(:to_json) }
         | 
| 6 8 | 
             
              end
         | 
| 7 9 |  | 
| 10 | 
            +
              def render_datatable_scopes(datatable)
         | 
| 11 | 
            +
                return unless datatable.scopes.present?
         | 
| 12 | 
            +
                datatable.view ||= self
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                render partial: 'effective/datatables/scopes', locals: { datatable: datatable }
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              def render_datatable_charts(datatable)
         | 
| 18 | 
            +
                return unless datatable.charts.present?
         | 
| 19 | 
            +
                datatable.view ||= self
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                datatable.charts.map { |name, _| render_datatable_chart(datatable, name) }.join.html_safe
         | 
| 22 | 
            +
              end
         | 
| 23 | 
            +
             | 
| 24 | 
            +
              def render_datatable_chart(datatable, name)
         | 
| 25 | 
            +
                return unless datatable.charts.present?
         | 
| 26 | 
            +
                return unless datatable.charts[name].present?
         | 
| 27 | 
            +
                datatable.view ||= self
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                unless @effective_datatables_chart_javascript_rendered
         | 
| 30 | 
            +
                  concat javascript_include_tag('https://www.google.com/jsapi')
         | 
| 31 | 
            +
                  concat javascript_tag("if(google && google.visualization === undefined) { google.load('visualization', '1', {packages:#{EffectiveDatatables.google_chart_packages}}); }")
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  @effective_datatables_chart_javascript_rendered = true
         | 
| 34 | 
            +
                end
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                options = datatable.charts[name]
         | 
| 37 | 
            +
                chart = datatable.to_json[:charts][name]
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                render partial: (options[:partial] || 'effective/datatables/chart'),
         | 
| 40 | 
            +
                  locals: { datatable: datatable, chart: chart }
         | 
| 41 | 
            +
              end
         | 
| 42 | 
            +
             | 
| 8 43 | 
             
              def render_simple_datatable(datatable, input_js_options = nil)
         | 
| 9 | 
            -
                datatable. | 
| 44 | 
            +
                return unless datatable.present?
         | 
| 45 | 
            +
                datatable.view ||= self
         | 
| 10 46 | 
             
                datatable.simple = true
         | 
| 47 | 
            +
             | 
| 11 48 | 
             
                render partial: 'effective/datatables/datatable',
         | 
| 12 49 | 
             
                  locals: {datatable: datatable, input_js_options: input_js_options.try(:to_json) }
         | 
| 13 50 | 
             
              end
         | 
| @@ -51,17 +88,6 @@ module EffectiveDatatablesHelper | |
| 51 88 | 
             
                }.to_json()
         | 
| 52 89 | 
             
              end
         | 
| 53 90 |  | 
| 54 | 
            -
              def datatable_scopes(datatable)
         | 
| 55 | 
            -
                return false unless datatable.scopes.present?
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                {
         | 
| 58 | 
            -
                  scopeHtml: render(
         | 
| 59 | 
            -
                    partial: 'effective/datatables/scopes',
         | 
| 60 | 
            -
                    locals: HashWithIndifferentAccess.new(datatable: datatable)
         | 
| 61 | 
            -
                  )
         | 
| 62 | 
            -
                }.to_json()
         | 
| 63 | 
            -
              end
         | 
| 64 | 
            -
             | 
| 65 91 | 
             
              def datatable_header_filter(form, name, value, opts)
         | 
| 66 92 | 
             
                return render(partial: opts[:header_partial], locals: {form: form, name: (opts[:label] || name), column: opts}) if opts[:header_partial].present?
         | 
| 67 93 |  | 
| @@ -7,10 +7,13 @@ module Effective | |
| 7 7 |  | 
| 8 8 | 
             
                delegate :render, :controller, :link_to, :mail_to, :number_to_currency, :number_to_percentage, :to => :@view
         | 
| 9 9 |  | 
| 10 | 
            -
                 | 
| 11 | 
            -
                 | 
| 10 | 
            +
                extend Effective::EffectiveDatatable::Dsl
         | 
| 11 | 
            +
                include Effective::EffectiveDatatable::Dsl::Charts
         | 
| 12 | 
            +
                include Effective::EffectiveDatatable::Dsl::Datatable
         | 
| 13 | 
            +
                include Effective::EffectiveDatatable::Dsl::Scopes
         | 
| 12 14 |  | 
| 13 15 | 
             
                include Effective::EffectiveDatatable::Ajax
         | 
| 16 | 
            +
                include Effective::EffectiveDatatable::Charts
         | 
| 14 17 | 
             
                include Effective::EffectiveDatatable::Helpers
         | 
| 15 18 | 
             
                include Effective::EffectiveDatatable::Hooks
         | 
| 16 19 | 
             
                include Effective::EffectiveDatatable::Options
         | 
| @@ -22,9 +25,20 @@ module Effective | |
| 22 25 | 
             
                    args.first.each { |k, v| self.attributes[k] = v }
         | 
| 23 26 | 
             
                  end
         | 
| 24 27 |  | 
| 25 | 
            -
                   | 
| 26 | 
            -
             | 
| 27 | 
            -
             | 
| 28 | 
            +
                  if respond_to?(:initialize_scopes)  # There was at least one scope defined in the scopes do .. end block
         | 
| 29 | 
            +
                    initialize_scopes
         | 
| 30 | 
            +
                    initialize_scope_options
         | 
| 31 | 
            +
                  end
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  if respond_to?(:initialize_datatable)
         | 
| 34 | 
            +
                    initialize_datatable          # This creates @table_columns based on the DSL datatable do .. end block
         | 
| 35 | 
            +
                    initialize_datatable_options  # This normalizes all the options
         | 
| 36 | 
            +
                  end
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                  if respond_to?(:initialize_charts)
         | 
| 39 | 
            +
                    initialize_charts
         | 
| 40 | 
            +
                    initialize_chart_options
         | 
| 41 | 
            +
                  end
         | 
| 28 42 |  | 
| 29 43 | 
             
                  unless active_record_collection? || array_collection?
         | 
| 30 44 | 
             
                    raise "Unsupported collection type. Should be ActiveRecord class, ActiveRecord relation, or an Array of Arrays [[1, 'something'], [2, 'something else']]"
         | 
| @@ -43,6 +57,10 @@ module Effective | |
| 43 57 | 
             
                  @scopes
         | 
| 44 58 | 
             
                end
         | 
| 45 59 |  | 
| 60 | 
            +
                def charts
         | 
| 61 | 
            +
                  @charts
         | 
| 62 | 
            +
                end
         | 
| 63 | 
            +
             | 
| 46 64 | 
             
                def aggregates
         | 
| 47 65 | 
             
                  @aggregates
         | 
| 48 66 | 
             
                end
         | 
| @@ -86,7 +104,8 @@ module Effective | |
| 86 104 | 
             
                      :data => (data || []),
         | 
| 87 105 | 
             
                      :recordsTotal => (total_records || 0),
         | 
| 88 106 | 
             
                      :recordsFiltered => (display_records || 0),
         | 
| 89 | 
            -
                      :aggregates => (aggregate_data(data) || [])
         | 
| 107 | 
            +
                      :aggregates => (aggregate_data(data) || []),
         | 
| 108 | 
            +
                      :charts => (charts_data || {})
         | 
| 90 109 | 
             
                    }
         | 
| 91 110 | 
             
                  end
         | 
| 92 111 | 
             
                end
         | 
| @@ -102,7 +121,6 @@ module Effective | |
| 102 121 | 
             
                def total_records
         | 
| 103 122 | 
             
                  @total_records ||= (
         | 
| 104 123 | 
             
                    if active_record_collection?
         | 
| 105 | 
            -
                      # https://github.com/rails/rails/issues/15331
         | 
| 106 124 | 
             
                      if collection_class.connection.respond_to?(:unprepared_statement)
         | 
| 107 125 | 
             
                        collection_sql = collection_class.connection.unprepared_statement { collection.to_sql }
         | 
| 108 126 | 
             
                        (collection_class.connection.execute("SELECT COUNT(*) FROM (#{collection_sql}) AS datatables_total_count").first.values.first rescue 1).to_i
         | 
| @@ -128,11 +146,11 @@ module Effective | |
| 128 146 | 
             
                  @view.effective_datatable = self
         | 
| 129 147 |  | 
| 130 148 | 
             
                  (self.class.instance_methods(false) - [:collection, :search_column, :order_column]).each do |view_method|
         | 
| 131 | 
            -
                    @view.class_eval { delegate view_method, : | 
| 149 | 
            +
                    @view.class_eval { delegate view_method, to: :@effective_datatable }
         | 
| 132 150 | 
             
                  end
         | 
| 133 151 |  | 
| 134 152 | 
             
                  Effective::EffectiveDatatable::Helpers.instance_methods(false).each do |helper_method|
         | 
| 135 | 
            -
                    @view.class_eval { delegate helper_method, : | 
| 153 | 
            +
                    @view.class_eval { delegate helper_method, to: :@effective_datatable }
         | 
| 136 154 | 
             
                  end
         | 
| 137 155 |  | 
| 138 156 | 
             
                  # Clear the search_terms memoization
         | 
| @@ -141,6 +159,10 @@ module Effective | |
| 141 159 | 
             
                  @order_direction = nil
         | 
| 142 160 | 
             
                end
         | 
| 143 161 |  | 
| 162 | 
            +
                def view_context
         | 
| 163 | 
            +
                  view
         | 
| 164 | 
            +
                end
         | 
| 165 | 
            +
             | 
| 144 166 | 
             
                def table_html_class
         | 
| 145 167 | 
             
                  @table_html_class.presence || 'table table-bordered table-striped'
         | 
| 146 168 | 
             
                end
         | 
| @@ -0,0 +1,20 @@ | |
| 1 | 
            +
            module Effective
         | 
| 2 | 
            +
              module EffectiveDatatable
         | 
| 3 | 
            +
                module Charts
         | 
| 4 | 
            +
             | 
| 5 | 
            +
                  def charts_data
         | 
| 6 | 
            +
                    HashWithIndifferentAccess.new().tap do |retval|
         | 
| 7 | 
            +
                      (charts || {}).each do |name, chart|
         | 
| 8 | 
            +
                        retval[name] = {
         | 
| 9 | 
            +
                          name: chart[:name],
         | 
| 10 | 
            +
                          type: chart[:type],
         | 
| 11 | 
            +
                          options: chart[:options],
         | 
| 12 | 
            +
                          data: (instance_exec(&chart[:block]) if chart[:block])
         | 
| 13 | 
            +
                        }
         | 
| 14 | 
            +
                      end
         | 
| 15 | 
            +
                    end
         | 
| 16 | 
            +
                  end
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                end
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
            end
         | 
| @@ -1,94 +1,19 @@ | |
| 1 | 
            -
            #  | 
| 1 | 
            +
            # These are Class level methods.
         | 
| 2 2 |  | 
| 3 3 | 
             
            module Effective
         | 
| 4 4 | 
             
              module EffectiveDatatable
         | 
| 5 5 | 
             
                module Dsl
         | 
| 6 6 |  | 
| 7 | 
            -
                   | 
| 8 | 
            -
                     | 
| 9 | 
            -
                      define_method('initialize_datatable') { instance_exec(&block) }
         | 
| 10 | 
            -
                    end
         | 
| 7 | 
            +
                  def datatable(&block)
         | 
| 8 | 
            +
                    define_method('initialize_datatable') { instance_exec(&block) }
         | 
| 11 9 | 
             
                  end
         | 
| 12 10 |  | 
| 13 | 
            -
                   | 
| 14 | 
            -
             | 
| 15 | 
            -
                    @default_order = {name => direction}
         | 
| 11 | 
            +
                  def scopes(&block)
         | 
| 12 | 
            +
                    define_method('initialize_scopes') { instance_exec(&block) }
         | 
| 16 13 | 
             
                  end
         | 
| 17 14 |  | 
| 18 | 
            -
                  def  | 
| 19 | 
            -
                     | 
| 20 | 
            -
                  end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
                  def table_column(name, options = {}, proc = nil, &block)
         | 
| 23 | 
            -
                    if block_given?
         | 
| 24 | 
            -
                      raise "You cannot use partial: ... with the block syntax" if options[:partial]
         | 
| 25 | 
            -
                      raise "You cannot use proc: ... with the block syntax" if options[:proc]
         | 
| 26 | 
            -
                      options[:block] = block
         | 
| 27 | 
            -
                    end
         | 
| 28 | 
            -
                    raise "You cannot use both partial: ... and proc: ..." if options[:partial] && options[:proc]
         | 
| 29 | 
            -
             | 
| 30 | 
            -
                    (@table_columns ||= HashWithIndifferentAccess.new)[name] = options
         | 
| 31 | 
            -
                  end
         | 
| 32 | 
            -
             | 
| 33 | 
            -
                  def array_column(name, options = {}, proc = nil, &block)
         | 
| 34 | 
            -
                    table_column(name, options.merge!(array_column: true), proc, &block)
         | 
| 35 | 
            -
                  end
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                  def actions_column(options = {}, proc = nil, &block)
         | 
| 38 | 
            -
                    show = options.fetch(:show, (EffectiveDatatables.actions_column[:show] rescue false))
         | 
| 39 | 
            -
                    edit = options.fetch(:edit, (EffectiveDatatables.actions_column[:edit] rescue false))
         | 
| 40 | 
            -
                    destroy = options.fetch(:destroy, (EffectiveDatatables.actions_column[:destroy] rescue false))
         | 
| 41 | 
            -
                    unarchive = options.fetch(:unarchive, (EffectiveDatatables.actions_column[:unarchive] rescue false))
         | 
| 42 | 
            -
                    name = options.fetch(:name, 'actions')
         | 
| 43 | 
            -
             | 
| 44 | 
            -
                    opts = {
         | 
| 45 | 
            -
                      sortable: false,
         | 
| 46 | 
            -
                      filter: false,
         | 
| 47 | 
            -
                      responsivePriority: 0,
         | 
| 48 | 
            -
                      partial_locals: { show_action: show, edit_action: edit, destroy_action: destroy, unarchive_action: unarchive }
         | 
| 49 | 
            -
                    }.merge(options)
         | 
| 50 | 
            -
             | 
| 51 | 
            -
                    opts[:partial_local] ||= :resource unless opts[:partial].present?
         | 
| 52 | 
            -
                    opts[:partial] ||= '/effective/datatables/actions_column' unless (block_given? || proc.present?)
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                    table_column(name, opts, proc, &block)
         | 
| 55 | 
            -
                  end
         | 
| 56 | 
            -
             | 
| 57 | 
            -
                  def bulk_actions_column(options = {}, proc = nil, &block)
         | 
| 58 | 
            -
                    name = options.fetch(:name, 'bulk_actions')
         | 
| 59 | 
            -
                    resource_method = options.fetch(:resource_method, :to_param)
         | 
| 60 | 
            -
             | 
| 61 | 
            -
                    opts = {
         | 
| 62 | 
            -
                      bulk_actions_column: true,
         | 
| 63 | 
            -
                      label: '',
         | 
| 64 | 
            -
                      partial_local: :resource,
         | 
| 65 | 
            -
                      partial: '/effective/datatables/bulk_actions_column',
         | 
| 66 | 
            -
                      partial_locals: { resource_method: resource_method },
         | 
| 67 | 
            -
                      sortable: false,
         | 
| 68 | 
            -
                      dropdown_partial: '/effective/datatables/bulk_actions_dropdown',
         | 
| 69 | 
            -
                      dropdown_block: block
         | 
| 70 | 
            -
                    }.merge(options)
         | 
| 71 | 
            -
             | 
| 72 | 
            -
                    table_column(name, opts, proc)
         | 
| 73 | 
            -
                  end
         | 
| 74 | 
            -
             | 
| 75 | 
            -
                  def scope(name, default, options = {}, &block)
         | 
| 76 | 
            -
                    if block_given?
         | 
| 77 | 
            -
                      raise "You cannot use partial: ... with the block syntax" if options[:partial]
         | 
| 78 | 
            -
                      options[:block] = block
         | 
| 79 | 
            -
                    end
         | 
| 80 | 
            -
             | 
| 81 | 
            -
                    # This needs to be a {} not WithIndifferentAccess or rendering _scopes won't work correctly
         | 
| 82 | 
            -
                    (@scopes ||= {})[name] = options.merge(default: default)
         | 
| 83 | 
            -
                  end
         | 
| 84 | 
            -
             | 
| 85 | 
            -
                  def aggregate(name, options = {}, &block)
         | 
| 86 | 
            -
                    if block_given?
         | 
| 87 | 
            -
                      raise "You cannot use proc: ... with the block syntax" if options[:proc]
         | 
| 88 | 
            -
                      options[:block] = block
         | 
| 89 | 
            -
                    end
         | 
| 90 | 
            -
             | 
| 91 | 
            -
                    (@aggregates ||= HashWithIndifferentAccess.new)[name] = options
         | 
| 15 | 
            +
                  def charts(&block)
         | 
| 16 | 
            +
                    define_method('initialize_charts') { instance_exec(&block) }
         | 
| 92 17 | 
             
                  end
         | 
| 93 18 |  | 
| 94 19 | 
             
                end
         | 
| @@ -0,0 +1,22 @@ | |
| 1 | 
            +
            module Effective
         | 
| 2 | 
            +
              module EffectiveDatatable
         | 
| 3 | 
            +
                module Dsl
         | 
| 4 | 
            +
                  module Charts
         | 
| 5 | 
            +
                    # Instance Methods inside the charts do .. end block
         | 
| 6 | 
            +
                    def chart(name, type, options = {}, &block)
         | 
| 7 | 
            +
             | 
| 8 | 
            +
                      options[:title] ||= (options[:label] || name.to_s.titleize)
         | 
| 9 | 
            +
                      options[:legend] = 'none' if options[:legend] == false
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                      (@charts ||= HashWithIndifferentAccess.new)[name] = {
         | 
| 12 | 
            +
                        name: name,
         | 
| 13 | 
            +
                        type: type,
         | 
| 14 | 
            +
                        partial: options.delete(:partial),
         | 
| 15 | 
            +
                        options: options,
         | 
| 16 | 
            +
                        block: (block if block_given?)
         | 
| 17 | 
            +
                      }
         | 
| 18 | 
            +
                    end
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
                end
         | 
| 21 | 
            +
              end
         | 
| 22 | 
            +
            end
         | 
| @@ -0,0 +1,78 @@ | |
| 1 | 
            +
            module Effective
         | 
| 2 | 
            +
              module EffectiveDatatable
         | 
| 3 | 
            +
                module Dsl
         | 
| 4 | 
            +
                  module Datatable
         | 
| 5 | 
            +
                    # Instance Methods inside the datatable do .. end block
         | 
| 6 | 
            +
                    def default_order(name, direction = :asc)
         | 
| 7 | 
            +
                      @default_order = {name => direction}
         | 
| 8 | 
            +
                    end
         | 
| 9 | 
            +
             | 
| 10 | 
            +
                    def default_entries(entries)
         | 
| 11 | 
            +
                      @default_entries = entries
         | 
| 12 | 
            +
                    end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
                    def table_column(name, options = {}, proc = nil, &block)
         | 
| 15 | 
            +
                      if block_given?
         | 
| 16 | 
            +
                        raise "You cannot use partial: ... with the block syntax" if options[:partial]
         | 
| 17 | 
            +
                        raise "You cannot use proc: ... with the block syntax" if options[:proc]
         | 
| 18 | 
            +
                        options[:block] = block
         | 
| 19 | 
            +
                      end
         | 
| 20 | 
            +
                      raise "You cannot use both partial: ... and proc: ..." if options[:partial] && options[:proc]
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                      (@table_columns ||= HashWithIndifferentAccess.new)[name] = options
         | 
| 23 | 
            +
                    end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                    def array_column(name, options = {}, proc = nil, &block)
         | 
| 26 | 
            +
                      table_column(name, options.merge!(array_column: true), proc, &block)
         | 
| 27 | 
            +
                    end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                    def actions_column(options = {}, proc = nil, &block)
         | 
| 30 | 
            +
                      show = options.fetch(:show, (EffectiveDatatables.actions_column[:show] rescue false))
         | 
| 31 | 
            +
                      edit = options.fetch(:edit, (EffectiveDatatables.actions_column[:edit] rescue false))
         | 
| 32 | 
            +
                      destroy = options.fetch(:destroy, (EffectiveDatatables.actions_column[:destroy] rescue false))
         | 
| 33 | 
            +
                      unarchive = options.fetch(:unarchive, (EffectiveDatatables.actions_column[:unarchive] rescue false))
         | 
| 34 | 
            +
                      name = options.fetch(:name, 'actions')
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                      opts = {
         | 
| 37 | 
            +
                        sortable: false,
         | 
| 38 | 
            +
                        filter: false,
         | 
| 39 | 
            +
                        responsivePriority: 0,
         | 
| 40 | 
            +
                        partial_locals: { show_action: show, edit_action: edit, destroy_action: destroy, unarchive_action: unarchive }
         | 
| 41 | 
            +
                      }.merge(options)
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                      opts[:partial_local] ||= :resource unless opts[:partial].present?
         | 
| 44 | 
            +
                      opts[:partial] ||= '/effective/datatables/actions_column' unless (block_given? || proc.present?)
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                      table_column(name, opts, proc, &block)
         | 
| 47 | 
            +
                    end
         | 
| 48 | 
            +
             | 
| 49 | 
            +
                    def bulk_actions_column(options = {}, proc = nil, &block)
         | 
| 50 | 
            +
                      name = options.fetch(:name, 'bulk_actions')
         | 
| 51 | 
            +
                      resource_method = options.fetch(:resource_method, :to_param)
         | 
| 52 | 
            +
             | 
| 53 | 
            +
                      opts = {
         | 
| 54 | 
            +
                        bulk_actions_column: true,
         | 
| 55 | 
            +
                        label: '',
         | 
| 56 | 
            +
                        partial_local: :resource,
         | 
| 57 | 
            +
                        partial: '/effective/datatables/bulk_actions_column',
         | 
| 58 | 
            +
                        partial_locals: { resource_method: resource_method },
         | 
| 59 | 
            +
                        sortable: false,
         | 
| 60 | 
            +
                        dropdown_partial: '/effective/datatables/bulk_actions_dropdown',
         | 
| 61 | 
            +
                        dropdown_block: block
         | 
| 62 | 
            +
                      }.merge(options)
         | 
| 63 | 
            +
             | 
| 64 | 
            +
                      table_column(name, opts, proc)
         | 
| 65 | 
            +
                    end
         | 
| 66 | 
            +
             | 
| 67 | 
            +
                    def aggregate(name, options = {}, &block)
         | 
| 68 | 
            +
                      if block_given?
         | 
| 69 | 
            +
                        raise "You cannot use proc: ... with the block syntax" if options[:proc]
         | 
| 70 | 
            +
                        options[:block] = block
         | 
| 71 | 
            +
                      end
         | 
| 72 | 
            +
             | 
| 73 | 
            +
                      (@aggregates ||= HashWithIndifferentAccess.new)[name] = options
         | 
| 74 | 
            +
                    end
         | 
| 75 | 
            +
                  end
         | 
| 76 | 
            +
                end
         | 
| 77 | 
            +
              end
         | 
| 78 | 
            +
            end
         | 
| @@ -0,0 +1,18 @@ | |
| 1 | 
            +
            module Effective
         | 
| 2 | 
            +
              module EffectiveDatatable
         | 
| 3 | 
            +
                module Dsl
         | 
| 4 | 
            +
                  module Scopes
         | 
| 5 | 
            +
                    # Instance Methods inside the scopes do .. end block
         | 
| 6 | 
            +
                    def scope(name, default, options = {}, &block)
         | 
| 7 | 
            +
                      if block_given?
         | 
| 8 | 
            +
                        raise "You cannot use partial: ... with the block syntax" if options[:partial]
         | 
| 9 | 
            +
                        options[:block] = block
         | 
| 10 | 
            +
                      end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                      # This needs to be a {} not WithIndifferentAccess or rendering _scopes won't work correctly
         | 
| 13 | 
            +
                      (@scopes ||= {})[name] = options.merge(default: default)
         | 
| 14 | 
            +
                    end
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
              end
         | 
| 18 | 
            +
            end
         | 
| @@ -4,12 +4,16 @@ module Effective | |
| 4 4 | 
             
              module EffectiveDatatable
         | 
| 5 5 | 
             
                module Options
         | 
| 6 6 |  | 
| 7 | 
            -
                  def  | 
| 8 | 
            -
                    @table_columns =  | 
| 7 | 
            +
                  def initialize_datatable_options
         | 
| 8 | 
            +
                    @table_columns = _initialize_datatable_options(@table_columns)
         | 
| 9 9 | 
             
                  end
         | 
| 10 10 |  | 
| 11 | 
            -
                  def  | 
| 12 | 
            -
                    @scopes =  | 
| 11 | 
            +
                  def initialize_scope_options
         | 
| 12 | 
            +
                    @scopes = _initialize_scope_options(@scopes)
         | 
| 13 | 
            +
                  end
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  def initialize_chart_options
         | 
| 16 | 
            +
                    @charts = _initialize_chart_options(@charts)
         | 
| 13 17 | 
             
                  end
         | 
| 14 18 |  | 
| 15 19 | 
             
                  def quote_sql(name)
         | 
| @@ -25,26 +29,27 @@ module Effective | |
| 25 29 |  | 
| 26 30 | 
             
                  # A scope comes to us like {:start_date => {default: Time.zone.now, filter: {as: :select, collection: ... input_html :}}}
         | 
| 27 31 | 
             
                  # We want to make sure an input_html: { value: default } exists
         | 
| 28 | 
            -
                  def  | 
| 32 | 
            +
                  def _initialize_scope_options(scopes)
         | 
| 29 33 | 
             
                    (scopes || []).each do |name, options|
         | 
| 30 34 | 
             
                      value = attributes.key?(name) ? attributes[name] : options[:default]
         | 
| 31 35 |  | 
| 36 | 
            +
                      if (options[:fallback] || options[:presence]) && attributes[name].blank? && attributes[name] != false
         | 
| 37 | 
            +
                        self.attributes[name] = options[:default]
         | 
| 38 | 
            +
                        value = options[:default]
         | 
| 39 | 
            +
                      end
         | 
| 40 | 
            +
             | 
| 32 41 | 
             
                      options[:filter] ||= {}
         | 
| 33 42 | 
             
                      options[:filter][:input_html] ||= {}
         | 
| 34 43 | 
             
                      options[:filter][:input_html][:value] = value
         | 
| 35 44 | 
             
                      options[:filter][:selected] = value
         | 
| 36 | 
            -
             | 
| 37 | 
            -
                      if attributes.key?(name) == false
         | 
| 38 | 
            -
                        self.attributes[name] = options[:default]
         | 
| 39 | 
            -
                      end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
                      if (options[:fallback] || options[:presence]) && attributes[name].blank? && attributes[name] != false
         | 
| 42 | 
            -
                        self.attributes[name] = options[:default]
         | 
| 43 | 
            -
                      end
         | 
| 44 45 | 
             
                    end
         | 
| 45 46 | 
             
                  end
         | 
| 46 47 |  | 
| 47 | 
            -
                  def  | 
| 48 | 
            +
                  def _initialize_chart_options(charts)
         | 
| 49 | 
            +
                    charts
         | 
| 50 | 
            +
                  end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                  def _initialize_datatable_options(cols)
         | 
| 48 53 | 
             
                    sql_table = (collection.table rescue nil)
         | 
| 49 54 |  | 
| 50 55 | 
             
                    # Here we identify all belongs_to associations and build up a Hash like:
         | 
| @@ -0,0 +1 @@ | |
| 1 | 
            +
            .effective-datatables-chart{id: "#{chart[:name].to_s.parameterize}-chart-#{Time.zone.now.nsec}", data: {name: chart[:name], type: chart[:type], options: chart[:options].to_json, data: chart[:data].to_json}}
         | 
| @@ -7,7 +7,6 @@ | |
| 7 7 | 
             
                  'bulk-actions' => datatable_bulk_actions(datatable),
         | 
| 8 8 | 
             
                  'columns' => datatable_columns(datatable),
         | 
| 9 9 | 
             
                  'input-js-options' => local_assigns[:input_js_options],
         | 
| 10 | 
            -
                  'scopes' => datatable_scopes(datatable),
         | 
| 11 10 | 
             
                  'simple' => datatable.simple?.to_s,
         | 
| 12 11 | 
             
                  'source' => effective_datatables.datatable_path(datatable, {format: 'json'}.merge(attributes: datatable.attributes)).chomp('?'),
         | 
| 13 12 | 
             
                  'default-order' => datatable_default_order(datatable),
         | 
| @@ -10,6 +10,6 @@ | |
| 10 10 | 
             
                    - else
         | 
| 11 11 | 
             
                      = form.input name, options[:filter]
         | 
| 12 12 |  | 
| 13 | 
            -
                  = form.submit ' | 
| 13 | 
            +
                  = form.submit 'Submit', class: 'btn btn-primary', 'data-disable-with' => 'Submitting...'
         | 
| 14 14 | 
             
                  = link_to 'Reset', '#', 'data-reset-form' => true
         | 
| 15 15 |  | 
    
        data/lib/effective_datatables.rb
    CHANGED
    
    
    
        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. | 
| 4 | 
            +
              version: 2.6.0
         | 
| 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: 2016-06- | 
| 11 | 
            +
            date: 2016-06-24 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rails
         | 
| @@ -121,6 +121,7 @@ files: | |
| 121 121 | 
             
            - app/assets/javascripts/dataTables/responsive/responsive.bootstrap.min.js
         | 
| 122 122 | 
             
            - app/assets/javascripts/effective_datatables.js
         | 
| 123 123 | 
             
            - app/assets/javascripts/effective_datatables/bulk_actions.js.coffee
         | 
| 124 | 
            +
            - app/assets/javascripts/effective_datatables/charts.js.coffee
         | 
| 124 125 | 
             
            - app/assets/javascripts/effective_datatables/initialize.js.coffee
         | 
| 125 126 | 
             
            - app/assets/javascripts/effective_datatables/responsive.js.coffee
         | 
| 126 127 | 
             
            - app/assets/javascripts/effective_datatables/scopes.js.coffee
         | 
| @@ -143,7 +144,11 @@ files: | |
| 143 144 | 
             
            - app/models/effective/array_datatable_tool.rb
         | 
| 144 145 | 
             
            - app/models/effective/datatable.rb
         | 
| 145 146 | 
             
            - app/models/effective/effective_datatable/ajax.rb
         | 
| 147 | 
            +
            - app/models/effective/effective_datatable/charts.rb
         | 
| 146 148 | 
             
            - app/models/effective/effective_datatable/dsl.rb
         | 
| 149 | 
            +
            - app/models/effective/effective_datatable/dsl/charts.rb
         | 
| 150 | 
            +
            - app/models/effective/effective_datatable/dsl/datatable.rb
         | 
| 151 | 
            +
            - app/models/effective/effective_datatable/dsl/scopes.rb
         | 
| 147 152 | 
             
            - app/models/effective/effective_datatable/helpers.rb
         | 
| 148 153 | 
             
            - app/models/effective/effective_datatable/hooks.rb
         | 
| 149 154 | 
             
            - app/models/effective/effective_datatable/options.rb
         | 
| @@ -151,6 +156,7 @@ files: | |
| 151 156 | 
             
            - app/views/effective/datatables/_actions_column.html.haml
         | 
| 152 157 | 
             
            - app/views/effective/datatables/_bulk_actions_column.html.haml
         | 
| 153 158 | 
             
            - app/views/effective/datatables/_bulk_actions_dropdown.html.haml
         | 
| 159 | 
            +
            - app/views/effective/datatables/_chart.html.haml
         | 
| 154 160 | 
             
            - app/views/effective/datatables/_datatable.html.haml
         | 
| 155 161 | 
             
            - app/views/effective/datatables/_scopes.html.haml
         | 
| 156 162 | 
             
            - app/views/effective/datatables/_spacer_template.html
         |