main.js 34 KB

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