related-popups.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. var $ = require('jquery');
  2. var WindowStorage = require('../utils/windowStorage');
  3. var RelatedPopups = function() {
  4. this.windowStorage = new WindowStorage('relatedWindows');
  5. };
  6. RelatedPopups.prototype = {
  7. updateLinks: function($select) {
  8. $select.find('~ .change-related, ~ .delete-related, ~ .add-another').each(function() {
  9. var $link = $(this);
  10. var hrefTemplate = $link.data('href-template');
  11. var value = $select.val();
  12. if (hrefTemplate == undefined) {
  13. return;
  14. }
  15. if (value) {
  16. $link.attr('href', hrefTemplate.replace('__fk__', value))
  17. } else {
  18. $link.removeAttr('href');
  19. }
  20. });
  21. },
  22. initLinks: function() {
  23. var obj = this;
  24. $('.form-row select').each(function() {
  25. var $select = $(this);
  26. obj.updateLinks($select);
  27. $select.find('~ .add-related, ~ .change-related, ~ .delete-related, ~ .add-another').each(function() {
  28. var $link = $(this);
  29. $link.on('click', function(e) {
  30. e.preventDefault();
  31. var href = $link.attr('href');
  32. if (href != undefined) {
  33. if (href.indexOf('_popup') == -1) {
  34. href += (href.indexOf('?') == -1) ? '?_popup=1' : '&_popup=1';
  35. }
  36. obj.showPopup($select, href);
  37. }
  38. });
  39. });
  40. }).on('change', function() {
  41. obj.updateLinks($(this));
  42. });
  43. $('.form-row input').each(function() {
  44. var $input = $(this);
  45. $input.find('~ .related-lookup').each(function() {
  46. var $link = $(this);
  47. $link.on('click', function(e) {
  48. e.preventDefault();
  49. var href = $link.attr('href');
  50. href += (href.indexOf('?') == -1) ? '?_popup=1' : '&_popup=1';
  51. obj.showPopup($input, href);
  52. });
  53. });
  54. });
  55. },
  56. initPopupBackButton: function() {
  57. var obj = this;
  58. $('.related-popup-back').on('click', function(e) {
  59. e.preventDefault();
  60. obj.closePopup();
  61. });
  62. },
  63. showPopup: function($input, href) {
  64. var $document = $(window.top.document);
  65. var $container = $document.find('.related-popup-container');
  66. var $loading = $container.find('.loading-indicator');
  67. var $body = $document.find('body').addClass('non-scrollable');
  68. var $popup = $('<iframe>')
  69. .attr('src', href)
  70. .data('input', $input)
  71. .addClass('related-popup')
  72. .on('load', function() {
  73. $popup.add($document.find('.related-popup-back')).fadeIn(200, 'swing', function() {
  74. $loading.hide();
  75. });
  76. });
  77. $loading.show();
  78. $container.fadeIn(200, 'swing', function() {
  79. $container.append($popup);
  80. });
  81. $body.addClass('non-scrollable');
  82. },
  83. closePopup: function(response) {
  84. var previousWindow = this.windowStorage.previous();
  85. var obj = this;
  86. (function($) {
  87. var $document = $(window.top.document);
  88. var $popups = $document.find('.related-popup');
  89. var $container = $document.find('.related-popup-container');
  90. var $popup = $popups.last();
  91. if (response != undefined) {
  92. var $input = $popup.data('input');
  93. switch (response.action) {
  94. case 'change':
  95. $input.find('option').each(function() {
  96. var $option = $(this);
  97. if ($option.val() == response.value) {
  98. $option.html(response.obj).val(response.new_value);
  99. }
  100. });
  101. $input.trigger('change').trigger('select:init');
  102. break;
  103. case 'delete':
  104. $input.find('option').each(function() {
  105. var $option = $(this);
  106. if ($option.val() == response.value) {
  107. $option.remove();
  108. }
  109. });
  110. $input.trigger('change').trigger('select:init');
  111. break;
  112. default:
  113. if ($input.is('select')) {
  114. var $option = $('<option>')
  115. .val(response.value)
  116. .html(response.obj);
  117. $input.append($option);
  118. $option.attr('selected', true);
  119. $input
  120. .trigger('change')
  121. .trigger('select:init');
  122. } else if ($input.is('input.vManyToManyRawIdAdminField') && $input.val()) {
  123. $input.val($input.val() + ',' + response.value);
  124. } else if ($input.is('input')) {
  125. $input.val(response.value);
  126. }
  127. break;
  128. }
  129. }
  130. obj.windowStorage.pop();
  131. if ($popups.length == 1) {
  132. $container.fadeOut(200, 'swing', function() {
  133. $document.find('.related-popup-back').hide();
  134. $document.find('body').removeClass('non-scrollable');
  135. $popup.remove();
  136. });
  137. } else {
  138. $popup.remove();
  139. }
  140. })(previousWindow ? previousWindow.jet.jQuery : $);
  141. },
  142. processPopupResponse: function() {
  143. var obj = this;
  144. $('#django-admin-popup-response-constants').each(function() {
  145. var $constants = $(this);
  146. var response = $constants.data('popup-response');
  147. obj.closePopup(response);
  148. });
  149. },
  150. overrideRelatedGlobals: function() {
  151. var obj = this;
  152. window.showRelatedObjectLookupPopup
  153. = window.showAddAnotherPopup
  154. = window.showRelatedObjectPopup
  155. = function() { };
  156. window.opener = this.windowStorage.previous();
  157. window.dismissRelatedLookupPopup = function(win, chosenId) {
  158. obj.closePopup({
  159. action: 'lookup',
  160. value: chosenId
  161. });
  162. };
  163. },
  164. initDeleteRelatedCancellation: function() {
  165. var obj = this;
  166. $('.popup.delete-confirmation .cancel-link').on('click', function(e) {
  167. e.preventDefault();
  168. obj.closePopup();
  169. }).removeAttr('onclick');
  170. },
  171. run: function() {
  172. this.windowStorage.push(window);
  173. try {
  174. this.initLinks();
  175. this.initPopupBackButton();
  176. this.processPopupResponse();
  177. this.overrideRelatedGlobals();
  178. this.initDeleteRelatedCancellation();
  179. this.overrideRelatedGlobals();
  180. } catch (e) {
  181. console.error(e);
  182. }
  183. }
  184. };
  185. $(document).ready(function() {
  186. new RelatedPopups().run();
  187. });