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

/sites/all/modules/panels/js/list.js

http://drupaltest.googlecode.com/
JavaScript | 381 lines | 288 code | 50 blank | 43 comment | 52 complexity | c05b20ad45490a91f407bae3a0cbbc95 MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0
  1. // $Id: list.js,v 1.2 2008/07/16 00:09:04 merlinofchaos Exp $
  2. /**
  3. * List object
  4. *
  5. * Settings:
  6. *
  7. * container
  8. * up
  9. * down
  10. * delete: input image
  11. * order: input hidden
  12. * add: input to add items
  13. * path: path to add items
  14. * tr: the base id of the tr
  15. */
  16. Drupal.list = function(base, settings) {
  17. // Set the properties for this object.
  18. if (settings.container == null) {
  19. settings.container = settings.row_class;
  20. }
  21. var max = function(array) {
  22. return Math.max.apply(Math, array);
  23. };
  24. this.settings = settings;
  25. this.base = '#' + base;
  26. // helper function to swap items in an array
  27. var swap = function(array, a, b) {
  28. var temp = array[a];
  29. array[a] = array[b];
  30. array[b] = temp;
  31. };
  32. var saveOrder = function(order) {
  33. var new_order = '';
  34. for (i in order) {
  35. if (new_order) {
  36. new_order += ',';
  37. }
  38. new_order += order[i];
  39. }
  40. $(settings.order).val(new_order);
  41. if (settings.hidden) {
  42. $(settings.hidden).show();
  43. }
  44. // console.log(order);
  45. };
  46. var changeOrder = function(item, how) {
  47. // If there isn't an order field, don't process this.
  48. if (!settings.order) {
  49. return;
  50. }
  51. // console.log(settings.order);
  52. var order_text = $(settings.order).val();
  53. if (order_text == '') {
  54. var order = [];
  55. }
  56. else {
  57. var order = order_text.split(',');
  58. }
  59. // console.log(order);
  60. if (how != 'add') {
  61. var tr = $(item).parents('tr').get(0);
  62. var id = $(tr).attr('id').replace(settings.tr, '');
  63. var index = -1;
  64. for (var i in order) {
  65. if (order[i] == id) {
  66. index = parseInt(i);
  67. break;
  68. }
  69. }
  70. }
  71. switch (how) {
  72. case 'add':
  73. order.push(item);
  74. break;
  75. case 'delete':
  76. order.splice(index, 1);
  77. break;
  78. case 'up':
  79. swap(order, index, index - 1);
  80. break;
  81. case 'down':
  82. swap(order, index, index + 1);
  83. break;
  84. }
  85. saveOrder(order);
  86. };
  87. this.changeOrder = changeOrder;
  88. var restripeTable = function(table) {
  89. // :even and :odd are reversed because jquery counts from 0 and
  90. // we count from 1, so we're out of sync.
  91. $('tbody tr:not(:hidden)', $(table))
  92. .removeClass('even')
  93. .removeClass('odd')
  94. .filter(':even')
  95. .addClass('odd')
  96. .end()
  97. .filter(':odd')
  98. .addClass('even');
  99. };
  100. this.restripeTable = restripeTable;
  101. var changed = function(item) {
  102. if (!item.is('.changed')) {
  103. item.addClass('changed');
  104. item.children('td:first').append(' <span class="star">*</span> ');
  105. }
  106. };
  107. // Set as a function so we can be both a closure and called later
  108. // when more items get added.
  109. this.bindButtons = function() {
  110. if (settings.remove) {
  111. $(settings.remove + ':not(.list-processed)')
  112. .addClass('list-processed')
  113. .click(function() { return false; })
  114. .click(function(e) {
  115. var item = $(this).parents(settings.container);
  116. changeOrder(this, 'delete');
  117. item.remove();
  118. restripeTable('#' + base);
  119. return false;
  120. });
  121. }
  122. if (settings.clear_list) {
  123. $(settings.clear_list + ':not(.list-processed)')
  124. .addClass('list-processed')
  125. .click(function() { return false; })
  126. .click(function(e) {
  127. $(settings.row_class).each(function() { $(this).remove() });
  128. saveOrder([]);
  129. });
  130. }
  131. if (settings.up) {
  132. $(settings.up + ':not(.list-processed)')
  133. .addClass('list-processed')
  134. .click(function() { return false; })
  135. .click(function(e) {
  136. var item = $(this).parents(settings.container);
  137. var prev = $(item).prev();
  138. if (prev.html() != null && item != prev) {
  139. // move item
  140. prev.before(item);
  141. restripeTable('#' + base);
  142. changed(item);
  143. changeOrder(this, 'up');
  144. }
  145. return false;
  146. });
  147. }
  148. if (settings.down) {
  149. $(settings.down + ':not(.list-processed)')
  150. .addClass('list-processed')
  151. .click(function() { return false; })
  152. .click(function(e) {
  153. var item = $(this).parents(settings.container);
  154. var next = $(item).next();
  155. if (next.html() != null && item != next) {
  156. // move item
  157. next.after(item);
  158. restripeTable('#' + base);
  159. changed(item);
  160. changeOrder(this, 'down');
  161. }
  162. return false;
  163. });
  164. }
  165. var bindAjaxResponse = function (data) {
  166. // Parse response
  167. data = Drupal.parseJson(data);
  168. if (data.debug) {
  169. alert(data.debug);
  170. }
  171. switch(data.type) {
  172. case 'display':
  173. // Display our modal popup
  174. $('#panels-modal').modalContent({
  175. opacity: '.40',
  176. background: '#fff'
  177. }
  178. );
  179. // append the output
  180. $('#modalContent span.modal-title').html(data.title);
  181. $('#modalContent div.modal-content').html(data.output);
  182. // Bind forms to ajax submit.
  183. $('div.panels-modal-content form').unbind('submit'); // be safe here.
  184. $('div.panels-modal-content form').submit(function() {
  185. $(this).ajaxSubmit({
  186. url: data.url,
  187. data: '',
  188. method: 'post',
  189. after: bindAjaxResponse
  190. });
  191. return false;
  192. });
  193. // hack: allow collapsible textareas to work
  194. Drupal.Panels.Subform.bindCollapsible();
  195. Drupal.Panels.Subform.bindAutocomplete();
  196. return;
  197. case 'add':
  198. // add new data
  199. Drupal.freezeHeight();
  200. // Hide the new content before adding to page.
  201. // Add the form and re-attach behavior.
  202. $('#' + base + ' tbody').append(data.output);
  203. changed($('#' + base + ' tbody tr:last'));
  204. changeOrder(data.position, 'add');
  205. // If we're told we have extra things to put out there, do so.
  206. // Must be done prior to button binding.
  207. if (settings.replace) {
  208. for (i in settings.replace) {
  209. if (data[settings.replace[i]]) {
  210. $(i).html(data[settings.replace[i]]);
  211. }
  212. }
  213. }
  214. // Run a bind for every list we know about
  215. for (list in Drupal.list.lists) {
  216. Drupal.list.lists[list].bindButtons();
  217. }
  218. Drupal.unfreezeHeight();
  219. // Add the extra data, if necessary
  220. if (data.extra && settings.extra) {
  221. var val = $(settings.extra).val();
  222. if (val) {
  223. val += ',';
  224. }
  225. val += data.extra;
  226. $(settings.extra).val(val);
  227. }
  228. if (settings.clear) {
  229. for (i in settings.clear) {
  230. $(settings.clear[i]).val('');
  231. }
  232. }
  233. $('#panels-modal').unmodalContent();
  234. return;
  235. case 'dismiss':
  236. // just dismiss the dialog.
  237. // console.log(data.replace);
  238. if (data.replace_id && data.replace) {
  239. $(data.replace_id).html(data.replace);
  240. changed($(data.replace_id));
  241. // Run a bind for every list we know about
  242. for (list in Drupal.list.lists) {
  243. Drupal.list.lists[list].bindButtons();
  244. }
  245. }
  246. $('#panels-modal').unmodalContent();
  247. return;
  248. default:
  249. $('#panels-modal').unmodalContent();
  250. alert("Unknown response from server.");
  251. return;
  252. }
  253. };
  254. if (settings.add) {
  255. $(settings.add + ':not(.list-processed)')
  256. .addClass('list-processed')
  257. .click(function() { return false; })
  258. .click(function(e) {
  259. var input = this;
  260. $(input).attr('disabled', true);
  261. $(input).parent().addClass('throbbing');
  262. var data = { };
  263. for (i in settings.post) {
  264. data[$(settings.post[i]).attr('name')] = $(settings.post[i]).val();
  265. }
  266. $.ajax({
  267. type: 'POST',
  268. data: data,
  269. url: settings.path,
  270. global: true,
  271. success: function(data) {
  272. $(input).parent().removeClass('throbbing');
  273. $(input).attr('disabled', false);
  274. bindAjaxResponse(data);
  275. },
  276. error: function(data) {
  277. alert('An error occurred while attempting to process the data.');
  278. $(input).parent().removeClass('throbbing');
  279. $(input).attr('disabled', false);
  280. }
  281. });
  282. return false;
  283. });
  284. }
  285. if (settings.configure) {
  286. $(settings.configure + ':not(.list-processed)')
  287. .addClass('list-processed')
  288. .click(function() { return false; })
  289. .click(function(e) {
  290. var input = this;
  291. var tr = $(this).parents('tr').get(0);
  292. var id = $(tr).attr('id').replace(settings.tr, '');
  293. var data = { position: id };
  294. $.ajax({
  295. type: 'POST',
  296. data: data,
  297. url: settings.configure_path,
  298. global: true,
  299. success: bindAjaxResponse,
  300. error: function(data) {
  301. alert('An error occurred while attempting to process the data.');
  302. }
  303. });
  304. return false;
  305. });
  306. }
  307. };
  308. // Focus if we're told to.
  309. if (settings.focus) {
  310. $(settings.focus).get(0).focus();
  311. }
  312. this.bindButtons();
  313. }
  314. Drupal.list.autoAttach = function() {
  315. if (Drupal.settings && Drupal.settings.list) {
  316. Drupal.list.lists = {};
  317. for (var base in Drupal.settings.list) {
  318. if (!$('#'+ base + '.list-processed').size()) {
  319. var settings = Drupal.settings.list[base];
  320. var list = new Drupal.list(base, settings);
  321. Drupal.list.lists[base] = list;
  322. $('#'+ base).addClass('list-processed');
  323. }
  324. }
  325. }
  326. Drupal.Panels.Subform.createModal();
  327. };
  328. if (Drupal.jsEnabled) {
  329. $(document).ready(Drupal.list.autoAttach);
  330. }
  331. Drupal.Panels = {};