// 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. function Tabulatr(id){ this.id = id; this.name = ''; this.moreResults = true; this.currentData = null; this.locked = false; } var tabulatr_tables; Tabulatr.prototype = { constructor: Tabulatr, createPaginationListItem: function(page, active){ var $page = $('
  • '+ page +'
  • '); if(active){ $page.addClass('active'); } return $page; }, updatePagination: function(currentPage, numPages){ var $paginatorUl = $('.pagination[data-table='+ this.id +'] > ul'); $paginatorUl.html(''); if(numPages < 13){ for(var i = 1; i <= numPages; i++){ $paginatorUl.append(this.createPaginationListItem(i, (i == currentPage))); } }else{ if(currentPage > 1){ $paginatorUl.append(this.createPaginationListItem(1, false)); } var between = Math.floor((1 + currentPage) / 2); if(between > 1 && between < currentPage - 2){ $paginatorUl.append('
  • ...
  • '); $paginatorUl.append(this.createPaginationListItem(between, false)); } if(currentPage > 4){ $paginatorUl.append('
  • ...
  • '); } if(currentPage > 3){ $paginatorUl.append(this.createPaginationListItem(currentPage-2, false)); $paginatorUl.append(this.createPaginationListItem(currentPage-1, false)); } $paginatorUl.append(this.createPaginationListItem(currentPage, true)); if(currentPage < numPages - 1){ $paginatorUl.append(this.createPaginationListItem(currentPage+1, false)); } if(currentPage < numPages - 2){ $paginatorUl.append(this.createPaginationListItem(currentPage+2, false)); } if(currentPage < numPages - 3){ $paginatorUl.append('
  • ...
  • '); } between = Math.floor((currentPage + numPages) / 2); if(between > currentPage + 3 && between < numPages - 1){ $paginatorUl.append(this.createPaginationListItem(between, false)); $paginatorUl.append('
  • ...
  • '); } if(currentPage < numPages){ $paginatorUl.append(this.createPaginationListItem(numPages, false)); } } }, updateTable: function(hash, forceReload) { var $table = $('#'+ this.id); if(hash.page !== undefined && !forceReload){ //old page should be stored this.storePage = true; // check if this page was already loaded $table.find('tbody tr').hide(); if($table.find('tbody tr[data-page='+ hash.page +']').length > 0){ $table.find('tbody tr[data-page='+ hash.page +']').show(); this.updatePagination(hash.page, $('.pagination[data-table='+ this.id +'] a:last').data('page'), this.id); return; } }else{ this.storePage = false; } if(this.locked){ return; } this.locked = true; var curTable = this; this.showLoadingSpinner(); $.ajax({ context: this, type: 'GET', url: $('table#'+ this.id).data('path') + '.json', data: this.createParameterString(hash, this.id), success: this.handleResponse, complete: this.hideLoadingSpinner }); }, checkIfCheckboxesAreMarked: function(){ return $('tr[data-page] input[type=checkbox]:checked').length > 0; }, currentCount: function(){ return $('#'+ this.id +' tbody tr.tabulatr-row').length; }, handleResponse: function(response) { this.insertTabulatrData(response); this.updatePagination(response.meta.page, response.meta.pages, response.meta.table_id); this.locked = false; }, insertTabulatrData: function(response){ var tableId = response.meta.table_id; var tbody = $('#'+ tableId +' tbody'); if(!response.meta.append){ if(this.storePage){ $('#'+ tableId +' tbody tr').hide(); }else{ $('#'+ tableId +' tbody').html(''); } } if(response.data.length === 0){ this.moreResults = false; $('.pagination_trigger[data-table='+ tableId +']').unbind('inview'); }else{ if(this.currentCount() + response.data.length >= response.meta.count){ this.moreResults = false; $('.pagination_trigger[data-table='+ tableId + ']').unbind('inview'); } // 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'); if(data._row_config.data){ tr.data(data._row_config.data); delete data._row_config.data; } tr.attr(data._row_config); 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 this.currentData[attribute]; }, makeAction: function(action, data){ this.currentData = data; return unescape(action).replace(/{{([\w:]+)}}/g, this.replacer); }, submitFilterForm: function(){ if($('.pagination[data-table='+ this.id +']').length === 0){ $('.pagination_trigger[data-table='+ this.id +']').unbind('inview', cbfn); $('.pagination_trigger[data-table='+ this.id +']').bind('inview', cbfn); } this.updateTable({page: 1, append: false}, true); return false; }, createParameterString: function(hash){ var tableName = this.id.split('_')[0]; if(hash === undefined){ hash = {}; hash.append = false; } var pagesize = hash.pagesize; if(pagesize === undefined){ pagesize = $('table#'+ this.id).data('pagesize'); } if(hash.page === undefined){ hash.page = Math.floor($('#'+ this.id +' tbody tr[class!=empty_row]').length/pagesize) + 1; if(!isFinite(hash.page)){ hash.page = 1; } } hash.pagesize = pagesize; hash.arguments = $.map($('#'+ this.id +' th'), function(n){ return $(n).data('tabulatr-column-name'); }).filter(function(n){return n; }).join(); hash.table_id = this.id; hash[tableName + '_search'] = $('input#'+ tableName +'_fuzzy_search_query').val(); var form_array = $('.tabulatr_filter_form[data-table="'+ this.id +'"]') .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(); }, showLoadingSpinner: function(){ $('.tabulatr-spinner-box[data-table='+ this.id +']').show(); }, hideLoadingSpinner: function(){ $('.tabulatr-spinner-box[data-table='+ this.id +']').hide(); } } $(document).on('ready page:load', function(){ tabulatr_tables = []; $('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 table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } var tableName = table_obj.id.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(!table_obj.moreResults){ table_obj.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); table_obj.updateTable({}); }); $('.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'); var table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } table_obj.updateTable(params, 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); } var table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } table_obj.updateTable({page: 1, append: false}, true); return false; }); $('form.tabulatr_filter_form').submit(function(){ var tableId = $(this).data('table'); var table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } table_obj.submitFilterForm(); 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); } var table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } table_obj.updateTable({}); return false; }); $('.tabulatr_mark_all').click(function(){ var tableId = $(this).data('table'); var table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } 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(table_obj.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'); var table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } 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(table_obj.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'); var table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } table_obj.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'); } table_obj.updateTable({page: 1}, true); }); if($('.tabulatr_table:not(".tabulatr_static_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'); } } var table_obj = undefined; $('.tabulatr_table:not(".tabulatr_static_table")').each(function(ix, el){ var tableId = $(el).attr('id'); tabulatr_tables.push(new Tabulatr(tableId)); for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } table_obj.updateTable({}); }); } }); $(document).on('click', '.pagination a', function(){ var a = $(this); if(a.parent().hasClass('active') || a.parent().hasClass('disabled')){ return false; } 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); var table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } table_obj.updateTable({append: false, page: a.data('page')}); return false; }); // TODO: We absolutely need to clean that up! $(document).on('click', 'a[data-show-table-filter]', function(){ var a = $(this); var name = a.data('show-table-filter'); $('div[data-filter-column-name="'+ name +'"]').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'); var table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } table_obj.submitFilterForm(); 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(''); } }); 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 { var tableId = $(event.currentTarget).data('table'); var table_obj = undefined; for(var i = 0; i < tabulatr_tables.length; i++){ if(tabulatr_tables[i].id == tableId){ table_obj = tabulatr_tables[i]; } } table_obj.updateTable({append: true}); } } };