main.js 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  1. (function ($) {
  2. $(document).ready(function() {
  3. var initFilters = function() {
  4. $('.changelist-filter-select').on('change', function () {
  5. var $select = $(this);
  6. var $selectedOption = $select.find('option:selected');
  7. var url = $selectedOption.data('url');
  8. var querysetLookup = $select.data('queryset--lookup');
  9. if (url) {
  10. document.location = $selectedOption.data('url');
  11. } else if (querysetLookup) {
  12. document.location = '?' + querysetLookup + '=' + $selectedOption.val();
  13. }
  14. });
  15. };
  16. var initChangeformTabs = function() {
  17. var $tabItems = $('.changeform-tabs-item');
  18. var $modules = $('.module');
  19. $('.changeform-tabs-item-link').click(function (e) {
  20. var $tabItemLink = $(this);
  21. var $tabItem = $tabItemLink.closest('.changeform-tabs-item');
  22. var moduleId = $tabItemLink.data('module-id');
  23. $tabItems.removeClass('selected');
  24. $tabItem.addClass('selected');
  25. var $module = $modules.removeClass('selected').filter('#' + moduleId).addClass('selected');
  26. $module.find('select').trigger('select:init');
  27. e.preventDefault();
  28. });
  29. };
  30. var initCheckboxesWithoutLabel = function () {
  31. var uniqueCheckboxIdCounter = 0;
  32. var uniqueCheckboxIdPrefix = 'unique_checkbox_id_';
  33. var addLabelToCheckbox = function($checkbox) {
  34. var checkboxId = $checkbox.attr('id') ? $checkbox.attr('id') : uniqueCheckboxIdPrefix + uniqueCheckboxIdCounter++;
  35. var $label = $('<label>').attr('for', checkboxId);
  36. $checkbox.hide().attr('id', checkboxId);
  37. $label.insertAfter($checkbox);
  38. };
  39. var addLabelToCheckboxes = function() {
  40. var $containers = $('.action-checkbox, .action-checkbox-column').add('.tabular.inline-related .form-row');
  41. var $checkboxes = $containers.find('input[type="checkbox"]').add('.checkbox-without-label');
  42. $checkboxes.each(function() {
  43. addLabelToCheckbox($(this));
  44. });
  45. };
  46. addLabelToCheckboxes();
  47. };
  48. var initUserTools = function() {
  49. var $userTools = $('.top-user-tools');
  50. var closeTimeout;
  51. $userTools.on('mouseenter', function() {
  52. if (closeTimeout) {
  53. clearTimeout(closeTimeout);
  54. }
  55. $userTools.addClass('opened');
  56. });
  57. $userTools.on('mouseleave', function() {
  58. closeTimeout = setTimeout(function() {
  59. $userTools.removeClass('opened');
  60. closeTimeout = null;
  61. }, 200);
  62. });
  63. };
  64. var initSideMenu = function() {
  65. var initPopupItems = function() {
  66. var $popupContainer = $('.sidebar-popup-container');
  67. var $popup = $('.sidebar-popup');
  68. var $popupItems = $('.sidebar-popup-item');
  69. var $popupLinks = $('.popup-item-link');
  70. var $popupLink;
  71. var t;
  72. var $currentPopupItem;
  73. var $currentPopupItemListItem;
  74. var $currentPopupItemListItems = function() { return $currentPopupItem.find('.sidebar-popup-list-item:visible') };
  75. var resetCurrentPopupItemListItems = function() {
  76. $currentPopupItemListItems().removeClass('selected');
  77. };
  78. var initPopupItemsSearch = function() {
  79. $popupItems.each(function() {
  80. var $popupItem = $(this);
  81. var $search = $popupItem.find('.sidebar-popup-search');
  82. var $items = $popupItem.find('.sidebar-popup-list-item');
  83. $search.on('change keyup', function() {
  84. var text = $(this).val();
  85. $items.hide();
  86. $popupItem
  87. .find('.sidebar-popup-list-item-link:icontains("' + text + '")')
  88. .closest('.sidebar-popup-list-item')
  89. .show();
  90. });
  91. });
  92. };
  93. var showPopup = function ($popupLink) {
  94. clearHideTimeout();
  95. var popupItemId = $popupLink.data('popup-item-id');
  96. var $popupItem = $('#' + popupItemId);
  97. var $search = $popupItem.find('.sidebar-popup-search');
  98. $popupItems.hide();
  99. $popupItem.show();
  100. $popupContainer.stop().fadeIn(200, 'swing');
  101. $popupLinks.removeClass('hovered');
  102. $popupLink.addClass('hovered');
  103. $('body').addClass('non-scrollable');
  104. $currentPopupItem = $popupItem;
  105. $currentPopupItemListItem = null;
  106. resetCurrentPopupItemListItems();
  107. $search.val('').trigger('change').focus();
  108. };
  109. var hidePopup = function () {
  110. t = setTimeout(function() {
  111. $popupItems.hide();
  112. $popupContainer.stop().fadeOut(200, 'swing');
  113. $popupLinks.removeClass('hovered');
  114. $('body').removeClass('non-scrollable');
  115. $currentPopupItem = null;
  116. }, 200);
  117. };
  118. var clearHideTimeout = function() {
  119. if (t != null) {
  120. clearTimeout(t);
  121. }
  122. t = null;
  123. };
  124. $popupLinks.on('mouseenter', function () {
  125. $popupLink = $(this);
  126. showPopup($popupLink);
  127. });
  128. $popupLinks.on('mouseleave', function (e) {
  129. var $toElement = $(e.toElement);
  130. if ($toElement.hasClass('sidebar-popup') || $toElement.parents('.sidebar-popup').length) {
  131. return;
  132. }
  133. hidePopup();
  134. });
  135. $popup.on('mouseenter', function (e) {
  136. clearHideTimeout();
  137. });
  138. $popup.on('mouseleave', function (e) {
  139. var $toElement = $(e.toElement);
  140. if ($toElement.hasClass('popup-item-link')
  141. && $popupLink.data('popup-item-id') == $toElement.data('popup-item-id')) {
  142. return;
  143. }
  144. hidePopup();
  145. });
  146. $popup.find('.sidebar-popup-list-item-link').on('mouseenter', function() {
  147. var $link = $(this);
  148. var $item = $link.closest('.sidebar-popup-list-item');
  149. $currentPopupItemListItem = $item;
  150. resetCurrentPopupItemListItems();
  151. $currentPopupItemListItem.addClass('selected');
  152. });
  153. var selectCurrentPopupItemListItem = function(next) {
  154. if ($currentPopupItemListItem != null) {
  155. $currentPopupItemListItem = next ? $currentPopupItemListItem.nextAll(':visible').first() : $currentPopupItemListItem.prevAll(':visible').first();
  156. }
  157. if ($currentPopupItemListItem == null || $currentPopupItemListItem.length == 0) {
  158. $currentPopupItemListItem = next ? $currentPopupItemListItems().first() : $currentPopupItemListItems().last();
  159. }
  160. resetCurrentPopupItemListItems();
  161. $currentPopupItemListItem.addClass('selected');
  162. };
  163. $(document).keydown(function(e) {
  164. if ($currentPopupItem == null) {
  165. return;
  166. }
  167. if (e.which == 38) { //up
  168. selectCurrentPopupItemListItem(false);
  169. } else if (e.which == 40) { //down
  170. selectCurrentPopupItemListItem(true);
  171. } else if (e.which == 13) {
  172. if ($currentPopupItemListItem) {
  173. document.location = $currentPopupItemListItem.find('a').attr('href');
  174. }
  175. } else {
  176. return;
  177. }
  178. e.preventDefault();
  179. });
  180. initPopupItemsSearch();
  181. };
  182. var initBookmarks = function() {
  183. var $addForm = $('#bookmarks-add-form');
  184. var $removeForm = $('#bookmarks-remove-form');
  185. var $addTitleInput = $addForm.find('input[name="title"]');
  186. var $addUrlInput = $addForm.find('input[name="url"]');
  187. var $removeIdInput = $removeForm.find('input[name="id"]');
  188. $('.bookmarks-add').on('click', function(e) {
  189. e.preventDefault();
  190. var $link = $(this);
  191. var defaultTitle = $link.data('title') ? $link.data('title') : document.title;
  192. var url = window.location.href;
  193. $addTitleInput.val(defaultTitle);
  194. $addUrlInput.val(url);
  195. var addBookmark = function() {
  196. $.ajax({
  197. url: $addForm.attr('action'),
  198. method: $addForm.attr('method'),
  199. dataType: 'json',
  200. data: $addForm.serialize(),
  201. success: function (result) {
  202. if (result.error) {
  203. return;
  204. }
  205. var $list = $('.bookmarks-list');
  206. var $item = $('.sidebar-menu-item-list-item.empty').clone().removeClass('empty');
  207. $item.find('.sidebar-menu-item-list-item-link')
  208. .attr('href', url)
  209. .append($addTitleInput.val());
  210. $item.find('.sidebar-menu-item-list-item-link-remove').attr('data-bookmark-id', result.id);
  211. $list.append($item);
  212. }
  213. });
  214. };
  215. var buttons = {};
  216. buttons[django.gettext('Add')] = function() {
  217. addBookmark();
  218. $(this).dialog('close');
  219. };
  220. buttons[django.gettext('Cancel')] = function() {
  221. $(this).dialog('close');
  222. };
  223. $('#bookmarks-add-dialog').dialog({
  224. resizable: false,
  225. modal: true,
  226. buttons: buttons
  227. });
  228. });
  229. $(document).on('click', '.bookmarks-remove', function(e) {
  230. e.preventDefault();
  231. var $remove = $(this);
  232. var bookmarkId = $remove.data('bookmark-id');
  233. var deleteBookmark = function() {
  234. $removeIdInput.val(bookmarkId);
  235. $.ajax({
  236. url: $removeForm.attr('action'),
  237. method: $removeForm.attr('method'),
  238. dataType: 'json',
  239. data: $removeForm.serialize(),
  240. success: function (result) {
  241. if (result.error) {
  242. return;
  243. }
  244. var $item = $remove.closest('.sidebar-menu-item-list-item');
  245. $item.remove();
  246. }
  247. });
  248. };
  249. var buttons = {};
  250. buttons[django.gettext('Delete')] = function() {
  251. deleteBookmark();
  252. $(this).dialog('close');
  253. };
  254. buttons[django.gettext('Cancel')] = function() {
  255. $(this).dialog('close');
  256. };
  257. $('#bookmarks-remove-dialog').dialog({
  258. resizable: false,
  259. modal: true,
  260. buttons: buttons
  261. });
  262. });
  263. };
  264. var initApplicationPinning = function() {
  265. var $appsList = $('.apps-list');
  266. var $pinnedAppsList = $('.apps-list-pinned');
  267. var $appsHide = $('.apps-hide');
  268. var updateAppsHide = function () {
  269. var text;
  270. if ($appsList.is(':visible')) {
  271. text = django.gettext('Hide applications');
  272. } else {
  273. text = django.gettext('Show hidden');
  274. }
  275. $appsHide.text(text);
  276. if (($appsList.children().length == 0 || $pinnedAppsList.children().length == 0) && $appsList.is(':visible')) {
  277. $appsHide.hide();
  278. } else {
  279. $appsHide.show();
  280. }
  281. };
  282. $appsHide.on('click', function (e) {
  283. e.preventDefault();
  284. $appsList.slideFadeToggle(200, 'swing', function () {
  285. localStorage['side_menu_apps_list_visible'] = $appsList.is(':visible');
  286. updateAppsHide();
  287. });
  288. });
  289. $('.app-item .pin-toggle').on('click', function (e) {
  290. var $appItem = $(this).closest('.app-item');
  291. var appLabel = $appItem.data('app-label');
  292. var $form = $('#toggle-application-pin-form');
  293. $form.find('input[name="app_label"]').val(appLabel);
  294. $.ajax({
  295. url: $form.attr('action'),
  296. method: $form.attr('method'),
  297. dataType: 'json',
  298. data: $form.serialize(),
  299. success: function (result) {
  300. if (result.error) {
  301. return;
  302. }
  303. var $target = result.pinned ? $('.apps-list-pinned') : $('.apps-list');
  304. if (result.pinned) {
  305. $appItem.addClass('pinned');
  306. } else {
  307. $appItem.removeClass('pinned');
  308. }
  309. $appItem.detach();
  310. $appItem.appendTo($target);
  311. updateAppsHide();
  312. }
  313. });
  314. e.preventDefault();
  315. });
  316. if (localStorage['side_menu_apps_list_visible'] === 'false') {
  317. if ($pinnedAppsList.children().length != 0) {
  318. $appsList.hide();
  319. } else {
  320. localStorage['side_menu_apps_list_visible'] = true;
  321. }
  322. }
  323. updateAppsHide();
  324. };
  325. initPopupItems();
  326. initBookmarks();
  327. initApplicationPinning();
  328. };
  329. var initDeleteObjects = function() {
  330. $('.delete-objects-list-item.collapsable').each(function() {
  331. var $item = $(this);
  332. var $link = $item.find('.delete-objects-list-item-row-collapse');
  333. var $collapsable = $item.find('.delete-objects-list-item-collapsable');
  334. $link.on('click', function(e) {
  335. e.preventDefault();
  336. $collapsable.slideToggle(200, 'swing');
  337. });
  338. });
  339. };
  340. var initjQueryCaseInsensitiveSelector = function() {
  341. $.expr[":"].icontains = $.expr.createPseudo(function (arg) {
  342. return function (elem) {
  343. return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
  344. };
  345. });
  346. };
  347. var initjQuerySlideFadeToggle = function() {
  348. $.fn.slideFadeToggle = function (speed, easing, callback) {
  349. return this.animate({opacity: 'toggle', height: 'toggle'}, speed, easing, callback);
  350. };
  351. };
  352. var initDateTimeWidgets = function() {
  353. var removePreviousSibling = function($element) {
  354. var node = $element[0].previousSibling;
  355. node.parentNode.removeChild(node);
  356. };
  357. var djangoDateTimeFormatToJs = function(format) {
  358. return format.toLowerCase().replace(/%\w/g, function(format) {
  359. format = format.replace(/%/,"");
  360. return format + format;
  361. });
  362. };
  363. var updateDatetimeLayout = function() {
  364. $('.form-row .datetime').each(function () {
  365. var $dateTime = $(this);
  366. var $dateField = $dateTime.find('.vDateField');
  367. var $timeField = $dateTime.find('.vTimeField');
  368. removePreviousSibling($dateField);
  369. removePreviousSibling($timeField);
  370. $dateField.nextAll('br').first().remove();
  371. });
  372. };
  373. var initDateWidget = function() {
  374. $('.form-row .vDateField').each(function () {
  375. var $dateField = $(this);
  376. var $dateLink = $('<a href="#">').addClass('vDateField-link');
  377. var $dateButton = $('<span>').addClass('icon-calendar');
  378. $dateLink.append($dateButton).insertAfter($dateField);
  379. $dateField.datepicker({
  380. dateFormat: djangoDateTimeFormatToJs(DATE_FORMAT),
  381. showButtonPanel: true,
  382. nextText: '',
  383. prevText: ''
  384. });
  385. $dateLink.on('click', function (e) {
  386. if ($dateField.datepicker('widget').is(':visible')) {
  387. $dateField.datepicker('hide');
  388. } else {
  389. $dateField.datepicker('show');
  390. }
  391. e.preventDefault();
  392. });
  393. });
  394. };
  395. var initTimeWidget = function() {
  396. $('.form-row .vTimeField').each(function () {
  397. var $timeField = $(this);
  398. var $timeLink = $('<a href="#">').addClass('vTimeField-link');
  399. var $timeButton = $('<span>').addClass('icon-clock');
  400. $timeLink.append($timeButton).insertAfter($timeField);
  401. $timeField.timepicker({
  402. showPeriodLabels: false,
  403. showCloseButton: true,
  404. showNowButton: true
  405. });
  406. $timeLink.on('click', function (e) {
  407. if ($timeField.datepicker('widget').is(':visible')) {
  408. $timeField.datepicker('hide');
  409. } else {
  410. $timeField.timepicker('show');
  411. }
  412. e.preventDefault();
  413. });
  414. });
  415. };
  416. updateDatetimeLayout();
  417. initDateWidget();
  418. initTimeWidget();
  419. };
  420. var initInlines = function() {
  421. $('.module').each(function() {
  422. var $module = $(this);
  423. var $items = function() { return $module.find('.stacked-inline-list-item'); };
  424. var $inlinesRelated = function() { return $module.find('.inline-related'); };
  425. $module.on('click', '.stacked-inline-list-item-link', function(e) {
  426. var $itemLink = $(this);
  427. var $item = $itemLink.closest('.stacked-inline-list-item');
  428. var moduleId = $itemLink.data('inline-related-id');
  429. $items().removeClass('selected');
  430. $item.addClass('selected');
  431. $inlinesRelated().removeClass('selected').filter('#' + moduleId).addClass('selected');
  432. e.preventDefault();
  433. });
  434. $module.on('click', '.stacked-inline-list-item-link-remove', function(e) {
  435. var $itemLink = $(this).closest('.stacked-inline-list-item-link');
  436. var $item = $itemLink.closest('.stacked-inline-list-item');
  437. var moduleId = $itemLink.data('inline-related-id');
  438. $item.remove();
  439. $inlinesRelated().filter('#' + moduleId).remove();
  440. e.preventDefault();
  441. });
  442. $module.find('.inline-related').each(function() {
  443. var $inline = $(this);
  444. $inline.find('.delete input').on('change', function(e) {
  445. var $input = $(this);
  446. var id = $inline.attr('id');
  447. var $link = $module.find('.stacked-inline-list-item-link[data-inline-related-id="' + id + '"]');
  448. var $item = $link.closest('.stacked-inline-list-item');
  449. if ($input.is(':checked')) {
  450. $item.addClass('delete');
  451. } else {
  452. $item.removeClass('delete');
  453. }
  454. });
  455. });
  456. $module.find('.add-row a').on('click', function() {
  457. $module.find('select').trigger('select:init');
  458. });
  459. });
  460. };
  461. var initChangelist = function() {
  462. var initChangelistHeaders = function() {
  463. var $originalThead = $('.results thead');
  464. if ($originalThead.length == 0) {
  465. return;
  466. }
  467. var $thead = $originalThead.clone();
  468. var $table = $('<table>').addClass('table helper').append($thead);
  469. $table.find('.action-checkbox-column').empty();
  470. $table.appendTo(document.body);
  471. var updateChangelistHeaderVisibility = function () {
  472. if ($(window).scrollTop() > $originalThead.offset().top) {
  473. $table.show();
  474. } else {
  475. $table.hide();
  476. }
  477. };
  478. var updateChangelistHeaderWidth = function () {
  479. var $originalTheadColumns = $originalThead.find('th');
  480. var $theadColumns = $thead.find('th');
  481. $originalTheadColumns.each(function (i) {
  482. $theadColumns.eq(i).css('width', $(this).width());
  483. });
  484. };
  485. $(window).on('scroll', updateChangelistHeaderVisibility);
  486. $(window).on('resize', updateChangelistHeaderWidth);
  487. updateChangelistHeaderWidth();
  488. };
  489. var initChangelistFooters = function() {
  490. var $changelistFooters = $('.changelist-footer');
  491. if ($changelistFooters.length == 0) {
  492. return;
  493. }
  494. var updateChangelistFooters = function () {
  495. $changelistFooters.each(function () {
  496. var $changelistFooter = $(this);
  497. var $results = $changelistFooter.siblings('.results');
  498. if ($(window).scrollTop() + $(window).height() < $(document).height()) {
  499. if (!$changelistFooter.hasClass('fixed')) {
  500. var previousScrollTop = $(window).scrollTop();
  501. $changelistFooter.addClass('fixed');
  502. $results.css('margin-bottom', ($changelistFooter.outerHeight(false) - 20 - 2) + 'px');
  503. $(window).scrollTop(previousScrollTop);
  504. }
  505. } else {
  506. if ($changelistFooter.hasClass('fixed')) {
  507. $changelistFooter.removeClass('fixed');
  508. $results.css('margin-bottom', 0);
  509. }
  510. }
  511. });
  512. };
  513. $(window).on('scroll', updateChangelistFooters);
  514. $(window).on('resize', updateChangelistFooters);
  515. updateChangelistFooters();
  516. };
  517. var initChangelistImages = function() {
  518. $('img[src$="admin/img/icon-yes.gif"]').after($('<span class="icon-tick">'));
  519. $('img[src$="admin/img/icon-no.gif"]').after($('<span class="icon-cross">'));
  520. $('img[src$="admin/img/icon-unknown.gif"]').after($('<span class="icon-question">'));
  521. };
  522. initChangelistHeaders();
  523. initChangelistFooters();
  524. initChangelistImages();
  525. };
  526. var initTooltips = function() {
  527. $('a[title],.tooltip[title]').tooltip({
  528. track: true
  529. });
  530. };
  531. var initDashboard = function() {
  532. var updateDashboardModules = function () {
  533. var $form = $('#update-dashboard-modules-form');
  534. var modules = [];
  535. $('.dashboard-column').each(function () {
  536. var $column = $(this);
  537. var column = $column.closest('.dashboard-column-wrapper').index();
  538. $column.find('.dashboard-item').each(function () {
  539. var $item = $(this);
  540. var order = $item.index();
  541. var id = $item.data('module-id');
  542. modules.push({
  543. id: id,
  544. column: column,
  545. order: order
  546. });
  547. });
  548. });
  549. $form.find('[name="modules"]').val(JSON.stringify(modules));
  550. $.ajax({
  551. url: $form.attr('action'),
  552. method: $form.attr('method'),
  553. dataType: 'json',
  554. data: $form.serialize()
  555. });
  556. };
  557. $('.dashboard-column').droppable({
  558. activeClass: 'active',
  559. hoverClass: 'hovered',
  560. tolerance: 'pointer',
  561. accept: '.dashboard-item'
  562. }).sortable({
  563. items: '.dashboard-item',
  564. handle: '.dashboard-item-header',
  565. tolerance: 'pointer',
  566. connectWith: '.dashboard-column',
  567. cursor: 'move',
  568. placeholder: 'dashboard-item placeholder',
  569. forcePlaceholderSize: true,
  570. update: function (event, ui) {
  571. updateDashboardModules();
  572. }
  573. });
  574. $('.dashboard-item.collapsible').each(function () {
  575. var $item = $(this);
  576. var $link = $item.find('.dashboard-item-collapse');
  577. var $collapsible = $item.find('.dashboard-item-content');
  578. var $form = $('#update-dashboard-module-collapse-form');
  579. var moduleId = $item.data('module-id');
  580. $link.on('click', function (e) {
  581. e.preventDefault();
  582. $collapsible.slideFadeToggle(200, 'swing', function () {
  583. var collapsed = $collapsible.is(':visible') == false;
  584. if (collapsed) {
  585. $item.addClass('collapsed')
  586. } else {
  587. $item.removeClass('collapsed')
  588. }
  589. $form.find('[name="id"]').val(moduleId);
  590. $form.find('[name="collapsed"]').val(collapsed ? 'true' : 'false');
  591. $.ajax({
  592. url: $form.attr('action'),
  593. method: $form.attr('method'),
  594. dataType: 'json',
  595. data: $form.serialize()
  596. });
  597. });
  598. });
  599. });
  600. $('.dashboard-item.deletable').each(function () {
  601. var $item = $(this);
  602. var $link = $item.find('.dashboard-item-remove');
  603. var $form = $('#remove-dashboard-module-form');
  604. var moduleId = $item.data('module-id');
  605. $link.on('click', function (e) {
  606. e.preventDefault();
  607. var buttons = {};
  608. var deleteModule = function () {
  609. $item.fadeOut(200, 'swing', function () {
  610. $form.find('[name="id"]').val(moduleId);
  611. $.ajax({
  612. url: $form.attr('action'),
  613. method: $form.attr('method'),
  614. dataType: 'json',
  615. data: $form.serialize()
  616. });
  617. });
  618. };
  619. buttons[django.gettext('Delete')] = function () {
  620. deleteModule();
  621. $(this).dialog('close');
  622. };
  623. buttons[django.gettext('Cancel')] = function () {
  624. $(this).dialog('close');
  625. };
  626. $('#module-remove-dialog').dialog({
  627. resizable: false,
  628. modal: true,
  629. buttons: buttons
  630. });
  631. });
  632. });
  633. var $form = $('#add-dashboard-module-form');
  634. $form.find('.add-dashboard-link').on('click', function (e) {
  635. var $typeInput = $form.find('[name="type"]');
  636. var type = $form.find('[name="module"] option:selected').data('type');
  637. if (type) {
  638. $typeInput.val(type);
  639. $.ajax({
  640. url: $form.attr('action'),
  641. method: $form.attr('method'),
  642. dataType: 'json',
  643. data: $form.serialize(),
  644. success: function (result) {
  645. if (result.error) {
  646. return;
  647. }
  648. document.location = result.success_url;
  649. }
  650. });
  651. }
  652. e.preventDefault();
  653. });
  654. $('.dashboard-item.ajax').each(function () {
  655. var $item = $(this);
  656. var $content = $item.find('.dashboard-item-content');
  657. var url = $item.data('ajax-url');
  658. var moduleId = $item.data('module-id');
  659. $form.find('[name="id"]').val(moduleId);
  660. $.ajax({
  661. url: url,
  662. dataType: 'json',
  663. success: function (result) {
  664. if (result.error) {
  665. $content.empty();
  666. return;
  667. }
  668. var oldHeight = $content.height();
  669. $content.html(result.html);
  670. var newHeight = $content.height();
  671. $content.height(oldHeight);
  672. $content.animate({
  673. height: newHeight
  674. }, 250);
  675. },
  676. error: function() {
  677. $content.empty();
  678. }
  679. });
  680. });
  681. $('.reset-dashboard-link').on('click', function(e) {
  682. var buttons = {};
  683. var resetDashboard = function () {
  684. var $form = $('#reset-dashboard-form');
  685. $.ajax({
  686. url: $form.attr('action'),
  687. method: $form.attr('method'),
  688. dataType: 'json',
  689. data: $form.serialize(),
  690. success: function (result) {
  691. if (result.error) {
  692. return;
  693. }
  694. location.reload();
  695. }
  696. });
  697. };
  698. buttons[django.gettext('Yes')] = function() {
  699. resetDashboard();
  700. $(this).dialog('close');
  701. };
  702. buttons[django.gettext('Cancel')] = function() {
  703. $(this).dialog('close');
  704. };
  705. $('#reset-dashboard-dialog').dialog({
  706. resizable: false,
  707. modal: true,
  708. buttons: buttons
  709. });
  710. e.preventDefault();
  711. });
  712. };
  713. var initUnsavedChangesWarning = function() {
  714. var $changeform = $('.changeform');
  715. if ($changeform.length) {
  716. var $inputs = $changeform.find('input, textarea, select');
  717. var bound = false;
  718. var onBeforeUnload = function (){
  719. return django.gettext('Warning: you have unsaved changes');
  720. };
  721. var onChange = function () {
  722. $inputs.off('change', onChange);
  723. if (!bound) {
  724. $(window).bind('beforeunload', onBeforeUnload);
  725. bound = true;
  726. }
  727. };
  728. $(document).on('submit', 'form', function() {
  729. $(window).off('beforeunload', onBeforeUnload);
  730. });
  731. $inputs.on('change', onChange);
  732. }
  733. };
  734. var initScrollbars = function() {
  735. $('.sidebar-menu-wrapper').perfectScrollbar();
  736. };
  737. var initThemeChoosing = function() {
  738. $('.choose-theme').on('click', function () {
  739. var $link = $(this);
  740. $.cookie('JET_THEME', $link.data('theme'), { expires: 365, path: '/' });
  741. var cssToLoad = [
  742. { url: $link.data('base-stylesheet'), class: 'base-stylesheet' },
  743. { url: $link.data('select2-stylesheet'), class: 'select2-stylesheet' },
  744. { url: $link.data('jquery-ui-stylesheet'), class: 'jquery-ui-stylesheet' }
  745. ];
  746. var loadedCss = 0;
  747. var onCssLoaded = function() {
  748. ++loadedCss;
  749. if (loadedCss == cssToLoad.length) {
  750. $(document).trigger('theme:changed');
  751. }
  752. };
  753. cssToLoad.forEach(function(css) {
  754. $('<link>')
  755. .attr('rel', 'stylesheet')
  756. .addClass(css['class'])
  757. .attr('href', css['url'])
  758. .load(onCssLoaded)
  759. .appendTo('head');
  760. $('.' + css['class'])
  761. .slice(0, -2)
  762. .remove();
  763. });
  764. $('.choose-theme').removeClass('selected');
  765. $link.addClass('selected');
  766. });
  767. };
  768. initjQueryCaseInsensitiveSelector();
  769. initjQuerySlideFadeToggle();
  770. initFilters();
  771. initChangeformTabs();
  772. initCheckboxesWithoutLabel();
  773. initUserTools();
  774. initSideMenu();
  775. initDeleteObjects();
  776. initDateTimeWidgets();
  777. initInlines();
  778. initChangelist();
  779. initTooltips();
  780. initDashboard();
  781. initUnsavedChangesWarning();
  782. initScrollbars();
  783. initThemeChoosing();
  784. });
  785. })(jet.jQuery);