1 /* 2 * ***** BEGIN LICENSE BLOCK ***** 3 * Zimbra Collaboration Suite Web Client 4 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. 5 * 6 * The contents of this file are subject to the Common Public Attribution License Version 1.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at: https://www.zimbra.com/license 9 * The License is based on the Mozilla Public License Version 1.1 but Sections 14 and 15 10 * have been added to cover use of software over a computer network and provide for limited attribution 11 * for the Original Developer. In addition, Exhibit A has been modified to be consistent with Exhibit B. 12 * 13 * Software distributed under the License is distributed on an "AS IS" basis, 14 * WITHOUT WARRANTY OF ANY KIND, either express or implied. 15 * See the License for the specific language governing rights and limitations under the License. 16 * The Original Code is Zimbra Open Source Web Client. 17 * The Initial Developer of the Original Code is Zimbra, Inc. All rights to the Original Code were 18 * transferred by Zimbra, Inc. to Synacor, Inc. on September 14, 2015. 19 * 20 * All portions of the code are Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Synacor, Inc. All Rights Reserved. 21 * ***** END LICENSE BLOCK ***** 22 */ 23 24 /** 25 * Creates a checkbox. 26 * @constructor 27 * @class 28 * This class represents a checkbox. 29 * 30 * @param {hash} params a hash of parameters 31 * @param {DwtComposite} params.parent the parent widget 32 * @param {DwtCheckbox.TEXT_LEFT|DwtCheckbox.TEXT_RIGHT} [params.style=DwtCheckbox.TEXT_RIGHT] the text style 33 * @param {string} params.name the input control name (required for IE) 34 * @param {string} params.value the input control value 35 * @param {boolean} params.checked the input control checked status (required for IE) 36 * @param {string} params.className the CSS class 37 * @param {constant} params.posStyle the positioning style (see {@link Dwt}) 38 * @param {string} params.id an explicit ID to use for the control's HTML element 39 * @param {number} params.index the index at which to add this control among parent's children 40 * 41 * @extends DwtControl 42 */ 43 DwtCheckbox = function(params) { 44 if (arguments.length == 0) { return; } 45 46 params = Dwt.getParams(arguments, DwtCheckbox.PARAMS); 47 params.className = params.className || "DwtCheckbox"; 48 49 DwtControl.call(this, params); 50 51 this._textPosition = DwtCheckbox.DEFAULT_POSITION; 52 this._initName = params.name; 53 this._initValue = params.value; 54 this._createHtml(); 55 56 this.setSelected(params.checked); 57 }; 58 59 DwtCheckbox.prototype = new DwtControl; 60 DwtCheckbox.prototype.constructor = DwtCheckbox; 61 62 DwtCheckbox.prototype.isDwtCheckbox = true; 63 DwtCheckbox.prototype.isInputControl = true; 64 DwtCheckbox.prototype.toString = function() { return "DwtCheckbox"; }; 65 66 // 67 // Constants 68 // 69 DwtCheckbox.PARAMS = [ 70 "parent", 71 "style", 72 "name", 73 "checked", 74 "className", 75 "posStyle", 76 "id", 77 "index", 78 "value" 79 ]; 80 /** 81 * Defines the "left" text style position. 82 */ 83 DwtCheckbox.TEXT_LEFT = "left"; 84 /** 85 * Defines the "right" text style position. 86 */ 87 DwtCheckbox.TEXT_RIGHT = "right"; 88 /** 89 * Defines the default text style position. 90 */ 91 DwtCheckbox.DEFAULT_POSITION = DwtCheckbox.TEXT_RIGHT; 92 93 // 94 // Data 95 // 96 DwtCheckbox.prototype.TEMPLATE = "dwt.Widgets#DwtCheckbox"; 97 98 DwtCheckbox.prototype.INPUT_TYPE = 'checkbox'; 99 100 // 101 // Public methods 102 // 103 DwtCheckbox.prototype.getInputElement = 104 function() { 105 return this._inputEl; 106 }; 107 108 DwtCheckbox.prototype._focus = 109 function() { 110 Dwt.addClass(this.getHtmlElement(), DwtControl.FOCUSED); 111 }; 112 113 DwtCheckbox.prototype._blur = 114 function() { 115 Dwt.delClass(this.getHtmlElement(), DwtControl.FOCUSED); 116 }; 117 118 // listeners 119 120 /** 121 * Adds a selection listener. 122 * 123 * @param {AjxListener} listener the listener 124 */ 125 DwtCheckbox.prototype.addSelectionListener = 126 function(listener) { 127 this.addListener(DwtEvent.SELECTION, listener); 128 }; 129 130 /** 131 * Removes a selection listener. 132 * 133 * @param {AjxListener} listener the listener 134 */ 135 DwtCheckbox.prototype.removeSelectionListener = 136 function(listener) { 137 this.removeListener(DwtEvent.SELECTION, listener); 138 }; 139 140 // properties 141 142 /** 143 * Sets the enabled state. 144 * 145 * @param {boolean} enabled if <code>true</code>, the checkbox is enabled 146 */ 147 DwtCheckbox.prototype.setEnabled = 148 function(enabled) { 149 if (enabled != this._enabled) { 150 DwtControl.prototype.setEnabled.call(this, enabled); 151 this._inputEl.disabled = !enabled; 152 var className = enabled ? "Text" : "DisabledText"; 153 if (this._textElLeft) this._textElLeft.className = className; 154 if (this._textElRight) this._textElRight.className = className; 155 } 156 }; 157 158 /** 159 * Sets the selected state. 160 * 161 * @param {boolean} selected if <code>true</code>, the checkbox is selected 162 */ 163 DwtCheckbox.prototype.setSelected = 164 function(selected) { 165 if (this._inputEl && this._inputEl.checked != selected) { 166 this._inputEl.checked = selected; 167 } 168 }; 169 170 /** 171 * Checks if the checkbox is selected state. 172 * 173 * @return {boolean} <code>true</code> if the checkbox is selected 174 */ 175 DwtCheckbox.prototype.isSelected = 176 function() { 177 return this._inputEl && this._inputEl.checked; 178 }; 179 180 /** 181 * Sets the checkbox text. 182 * 183 * @param {string} text the text 184 */ 185 DwtCheckbox.prototype.setText = 186 function(text) { 187 if (this._textEl && this._text != text) { 188 this._text = text; 189 this._textEl.innerHTML = text || ""; 190 } 191 }; 192 193 /** 194 * Gets the checkbox text. 195 * 196 * @return {string} the text 197 */ 198 DwtCheckbox.prototype.getText = 199 function() { 200 return this._text; 201 }; 202 203 /** 204 * Sets the text position. 205 * 206 * @param {DwtCheckbox.TEXT_LEFT|DwtCheckbox.TEXT_RIGHT} position the position 207 */ 208 DwtCheckbox.prototype.setTextPosition = 209 function(position) { 210 this._textEl = position == DwtCheckbox.TEXT_LEFT ? this._textElLeft : this._textElRight; 211 if (this._textPosition != position) { 212 this._textPosition = position; 213 if (this._textElLeft) this._textElLeft.innerHTML = ""; 214 if (this._textElRight) this._textElRight.innerHTML = ""; 215 this.setText(this._text); 216 } 217 }; 218 219 /** 220 * Gets the text position. 221 * 222 * @return {DwtCheckbox.TEXT_LEFT|DwtCheckbox.TEXT_RIGHT} the position 223 */ 224 DwtCheckbox.prototype.getTextPosition = 225 function() { 226 return this._textPosition; 227 }; 228 229 /** 230 * Sets the value. 231 * 232 * @param {string} value the value 233 */ 234 DwtCheckbox.prototype.setValue = 235 function(value) { 236 var object = this._inputEl || this; 237 if (object.value !== value) { 238 object.value = value; 239 } 240 }; 241 242 /** 243 * Gets the value. 244 * 245 * @return {string} the value 246 */ 247 DwtCheckbox.prototype.getValue = 248 function() { 249 var object = this._inputEl || this; 250 return object.value != null ? object.value : this.getText(); 251 }; 252 253 /** 254 * Gets the input element. 255 * 256 * @return {Element} the element 257 */ 258 DwtCheckbox.prototype.getInputElement = 259 function() { 260 return this._inputEl; 261 }; 262 263 // 264 // DwtControl methods 265 // 266 267 DwtCheckbox.prototype.setToolTipContent = function(content) { 268 if (content && !this.__mouseEventsSet) { 269 // NOTE: We need mouse events in order to initiate tooltips on hover. 270 // TODO: This should be done transparently in DwtControl for all 271 // TODO: controls with tooltips. 272 this.__mouseEventsSet = true; 273 this._setMouseEvents(); 274 } 275 DwtControl.prototype.setToolTipContent.apply(this, arguments); 276 }; 277 278 // 279 // Protected methods 280 // 281 282 /** 283 * The input field inherits the id for accessibility purposes. 284 * 285 * @private 286 */ 287 DwtCheckbox.prototype._replaceElementHook = 288 function(oel, nel, inheritClass, inheritStyle) { 289 nel = this.getInputElement(); 290 DwtControl.prototype._replaceElementHook.call(this, oel, nel, inheritClass, inheritStyle); 291 if (oel.id) { 292 this.setHtmlElementId(oel.id+"_control"); 293 nel.id = oel.id; 294 if (this._textEl) { 295 this._textEl.setAttribute(AjxEnv.isIE ? "htmlFor" : "for", oel.id); 296 } 297 } 298 }; 299 300 // 301 // Private methods 302 // 303 304 DwtCheckbox.prototype._createHtml = 305 function(templateId) { 306 var data = { id: this._htmlElId }; 307 this._createHtmlFromTemplate(templateId || this.TEMPLATE, data); 308 }; 309 310 DwtCheckbox.prototype._createHtmlFromTemplate = 311 function(templateId, data) { 312 // NOTE: If you don't set the name and checked status when 313 // creating checkboxes and radio buttons on IE, they will 314 // not take the first programmatic value. So we pass in 315 // the init values from the constructor. 316 data.name = this._initName || this._htmlElId; 317 data.value = this._initValue; 318 data.type = this.INPUT_TYPE; 319 DwtControl.prototype._createHtmlFromTemplate.call(this, templateId, data); 320 this._inputEl = document.getElementById(data.id+"_input"); 321 if (this._inputEl) { 322 var keyboardMgr = DwtShell.getShell(window).getKeyboardMgr(); 323 var handleFocus = AjxCallback.simpleClosure(keyboardMgr.grabFocus, keyboardMgr, this.getInputElement()); 324 Dwt.setHandler(this._inputEl, DwtEvent.ONFOCUS, handleFocus); 325 Dwt.setHandler(this._inputEl, DwtEvent.ONCLICK, DwtCheckbox.__handleClick); 326 this.setFocusElement(); 327 } 328 this._textElLeft = document.getElementById(data.id+"_text_left"); 329 this._textElRight = document.getElementById(data.id+"_text_right"); 330 this.setTextPosition(this._textPosition); 331 }; 332 333 // 334 // Private functions 335 // 336 337 DwtCheckbox.__handleClick = 338 function(evt) { 339 var event = DwtUiEvent.getEvent(evt); 340 var target = DwtUiEvent.getTarget(event); 341 342 var selEv = DwtShell.selectionEvent; 343 DwtUiEvent.copy(selEv, event); 344 selEv.item = this; 345 selEv.detail = target.checked; 346 347 var checkbox = DwtControl.findControl(target); 348 checkbox.setSelected(target.checked); 349 checkbox.focus(); 350 checkbox.notifyListeners(DwtEvent.SELECTION, selEv); 351 }; 352