mambax7/alumni-26x

View on GitHub
media/jquery/tablesorter-master/js/widgets/widget-filter-formatter-html5.js

Summary

Maintainability
F
6 days
Test Coverage
/*! Widget: filter, html5 formatter functions - updated 7/17/2014 (v2.17.5) *//*
 * requires: tableSorter (FORK) 2.15+ and jQuery 1.4.3+
 *
 * html5Number (spinner)
 * html5Range (slider)
 * html5Color (color)
 */
/*jshint browser:true, jquery:true, unused:false */
/*global jQuery: false */
;(function($){
    'use strict';

    var ts = $.tablesorter || {},

    // compare option selector class name (jQuery selector)
    compareSelect = '.compare-select',

    tsff = ts.filterFormatter = $.extend( {}, ts.filterFormatter, {

        addCompare: function($cell, indx, options){
            if (options.compare && $.isArray(options.compare) && options.compare.length > 1) {
                var opt = '',
                    compareSelectClass = [ compareSelect.slice(1), ' ' + compareSelect.slice(1), '' ],
                    txt = options.cellText ? '<label class="' + compareSelectClass.join('-label') + indx + '">' + options.cellText + '</label>' : '';
                $.each(options.compare, function(i, c){
                    opt += '<option ' + (options.selected === i ? 'selected' : '') + '>' + c + '</option>';
                });
                $cell
                    .wrapInner('<div class="' + compareSelectClass.join('-wrapper') + indx + '" />')
                    .prepend( txt + '<select class="' + compareSelectClass.join('') + indx + '" />' )
                    .find('select')
                    .append(opt);
            }
        },

        updateCompare : function($cell, $input, o) {
            var val = $input.val() || '',
                num = val.replace(/\s*?[><=]\s*?/g, ''),
                compare = val.match(/[><=]/g) || '';
            if (o.compare) {
                if ($.isArray(o.compare)){
                    compare = (compare || []).join('') || o.compare[o.selected || 0];
                }
                $cell.find(compareSelect).val( compare );
            }
            return [ val, num ];
        },

        /**********************\
        HTML5 Number (spinner)
        \**********************/
        html5Number : function($cell, indx, def5Num) {
            var t, o = $.extend({
                value : 0,
                min : 0,
                max : 100,
                step : 1,
                delayed : true,
                disabled : false,
                addToggle : false,
                exactMatch : false,
                cellText : '',
                compare : '',
                skipTest: false
            }, def5Num),

            $input,
            // test browser for HTML5 range support
            $number = $('<input type="number" style="visibility:hidden;" value="test">').appendTo($cell),
            // test if HTML5 number is supported - from Modernizr
            numberSupported = o.skipTest || $number.attr('type') === 'number' && $number.val() !== 'test',
            $shcell = [],
            c = $cell.closest('table')[0].config,

            updateNumber = function(delayed, notrigger){
                var chkd = o.addToggle ? $cell.find('.toggle').is(':checked') : true,
                    v = $cell.find('.number').val(),
                    compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
                    searchType = c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) || '' : true;
                $input
                    // add equal to the beginning, so we filter exact numbers
                    .val( !o.addToggle || chkd ? (compare ? compare : o.exactMatch ? '=' : '') + v : '' )
                    .trigger( notrigger ? '' : 'search', searchType ).end()
                    .find('.number').val(v);
                if ($cell.find('.number').length) {
                    $cell.find('.number')[0].disabled = (o.disabled || !chkd);
                }
                // update sticky header cell
                if ($shcell.length) {
                    $shcell.find('.number').val(v)[0].disabled = (o.disabled || !chkd);
                    $shcell.find(compareSelect).val(compare);
                    if (o.addToggle) {
                        $shcell.find('.toggle')[0].checked = chkd;
                    }
                }
            };
            $number.remove();

            if (numberSupported) {
                t = o.addToggle ? '<div class="button"><input id="html5button' + indx + '" type="checkbox" class="toggle" />' +
                    '<label for="html5button' + indx + '"></label></div>' : '';
                t += '<input class="number" type="number" min="' + o.min + '" max="' + o.max + '" value="' +
                    o.value + '" step="' + o.step + '" />';
                // add HTML5 number (spinner)
                $cell
                    .append(t + '<input type="hidden" />')
                    .find('.toggle, .number').bind('change', function(){
                        updateNumber();
                    })
                    .closest('thead').find('th[data-column=' + indx + ']')
                    .addClass('filter-parsed') // get exact numbers from column
                    // on reset
                    .closest('table').bind('filterReset', function(){
                        if ($.isArray(o.compare)) {
                            $cell.add($shcell).find(compareSelect).val( o.compare[ o.selected || 0 ] );
                        }
                        // turn off the toggle checkbox
                        if (o.addToggle) {
                            $cell.find('.toggle')[0].checked = false;
                            if ($shcell.length) {
                                $shcell.find('.toggle')[0].checked = false;
                            }
                        }
                        $cell.find('.number').val( o.value );
                        setTimeout(function(){
                            updateNumber();
                        }, 0);
                    });
                $input = $cell.find('input[type=hidden]').bind('change', function(){
                    $cell.find('.number').val( this.value );
                    updateNumber();
                });

                // update slider from hidden input, in case of saved filters
                c.$table.bind('filterFomatterUpdate', function(){
                    var val = tsff.updateCompare($cell, $input, o)[0] || o.value;
                    $cell.find('.number').val( ((val || '') + '').replace(/[><=]/g, '') );
                    updateNumber(false, true);
                    ts.filter.formatterUpdated($cell, indx);
                });

                if (o.compare) {
                    // add compare select
                    tsff.addCompare($cell, indx, o);
                    $cell.find(compareSelect).bind('change', function(){
                        updateNumber();
                    });
                }

                // has sticky headers?
                c.$table.bind('stickyHeadersInit', function(){
                    $shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
                    $shcell
                        .append(t)
                        .find('.toggle, .number').bind('change', function(){
                            $cell.find('.number').val( $(this).val() );
                            updateNumber();
                        });

                    if (o.compare) {
                        // add compare select
                        tsff.addCompare($shcell, indx, o);
                        $shcell.find(compareSelect).bind('change', function(){
                            $cell.find(compareSelect).val( $(this).val() );
                            updateNumber();
                        });
                    }

                    updateNumber();
                });

                updateNumber();

            }

            return numberSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
        },

        /**********************\
        HTML5 range slider
        \**********************/
        html5Range : function($cell, indx, def5Range) {
            var o = $.extend({
                value : 0,
                min : 0,
                max : 100,
                step : 1,
                delayed : true,
                valueToHeader : true,
                exactMatch : true,
                cellText : '',
                compare : '',
                allText : 'all',
                skipTest : false
            }, def5Range),

            $input,
            // test browser for HTML5 range support
            $range = $('<input type="range" style="visibility:hidden;" value="test">').appendTo($cell),
            // test if HTML5 range is supported - from Modernizr (but I left out the method to detect in Safari 2-4)
            // see https://github.com/Modernizr/Modernizr/blob/master/feature-detects/inputtypes.js
            rangeSupported = o.skipTest || $range.attr('type') === 'range' && $range.val() !== 'test',
            $shcell = [],
            c = $cell.closest('table')[0].config,

            updateRange = function(v, delayed, notrigger){
                /*jshint eqeqeq:false */
                // hidden input changes may include compare symbols
                v = ( typeof v === 'undefined' ? $input.val() : v ).toString().replace(/[<>=]/g, '') || o.value;
                var compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '',
                    t = ' (' + (compare ? compare + v : v == o.min ? o.allText : v) + ')',
                    searchType =  c.$table[0].hasInitialized ? (delayed ? delayed : o.delayed) || '' : true;
                $cell.find('input[type=hidden]')
                    // add equal to the beginning, so we filter exact numbers
                    .val( ( compare ? compare + v : ( v == o.min ? '' : ( o.exactMatch ? '=' : '' ) + v ) ) )
                    // ( val == o.min ? '' : val + (o.exactMatch ? '=' : ''))
                    .trigger( notrigger ? '' : 'search', searchType ).end()
                    .find('.range').val(v);
                // or add current value to the header cell, if desired
                $cell.closest('thead').find('th[data-column=' + indx + ']').find('.curvalue').html(t);
                // update sticky header cell
                if ($shcell.length) {
                    $shcell
                        .find('.range').val(v).end()
                        .find(compareSelect).val( compare );
                    $shcell.closest('thead').find('th[data-column=' + indx + ']').find('.curvalue').html(t);
                }
            };
            $range.remove();

            if (rangeSupported) {
                // add HTML5 range
                $cell
                    .html('<input type="hidden"><input class="range" type="range" min="' + o.min + '" max="' + o.max + '" value="' + o.value + '" />')
                    .closest('thead').find('th[data-column=' + indx + ']')
                    .addClass('filter-parsed') // get exact numbers from column
                    // add span to header for the current slider value
                    .find('.tablesorter-header-inner').append('<span class="curvalue" />');
                // hidden filter update namespace trigger by filter widget
                $input = $cell.find('input[type=hidden]').bind('change' + c.namespace + 'filter', function(){
                    /*jshint eqeqeq:false */
                    var v = this.value,
                        compare = ($.isArray(o.compare) ? $cell.find(compareSelect).val() || o.compare[ o.selected || 0] : o.compare) || '';
                    if (v !== this.lastValue) {
                        this.lastValue = ( compare ? compare + v : ( v == o.min ? '' : ( o.exactMatch ? '=' : '' ) + v ) );
                        this.value = this.lastValue;
                        updateRange( v );
                    }
                });

                $cell.find('.range').bind('change', function(){
                    updateRange( this.value );
                });

                // update spinner from hidden input, in case of saved filters
                c.$table.bind('filterFomatterUpdate', function(){
                    var val = tsff.updateCompare($cell, $input, o)[0];
                    $cell.find('.range').val( val );
                    updateRange(val, false, true);
                    ts.filter.formatterUpdated($cell, indx);
                });

                if (o.compare) {
                    // add compare select
                    tsff.addCompare($cell, indx, o);
                    $cell.find(compareSelect).bind('change', function(){
                        updateRange();
                    });
                }

                // has sticky headers?
                c.$table.bind('stickyHeadersInit', function(){
                    $shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx).empty();
                    $shcell
                        .html('<input class="range" type="range" min="' + o.min + '" max="' + o.max + '" value="' + o.value + '" />')
                        .find('.range').bind('change', function(){
                            updateRange( $shcell.find('.range').val() );
                        });
                    updateRange();

                    if (o.compare) {
                        // add compare select
                        tsff.addCompare($shcell, indx, o);
                        $shcell.find(compareSelect).bind('change', function(){
                            $cell.find(compareSelect).val( $(this).val() );
                            updateRange();
                        });
                    }

                });

                // on reset
                $cell.closest('table').bind('filterReset', function(){
                    if ($.isArray(o.compare)) {
                        $cell.add($shcell).find(compareSelect).val( o.compare[ o.selected || 0 ] );
                    }
                    setTimeout(function(){
                        updateRange(o.value, false, true);
                    }, 0);
                });
                updateRange();

            }

            return rangeSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
        },

        /**********************\
        HTML5 Color picker
        \**********************/
        html5Color: function($cell, indx, defColor) {
            var t, o = $.extend({
                value : '#000000',
                disabled : false,
                addToggle : true,
                exactMatch : true,
                valueToHeader : false,
                skipTest : false
            }, defColor),
            $input,
            // Add a hidden input to hold the range values
            $color = $('<input type="color" style="visibility:hidden;" value="test">').appendTo($cell),
            // test if HTML5 color is supported - from Modernizr
            colorSupported = o.skipTest || $color.attr('type') === 'color' && $color.val() !== 'test',
            $shcell = [],
            c = $cell.closest('table')[0].config,

            updateColor = function(v, notrigger) {
                v = ( typeof v === 'undefined' ? $input.val() : v ).toString().replace('=', '') || o.value;
                var chkd = true,
                    t = ' (' + v + ')';
                if (o.addToggle) {
                    chkd = $cell.find('.toggle').is(':checked');
                }
                if ($cell.find('.colorpicker').length) {
                    $cell.find('.colorpicker').val(v)[0].disabled = (o.disabled || !chkd);
                }

                $input
                    .val( chkd ? v + (o.exactMatch ? '=' : '') : '' )
                    .trigger( !c.$table[0].hasInitialized || notrigger ? '' : 'search' );
                if (o.valueToHeader) {
                    // add current color to the header cell
                    $cell.closest('thead').find('th[data-column=' + indx + ']').find('.curcolor').html(t);
                } else {
                    // current color to span in cell
                    $cell.find('.currentColor').html(t);
                }

                // update sticky header cell
                if ($shcell.length) {
                    $shcell.find('.colorpicker').val(v)[0].disabled = (o.disabled || !chkd);
                    if (o.addToggle) {
                        $shcell.find('.toggle')[0].checked = chkd;
                    }
                    if (o.valueToHeader) {
                        // add current color to the header cell
                        $shcell.closest('thead').find('th[data-column=' + indx + ']').find('.curcolor').html(t);
                    } else {
                        // current color to span in cell
                        $shcell.find('.currentColor').html(t);
                    }
                }
            };
            $color.remove();

            if (colorSupported) {
                t = '' + indx + Math.round(Math.random() * 100);
                // add HTML5 color picker
                t = '<div class="color-controls-wrapper">' +
                    (o.addToggle ? '<div class="button"><input id="colorbutton' + t + '" type="checkbox" class="toggle" /><label for="colorbutton' +
                    t + '"></label></div>' : '') +
                    '<input type="hidden"><input class="colorpicker" type="color" />' +
                    (o.valueToHeader ? '' : '<span class="currentColor">(#000000)</span>') + '</div>';
                $cell.html(t);
                // add span to header for the current color value - only works if the line in the updateColor() function is also un-commented out
                if (o.valueToHeader) {
                    $cell.closest('thead').find('th[data-column=' + indx + ']').find('.tablesorter-header-inner').append('<span class="curcolor" />');
                }

                $cell.find('.toggle, .colorpicker').bind('change', function(){
                    updateColor( $cell.find('.colorpicker').val() );
                });

                // hidden filter update namespace trigger by filter widget
                $input = $cell.find('input[type=hidden]').bind('change' + c.namespace + 'filter', function(){
                    updateColor( this.value );
                });

                // update slider from hidden input, in case of saved filters
                c.$table.bind('filterFomatterUpdate', function(){
                    updateColor( $input.val(), true );
                    ts.filter.formatterUpdated($cell, indx);
                });

                // on reset
                $cell.closest('table').bind('filterReset', function(){
                    // just turn off the colorpicker
                    if (o.addToggle) {
                        $cell.find('.toggle')[0].checked = false;
                    }
                    // delay needed because default color needs to be set in the filter
                    // there is no compare option here, so if addToggle = false,
                    // default color is #000000 (even with no value set)
                    setTimeout(function(){
                        updateColor();
                    }, 0);
                });

                // has sticky headers?
                c.$table.bind('stickyHeadersInit', function(){
                    $shcell = c.widgetOptions.$sticky.find('.tablesorter-filter-row').children().eq(indx);
                    $shcell
                        .html(t)
                        .find('.toggle, .colorpicker').bind('change', function(){
                            updateColor( $shcell.find('.colorpicker').val() );
                        });
                    updateColor( $shcell.find('.colorpicker').val() );
                });

                updateColor( o.value );
            }
            return colorSupported ? $cell.find('input[type="hidden"]') : $('<input type="search">');
        }

    });

})(jQuery);