1 // ========================================================================== 2 // Project: SproutCore - JavaScript Application Framework 3 // Copyright: ©2006-2011 Strobe Inc. and contributors. 4 // Portions ©2008-2011 Apple Inc. All rights reserved. 5 // License: Licensed under MIT license (see license.js) 6 // ========================================================================== 7 8 /** @class 9 10 Represents a Checkbox Button. 11 12 The view is an `SC.ButtonView` put into toggle mode and with the 'theme' property 13 set to "checkbox". 14 15 Rendering 16 ---------------------------- 17 SC.ButtonView delegates its rendering to its theme. As the theme is set 18 to "checkbox", the way the checkbox renders (including DOM) will actually 19 be different than SC.ButtonView's. 20 21 @extends SC.ButtonView 22 @since SproutCore 1.0 23 */ 24 SC.CheckboxView = SC.ButtonView.extend( 25 /** @scope SC.CheckboxView.prototype */ { 26 27 /** 28 @type Array 29 @default ['sc-checkbox-view', 'sc-checkbox-control'] 30 @see SC.View#classNames 31 */ 32 classNames: ['sc-checkbox-view', 'sc-checkbox-control'], 33 34 /** 35 The WAI-ARIA role of checkbox. 36 37 @type String 38 @readOnly 39 */ 40 ariaRole: 'checkbox', 41 42 // no special theme for Checkbox; button defaults to 'square', so we have to stop that. 43 themeName: null, 44 45 /** 46 @type String 47 @default 'checkboxRenderDelegate' 48 */ 49 renderDelegateName: 'checkboxRenderDelegate', 50 51 /** 52 Ellipsis is disabled by default to allow multiline text 53 54 @type Boolean 55 @default NO 56 */ 57 needsEllipsis: NO, 58 59 /** 60 `YES` if `isEnabledInPane` is `YES`, `NO` otherwise 61 62 @type Boolean 63 @default NO 64 @observes isEnabledInPane 65 */ 66 acceptsFirstResponder: function() { 67 if (SC.FOCUS_ALL_CONTROLS) { return this.get('isEnabledInPane'); } 68 return NO; 69 }.property('isEnabledInPane'), 70 71 /** @private */ 72 _toggleValue: function(){ 73 var isOn = this.get('value') === this.get('toggleOnValue'); 74 this.set('value', isOn ? this.get('toggleOffValue') : this.get('toggleOnValue')); 75 }, 76 77 /** @private */ 78 mouseDown: function(evt) { 79 // Fast path, reject secondary clicks. 80 if (evt.which && evt.which !== 1) return false; 81 82 if(!this.get('isEnabledInPane')) return YES; 83 this.set('isActive', YES); 84 this._isMouseDown = YES; 85 if (evt && this.get('acceptsFirstResponder')) evt.allowDefault(); 86 return YES; 87 }, 88 89 /** @private */ 90 mouseUp: function(evt) { 91 if(!this.get('isEnabledInPane')) return YES; 92 93 this.set('isActive', NO); 94 this._isMouseDown = NO; 95 96 // fire action 97 if (this.get('buttonBehavior') !== SC.HOLD_BEHAVIOR) { 98 if (this.$().within(evt.target)) { 99 this._toggleValue(); 100 this._action(evt); 101 } 102 } 103 104 return YES; 105 106 }, 107 108 /** @private */ 109 keyDown: function(evt) { 110 // handle tab key 111 if(!this.get('isEnabledInPane')) return YES; 112 113 if (evt.which === 9 || evt.keyCode === 9) { 114 var view = evt.shiftKey ? this.get('previousValidKeyView') : this.get('nextValidKeyView'); 115 if(view) view.becomeFirstResponder(); 116 else evt.allowDefault(); 117 return YES ; // handled 118 } 119 120 if (evt.which === 13 || evt.which === 32) { 121 this._toggleValue(); 122 123 // fire action 124 if (this.get('buttonBehavior') !== SC.HOLD_BEHAVIOR) { 125 if (this.$().within(evt.target)) { this._action(evt); } 126 } 127 128 return YES ; // handled 129 } 130 131 // let other keys through to browser 132 evt.allowDefault(); 133 134 return NO; 135 }, 136 137 138 139 /** @private */ 140 touchStart: function(evt) { 141 return this.mouseDown(evt); 142 }, 143 144 /** @private */ 145 touchEnd: function(evt) { 146 return this.mouseUp(evt); 147 } 148 149 }); 150