(function( $ ){ 'use strict'; var element, callbacks = {}, resultsTitle, resultsDivID; var methods = { setup : function(options){ element = this; // set element for build_containers() if (options.callbacks) callbacks = options.callbacks; if(options.resultsDivID){ resultsDivID = options.resultsDivID; } else { resultsDivID = 'results'; } if (options.url !== undefined) methods.process_from_url(options); else methods.process(options); }, process : function(options){ if (callbacks.beforePopulate) { callbacks.beforePopulate(); }; var self = methods; pivot.init(options); resultsTitle = options.resultsTitle; if (options.skipBuildContainers === undefined || options.skipBuildContainers === false) self.build_containers(); self.populate_containers(); $(document).on('change', '.row-labelable', function(event) { self.update_label_fields('row'); }); $(document).on('change', '.column-labelable', function(event) { self.update_label_fields('column'); }); $(document).on('change', '.summary', function(event) { self.update_summary_fields(); }); methods.update_results(); if (callbacks.afterPopulate) { callbacks.afterPopulate(); }; }, process_from_url : function(options){ var re = /\.json$/i, dataType; if (re.test(options.url)) dataType = 'text/json' else dataType = 'text/csv' $.ajax({ url: options.url, dataType: "text", accepts: "text/csv", success: function(data, status){ if (dataType === 'text/json') options['json'] = data else options['csv'] = data methods.process(options) } }); }, populate_containers: function(){ methods.build_toggle_fields('#row-label-fields', pivot.fields().rowLabelable, 'row-labelable'); methods.build_toggle_fields('#column-label-fields', pivot.fields().columnLabelable, 'column-labelable'); methods.build_toggle_fields('#summary-fields', pivot.fields().summarizable, 'summary'); methods.build_filter_list(); }, reprocess_display : function(options){ if (options.rowLabels === undefined) options.rowLabels = []; if (options.columnLabels === undefined) options.columnLabels = []; if (options.summaries === undefined) options.summaries = []; if (options.filters === undefined) options.filters = {}; if (options.callbacks === undefined) options.callbacks = {}; if (options.callbacks.beforeReprocessDisplay) { options.callbacks.afterReprocessDisplay(); } pivot.filters().set(options.filters); pivot.display().summaries().set(options.summaries); pivot.display().rowLabels().set(options.rowLabels); pivot.display().columnLabels().set(options.columnLabels); methods.populate_containers(); methods.update_results(); if (options.callbacks.afterReprocessDisplay) { options.callbacks.afterReprocessDisplay(); } }, build_containers : function(){ var containers = '
' + '
' + ' Filter Fields' + '
' + '
' + '
' + ' Row Label Fields' + '
' + '
' + '
' + ' Column Label Fields' + '
' + '
' + '
' + ' Summary Fields' + '
' + '
' + '
'; $(element).append(containers); }, // Filters build_filter_list : function(){ var select = '' $('#filter-list').empty().append(select); // show pre-defined filters (from init) $.each(pivot.filters().all(), function(fieldName, restriction){ methods.build_filter_field(fieldName, restriction); }); // Bind build action to select-constructor explicitly $('#select-constructor').change(function(){ methods.build_filter_field($(this).val()); }) }, build_filter_field : function(fieldName, selectedValue) { var snip, remove_filter, field = pivot.fields().get(fieldName); if (fieldName === '') return; // Check to see if this field has already been built var filterExists = $('#filter-list select[data-field="' + field.name + '"]'); if (filterExists.length) return; if (field.filterType === 'regexp') snip = methods.build_regexp_filter_field(field, selectedValue); else snip = methods.build_select_filter_field(field, selectedValue); remove_filter = '(X)'; $('#filter-list').append('

'); //Optional Chosen/Select2 integration if($.fn.chosen!==undefined) $('select.filter').chosen(); else if($.fn.select2!==undefined) $('select.filter').select2(); // Update field listeners $('select.filter').on('change', function(event) { methods.update_filtered_rows(); }); $('input[type=text].filter').on('keyup', function(event) { var filterInput = this, eventValue = $(filterInput).val(); setTimeout(function(){ if ($(filterInput).val() === eventValue) methods.update_filtered_rows()}, 500); }); // remove_filter listener $('.remove-filter-field').click(function(){ $(this).parents('div').first().remove(); methods.update_filtered_rows(); }) }, build_select_filter_field : function(field, selectedValue){ var snip = '' return snip; }, build_regexp_filter_field : function(field, value){ if (value === undefined) value = ""; return ''; }, update_filtered_rows : function(){ var restrictions = {}, field; $('.filter').each(function(index){ field = pivot.fields().get($(this).attr('data-field')); if (field) { if ($(this).val() !== null && $(this).val()[0] !== ''){ if (field.filterType === 'regexp') restrictions[$(this).attr('data-field')] = new RegExp($(this).val(),'i'); else restrictions[$(this).attr('data-field')] = $(this).val(); } } }); pivot.filters().set(restrictions); methods.update_results(); }, //toggles build_toggle_fields : function(div, fields, klass){ $(div).empty(); $.each(fields, function(index, field){ $(div).append(''); }); var displayFields; if (klass === 'row-labelable') displayFields = pivot.display().rowLabels().get else if (klass === 'column-labelable') displayFields = pivot.display().columnLabels().get else displayFields = pivot.display().summaries().get for (var fieldName in displayFields) { var elem = $(div + ' input[data-field="' + fieldName +'"]'); elem.prop("checked", true); methods.orderChecked(div, elem); }; // order listener $(div + ' input').on("click", function(){ if (this.checked) { methods.orderChecked(div, this); } else { var field = $(this).parent().detach()[0]; $(div).append( field ); }; }); }, orderChecked : function(parent, elem){ var last_checked = $(parent + ' input:checked'); // last changed field (lcf) var field = $(elem).parent().detach()[0]; // pluck item from div var children = $(parent).children(); //subtract 1 because clicked field is already checked insert plucked item into div at index if ((last_checked.length-1) === 0) $(parent).prepend( field ); else if (children.length < last_checked.length) $(parent).append( field ); else $(children[last_checked.length-1]).before( field ); }, update_result_details : function(){ var snip = ''; var filters = ''; $.each(pivot.filters().all(), function(k,v) { filters += '' + k + '' + " => " + v + " " }); if ($('#pivot-detail').length !== 0) snip += 'Filters: ' + filters + "
" $('#pivot-detail').html(snip); }, update_results : function(){ if (callbacks && callbacks.beforeUpdateResults) { callbacks.beforeUpdateResults(); }; var results = pivot.results().all(), config = pivot.config(), columns = pivot.results().columns(), snip = '', fieldName; var result_table = $('#' + resultsDivID), result_rows; result_table.empty(); snip += ''; // build columnLabel header row if (config.columnLabels.length > 0 && config.summaries.length > 1) { var summarySnip = '', summaryRow = ''; $.each(config.summaries, function(index, fieldName){ summarySnip += ''; }) snip += '' $.each(columns, function(index, column){ switch (column.type){ case 'row': snip += ''; break; case 'column': snip += ''; summaryRow += summarySnip break; } }); snip += '' + summaryRow + ''; } else { snip += '' $.each(columns, function(index, column){ if (column.type !== 'column' || config.summaries.length <= 1) { snip += ''; } else { $.each(config.summaries, function(index, fieldName){ snip += ''; }); } }); snip += '' } snip += '
' + fieldName + '
'+ column.fieldName + '' + column.fieldName + '
' + column.fieldName + '' + fieldName + '
'; result_table.append(snip); result_rows = $('#result-rows'); $.each(results,function(index, row){ snip = ''; $.each(columns, function(index, column){ if (column.type !== 'column') snip += '' + row[column.fieldName] + ''; else { $.each(config.summaries, function(index, fieldName){ if (row[column.fieldName] !== undefined) snip += '' + row[column.fieldName][fieldName] + ''; else snip += ' '; }); } }); snip += ''; result_rows.append(snip); }); methods.update_result_details(); if (callbacks && callbacks.afterUpdateResults) { callbacks.afterUpdateResults(); }; }, update_label_fields : function(type){ var display_fields = []; $('.' + type + '-labelable:checked').each(function(index){ display_fields.push($(this).attr('data-field')); }); pivot.display()[type + 'Labels']().set(display_fields); methods.update_results(); }, update_summary_fields : function(){ var summary_fields = []; $('.summary:checked').each(function(index){ summary_fields.push($(this).attr('data-field')); }); pivot.display().summaries().set(summary_fields); methods.update_results(); } }; $.fn.pivot_display = function( method ) { if ( methods[method] ) { return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); } else if ( typeof method === 'object' || ! method ) { return methods.init.apply( this, arguments ); } else { $.error( 'Method ' + method + ' doesn\'t exists'); } }; })( jQuery );