icon_select.js 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  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. if (this.options.items.length > 0)
  23. {
  24. sIcon = this.options.items[this.options.current_idx].icon;
  25. sLabel = this.options.items[this.options.current_idx].label;
  26. }
  27. this.oImg = $('<img src="'+sIcon+'" style="vertical-align: middle;">');
  28. this.oLabel = $('<span>'+sLabel+'</span>');
  29. this.oButton = $('<button><div style="display: inline-block;vertical-align: middle;"><span class="ui-icon ui-icon-triangle-1-s"/></div></button>');
  30. this.oButton.prepend(this.oLabel).prepend(this.oImg);
  31. this.element.after(this.oButton);
  32. this.element.addClass( "itop-icon-select" ).button();
  33. this.element.bind( "reverted.itop-icon-select", function(ev, data) {
  34. var idx = me._find_item(data.previous_value);
  35. if (idx != null)
  36. {
  37. me.oImg.attr('src', me.options.items[idx].icon);
  38. me.oLabel.text(me.options.items[idx].label);
  39. }
  40. });
  41. if (this.options.post_upload_to != null)
  42. {
  43. this.oUploadBtn = $('<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>');
  44. this.oUploadBtn.click( function() { me._upload_dlg(); } );
  45. this.oButton.after(this.oUploadBtn);
  46. }
  47. this.oUploadDlg = null;
  48. this._refresh();
  49. },
  50. // called when created, and later when changing options
  51. _refresh: function()
  52. {
  53. if (this.options.items.length > 0)
  54. {
  55. this.element.val(this.options.items[this.options.current_idx].value);
  56. this.oImg.attr('src', this.options.items[this.options.current_idx].icon);
  57. this.oLabel.text(this.options.items[this.options.current_idx].label);
  58. }
  59. this._create_menu();
  60. },
  61. _create_menu: function()
  62. {
  63. var me = this;
  64. var sMenu = '<ul>';
  65. for(var i in this.options.items)
  66. {
  67. 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>';
  68. }
  69. sMenu = sMenu + '</ul>';
  70. var iWidth = Math.max(250, this.oButton.width());
  71. 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} });
  72. },
  73. // events bound via _bind are removed automatically
  74. // revert other modifications here
  75. _destroy: function()
  76. {
  77. this.element.removeClass( "itop-icon-select" );
  78. this.oButton._destroy();
  79. },
  80. // _setOptions is called with a hash of all options that are changing
  81. // always refresh when changing options
  82. _setOptions: function()
  83. {
  84. // in 1.9 would use _superApply
  85. this._superApply(arguments);
  86. this._refresh();
  87. },
  88. // _setOption is called for each individual option that is changing
  89. _setOption: function( key, value )
  90. {
  91. if (key == 'current_idx')
  92. {
  93. this.element.val(this.options.items[value].value).trigger('change');
  94. }
  95. // in 1.9 would use _super
  96. this._superApply(arguments);
  97. },
  98. _on_icon_selection: function(data)
  99. {
  100. this._setOptions({current_idx: data.item.attr('value')});
  101. },
  102. _find_item: function(value)
  103. {
  104. var res = null;
  105. for(var idx in this.options.items)
  106. {
  107. if (value == this.options.items[idx].value)
  108. {
  109. res = idx;
  110. break;
  111. }
  112. }
  113. return res;
  114. },
  115. add_item: function(value, label, icon, position)
  116. {
  117. if (position == 'bottom')
  118. {
  119. this.options.items.push({value: value, label: label, icon: icon });
  120. }
  121. else
  122. {
  123. // Assume 'top'
  124. this.options.items.unshift({value: value, label: label, icon: icon });
  125. }
  126. this._refresh();
  127. },
  128. _upload_dlg: function()
  129. {
  130. var me = this;
  131. this.oUploadDlg = $('<div><p>'+this.options.labels['pick_icon_file']+'</p><p><input type="file" name="file" id="file"/></p></div>');
  132. this.element.after(this.oUploadDlg);
  133. $('input[type=file]').bind('change', function() { me._do_upload(); });
  134. this.oUploadDlg.dialog({
  135. width: 400,
  136. modal: true,
  137. title: this.options.labels['upload_dlg_title'],
  138. buttons: [
  139. { text: this.options.labels['cancel'], click: function() {
  140. me.oUploadDlg.dialog( "close" );
  141. }
  142. }
  143. ],
  144. close: function() { me._on_upload_close(); }
  145. });
  146. },
  147. _on_upload_close: function()
  148. {
  149. this.oUploadDlg.remove();
  150. this.oUploadDlg = null;
  151. },
  152. _do_upload: function()
  153. {
  154. var me = this;
  155. $.ajaxFileUpload
  156. (
  157. {
  158. url: this.options.post_upload_to,
  159. secureuri:false,
  160. fileElementId:'file',
  161. dataType: 'json',
  162. success: function (data, status)
  163. {
  164. me._on_upload_complete(data);
  165. },
  166. error: function (data, status, e)
  167. {
  168. me._on_upload_error(data, status, e);
  169. }
  170. }
  171. );
  172. },
  173. _on_upload_complete: function(data)
  174. {
  175. console.log(data);
  176. console.log(data.icon);
  177. var sIcon = data.icon.replace(/&amp;/g, "&");
  178. console.log(sIcon);
  179. this.add_item(data.id, data.msg, sIcon, 'top');
  180. this.element.val(data.id);
  181. var idx = this._find_item(data.id);
  182. if (idx != null)
  183. {
  184. this.oImg.attr('src', this.options.items[idx].icon);
  185. this.oLabel.text(this.options.items[idx].label);
  186. }
  187. this.element.trigger('change');
  188. this.oUploadDlg.dialog( "close" );
  189. },
  190. _on_upload_error: function(data, status, e)
  191. {
  192. alert(e);
  193. }
  194. });
  195. });