// Copyright (c) 2010-2014 Peter Horn & Florian Thomas, Provideal GmbH // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Tabulatr = { moreResults: true, storePage: false, currentData: null, locked: false, updatePagination: function(currentPage, numPages, tableId){ var ul = $('.pagination[data-table='+ tableId +'] > ul'); if(ul.length == 0){ // bootstrap 3 ul = $('.pagination[data-table='+ tableId +']'); } ul.html(''); if(numPages < 13){ for(var i = 1; i <= numPages; i++){ var cls = ''; if(i == currentPage){ cls = 'active'; } ul.append('
  • '+ i +'
  • '); } }else{ if(currentPage > 1){ ul.append('
  • 1
  • '); } var between = Math.floor((1 + currentPage) / 2); if(between > 1 && between < currentPage - 2){ ul.append('
  • ...
  • '); ul.append('
  • '+ between +' 4){ ul.append('
  • ...
  • '); } if(currentPage > 3){ ul.append('
  • '+ (currentPage-2) +'
  • '); ul.append('
  • '+ (currentPage-1) +'
  • '); } ul.append('
  • '+ currentPage +'
  • '); if(currentPage < numPages - 1){ ul.append('
  • '+ (currentPage+1) +'
  • '); } if(currentPage < numPages - 2){ ul.append('
  • '+ (currentPage+2) +'
  • '); } if(currentPage < numPages - 3){ ul.append('
  • ...
  • '); } between = Math.floor((currentPage + numPages) / 2); if(between > currentPage + 3 && between < numPages - 1){ ul.append('
  • '+ between +'
  • '); ul.append('
  • ...
  • '); } if(currentPage < numPages){ ul.append('
  • '+ numPages +'
  • '); } } }, updateTable: function(hash, tableId, forceReload) { if(hash.page !== undefined && !forceReload){ //old page should be stored Tabulatr.storePage = true; // check if this page was already loaded if($('#'+ tableId + ' tbody tr[data-page='+ hash.page +']').length > 0){ $('#'+ tableId + ' tbody tr').hide(); $('#'+ tableId + ' tbody tr[data-page='+ hash.page +']').show(); Tabulatr.updatePagination(hash.page, $('.pagination[data-table='+ tableId +'] a:last').data('page'), tableId); return; } }else{ Tabulatr.storePage = false; } if(Tabulatr.locked){ return; } Tabulatr.locked = true; jQuery.get($('table#'+ tableId).data('path') + '.json', Tabulatr.createParameterString(hash, tableId), Tabulatr.handleResponse ); }, checkIfCheckboxesAreMarked: function(){ return $('tr[data-page] input[type=checkbox]:checked').length > 0; }, handleResponse: function(response) { Tabulatr.insertTabulatrData(response); Tabulatr.updatePagination(response.meta.page, response.meta.pages, response.meta.table_id); Tabulatr.locked = false; }, insertTabulatrData: function(response){ var columns = []; var tableId = response.meta.table_id; var tableName = tableId.split('_')[0]; var tbody = $('#'+ tableId +' tbody'); if(!response.meta.append){ if(Tabulatr.storePage){ $('#'+ tableId +' tbody tr').hide(); }else{ $('#'+ tableId +' tbody').html(''); } } if(response.data.length == 0){ Tabulatr.moreResults = false; $('.pagination_trigger[data-table='+ tableId +']').unbind('inview'); }else{ if(response.data.length < response.meta.pagesize){ Tabulatr.moreResults = false; $('.pagination_trigger[data-table='+ tableId + ']').unbind('inview'); }else{ Tabulatr.moreResults = true; } // insert the actual data for(var i = 0; i < response.data.length; i++){ var data = response.data[i]; var id = data.id; var tr = $('tr.empty_row').clone(); tr.removeClass('empty_row'); tr.attr('data-page', response.meta.page); tr.attr('data-id', id); tr.find('td').each(function(i,td_raw) { var td = $(td_raw); var coltype = td.data('tabulatr-type'); var name = td.data('tabulatr-column-name'); var cont = data[name] if(coltype === 'checkbox') { cont = $("").attr('type', 'checkbox').val(id).addClass('tabulatr-checkbox'); } td.html(cont); }); tbody.append(tr); } } var count_string = $('.tabulatr_count[data-table='+ tableId +']').data('format-string'); count_string = count_string.replace(/%\{current\}/, response.meta.count); count_string = count_string.replace(/%\{total\}/, response.meta.total); count_string = count_string.replace(/%\{per_page\}/, response.meta.pagesize); $('.tabulatr_count[data-table='+ tableId +']').html(count_string); }, replacer: function(match, attribute, offset, string){ return Tabulatr.currentData[attribute]; }, makeAction: function(action, data){ Tabulatr.currentData = data; return unescape(action).replace(/{{([\w:]+)}}/g, Tabulatr.replacer); }, submitFilterForm: function(tableId){ if($('.pagination[data-table='+ tableId +']').length == 0){ $('.pagination_trigger[data-table='+ tableId +']').unbind('inview', cbfn); $('.pagination_trigger[data-table='+ tableId +']').bind('inview', cbfn); } Tabulatr.updateTable({page: 1, append: false}, tableId, true); return false; }, createParameterString: function(hash, tableId){ var tableName = tableId.split('_')[0]; if(hash === undefined){ hash = {}; hash.append = false; } if(hash.pagesize === undefined){ var pagesize = $('table#'+ tableId).data('pagesize'); if(pagesize == null) { console.log('Tabulatr: No pagesize specified') } } if(hash.page === undefined){ hash.page = Math.floor($('#'+ tableId +' tbody tr[class!=empty_row]').length/pagesize) + 1; if(!isFinite(hash.page)){ hash.page = 1; } } hash.pagesize = pagesize; hash.arguments = $.map($('#'+ tableId +' th'), function(n){ return $(n).data('tabulatr-column-name') }).filter(function(n){return n}).join(); hash.table_id = tableId; hash[tableName + '_search'] = $('input#'+ tableName +'_fuzzy_search_query').val(); var form_array = $('.tabulatr_filter_form[data-table="'+ tableId +'"]') .find('input:visible,select:visible,input[type=hidden]').serializeArray(); for(var i = 0; i < form_array.length; i++){ hash[form_array[i].name] = form_array[i].value; } return hash; }, localDate: function(value, $td, $tr, obj){ return new Date(value).toLocaleString(); } } $(document).on('ready page:load', function(){ $('th.tabulatr-sortable').click(function(){ var th = $(this); var sort_by = th.data('tabulatr-column-name'); var dir = th.attr('data-sorted'); var table = th.parents('table'); var tableId = table.attr('id'); var tableName = tableId.split('_')[0]; table.find('th.tabulatr-sortable.sorted').removeClass('sorted').removeAttr('data-sorted'); dir = (dir === 'asc') ? 'desc' : 'asc'; th.addClass('sorted').attr('data-sorted', dir); $('.tabulatr_filter_form[data-table='+ tableId +'] input[name='+ tableName +'_sort]').val(sort_by + ' '+ dir); if(!Tabulatr.moreResults){ Tabulatr.moreResults = true; if($('.pagination[data-table='+ tableId +']').length == 0){ $('.pagination_trigger[data-table='+ tableId +']').bind('inview', cbfn); } } $($(this).parents('table').find('tbody tr')).remove(); $('.tabulatr_mark_all[data-table='+ tableName +']').prop('checked', false).prop('indeterminate', false); Tabulatr.updateTable({}, tableId); }); var cbfn = function(event, isInView, visiblePartX, visiblePartY) { if (isInView) { // element is now visible in the viewport if (visiblePartY == 'top') { // top part of element is visible } else if (visiblePartY == 'bottom') { // bottom part of element is visible } else { Tabulatr.updateTable({append: true}, $(event.currentTarget).data('table')); } } }; $('.tabulatr_table').each(function(ix, el){ if($('.pagination[data-table='+ $(el).attr('id') +']').length == 0){ $('.pagination_trigger[data-table='+ $(el).attr('id') +']').bind('inview', cbfn); } }); $('.batch-action-inputs').click(function(){ var a = $(this); var name = a.data('do-batch-action-name'); var key = a.data('do-batch-action'); var tableId = a.data('table-id'); var params = {page: 1}; params[name] = key; params['tabulatr_checked'] = {checked_ids: jQuery.map($('#'+ tableId +' .tabulatr-checkbox:checked'), function(el){return $(el).val();}).join(',')}; $('.tabulatr_mark_all[data-table='+ tableId +']').prop('indeterminate', false).prop('checked', false); $('#'+ tableId +' .tabulatr-wrench').addClass('disabled'); Tabulatr.updateTable(params, tableId, true); }); $('form.tabulatr-fuzzy-search').submit(function(){ var tableId = $(this).data('table'); if($('.pagination[data-table='+ tableId +']').length == 0){ $('.pagination_trigger[data-table='+ tableId +']').unbind('inview', cbfn); $('.pagination_trigger[data-table='+ tableId +']').bind('inview', cbfn); } Tabulatr.updateTable({page: 1, append: false}, tableId, true); return false; }); $('form.tabulatr_filter_form').submit(function(ev){ var tableId = $(this).data('table'); Tabulatr.submitFilterForm(tableId); return false; }); $('.tabulatr_table').on('click', 'i.tabulatr_remove_filter', function(){ var $th = $(this).closest('th'); var name = $th.data('tabulatr-form-name'). replace(/\[(like|checkbox|from|to)\]/, ''); name = name.replace(/(:|\.|\[|\])/g,'\\$1'); $th.removeClass('tabulatr_filtered_column'); if($('[name^='+ name +']').is(':checkbox')){ $('[name^='+ name +']').prop('checked', false); }else{ $('[name^='+ name +']').val(''); } var tableId = $(this).closest('.tabulatr_table').attr('id'); $(this).remove(); if($('.pagination[data-table='+ tableId +']').length == 0){ $('.pagination_trigger[data-table='+ tableId +']').bind('inview', cbfn); } Tabulatr.updateTable({}, tableId); return false; }); $('.tabulatr_mark_all').click(function(){ var tableId = $(this).data('table'); if($(this).is(':checked')){ $('#'+ tableId +' tr[data-page]:visible input[type=checkbox]').prop('checked', true); $('#'+ tableId +' .tabulatr-wrench').removeClass('disabled'); }else{ $('#'+ tableId +' tr[data-page]:visible input[type=checkbox]').prop('checked', false); if(Tabulatr.checkIfCheckboxesAreMarked()){ $('#'+ tableId +' .tabulatr-wrench').removeClass('disabled'); }else{ $('#'+ tableId +' .tabulatr-wrench').addClass('disabled'); } } }); $('.tabulatr_table').on('click', 'input.tabulatr-checkbox', function(){ var tableId = $(this).closest('.tabulatr_table').attr('id'); if($(this).is(':checked')){ if($('#'+ tableId +' tr[data-page]:visible input[type=checkbox]').not(':checked').length > 0){ $('.tabulatr_mark_all[data-table='+ tableId +']').prop("indeterminate", true); }else{ $('.tabulatr_mark_all[data-table='+ tableId +']').prop('indeterminate', false); $('.tabulatr_mark_all[data-table='+ tableId +']').prop('checked', true); } $('#'+ tableId +' .tabulatr-wrench').removeClass('disabled'); }else{ if($('#'+ tableId +' tr[data-page]:visible input[type=checkbox]:checked').length > 0){ $('.tabulatr_mark_all[data-table='+ tableId +']').prop('indeterminate', true); $('#'+ tableId +' .tabulatr-wrench').removeClass('disabled'); }else{ $('.tabulatr_mark_all[data-table='+ tableId +']').prop('indeterminate', false); $('.tabulatr_mark_all[data-table='+ tableId +']').prop('checked', false); if(Tabulatr.checkIfCheckboxesAreMarked()){ $('#'+ tableId +' .tabulatr-wrench').removeClass('disabled'); }else{ $('#'+ tableId +' .tabulatr-wrench').addClass('disabled'); } } } }); $('.tabulatr-per-page a').click(function(){ if($(this).hasClass('active')){ return false; } $(this).closest('div').find('a').removeClass('active'); $(this).addClass('active'); var tableId = $(this).closest('div').data('table'); Tabulatr.moreResults = true; if($('.pagination[data-table='+ tableId +']').length == 0){ $('.pagination_trigger[data-table='+ tableId +']').bind('inview', cbfn); } if(typeof(Storage) !== undefined){ localStorage.tabulatr_page_display_count = $(this).data('items-per-page'); } Tabulatr.updateTable({page: 1}, tableId, true); }); if($('.tabulatr_table').length > 0){ if(typeof(Storage) !== undefined){ var count = localStorage.tabulatr_page_display_count; if(count !== undefined){ $('.tabulatr-per-page a').removeClass('active'); $('.tabulatr-per-page a[data-items-per-page='+ count +']'). addClass('active'); } } $('.tabulatr_table').each(function(ix, el){ Tabulatr.updateTable({}, $(el).attr('id')); }); } }); $(document).on('click', '.pagination a', function(){ var a = $(this); if(a.parent().hasClass('active') || a.parent().hasClass('disabled')){ return; } var tableId = $(a).closest('.pagination').data('table'); $('.tabulatr_mark_all[data-table='+ tableId +']').prop('checked', false); $('.tabulatr_mark_all[data-table='+ tableId +']').prop('indeterminate', false); Tabulatr.updateTable({append: false, page: a.data('page')}, tableId); return false; }); // TODO: We absolutely need to clean that up! $(document).on('click', 'a[data-show-table-filter]', function(){ var a = $(this); var nam = a.data('show-table-filter'); $('div[data-filter-column-name="'+nam+'"]').show('blind'); $('div[data-filter-column-name="_submit"]').show('blind'); a.hide(); return false; }) $(document).on('click', 'a[data-hide-table-filter]', function(){ var a = $(this); var nam = a.data('hide-table-filter'); var t = $('div[data-filter-column-name="'+nam+'"]'); t.hide('blind'); t.find('input[type=text]').val(""); $('a[data-show-table-filter="'+nam+'"]').show(); if ($('div[data-filter-column-name]:visible').length <= 2) $('div[data-filter-column-name="_submit"]').hide('blind'); var tableId = $(this).parents('form').data('table'); Tabulatr.submitFilterForm(tableId); return false; }) $(document).on('change', 'select[data-tabulatr-date-filter]', function() { var select = $(this); var option = select.find('option:selected'); var val = option.val(); if (val === 'from_to') { select.parents('.controls').find(".from_to").show().removeClass('hidden'); } else { select.parents('.controls').find(".from_to").hide().val(''); } });