icon_select.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. //iTop Designer combo box for icons
  2. $(function()
  3. {
  4. // the widget definition, where "itop" is the namespace,
  5. // "icon_select" the widget name
  6. $.widget( "itop.icon_select",
  7. {
  8. // default options
  9. options:
  10. {
  11. items: [],
  12. current_idx: 0,
  13. labels: {cancel: 'Cancel', pick_icon_file: 'Select an icon file to upload:', upload_dlg_title: 'Icon Upload...', upload: 'Upload...'},
  14. post_upload_to: null
  15. },
  16. // the constructor
  17. _create: function()
  18. {
  19. var me = this;
  20. var sLabel = '';
  21. var sIcon = '';
  22. for(var i in this.options.items)
  23. {
  24. if(this.options.items[i].icon == '')
  25. {
  26. this.options.items[i].icon = GetAbsoluteUrlAppRoot()+'images/transparent_32_32.png';
  27. }
  28. }
  29. if (this.options.items.length > 0)
  30. {
  31. sIcon = this.options.items[this.options.current_idx].icon;
  32. sLabel = this.options.items[this.options.current_idx].label;
  33. }
  34. this.oImg = $('<img src="'+sIcon+'" style="vertical-align: middle;" foo="bar">');
  35. this.oLabel = $('<span>'+sLabel+'</span>');
  36. this.oButton = $('<button type="button" class="icon-select"><div style="display: inline-block;vertical-align: middle;"><span class="ui-icon ui-icon-triangle-1-s"/></div></button>');
  37. this.oButton.prepend(this.oLabel).prepend(this.oImg);
  38. this.oButton.click(function(event, ui) { me._on_button_clicked(event, ui); });
  39. this.element.after(this.oButton);
  40. this.element.addClass( "itop-icon-select" ).button();
  41. this.element.bind( "reverted.itop-icon-select", function(ev, data) {
  42. var idx = me._find_item(data.previous_value);
  43. if (idx != null)
  44. {
  45. me.oImg.attr('src', me.options.items[idx].icon);
  46. me.oLabel.text(me.options.items[idx].label);
  47. }
  48. });
  49. if (this.options.post_upload_to != null)
  50. {
  51. this.oUploadBtn = $('<button class="icon-select" type="button" title="'+this.options.labels['upload']+'"><div style="display: inline-block;position: relative;vertical-align:middle;height:48px; line-height:48px; width:16px"><span style="height:16px;display:block;position:absolute;top:50%;margin-top:-8px" class="ui-icon ui-icon-circle-plus"/></div></button>');
  52. this.oUploadBtn.click( function() { me._upload_dlg(); } );
  53. this.oButton.after(this.oUploadBtn);
  54. }
  55. var id = this.element.attr('id');
  56. $('#event_bus').bind('tabshow.itop-icon-select'+id, function(event) {
  57. // Compute the offsetX the first time the 'element' becomes visible...
  58. var bVisible = me.element.parent().is(':visible');
  59. if ((me.options.offsetX == null) && (bVisible))
  60. {
  61. me._refresh();
  62. }
  63. });
  64. this.oUploadDlg = null;
  65. this._refresh();
  66. },
  67. // called when created, and later when changing options
  68. _refresh: function()
  69. {
  70. if (!this.element.parent().is(':visible'))
  71. {
  72. this.options.offsetX = null; // Menu needs to be reconstructed when the button becomes visible
  73. }
  74. else
  75. {
  76. if (this.options.items.length > 0)
  77. {
  78. this.element.val(this.options.items[this.options.current_idx].value);
  79. this.oImg.attr('src', this.options.items[this.options.current_idx].icon);
  80. this.oLabel.text(this.options.items[this.options.current_idx].label);
  81. }
  82. this._create_menu();
  83. }
  84. },
  85. _create_menu: function()
  86. {
  87. var me = this;
  88. var sMenu = '<ul>';
  89. for(var i in this.options.items)
  90. {
  91. sMenu = sMenu + '<li><a href="#" value="'+i+'"><img src="'+this.options.items[i].icon+'" style="vertical-align: middle;">'+this.options.items[i].label+'</a></li>';
  92. }
  93. sMenu = sMenu + '</ul>';
  94. var iWidth = Math.max(250, this.oButton.width());
  95. this.oMenu = this.oButton.menu({ content: sMenu, callback: function(data) {me._on_icon_selection(data);}, showSpeed: 0, maxHeight: 300, flyOut: true, width: iWidth, positionOpts: {posX: 'left', posY: 'top', offsetX: 0, offsetY: 0} });
  96. },
  97. _on_button_clicked: function(event, ui)
  98. {
  99. // Adjust the position of the menu, in case the button was moved...
  100. // The simpler is to kill and rebuild the menu !!!
  101. KillAllMenus();
  102. this._create_menu();
  103. },
  104. // events bound via _bind are removed automatically
  105. // revert other modifications here
  106. _destroy: function()
  107. {
  108. this.element.removeClass( "itop-icon-select" );
  109. this.oButton.button( "destroy" );
  110. },
  111. // _setOptions is called with a hash of all options that are changing
  112. // always refresh when changing options
  113. _setOptions: function()
  114. {
  115. // in 1.9 would use _superApply
  116. this._superApply(arguments);
  117. this._refresh();
  118. },
  119. // _setOption is called for each individual option that is changing
  120. _setOption: function( key, value )
  121. {
  122. if (key == 'current_idx')
  123. {
  124. this.element.val(this.options.items[value].value).trigger('change');
  125. }
  126. // in 1.9 would use _super
  127. this._superApply(arguments);
  128. },
  129. _on_icon_selection: function(data)
  130. {
  131. this._setOptions({current_idx: data.item.attr('value')});
  132. },
  133. _find_item: function(value)
  134. {
  135. var res = null;
  136. for(var idx in this.options.items)
  137. {
  138. if (value == this.options.items[idx].value)
  139. {
  140. res = idx;
  141. break;
  142. }
  143. }
  144. return res;
  145. },
  146. add_item: function(value, label, icon, position)
  147. {
  148. if (position == 'bottom')
  149. {
  150. this.options.items.push({value: value, label: label, icon: icon });
  151. }
  152. else
  153. {
  154. // Assume 'top'
  155. this.options.items.unshift({value: value, label: label, icon: icon });
  156. }
  157. this._refresh();
  158. },
  159. get_post_upload_to: function()
  160. {
  161. return this.options.post_upload_to;
  162. },
  163. _upload_dlg: function()
  164. {
  165. var me = this;
  166. this.oUploadDlg = $('<div><p>'+this.options.labels['pick_icon_file']+'</p><p><input type="file" name="file" id="file"/></p></div>');
  167. this.element.after(this.oUploadDlg);
  168. $('input[type=file]').bind('change', function() { me._do_upload(); });
  169. this.oUploadDlg.dialog({
  170. width: 400,
  171. modal: true,
  172. title: this.options.labels['upload_dlg_title'],
  173. buttons: [
  174. { text: this.options.labels['cancel'], click: function() {
  175. me.oUploadDlg.dialog( "close" );
  176. }
  177. }
  178. ],
  179. close: function() { me._on_upload_close(); }
  180. });
  181. },
  182. _on_upload_close: function()
  183. {
  184. this.oUploadDlg.remove();
  185. this.oUploadDlg = null;
  186. },
  187. _do_upload: function()
  188. {
  189. var me = this;
  190. var $element = this.oUploadDlg.find('#file');
  191. this.oUploadDlg.closest('.ui-dialog').find('.ui-button').button('disable');
  192. if (ReplaceWithAnimation)
  193. {
  194. ReplaceWithAnimation($element);
  195. }
  196. $.ajaxFileUpload
  197. (
  198. {
  199. url: this.options.post_upload_to,
  200. secureuri:false,
  201. fileElementId:'file',
  202. dataType: 'json',
  203. success: function (data, status)
  204. {
  205. me._on_upload_complete(data);
  206. },
  207. error: function (data, status, e)
  208. {
  209. me._on_upload_error(data, status, e);
  210. }
  211. }
  212. );
  213. },
  214. _on_upload_complete: function(data)
  215. {
  216. //console.log(data);
  217. //console.log(data.icon);
  218. var sIcon = data.icon.replace(/&amp;/g, "&");
  219. //console.log(sIcon);
  220. this.add_item(data.id, data.msg, sIcon, 'top');
  221. this.element.val(data.id);
  222. var idx = this._find_item(data.id);
  223. if (idx != null)
  224. {
  225. this.oImg.attr('src', this.options.items[idx].icon);
  226. this.oLabel.text(this.options.items[idx].label);
  227. }
  228. this.element.trigger('change');
  229. this.oUploadDlg.dialog('close');
  230. },
  231. _on_upload_error: function(data, status, e)
  232. {
  233. alert(e);
  234. this.oUploadDlg.closest('.ui-dialog').find('.ui-button').button('enable');
  235. }
  236. });
  237. });