jquery.portlet.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. /*
  2. * jquery.portlet 1.1.3
  3. */
  4. (function($) {
  5. $.widget("ui.portlet", {
  6. options: {
  7. columns: {},
  8. sortable: true,
  9. singleView: true,
  10. removeItem: null,
  11. beforeDrag:null,
  12. afterDrag:null
  13. },
  14. /**
  15. * create portlet widget
  16. */
  17. _create: function() {
  18. this.element.addClass("ui-portlet");
  19. var _this = this;
  20. var _ele = _this.element;
  21. var o = _this.options;
  22. $.each(o.columns, function(ci, c) {
  23. var $column = $('<div/>', {
  24. width: c.width
  25. }).addClass('ui-portlet-column').appendTo(_ele);
  26. $.each(c.portlets, function(pi, p) {
  27. var item = $('<div/>').addClass('ui-portlet-item ui-widget ui-widget-content ui-helper-clearfix ui-corner-all').data('option', p).appendTo($column);
  28. if(p.attrs) {
  29. item.attr(p.attrs);
  30. }
  31. item.attr('title',p.title);
  32. item.attr('moreurl',p.more);
  33. // title
  34. var title = $('<div/>', {
  35. 'class': 'ui-portlet-header ui-widget-header ui-corner-all',
  36. html: function() {
  37. if($.isFunction(p.title)) {
  38. return p.title;
  39. }
  40. return "<span class='" + p.icon + "'></span>" + p.title;
  41. }
  42. }).appendTo(item);
  43. // add icon for title
  44. if(p.icon) {
  45. title.prepend("<span class='ui-portlet-header-icon ui-icon " + p.icon + "'></span>");
  46. }
  47. // event element
  48. title.prepend("<a href='#' class='ui-corner-all ui-portlet-event'><span class='ui-icon ui-icon-minusthick ui-portlet-toggle'></span></a>");
  49. title.prepend("<a href='#' class='ui-corner-all ui-portlet-event'><span class='ui-icon ui-icon-closethick ui-portlet-close'></span></a>");
  50. if(p.more){
  51. var url='"'+p.more+'"';
  52. title.prepend("<a href='#' onclick='getMore("+url+")' class='ui-corner-all ui-portlet-event'><span class='ui-icon ui-icon-folder-open'></span></a>");
  53. }
  54. // content
  55. var ct = $('<div/>', {
  56. 'class': 'ui-portlet-content'
  57. }).appendTo(item);
  58. // set content style
  59. if(p.content.style) {
  60. $(ct).css(p.content.style);
  61. }
  62. // set attrs
  63. if(p.content.attrs) {
  64. $.each(p.content.attrs, function(k, v) {
  65. var attr = ct.attr(k);
  66. if(attr) {
  67. if(k == 'style' && v.substr(v.length - 1) != ';') {
  68. attr += ';';
  69. }
  70. if(k == 'class') {
  71. attr += ' ';
  72. }
  73. attr += v;
  74. }
  75. ct.attr(k, attr);
  76. });
  77. }
  78. // load content
  79. _this._content.call(_ele, item, p, function(data) {
  80. // load scripts
  81. _this._loadScripts(p.scripts);
  82. });
  83. });
  84. });
  85. // init events
  86. _this._initEvents();
  87. // bind single view
  88. if (o.singleView === true) {
  89. _this._regSingleView();
  90. }
  91. // enable/disable sortable
  92. _this._sortable(o.sortable);
  93. },
  94. /**
  95. * set option for plugin
  96. * @param {[type]} key key
  97. * @param {[type]} value value
  98. */
  99. _setOption: function(key, value) {
  100. // static options
  101. if(this.options[key]) {
  102. this.options[key] = value;
  103. }
  104. // need handle speical
  105. switch(key) {
  106. case "sortable":
  107. this._sortable(value);
  108. break;
  109. }
  110. },
  111. /**
  112. * single view
  113. */
  114. _regSingleView: function() {
  115. var _ele = this.element;
  116. $(_ele).find('.ui-portlet-header').dblclick(function() {
  117. var $item = $(this).parents('.ui-portlet-item');
  118. var p = $item.data('option');
  119. // recovery normal model
  120. if($item.hasClass('ui-portlet-single-view')) {
  121. $(_ele).find('.ui-portlet-item').show();
  122. $item.removeClass('ui-portlet-single-view').animate({
  123. width: $item.data('width'),
  124. height: $item.data('height')
  125. }).css({
  126. position: 'static'
  127. }).removeData('width').removeData('height');
  128. // callback
  129. if(p.singleView) {
  130. if($.isFunction(p.singleView.recovery)) {
  131. p.singleView.recovery.call($item, p);
  132. }
  133. }
  134. } else {
  135. // enable single view
  136. $(_ele).find('.ui-portlet-item').hide();
  137. // move left:0 top:0, set width use body's width
  138. $item.show().addClass('ui-portlet-single-view').data({
  139. width: $item.width(),
  140. height: $item.height()
  141. }).css({
  142. position: 'absolute',
  143. left: 0,
  144. top: 0
  145. });
  146. // set width and height when enable single view
  147. var wh = {};
  148. if(p.singleView) {
  149. // use custom width and height
  150. if(p.singleView.width) {
  151. if($.isFunction(p.singleView.width)) {
  152. wh.width = p.singleView.width.call($item, p);
  153. } else {
  154. wh.width = p.singleView.width;
  155. }
  156. }
  157. if(p.singleView.height) {
  158. if($.isFunction(p.singleView.height)) {
  159. wh.height = p.singleView.height.call($item, p);
  160. } else {
  161. wh.height = p.singleView.height;
  162. }
  163. }
  164. } else {
  165. // use default width
  166. wh.width = $(_ele).width() + 14;
  167. }
  168. $item.animate({
  169. width: wh.width,
  170. height: wh.height
  171. });
  172. // callback
  173. if(p.singleView && $.isFunction(p.singleView.enable)) {
  174. p.singleView.enable.call($item, p);
  175. }
  176. }
  177. });
  178. },
  179. /**
  180. * load java scripts
  181. * @param {[string]} scripts [description]
  182. */
  183. _loadScripts: function(scripts) {
  184. if(scripts) {
  185. $.each(scripts, function() {
  186. var head = $('head').remove('#loadScript');
  187. $("<script>" + "</script>").attr({
  188. src: this,
  189. type: 'text/javascript',
  190. id: 'loadScript'
  191. }).appendTo(head);
  192. });
  193. }
  194. },
  195. /**
  196. * enable/disable sortable
  197. * @param {[type]} value [true|false]
  198. */
  199. _sortable: function(value) {
  200. var _this=this;
  201. var o=_this.options;
  202. var element=this.element;
  203. var st = $(".ui-portlet-column", element).sortable({
  204. connectWith: ".ui-portlet-column",
  205. start:function(e,u){
  206. var colNum=element.parent().index();
  207. var sn=element.index();
  208. if($.isFunction(o.beforeDrag)){
  209. o.beforeDrag(colNum,sn);
  210. }
  211. },
  212. update:function(e,u){
  213. if($.isFunction(o.afterDrag)){
  214. o.afterDrag();
  215. }
  216. }
  217. }).disableSelection();
  218. if(value === true) {
  219. $(this.element).find('.ui-portlet-header').css('cursor', 'move');
  220. st.sortable('enable');
  221. $(".ui-portlet-content", this.element).draggable({
  222. start: function(e, ui) {
  223. return false;
  224. }
  225. });
  226. } else {
  227. $(this.element).find('.ui-portlet-header').css('cursor', 'default');
  228. st.sortable('disable');
  229. }
  230. },
  231. /**
  232. * events and handlers
  233. * @return {[type]} [description]
  234. */
  235. _initEvents: function() {
  236. var _this = this;
  237. // toggle contents
  238. var toggle = $(".ui-portlet-toggle", this.element).click(function(event) {
  239. $(this).toggleClass("ui-icon-minusthick").toggleClass("ui-icon-plusthick");
  240. $(this).parents(".ui-portlet-item:first").find(".ui-portlet-content").slideToggle();
  241. }).dblclick(function(event) {
  242. event.stopPropagation();
  243. });
  244. var refresh = $(".ui-portlet-refresh", this.element).click(function(event) {
  245. _this.refresh.call(_this, event);
  246. }).dblclick(function(event) {
  247. event.stopPropagation();
  248. });
  249. var close = $(".ui-portlet-close", this.element).click(function(event) {
  250. _this._destoryItem.call(_this, event);
  251. }).dblclick(function(event) {
  252. event.stopPropagation();
  253. });
  254. this._hoverable(toggle.parent());
  255. this._hoverable(refresh.parent());
  256. },
  257. /**
  258. * hoverable
  259. */
  260. _hoverable: function(element) {
  261. $(element).hover(function() {
  262. $(this).addClass('ui-state-hover');
  263. }, function() {
  264. $(this).removeClass('ui-state-hover');
  265. });
  266. },
  267. /**
  268. * destory single portlet
  269. */
  270. _destoryItem: function(event) {
  271. var o = this.options;
  272. var item = $(event.target).parents('.ui-portlet-item');
  273. var i=item.index();
  274. var j=item.parents('.ui-sortable').index();
  275. item.remove();
  276. if($.isFunction(o.removeItem)) {
  277. o.removeItem(i,j);
  278. }
  279. },
  280. /**
  281. * refresh contents
  282. */
  283. refresh: function(event) {
  284. var o = this.options;
  285. var portlet = $(event.target).parents('.ui-portlet');
  286. var item = $(event.target).parents('.ui-portlet-item');
  287. var pio = item.data('option');
  288. var ct = item.find('.ui-portlet-content');
  289. var pt = item.parents('.ui-portlet');
  290. // callback
  291. if($.isFunction(pio.beforeRefresh)) {
  292. pio.beforeRefresh.call(pt, pio);
  293. }
  294. // set contents
  295. this._content.call(portlet, item, pio, function(data) {
  296. // callback
  297. if($.isFunction(pio.afterRefresh)) {
  298. pio.afterRefresh.call(pt, data, pio);
  299. }
  300. });
  301. // load scripts
  302. this._loadScripts(pio.scripts);
  303. },
  304. /**
  305. * get content from multi styles
  306. * @param {[type]} item [.ui-portlet-item]
  307. * @param {[type]} pio [portlet configs]
  308. * @param {[type]} cl [callback after load]
  309. */
  310. _content: function(item, pio, cl) {
  311. var o = this.options;
  312. var that = this;
  313. var type = pio.content.type;
  314. var content = null;
  315. var ct = item.find('.ui-portlet-content');
  316. // before show callback
  317. if($.isFunction(pio.content.beforeShow)) {
  318. pio.content.beforeShow.call(this, pio.content.text);
  319. }
  320. if(type == 'text') {
  321. content = pio.content.text;
  322. // get content from function
  323. if($.isFunction(content)) {
  324. content = content(that, item, pio);
  325. }
  326. if($.isFunction(cl)) {
  327. cl.call(that, content);
  328. }
  329. ct.html(content);
  330. _callAfterShow(pio.content.text);
  331. } else if(type == 'ajax') {
  332. var dataType = pio.content.dataType || 'html';
  333. $.ajax({
  334. url: pio.content.url,
  335. dataType: dataType,
  336. beforeSend: function() {
  337. $(ct).html('Loading...');
  338. },
  339. success: function(data, textStatus, jqXHR) {
  340. if(dataType == 'html') {
  341. content = data;
  342. $(ct).html(data);
  343. } else if(dataType == 'json') {
  344. if($.isFunction(pio.content.formatter)) {
  345. content = pio.content.formatter(o, pio, data);
  346. $(ct).html(content);
  347. }
  348. }
  349. _callAfterShow(content);
  350. if($.isFunction(cl)) {
  351. cl.call(that, data);
  352. }
  353. },
  354. error: function(jqXHR, textStatus, errorThrown) {
  355. var content = "<span style='padding:0.2em' class='ui-state-error ui-corner-all'>Load Error...</span>";
  356. $(ct).html(content);
  357. if ($.isFunction(pio.content.error)) {
  358. pio.content.error.call(ct, jqXHR, textStatus, errorThrown);
  359. }
  360. }
  361. });
  362. }
  363. /**
  364. * after show callback
  365. */
  366. function _callAfterShow(content) {
  367. if($.isFunction(pio.content.afterShow)) {
  368. pio.content.afterShow.call(that, content);
  369. }
  370. }
  371. },
  372. /**
  373. * destory portlet
  374. */
  375. _destroy: function() {
  376. this.element.removeClass("ui-portlet").text("");
  377. // call the base destroy function
  378. $.Widget.prototype.destroy.call(this);
  379. return this;
  380. }
  381. });
  382. })(jQuery);