commit/galaxy-central: carlfeberhard: Client build: modularize filter control plugin from ui.js
1 new commit in galaxy-central: https://bitbucket.org/galaxy/galaxy-central/commits/a667776c4a1b/ Changeset: a667776c4a1b User: carlfeberhard Date: 2014-12-08 20:12:58+00:00 Summary: Client build: modularize filter control plugin from ui.js Affected #: 3 files diff -r c600b74bc7ce2dc669e3c34b9b8fde3ddb5ce717 -r a667776c4a1bc13cf1645c9ddd5af8892cc32b28 client/galaxy/scripts/jq-plugins/ui/filter-control.js --- /dev/null +++ b/client/galaxy/scripts/jq-plugins/ui/filter-control.js @@ -0,0 +1,149 @@ +// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js +// Uses AMD or browser globals to create a jQuery plugin. +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else { + // Browser globals + factory(jQuery); + } + +}(function ($) { + /** + * Creates a three part bootstrap button group (key, op, value) meant to + * allow the user control of filters (e.g. { key: 'name', op: 'contains', value: 'my_history' }) + * + * Each field uses a dropDownSelect (from ui.js) to allow selection + * (with the 'value' field appearing as an input when set to do so). + * + * Any change or update in any of the fields will trigger a 'change.filter-control' + * event which will be passed an object containing those fields (as the example above). + * + * Pass in an array of possible filter objects to control what the user can select. + * Each filter object should have: + * key : generally the attribute name on which to filter something + * ops : an array of 1 or more filter operations (e.g. [ 'is', '<', 'contains', '!=' ]) + * values (optional) : an array of possible values for the filter (e.g. [ 'true', 'false' ]) + * @example: + * $( '.my-div' ).filterControl({ + * filters : [ + * { key: 'name', ops: [ 'is exactly', 'contains' ] } + * { key: 'deleted', ops: [ 'is' ], values: [ 'true', 'false' ] } + * ] + * }); + * // after initialization, you can prog. get the current value using: + * $( '.my-div' ).filterControl( 'val' ) + * + */ + function FilterControl( element, options ){ + return this.init( element, options ); + } + /** the data key that this object will be stored under in the DOM element */ + FilterControl.prototype.DATA_KEY = 'filter-control'; + + /** parses options, sets up instance vars, and does initial render */ + FilterControl.prototype.init = function _init( element, options ){ + options = options || { filters: [] }; + this.$element = $( element ).addClass( 'filter-control btn-group' ); + this.options = jQuery.extend( true, {}, this.defaults, options ); + + this.currFilter = this.options.filters[0]; + return this.render(); + }; + + /** render (or re-render) the controls on the element */ + FilterControl.prototype.render = function _render(){ + this.$element.empty() + .append([ this._renderKeySelect(), this._renderOpSelect(), this._renderValueInput() ]); + return this; + }; + + /** render the key dropDownSelect, bind a change event to it, and return it */ + FilterControl.prototype._renderKeySelect = function __renderKeySelect(){ + var filterControl = this; + var keys = this.options.filters.map( function( filter ){ + return filter.key; + }); + this.$keySelect = dropDownSelect( keys, this.currFilter.key ) + .addClass( 'filter-control-key' ) + .on( 'change.dropdown-select', function( event, selection ){ + filterControl.currFilter = _.findWhere( filterControl.options.filters, { key: selection }); + // when the filter/key changes, re-render the control entirely + filterControl.render()._triggerChange(); + }); + return this.$keySelect; + }; + + /** render the op dropDownSelect, bind a change event to it, and return it */ + FilterControl.prototype._renderOpSelect = function __renderOpSelect(){ + var filterControl = this, + ops = this.currFilter.ops; + //TODO: search for currOp in avail. ops: use that for selected if there; otherwise: first op + this.$opSelect = dropDownSelect( ops, ops[0] ) + .addClass( 'filter-control-op' ) + .on( 'change.dropdown-select', function( event, selection ){ + filterControl._triggerChange(); + }); + return this.$opSelect; + }; + + /** render the value control, bind a change event to it, and return it */ + FilterControl.prototype._renderValueInput = function __renderValueInput(){ + var filterControl = this; + // if a values attribute is prov. on the filter - make this a dropdown; otherwise, use an input + if( this.currFilter.values ){ + this.$valueSelect = dropDownSelect( this.currFilter.values, this.currFilter.values[0] ) + .on( 'change.dropdown-select', function( event, selection ){ + filterControl._triggerChange(); + }); + } else { + //TODO: allow setting a value type (mainly for which html5 input to use: range, number, etc.) + this.$valueSelect = $( '<input/>' ).addClass( 'form-control' ) + .on( 'change', function( event, value ){ + filterControl._triggerChange(); + }); + } + this.$valueSelect.addClass( 'filter-control-value' ); + return this.$valueSelect; + }; + + /** return the current state/setting for the filter as a three key object: key, op, value */ + FilterControl.prototype.val = function _val(){ + var key = this.$element.find( '.filter-control-key .dropdown-select-selected' ).text(), + op = this.$element.find( '.filter-control-op .dropdown-select-selected' ).text(), + // handle either a dropdown or plain input + $value = this.$element.find( '.filter-control-value' ), + value = ( $value.hasClass( 'dropdown-select' ) )?( $value.find( '.dropdown-select-selected' ).text() ) + :( $value.val() ); + return { key: key, op: op, value: value }; + }; + + // single point of change for change event + FilterControl.prototype._triggerChange = function __triggerChange(){ + this.$element.trigger( 'change.filter-control', this.val() ); + }; + + // as jq plugin + jQuery.fn.extend({ + filterControl : function $filterControl( options ){ + var nonOptionsArgs = jQuery.makeArray( arguments ).slice( 1 ); + return this.map( function(){ + var $this = $( this ), + data = $this.data( FilterControl.prototype.DATA_KEY ); + + if( jQuery.type( options ) === 'object' ){ + data = new FilterControl( $this, options ); + $this.data( FilterControl.prototype.DATA_KEY, data ); + } + if( data && jQuery.type( options ) === 'string' ){ + var fn = data[ options ]; + if( jQuery.type( fn ) === 'function' ){ + return fn.apply( data, nonOptionsArgs ); + } + } + return this; + }); + } + }); +})); diff -r c600b74bc7ce2dc669e3c34b9b8fde3ddb5ce717 -r a667776c4a1bc13cf1645c9ddd5af8892cc32b28 static/scripts/jq-plugins/ui/filter-control.js --- /dev/null +++ b/static/scripts/jq-plugins/ui/filter-control.js @@ -0,0 +1,149 @@ +// from: https://raw.githubusercontent.com/umdjs/umd/master/jqueryPlugin.js +// Uses AMD or browser globals to create a jQuery plugin. +(function (factory) { + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else { + // Browser globals + factory(jQuery); + } + +}(function ($) { + /** + * Creates a three part bootstrap button group (key, op, value) meant to + * allow the user control of filters (e.g. { key: 'name', op: 'contains', value: 'my_history' }) + * + * Each field uses a dropDownSelect (from ui.js) to allow selection + * (with the 'value' field appearing as an input when set to do so). + * + * Any change or update in any of the fields will trigger a 'change.filter-control' + * event which will be passed an object containing those fields (as the example above). + * + * Pass in an array of possible filter objects to control what the user can select. + * Each filter object should have: + * key : generally the attribute name on which to filter something + * ops : an array of 1 or more filter operations (e.g. [ 'is', '<', 'contains', '!=' ]) + * values (optional) : an array of possible values for the filter (e.g. [ 'true', 'false' ]) + * @example: + * $( '.my-div' ).filterControl({ + * filters : [ + * { key: 'name', ops: [ 'is exactly', 'contains' ] } + * { key: 'deleted', ops: [ 'is' ], values: [ 'true', 'false' ] } + * ] + * }); + * // after initialization, you can prog. get the current value using: + * $( '.my-div' ).filterControl( 'val' ) + * + */ + function FilterControl( element, options ){ + return this.init( element, options ); + } + /** the data key that this object will be stored under in the DOM element */ + FilterControl.prototype.DATA_KEY = 'filter-control'; + + /** parses options, sets up instance vars, and does initial render */ + FilterControl.prototype.init = function _init( element, options ){ + options = options || { filters: [] }; + this.$element = $( element ).addClass( 'filter-control btn-group' ); + this.options = jQuery.extend( true, {}, this.defaults, options ); + + this.currFilter = this.options.filters[0]; + return this.render(); + }; + + /** render (or re-render) the controls on the element */ + FilterControl.prototype.render = function _render(){ + this.$element.empty() + .append([ this._renderKeySelect(), this._renderOpSelect(), this._renderValueInput() ]); + return this; + }; + + /** render the key dropDownSelect, bind a change event to it, and return it */ + FilterControl.prototype._renderKeySelect = function __renderKeySelect(){ + var filterControl = this; + var keys = this.options.filters.map( function( filter ){ + return filter.key; + }); + this.$keySelect = dropDownSelect( keys, this.currFilter.key ) + .addClass( 'filter-control-key' ) + .on( 'change.dropdown-select', function( event, selection ){ + filterControl.currFilter = _.findWhere( filterControl.options.filters, { key: selection }); + // when the filter/key changes, re-render the control entirely + filterControl.render()._triggerChange(); + }); + return this.$keySelect; + }; + + /** render the op dropDownSelect, bind a change event to it, and return it */ + FilterControl.prototype._renderOpSelect = function __renderOpSelect(){ + var filterControl = this, + ops = this.currFilter.ops; + //TODO: search for currOp in avail. ops: use that for selected if there; otherwise: first op + this.$opSelect = dropDownSelect( ops, ops[0] ) + .addClass( 'filter-control-op' ) + .on( 'change.dropdown-select', function( event, selection ){ + filterControl._triggerChange(); + }); + return this.$opSelect; + }; + + /** render the value control, bind a change event to it, and return it */ + FilterControl.prototype._renderValueInput = function __renderValueInput(){ + var filterControl = this; + // if a values attribute is prov. on the filter - make this a dropdown; otherwise, use an input + if( this.currFilter.values ){ + this.$valueSelect = dropDownSelect( this.currFilter.values, this.currFilter.values[0] ) + .on( 'change.dropdown-select', function( event, selection ){ + filterControl._triggerChange(); + }); + } else { + //TODO: allow setting a value type (mainly for which html5 input to use: range, number, etc.) + this.$valueSelect = $( '<input/>' ).addClass( 'form-control' ) + .on( 'change', function( event, value ){ + filterControl._triggerChange(); + }); + } + this.$valueSelect.addClass( 'filter-control-value' ); + return this.$valueSelect; + }; + + /** return the current state/setting for the filter as a three key object: key, op, value */ + FilterControl.prototype.val = function _val(){ + var key = this.$element.find( '.filter-control-key .dropdown-select-selected' ).text(), + op = this.$element.find( '.filter-control-op .dropdown-select-selected' ).text(), + // handle either a dropdown or plain input + $value = this.$element.find( '.filter-control-value' ), + value = ( $value.hasClass( 'dropdown-select' ) )?( $value.find( '.dropdown-select-selected' ).text() ) + :( $value.val() ); + return { key: key, op: op, value: value }; + }; + + // single point of change for change event + FilterControl.prototype._triggerChange = function __triggerChange(){ + this.$element.trigger( 'change.filter-control', this.val() ); + }; + + // as jq plugin + jQuery.fn.extend({ + filterControl : function $filterControl( options ){ + var nonOptionsArgs = jQuery.makeArray( arguments ).slice( 1 ); + return this.map( function(){ + var $this = $( this ), + data = $this.data( FilterControl.prototype.DATA_KEY ); + + if( jQuery.type( options ) === 'object' ){ + data = new FilterControl( $this, options ); + $this.data( FilterControl.prototype.DATA_KEY, data ); + } + if( data && jQuery.type( options ) === 'string' ){ + var fn = data[ options ]; + if( jQuery.type( fn ) === 'function' ){ + return fn.apply( data, nonOptionsArgs ); + } + } + return this; + }); + } + }); +})); diff -r c600b74bc7ce2dc669e3c34b9b8fde3ddb5ce717 -r a667776c4a1bc13cf1645c9ddd5af8892cc32b28 static/scripts/packed/jq-plugins/ui/filter-control.js --- /dev/null +++ b/static/scripts/packed/jq-plugins/ui/filter-control.js @@ -0,0 +1,1 @@ +(function(a){if(typeof define==="function"&&define.amd){define(["jquery"],a)}else{a(jQuery)}}(function(c){function f(l,k){return this.init(l,k)}f.prototype.DATA_KEY="filter-control";f.prototype.init=function i(l,k){k=k||{filters:[]};this.$element=c(l).addClass("filter-control btn-group");this.options=jQuery.extend(true,{},this.defaults,k);this.currFilter=this.options.filters[0];return this.render()};f.prototype.render=function e(){this.$element.empty().append([this._renderKeySelect(),this._renderOpSelect(),this._renderValueInput()]);return this};f.prototype._renderKeySelect=function a(){var k=this;var l=this.options.filters.map(function(m){return m.key});this.$keySelect=dropDownSelect(l,this.currFilter.key).addClass("filter-control-key").on("change.dropdown-select",function(n,m){k.currFilter=_.findWhere(k.options.filters,{key:m});k.render()._triggerChange()});return this.$keySelect};f.prototype._renderOpSelect=function j(){var k=this,l=this.currFilter.ops;this.$opSelect=dropDownSelect(l,l[0]).addClass("filter-control-op").on("change.dropdown-select",function(n,m){k._triggerChange()});return this.$opSelect};f.prototype._renderValueInput=function d(){var k=this;if(this.currFilter.values){this.$valueSelect=dropDownSelect(this.currFilter.values,this.currFilter.values[0]).on("change.dropdown-select",function(m,l){k._triggerChange()})}else{this.$valueSelect=c("<input/>").addClass("form-control").on("change",function(l,m){k._triggerChange()})}this.$valueSelect.addClass("filter-control-value");return this.$valueSelect};f.prototype.val=function b(){var l=this.$element.find(".filter-control-key .dropdown-select-selected").text(),n=this.$element.find(".filter-control-op .dropdown-select-selected").text(),k=this.$element.find(".filter-control-value"),m=(k.hasClass("dropdown-select"))?(k.find(".dropdown-select-selected").text()):(k.val());return{key:l,op:n,value:m}};f.prototype._triggerChange=function h(){this.$element.trigger("change.filter-control",this.val())};jQuery.fn.extend({filterControl:function g(l){var k=jQuery.makeArray(arguments).slice(1);return this.map(function(){var o=c(this),n=o.data(f.prototype.DATA_KEY);if(jQuery.type(l)==="object"){n=new f(o,l);o.data(f.prototype.DATA_KEY,n)}if(n&&jQuery.type(l)==="string"){var m=n[l];if(jQuery.type(m)==="function"){return m.apply(n,k)}}return this})}})})); \ No newline at end of file Repository URL: https://bitbucket.org/galaxy/galaxy-central/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.
participants (1)
-
commits-noreply@bitbucket.org