diff --git a/lib/osom_tables/helper.rb b/lib/osom_tables/helper.rb index 9d288c2..898a4c0 100644 --- a/lib/osom_tables/helper.rb +++ b/lib/osom_tables/helper.rb @@ -1,21 +1,39 @@ module OsomTables::Helper - def osom_table_for(items, options={}, &block) + # @param [Object] items items to be displayed, not needed if the async option is set + # @param [Hash] options + # @option opts [Boolean] :async Load the table content asynchronously on dom ready + # + # TODO: Fill all these in + def osom_table_for(*args, &block) + options = args.extract_options! + items = args.first || [] push = options[:push] == true and options.delete(:push) url = options[:url] || request.fullpath and options.delete(:url) search = options[:search] == true and options.delete(:search) paginate = options[:paginate] || {} and options.delete(:paginate) url = url.gsub(/(\?|&)osom_tables_cache_killa=[^&]*?/, '') + # Allow the table to be loaded asynchronously + if options[:async] + options[:class] ||= [] + options[:class] << 'async' + end + options[:data] ||= {} options[:data][:url] = url options[:data][:push] = true if push - content_tag :div, class: 'osom-table' do + content_tag :div, class: "osom-table #{"empty" if items.empty?}" do osom_tables_search(url, search) + content_tag(:table, options) { - content_tag(:caption, image_tag('osom-tables-spinner.gif', alt: nil), class: 'locker') + + caption = if items.empty? + content_tag(:span) { "No items to display here!" } + else + image_tag('osom-tables-spinner.gif', alt: nil) + end + content_tag(:caption, caption, class: 'locker') + capture(Table.new(self, items), &block) } + @@ -28,6 +46,7 @@ def osom_tables_search(url, search) end def osom_tables_pagination(items, url, options) + return ''.html_safe if items.empty? if respond_to?(:paginate) # kaminari options[:params] = Rails.application.routes.recognize_path(url, method: :get).merge(options[:params] || {}) paginate(items, options) diff --git a/vendor/assets/javascripts/osom-tables.js b/vendor/assets/javascripts/osom-tables.js index ace9d91..2f352d2 100644 --- a/vendor/assets/javascripts/osom-tables.js +++ b/vendor/assets/javascripts/osom-tables.js @@ -7,56 +7,8 @@ if (!$) { return console.log("No jQuery? Osom!"); } - $(document).on('click', '.osom-table .pagination a', function(e) { - e.preventDefault(); - load_table($(this).closest('.osom-table'), this.getAttribute('href')); - }); - - $(document).on('click', '.osom-table th[data-order]', function(e) { - var order = $(this).data('order'), asc = $(this).hasClass('asc'); - - load_table($(this).closest('.osom-table'), build_url( - $(this).closest('table').data('url'), { - order: order + (asc ? '_desc' : ''), page: 1 - } - )); - }); - - $(window).on('popstate', function(e) { - var state = e.originalEvent.state; - if (state && state.url) { - if (current_table && current_table.find('table').data('push')) { - load_table(current_table, state.url, true); - } else { - document.location.href = state.url; - } - } - }); - var current_table = null; - function load_table(container, url, no_push) { - current_table = container.addClass('loading'); - actual_table = container.find('table'); - - actual_table.trigger('osom-table:request'); - - if (history.pushState && !no_push && actual_table.data('push')) { - history.pushState({url: url}, 'osom-table', url); - url = build_url(url, {osom_tables_cache_killa: true}); - } - - $.ajax(url, { - success: function(new_content) { - container.replaceWith(new_content); - }, - complete: function() { - container.removeClass('loading'); - actual_table.trigger('osom-table:loaded'); - } - }); - }; - /** * Rebuilds the url with the extra prams */ @@ -101,4 +53,60 @@ return [path, args]; } + var osom_table = $.fn.osom_table = $.osom_table = function(container, url, no_push) { + current_table = container.addClass('loading'); + actual_table = container.find('table'); + + actual_table.trigger('osom-table:request'); + + if (history.pushState && !no_push && actual_table.data('push')) { + history.pushState({url: url}, 'osom-table', url); + url = build_url(url, {osom_tables_cache_killa: true}); + } + + $.ajax(url, { + success: function(new_content) { + container.replaceWith(new_content); + }, + complete: function() { + container.removeClass('loading'); + actual_table.trigger('osom-table:loaded'); + } + }); + }; + + $(document).on('click', '.osom-table .pagination a', function(e) { + e.preventDefault(); + $.osom_table($(this).closest('.osom-table'), this.getAttribute('href')); + }); + + $(document).on('click', '.osom-table th[data-order]', function(e) { + var order = $(this).data('order'), asc = $(this).hasClass('asc'); + + $.osom_table($(this).closest('.osom-table'), build_url( + $(this).closest('table').data('url'), { + order: order + (asc ? '_desc' : ''), page: 1 + } + )); + }); + + /* Load async tables */ + $(document).ready(function() { + $('.osom-table .async').each(function(index, element) { + var table = $(element); + return $.osom_table(table.closest('.osom-table'), table.data('url')); + }); + }); + + $(window).on('popstate', function(e) { + var state = e.originalEvent.state; + if (state && state.url) { + if (current_table && current_table.find('table').data('push')) { + $.osom_table(current_table, state.url, true); + } else { + document.location.href = state.url; + } + } + }); + })(jQuery); diff --git a/vendor/assets/stylesheets/osom-tables.css.scss b/vendor/assets/stylesheets/osom-tables.css.scss index 6dd21d4..f3ca6d3 100644 --- a/vendor/assets/stylesheets/osom-tables.css.scss +++ b/vendor/assets/stylesheets/osom-tables.css.scss @@ -13,7 +13,7 @@ .locker { display: none; position: absolute; - z-index: 9999; + z-index: 100; left: 0; top: 0; width: 100%; @@ -34,6 +34,16 @@ background-color: #fff; border-radius: 1em; } + + span { + position: relative; + top: 5px; + max-height: 5em; + max-width: 5em; + padding: 1em; + background-color: #fff; + border-radius: 1em; + } } thead th.sortable { @@ -70,7 +80,7 @@ } } - &.loading { + &.loading, &.empty { table { th, td { -webkit-filter: blur(1.5px);