src/pyams_skin/resources/js/ext/tinymce/dev/classes/ui/ComboBox.js
changeset 69 a361355b55c7
equal deleted inserted replaced
68:fd8fb93e1b6a 69:a361355b55c7
       
     1 /**
       
     2  * ComboBox.js
       
     3  *
       
     4  * Copyright, Moxiecode Systems AB
       
     5  * Released under LGPL License.
       
     6  *
       
     7  * License: http://www.tinymce.com/license
       
     8  * Contributing: http://www.tinymce.com/contributing
       
     9  */
       
    10 
       
    11 /**
       
    12  * This class creates a combobox control. Select box that you select a value from or
       
    13  * type a value into.
       
    14  *
       
    15  * @-x-less ComboBox.less
       
    16  * @class tinymce.ui.ComboBox
       
    17  * @extends tinymce.ui.Widget
       
    18  */
       
    19 define("tinymce/ui/ComboBox", [
       
    20 	"tinymce/ui/Widget",
       
    21 	"tinymce/ui/Factory",
       
    22 	"tinymce/ui/DomUtils"
       
    23 ], function(Widget, Factory, DomUtils) {
       
    24 	"use strict";
       
    25 
       
    26 	return Widget.extend({
       
    27 		/**
       
    28 		 * Constructs a new control instance with the specified settings.
       
    29 		 *
       
    30 		 * @constructor
       
    31 		 * @param {Object} settings Name/value object with settings.
       
    32 		 * @setting {String} placeholder Placeholder text to display.
       
    33 		 */
       
    34 		init: function(settings) {
       
    35 			var self = this;
       
    36 
       
    37 			self._super(settings);
       
    38 			self.addClass('combobox');
       
    39 			self.subinput = true;
       
    40 			self.ariaTarget = 'inp'; // TODO: Figure out a better way
       
    41 
       
    42 			settings = self.settings;
       
    43 			settings.menu = settings.menu || settings.values;
       
    44 
       
    45 			if (settings.menu) {
       
    46 				settings.icon = 'caret';
       
    47 			}
       
    48 
       
    49 			self.on('click', function(e) {
       
    50 				var elm = e.target, root = self.getEl();
       
    51 
       
    52 				while (elm && elm != root) {
       
    53 					if (elm.id && elm.id.indexOf('-open') != -1) {
       
    54 						self.fire('action');
       
    55 
       
    56 						if (settings.menu) {
       
    57 							self.showMenu();
       
    58 
       
    59 							if (e.aria) {
       
    60 								self.menu.items()[0].focus();
       
    61 							}
       
    62 						}
       
    63 					}
       
    64 
       
    65 					elm = elm.parentNode;
       
    66 				}
       
    67 			});
       
    68 
       
    69 			// TODO: Rework this
       
    70 			self.on('keydown', function(e) {
       
    71 				if (e.target.nodeName == "INPUT" && e.keyCode == 13) {
       
    72 					self.parents().reverse().each(function(ctrl) {
       
    73 						e.preventDefault();
       
    74 						self.fire('change');
       
    75 
       
    76 						if (ctrl.hasEventListeners('submit') && ctrl.toJSON) {
       
    77 							ctrl.fire('submit', {data: ctrl.toJSON()});
       
    78 							return false;
       
    79 						}
       
    80 					});
       
    81 				}
       
    82 			});
       
    83 
       
    84 			if (settings.placeholder) {
       
    85 				self.addClass('placeholder');
       
    86 
       
    87 				self.on('focusin', function() {
       
    88 					if (!self._hasOnChange) {
       
    89 						DomUtils.on(self.getEl('inp'), 'change', function() {
       
    90 							self.fire('change');
       
    91 						});
       
    92 
       
    93 						self._hasOnChange = true;
       
    94 					}
       
    95 
       
    96 					if (self.hasClass('placeholder')) {
       
    97 						self.getEl('inp').value = '';
       
    98 						self.removeClass('placeholder');
       
    99 					}
       
   100 				});
       
   101 
       
   102 				self.on('focusout', function() {
       
   103 					if (self.value().length === 0) {
       
   104 						self.getEl('inp').value = settings.placeholder;
       
   105 						self.addClass('placeholder');
       
   106 					}
       
   107 				});
       
   108 			}
       
   109 		},
       
   110 
       
   111 		showMenu: function() {
       
   112 			var self = this, settings = self.settings, menu;
       
   113 
       
   114 			if (!self.menu) {
       
   115 				menu = settings.menu || [];
       
   116 
       
   117 				// Is menu array then auto constuct menu control
       
   118 				if (menu.length) {
       
   119 					menu = {
       
   120 						type: 'menu',
       
   121 						items: menu
       
   122 					};
       
   123 				} else {
       
   124 					menu.type = menu.type || 'menu';
       
   125 				}
       
   126 
       
   127 				self.menu = Factory.create(menu).parent(self).renderTo(self.getContainerElm());
       
   128 				self.fire('createmenu');
       
   129 				self.menu.reflow();
       
   130 				self.menu.on('cancel', function(e) {
       
   131 					if (e.control === self.menu) {
       
   132 						self.focus();
       
   133 					}
       
   134 				});
       
   135 
       
   136 				self.menu.on('show hide', function(e) {
       
   137 					e.control.items().each(function(ctrl) {
       
   138 						ctrl.active(ctrl.value() == self.value());
       
   139 					});
       
   140 				}).fire('show');
       
   141 
       
   142 				self.menu.on('select', function(e) {
       
   143 					self.value(e.control.value());
       
   144 				});
       
   145 
       
   146 				self.on('focusin', function(e) {
       
   147 					if (e.target.tagName.toUpperCase() == 'INPUT') {
       
   148 						self.menu.hide();
       
   149 					}
       
   150 				});
       
   151 
       
   152 				self.aria('expanded', true);
       
   153 			}
       
   154 
       
   155 			self.menu.show();
       
   156 			self.menu.layoutRect({w: self.layoutRect().w});
       
   157 			self.menu.moveRel(self.getEl(), self.isRtl() ? ['br-tr', 'tr-br'] : ['bl-tl', 'tl-bl']);
       
   158 		},
       
   159 
       
   160 		/**
       
   161 		 * Getter/setter function for the control value.
       
   162 		 *
       
   163 		 * @method value
       
   164 		 * @param {String} [value] Value to be set.
       
   165 		 * @return {String|tinymce.ui.ComboBox} Value or self if it's a set operation.
       
   166 		 */
       
   167 		value: function(value) {
       
   168 			var self = this;
       
   169 
       
   170 			if (typeof value != "undefined") {
       
   171 				self._value = value;
       
   172 				self.removeClass('placeholder');
       
   173 
       
   174 				if (self._rendered) {
       
   175 					self.getEl('inp').value = value;
       
   176 				}
       
   177 
       
   178 				return self;
       
   179 			}
       
   180 
       
   181 			if (self._rendered) {
       
   182 				value = self.getEl('inp').value;
       
   183 
       
   184 				if (value != self.settings.placeholder) {
       
   185 					return value;
       
   186 				}
       
   187 
       
   188 				return '';
       
   189 			}
       
   190 
       
   191 			return self._value;
       
   192 		},
       
   193 
       
   194 		/**
       
   195 		 * Getter/setter function for the disabled state.
       
   196 		 *
       
   197 		 * @method value
       
   198 		 * @param {Boolean} [state] State to be set.
       
   199 		 * @return {Boolean|tinymce.ui.ComboBox} True/false or self if it's a set operation.
       
   200 		 */
       
   201 		disabled: function(state) {
       
   202 			var self = this;
       
   203 
       
   204 			if (self._rendered && typeof state != 'undefined') {
       
   205 				self.getEl('inp').disabled = state;
       
   206 			}
       
   207 
       
   208 			return self._super(state);
       
   209 		},
       
   210 
       
   211 		/**
       
   212 		 * Focuses the input area of the control.
       
   213 		 *
       
   214 		 * @method focus
       
   215 		 */
       
   216 		focus: function() {
       
   217 			this.getEl('inp').focus();
       
   218 		},
       
   219 
       
   220 		/**
       
   221 		 * Repaints the control after a layout operation.
       
   222 		 *
       
   223 		 * @method repaint
       
   224 		 */
       
   225 		repaint: function() {
       
   226 			var self = this, elm = self.getEl(), openElm = self.getEl('open'), rect = self.layoutRect();
       
   227 			var width, lineHeight;
       
   228 
       
   229 			if (openElm) {
       
   230 				width = rect.w - DomUtils.getSize(openElm).width - 10;
       
   231 			} else {
       
   232 				width = rect.w - 10;
       
   233 			}
       
   234 
       
   235 			// Detect old IE 7+8 add lineHeight to align caret vertically in the middle
       
   236 			var doc = document;
       
   237 			if (doc.all && (!doc.documentMode || doc.documentMode <= 8)) {
       
   238 				lineHeight = (self.layoutRect().h - 2) + 'px';
       
   239 			}
       
   240 
       
   241 			DomUtils.css(elm.firstChild, {
       
   242 				width: width,
       
   243 				lineHeight: lineHeight
       
   244 			});
       
   245 
       
   246 			self._super();
       
   247 
       
   248 			return self;
       
   249 		},
       
   250 
       
   251 		/**
       
   252 		 * Post render method. Called after the control has been rendered to the target.
       
   253 		 *
       
   254 		 * @method postRender
       
   255 		 * @return {tinymce.ui.ComboBox} Current combobox instance.
       
   256 		 */
       
   257 		postRender: function() {
       
   258 			var self = this;
       
   259 
       
   260 			DomUtils.on(this.getEl('inp'), 'change', function() {
       
   261 				self.fire('change');
       
   262 			});
       
   263 
       
   264 			return self._super();
       
   265 		},
       
   266 
       
   267 		remove: function() {
       
   268 			DomUtils.off(this.getEl('inp'));
       
   269 			this._super();
       
   270 		},
       
   271 
       
   272 		/**
       
   273 		 * Renders the control as a HTML string.
       
   274 		 *
       
   275 		 * @method renderHtml
       
   276 		 * @return {String} HTML representing the control.
       
   277 		 */
       
   278 		renderHtml: function() {
       
   279 			var self = this, id = self._id, settings = self.settings, prefix = self.classPrefix;
       
   280 			var value = settings.value || settings.placeholder || '';
       
   281 			var icon, text, openBtnHtml = '', extraAttrs = '';
       
   282 
       
   283 			if ("spellcheck" in settings) {
       
   284 				extraAttrs += ' spellcheck="' + settings.spellcheck + '"';
       
   285 			}
       
   286 
       
   287 			if (settings.maxLength) {
       
   288 				extraAttrs += ' maxlength="' + settings.maxLength + '"';
       
   289 			}
       
   290 
       
   291 			if (settings.size) {
       
   292 				extraAttrs += ' size="' + settings.size + '"';
       
   293 			}
       
   294 
       
   295 			if (settings.subtype) {
       
   296 				extraAttrs += ' type="' + settings.subtype + '"';
       
   297 			}
       
   298 
       
   299 			if (self.disabled()) {
       
   300 				extraAttrs += ' disabled="disabled"';
       
   301 			}
       
   302 
       
   303 			icon = settings.icon;
       
   304 			if (icon && icon != 'caret') {
       
   305 				icon = prefix + 'ico ' + prefix + 'i-' + settings.icon;
       
   306 			}
       
   307 
       
   308 			text = self._text;
       
   309 
       
   310 			if (icon || text) {
       
   311 				openBtnHtml = (
       
   312 					'<div id="' + id + '-open" class="' + prefix + 'btn ' + prefix + 'open" tabIndex="-1" role="button">' +
       
   313 						'<button id="' + id + '-action" type="button" hidefocus="1" tabindex="-1">' +
       
   314 							(icon != 'caret' ? '<i class="' + icon + '"></i>' : '<i class="' + prefix + 'caret"></i>') +
       
   315 							(text ? (icon ? ' ' : '') + text : '') +
       
   316 						'</button>' +
       
   317 					'</div>'
       
   318 				);
       
   319 
       
   320 				self.addClass('has-open');
       
   321 			}
       
   322 
       
   323 			return (
       
   324 				'<div id="' + id + '" class="' + self.classes() + '">' +
       
   325 					'<input id="' + id + '-inp" class="' + prefix + 'textbox ' + prefix + 'placeholder" value="' +
       
   326 					value + '" hidefocus="1"' + extraAttrs + ' />' +
       
   327 					openBtnHtml +
       
   328 				'</div>'
       
   329 			);
       
   330 		}
       
   331 	});
       
   332 });