/* NAME: MD.Button AUTHOR: Ben Delaney DESCRIPTION: A class for creating and controlling user interface buttons. REQUIREMENTS: The 'text' option (see below) PROVIDES: MD.Button OPTIONS: icon: '' [string] If left empty, no icon will be inserted. This string needs to correspond to a CSS class that determines which icon will be visible. ,text: '' [string] The text of the button. ,size: null [string OR object] Can be a string of 'small' or 'large' (case insensitive) OR an object that represents an exact size, e.g., {height: [int], width: [int]}. If a string is used, it will be inserted as a CSS classname. ,id: null [string] The id property of the element. ,className: '' [string] The classname property of the element. ,classNameActive: 'Active' [string] The 'active' classname to be applied when the button's .activate() method is called. ,classNamePressed: 'Pressed' [string] The classname to be applied when the button is pressed down by the user (the mouseDown event). ,classNameHover: 'On' [string] The classname to be applied when the button is hovered over by the user (the mouseEnter event). Removed on the mouseLeave event. ,fitWidthToContainer: false [bool] Whether the button should occupy the full width of whatever container it inhabits. ,styles: {} [object] An object to pass in any specific CSS styles to the button. ,properties: {} [object] An object to pass in any properties to the button's HTML element (div). ,spinnerOptions: {} [object] These are utilized by the MD.Spin class, which MD.Button implements. // ,onClick: function(this){} [function] Function that corresponds to it's javascript event name-equivalent. Receives this object ('this') as a parameter. // ,onMouseenter: function(this){} [function] Function that corresponds to it's javascript event name-equivalent. Receives this object ('this') as a parameter. // ,onMouseleave: function(this){} [function] Function that corresponds to it's javascript event name-equivalent. Receives this object ('this') as a parameter. // ,onMousedown: function(this){} [function] Function that corresponds to it's javascript event name-equivalent. Receives this object ('this') as a parameter. // ,onMouseup: function(this){} [function] Function that corresponds to it's javascript event name-equivalent. Receives this object ('this') as a parameter. METHODS: .enable([clickFunction]) .disable() .activate(optionalClassName) .deactivate() .toggleEnabled() .toggleActive() .isActive() returns a boolean which reflects the value of this._active. .isEnabled() returns a boolean which reflects the value of this._enabled. .isDisabled() returns a boolean which reflects the value of this._disabled. .addClass(className) .removeClass(className) .hasClass() .setText(text) sets the text of the button. .setProperties(propertiesObject) .destroy() .show() .hide() .toElement() returns the value of this.html, which is the main HTML element. RETURNS: An object with all methods and properties ready for use. To use the button, it must be inserted into the DOM via the .toElement() method. HOW TO USE: new MD.Input.Button([options]); EXAMPLE: var myButton = new MD.Input.Button({ icon: 'Edit' ,text: 'Edit' ,className: 'StudentEditButton' ,styles: { top: 15 ,left: 15 } ,onClick: function(this){ alert('Do the edit'); } }); $('AnotherElement').grab(myButton.toElement()); -- OR -- var myButton = new MD.Input.Button({[options]}).toElement(); $('AnotherElement').grab(myButton); -- OR -- var myButton = new MD.Input.Button({[options]}); $(myButton).inject(ParentElement); */ MD.Input.Button = new Class({ Extends: MD.Input.Base ,Implements: [Options,Events,MD.Spin] ,options: { icon: '' ,iconLocation: 'top' // top, bottom ,text: '' ,size: '' // Small , [default] , Large ,id: '' ,className: '' ,classNameActive: 'Active' ,classNamePressed: 'Pressed' ,classNameHover: 'On' ,fitWidthToContainer: false ,activate: false ,styles: {} ,properties: {} ,spinnerOptions: { size: 'small' } // ,onClick: function(clickEvent, this){} // ,onMouseenter: function(buttonObj){} // ,onMouseleave: function(buttonObj){} // ,onMousedown: function(buttonObj){} // ,onMouseup: function(buttonObj){} } ,initialize: function(options){ this.setOptions(options); this._active = false; this.parent(); } ,_setup: function() { if (this.options.icon) { this.icon = new Element('i', {'class': 'Icon-'+this.options.icon}); } else { this.icon = new Element('i'); } this.text = new Element('span', {'text':this.options.text, title: this.options.text}); this.html = new Element('div').adopt( (this.options.text !== '' ? this.text : '') ); if (this.options.icon != '') { this.icon.inject(this.html, this.options.iconLocation.toLowerCase()); } if (this.options.properties !== {}) { this.setProperties(this.options.properties); } if (this.options.id !== '') { this.html.setProperty('id',this.options.id); } if (this.options.styles !== {}) { // Allow the setting of a backgroud-color that overrides the normal 'background' property... if (this.options.styles['background-color'] !== undefined) { this.html.setStyle('background', this.options.styles['background-color']); delete this.options.styles['background-color']; } this.html.setStyles(this.options.styles); } if (this.options.fitWidthToContainer) { this.html.setStyle('width', '100%'); } var classNames = this._getBaseClassName() + ' Button'; classNames += (this.options.size !== '' ? ' Size-'+this.options.size.toLowerCase().capitalize() : ''); classNames += (this.html.get('class') !== null ? ' '+this.html.get('class') : ''); classNames += (this.options.className !== '' ? ' '+this.options.className : ''); this.html.addClass(classNames); if (this.options.activate) { this.activate(); } } ,_setupEventHandlers: function(clickFunction) { this.html.addEvents({ click: function(e){ e.stop(); }.bind(this) ,mouseenter: function(){ this.html.addClass('Over'); this.fireEvent('mouseenter', this); }.bind(this) ,mouseleave: function(){ this.html.removeClass('Over'); // need to decide if we need this... it causes problems... // if (this.mousedown) { // this.deactivate(); // } this.fireEvent('mouseleave', this); }.bind(this) ,mousedown: function(){ this.mousedown = true; this.html.addClass(this.options.classNamePressed); this.fireEvent('mousedown', this); }.bind(this) ,mouseup: function(e){ this.mousedown = false; this.html.removeClass(this.options.classNamePressed); this.fireEvent('mouseup', this); if (clickFunction) { clickFunction.call(this); } else { this.fireEvent('click', [e, this]); } }.bind(this) ,focus: function(){ this.html.addClass(this.options.classNameHover); }.bind(this) ,blur: function(){ this.html.removeClass(this.options.classNameHover); }.bind(this) ,selectstart: function(){ return false; } ,touchstart: function() { this.mousedown = true; this.html.addClass(this.options.classNamePressed); this.fireEvent('touchstart', this); this.fireEvent('mousedown', this); }.bind(this) ,touchend: function(e) { e.stop(); this.mousedown = false; this.html.removeClass(this.options.classNamePressed); this.fireEvent('mouseup', this); this.fireEvent('touchend', this); if (clickFunction) { clickFunction.call(this); } else { this.fireEvent('click', [e, this]); } }.bind(this) }); } ,doAction: function() { this.html.fireEvent('mouseup'); } ,enable: function(clickFunction){ this.html.removeEvents(); this._setupEventHandlers(clickFunction); this.html.removeClass('Disabled'); this._enabled = true; this._disabled = false; return this; } ,disable: function(){ this.html.removeEvents(); this.html.addClass('Disabled'); this._enabled = false; this._disabled = true; return this; } ,activate: function(additionalActiveClass){ this.html.addClass('Active'); if (additionalActiveClass) { this._additionalActiveClass = additionalActiveClass; this.html.addClass(this._additionalActiveClass); } this._active = true; return this; } ,deactivate: function(){ this.html.removeClass('Active'); this.html.removeClass(this.options.classNamePressed); this.html.removeClass(this.options.classNameHover); if (this._additionalActiveClass) { this.html.removeClass(this._additionalActiveClass); delete this._additionalActiveClass; } this._active = false; return this; } ,toggleEnabled: function() { if (this.isEnabled()) { this.disable(); } else { this.enable(); } } ,toggleActive: function() { if (this.isActive()) { this.deactivate(); } else { this.activate(); } } ,isActive: function(){ return this._active; } ,isEnabled: function(){ return this._enabled; } ,isDisabled: function(){ return this._disabled; } ,addClass: function(className){ this.html.addClass(className); return this; } ,removeClass: function(className){ this.html.removeClass(className); return this; } ,toggleClass: function(className) { this.html.toggleClass(className); return this; } ,hasClass: function(className) { return this.html.hasClass(className); } ,setText: function(newText){ this.text.setProperty('text', newText); if (!this.html.contains(this.text)) { this.text.inject(this.html); } return this; } ,setTitle: function(newTitle) { this.text.set('title', newTitle); return this; } ,getText: function() { return this.text.get('text'); } ,setIcon: function(newIcon){ if (this.html.contains(this.icon)) { this.icon.swapClass(this.icon.getProperty('class'), 'Icon-'+newIcon); } else { this.icon.addClass('Icon-'+newIcon).inject(this.html, 'top'); } return this; } ,swapClass: function(classToRemove, classToAdd) { this.html.swapClass(classToRemove, classToAdd); return this; } ,setProperties: function(properties) { if (properties) { this.html.setProperties(properties); } else { console.error("No properties passed to MDButton.js .setProperties()"); } return this; } ,destroy: function(){ this.html.destroy(); return this; } });