PageRenderTime 72ms CodeModel.GetById 41ms RepoModel.GetById 0ms app.codeStats 0ms

/WebContent/core/ui-attributefield.js

https://github.com/scottgonzalez/Aloha-Editor
JavaScript | 457 lines | 306 code | 29 blank | 122 comment | 67 complexity | 1da4c617f1ba47fd5be36a69350542e9 MD5 | raw file
  1. /*!
  2. * This file is part of Aloha Editor
  3. * Author & Copyright (c) 2010 Gentics Software GmbH, aloha@gentics.com
  4. * Licensed unter the terms of http://www.aloha-editor.com/license.html
  5. *//*
  6. * Aloha Editor is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Affero General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.*
  10. *
  11. * Aloha Editor is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Affero General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Affero General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. Ext.ux.AlohaAttributeField = Ext.extend(Ext.form.ComboBox, {
  20. typeAhead: false,
  21. mode: 'remote',
  22. triggerAction: 'all',
  23. width: 300,
  24. hideTrigger: true,
  25. minChars: 3,
  26. valueField: 'id',
  27. displayField: 'name',
  28. enableKeyEvents: true,
  29. store: new Ext.data.Store({
  30. proxy: new Ext.data.AlohaProxy(),
  31. reader: new Ext.data.AlohaObjectReader()
  32. }),
  33. clickAttached: false, // remember that the click event has been attached to the innerList, as this is not implemented in the combobox
  34. tpl: new Ext.XTemplate(
  35. '<tpl for="."><div class="x-combo-list-item">',
  36. '<tpl if="this.hasRepositoryTemplate(values)">{[ this.renderRepositoryTemplate(values) ]}</tpl>',
  37. '<tpl if="!this.hasRepositoryTemplate(values)"><span><b>{name}</b></span></tpl>',
  38. '</div></tpl>',
  39. {
  40. hasRepositoryTemplate : function(values) {
  41. var rep = GENTICS.Aloha.RepositoryManager.getRepository(values.repositoryId);
  42. return rep && rep.hasTemplate();
  43. },
  44. renderRepositoryTemplate : function(values) {
  45. var rep = GENTICS.Aloha.RepositoryManager.getRepository(values.repositoryId);
  46. if (rep && rep.hasTemplate()) {
  47. return rep.getTemplate().apply(values);
  48. }
  49. }
  50. }
  51. ),
  52. onSelect: function (item) {
  53. this.setItem(item.data);
  54. if ( typeof this.alohaButton.onSelect == 'function' ) {
  55. this.alohaButton.onSelect.call(this.alohaButton, item.data);
  56. }
  57. this.collapse();
  58. },
  59. listeners: {
  60. // repository object types could have changed
  61. 'beforequery': function (event) {
  62. if( this.noQuery ) {
  63. event.cancel = true;
  64. return;
  65. }
  66. if (this.store != null && this.store.proxy != null) {
  67. this.store.proxy.setParams({
  68. objectTypeFilter: this.getObjectTypeFilter(),
  69. queryString: event.query
  70. });
  71. }
  72. },
  73. 'afterrender': function (obj, event) {
  74. var that = this;
  75. jQuery(this.wrap.dom.children[0]).blur(function(e){
  76. that.triggerBlur();
  77. });
  78. },
  79. 'keydown': function (obj, event) {
  80. // unset the currently selected object
  81. this.resourceItem = null;
  82. // on ENTER or ESC leave the editing
  83. // just remember here the status and remove cursor on keyup event
  84. // Otherwise cursor moves to content and no more blur event happens!!??
  85. if (event.keyCode == 13 || event.keyCode == 27) {
  86. if ( this.isExpanded() ) {
  87. this.ALOHAwasExpanded = true;
  88. } else {
  89. this.ALOHAwasExpanded = false;
  90. }
  91. }
  92. },
  93. 'keyup': function (obj, event) {
  94. if ((event.keyCode == 13 || event.keyCode == 27) && !this.ALOHAwasExpanded) {
  95. // work around stupid behavior when moving focus :/
  96. setTimeout( function() {
  97. // Set focus to link element and select the object
  98. GENTICS.Aloha.activeEditable.obj[0].focus();
  99. GENTICS.Aloha.Selection.getRangeObject().select();
  100. }, 0);
  101. }
  102. // update attribute, but only if no resource item was selected
  103. if (!this.resourceItem) {
  104. var v = this.wrap.dom.children[0].value;
  105. this.setAttribute(this.targetAttribute, v);
  106. }
  107. },
  108. 'focus': function(obj, event) {
  109. // set background color to give visual feedback which link is modified
  110. var target = jQuery(this.getTargetObject());
  111. var s = target.css('background-color');
  112. if ( target && target.context.style && target.context.style['background-color'] ) {
  113. target.attr('data-original-background-color', target.context.style['background-color']);
  114. }
  115. target.css('background-color','Highlight');
  116. },
  117. 'blur': function(obj, event) {
  118. // remove the highlighting and restore original color if was set before
  119. var target = jQuery(this.getTargetObject());
  120. if ( target ) {
  121. if ( color = target.attr('data-original-background-color') ) {
  122. jQuery(target).css('background-color', color);
  123. } else {
  124. jQuery(target).removeCss('background-color');
  125. }
  126. jQuery(target).removeAttr('data-original-background-color');
  127. }
  128. },
  129. 'expand': function (combo ) {
  130. if( this.noQuery ) {
  131. this.collapse();
  132. }
  133. if (!this.clickAttached) {
  134. var that = this;
  135. // attach the missing mousedown event to be able to select autocomplete items by clicking on them
  136. this.mon(this.innerList, 'mousedown', function (event) {
  137. this.onViewClick(true); // select the item that has been clicked
  138. event.stopEvent(); // stop floating menu from closing
  139. }, this);
  140. this.clickAttached = true;
  141. }
  142. }
  143. },
  144. setItem: function( item, displayField ) {
  145. this.resourceItem = item;
  146. if ( item ) {
  147. displayField = (displayField) ? displayField : this.displayField;
  148. // TODO split display field by '.' and get corresponding attribute, because it could be a properties attribute.
  149. var v = item[displayField];
  150. this.setValue( v );
  151. this.setAttribute(this.targetAttribute, item[this.valueField]);
  152. // call the repository marker
  153. GENTICS.Aloha.RepositoryManager.markObject(this.targetObject, item);
  154. }
  155. },
  156. getItem: function( ) {
  157. return this.resourceItem;
  158. },
  159. // Private hack to allow attribute setting by regex
  160. setAttribute: function (attr, value, regex, reference) {
  161. if ( this.targetObject) {
  162. // set the attribute
  163. var setAttr = true;
  164. // check if a reference value is submitted to check against with a regex
  165. if ( typeof reference != 'undefined' ) {
  166. var regxp = new RegExp( regex );
  167. if ( !reference.match(regxp) ) {
  168. setAttr = false;
  169. }
  170. }
  171. // if no regex was successful or no reference value
  172. // was submitted remove the attribute
  173. if ( setAttr ) {
  174. jQuery(this.targetObject).attr(attr, value);
  175. } else {
  176. jQuery(this.targetObject).removeAttr(attr);
  177. }
  178. }
  179. },
  180. setTargetObject : function (obj, attr) {
  181. this.targetObject = obj;
  182. this.targetAttribute = attr;
  183. if (this.targetObject && this.targetAttribute) {
  184. this.setValue(jQuery(this.targetObject).attr(this.targetAttribute));
  185. } else {
  186. this.setValue('');
  187. }
  188. // check whether a repository item is linked to the object
  189. var that = this;
  190. GENTICS.Aloha.RepositoryManager.getObject(obj, function (items) {
  191. if (items && items.length > 0) {
  192. that.setItem(items[0]);
  193. }
  194. });
  195. },
  196. getTargetObject : function () {
  197. return this.targetObject;
  198. },
  199. setObjectTypeFilter : function (otFilter) {
  200. this.objectTypeFilter = otFilter;
  201. },
  202. getObjectTypeFilter : function () {
  203. return this.objectTypeFilter;
  204. },
  205. noQuery: true
  206. });
  207. /**
  208. * Register the Aloha attribute field
  209. * @hide
  210. */
  211. Ext.reg('alohaattributefield', Ext.ux.AlohaAttributeField);
  212. /**
  213. * Aloha Attribute Field Button
  214. * @namespace GENTICS.Aloha.ui
  215. * @class AttributeField
  216. */
  217. GENTICS.Aloha.ui.AttributeField = function (properties) {
  218. /**
  219. * @cfg Function called when an element is selected
  220. */
  221. this.onSelect = null;
  222. this.listenerQueue = [];
  223. this.objectTypeFilter = null;
  224. this.tpl = null;
  225. this.displayField = null;
  226. this.valueField = null;
  227. this.init(properties);
  228. };
  229. /**
  230. * Inherit all methods and properties from GENTICS.Aloha.ui.Button
  231. * @hide
  232. */
  233. GENTICS.Aloha.ui.AttributeField.prototype = new GENTICS.Aloha.ui.Button();
  234. /**
  235. * Create a extjs alohaattributefield
  236. * @hide
  237. */
  238. GENTICS.Aloha.ui.AttributeField.prototype.getExtConfigProperties = function() {
  239. var props = {
  240. alohaButton: this,
  241. xtype : 'alohaattributefield',
  242. rowspan: this.rowspan||undefined,
  243. width: this.width||undefined,
  244. id : this.id
  245. };
  246. if (this.valueField) {
  247. props.valueField = this.valueField;
  248. }
  249. if (this.displayField) {
  250. props.displayField = this.displayField;
  251. }
  252. return props;
  253. };
  254. /**
  255. * Sets the target Object of which the Attribute should be modified
  256. * @param {jQuery} obj the target object
  257. * @param {String} attr Attribute to be modified ex. "href" of a link
  258. * @void
  259. */
  260. GENTICS.Aloha.ui.AttributeField.prototype.setTargetObject = function (obj, attr) {
  261. if (this.extButton) {
  262. this.extButton.setTargetObject(obj, attr);
  263. }
  264. };
  265. /**
  266. * @return {jQuery} object Returns the current target Object
  267. */
  268. GENTICS.Aloha.ui.AttributeField.prototype.getTargetObject = function () {
  269. if (this.extButton) {
  270. return this.extButton.getTargetObject();
  271. } else {
  272. return null;
  273. }
  274. };
  275. /**
  276. * Focus to this field
  277. * @void
  278. */
  279. GENTICS.Aloha.ui.AttributeField.prototype.focus = function () {
  280. if (this.extButton) {
  281. this.extButton.focus();
  282. if ( this.extButton.getValue().length > 0 ) {
  283. this.extButton.selectText( 0, this.extButton.getValue().length );
  284. }
  285. }
  286. };
  287. /**
  288. * Adding a listener to the field
  289. * @param {String} eventname The name of the event. Ex. 'keyup'
  290. * @param {function} handler The function that should be called when the event happens.
  291. * @param {Object} scope The scope object which the event should be attached
  292. */
  293. GENTICS.Aloha.ui.AttributeField.prototype.addListener = function ( eventName, handler, scope) {
  294. if (this.extButton) {
  295. this.extButton.addListener(eventName, handler, null);
  296. } else {
  297. // if extButton not yet initialized adding listeners could be a problem
  298. // so all events are collected in a queue and added on initalizing
  299. listener = {
  300. 'eventName': eventName,
  301. 'handler': handler,
  302. 'scope': scope,
  303. 'options': null
  304. };
  305. this.listenerQueue.push(listener);
  306. }
  307. };
  308. /**
  309. * Sets an attribute optionally based on a regex on reference
  310. * @param {String} attr The Attribute name which should be set. Ex. "lang"
  311. * @param {String} value The value to set. Ex. "de-AT"
  312. * @param {String} regex The regex when the attribute should be set. The regex is applied to the value of refernece.
  313. * @param {String} reference The value for the regex.
  314. */
  315. GENTICS.Aloha.ui.AttributeField.prototype.setAttribute = function (attr, value, regex, reference) {
  316. if (this.extButton) {
  317. this.extButton.setAttribute(attr, value, regex, reference);
  318. }
  319. };
  320. /**
  321. * When at least on objectType is set the value in the Attribute field does a query to all registered repositories.
  322. * @param {Array} objectTypeFilter The array of objectTypeFilter to be searched for.
  323. * @void
  324. */
  325. GENTICS.Aloha.ui.AttributeField.prototype.setObjectTypeFilter = function (objectTypeFilter) {
  326. if (this.extButton) {
  327. this.noQuery = false;
  328. this.extButton.setObjectType(objectTypeFilter);
  329. } else {
  330. if ( !objectTypeFilter ) {
  331. objectTypeFilter = 'all';
  332. }
  333. this.objectTypeFilter = objectTypeFilter;
  334. }
  335. };
  336. /**
  337. * Sets an item to the link tag.
  338. * @param {resourceItem} item
  339. */
  340. GENTICS.Aloha.ui.AttributeField.prototype.setItem = function ( item , displayField ) {
  341. if (this.extButton) {
  342. this.extButton.setItem( item, displayField );
  343. }
  344. };
  345. /**
  346. * Gets current item set.
  347. * @return {resourceItem} item
  348. */
  349. GENTICS.Aloha.ui.AttributeField.prototype.getItem = function ( ) {
  350. if (this.extButton) {
  351. return this.extButton.getItem();
  352. }
  353. return null;
  354. };
  355. /**
  356. * Returns the current value
  357. * @return {String} attributeValue
  358. */
  359. GENTICS.Aloha.ui.AttributeField.prototype.getValue = function () {
  360. if (this.extButton) {
  361. return this.extButton.getValue();
  362. }
  363. return null;
  364. };
  365. /**
  366. * Sets the current value
  367. * @param {String} va attributeValue
  368. */
  369. GENTICS.Aloha.ui.AttributeField.prototype.setValue = function (v) {
  370. if (this.extButton) {
  371. this.extButton.setValue(v);
  372. }
  373. };
  374. /**
  375. * Returns the current query value.
  376. * @return {String} queryValue
  377. */
  378. GENTICS.Aloha.ui.AttributeField.prototype.getQueryValue = function () {
  379. if (this.extButton) {
  380. //return this.extButton.getValue();
  381. return this.extButton.wrap.dom.children[0].value;
  382. }
  383. return null;
  384. };
  385. /**
  386. * Set the display field, which is displayed in the combobox
  387. * @param {String} displayField name of the field to be displayed
  388. * @return display field name on success, null otherwise
  389. */
  390. GENTICS.Aloha.ui.AttributeField.prototype.setDisplayField = function (displayField) {
  391. if (this.extButton) {
  392. return this.extButton.displayField = displayField;
  393. } else {
  394. return this.displayField = displayField;
  395. }
  396. return null;
  397. };
  398. /**
  399. * Set the row template for autocomplete hints. The default template is:
  400. * <span><b>{name}</b><br />{url}</span>
  401. * @param {String} tpl template to be rendered for each row
  402. * @return template on success or null otherwise
  403. */
  404. GENTICS.Aloha.ui.AttributeField.prototype.setTemplate = function (tpl) {
  405. var template = new Ext.XTemplate(
  406. '<tpl for="."><div class="x-combo-list-item">',
  407. '<tpl if="this.hasRepositoryTemplate(values)">{[ this.renderRepositoryTemplate(values) ]}</tpl>',
  408. '<tpl if="!this.hasRepositoryTemplate(values)">' + tpl + '</tpl>',
  409. '</div></tpl>',
  410. {
  411. hasRepositoryTemplate : function(values) {
  412. var rep = GENTICS.Aloha.RepositoryManager.getRepository(values.repositoryId);
  413. return rep && rep.hasTemplate();
  414. },
  415. renderRepositoryTemplate : function(values) {
  416. var rep = GENTICS.Aloha.RepositoryManager.getRepository(values.repositoryId);
  417. if (rep && rep.hasTemplate()) {
  418. return rep.getTemplate().apply(values);
  419. }
  420. }
  421. }
  422. );
  423. if (this.extButton) {
  424. return this.extButton.tpl = template;
  425. } else {
  426. return this.tpl = template;
  427. }
  428. };