actions.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*global _actions_icnt, gettext, interpolate, ngettext*/
  2. (function($) {
  3. 'use strict';
  4. var lastChecked;
  5. $.fn.actions = function(opts) {
  6. var options = $.extend({}, $.fn.actions.defaults, opts);
  7. var actionCheckboxes = $(this);
  8. var list_editable_changed = false;
  9. var showQuestion = function() {
  10. $(options.acrossClears).hide();
  11. $(options.acrossQuestions).show();
  12. $(options.allContainer).hide();
  13. },
  14. showClear = function() {
  15. $(options.acrossClears).show();
  16. $(options.acrossQuestions).hide();
  17. $(options.actionContainer).toggleClass(options.selectedClass);
  18. $(options.allContainer).show();
  19. $(options.counterContainer).hide();
  20. },
  21. reset = function() {
  22. $(options.acrossClears).hide();
  23. $(options.acrossQuestions).hide();
  24. $(options.allContainer).hide();
  25. $(options.counterContainer).show();
  26. },
  27. clearAcross = function() {
  28. reset();
  29. $(options.acrossInput).val(0);
  30. $(options.actionContainer).removeClass(options.selectedClass);
  31. },
  32. checker = function(checked) {
  33. if (checked) {
  34. showQuestion();
  35. } else {
  36. reset();
  37. }
  38. $(actionCheckboxes).prop("checked", checked)
  39. .parent().parent().toggleClass(options.selectedClass, checked);
  40. },
  41. updateCounter = function() {
  42. var sel = $(actionCheckboxes).filter(":checked").length;
  43. // _actions_icnt is defined in the generated HTML
  44. // and contains the total amount of objects in the queryset
  45. $(options.counterContainer).html(interpolate(
  46. ngettext('%(sel)s of %(cnt)s selected', '%(sel)s of %(cnt)s selected', sel), {
  47. sel: sel,
  48. cnt: _actions_icnt
  49. }, true));
  50. $(options.allToggle).prop("checked", function() {
  51. var value;
  52. if (sel === actionCheckboxes.length) {
  53. value = true;
  54. showQuestion();
  55. } else {
  56. value = false;
  57. clearAcross();
  58. }
  59. return value;
  60. });
  61. };
  62. // Show counter by default
  63. $(options.counterContainer).show();
  64. // Check state of checkboxes and reinit state if needed
  65. $(this).filter(":checked").each(function(i) {
  66. $(this).parent().parent().toggleClass(options.selectedClass);
  67. updateCounter();
  68. if ($(options.acrossInput).val() === 1) {
  69. showClear();
  70. }
  71. });
  72. $(options.allToggle).show().click(function() {
  73. checker($(this).prop("checked"));
  74. updateCounter();
  75. });
  76. $("a", options.acrossQuestions).click(function(event) {
  77. event.preventDefault();
  78. $(options.acrossInput).val(1);
  79. showClear();
  80. });
  81. $("a", options.acrossClears).click(function(event) {
  82. event.preventDefault();
  83. $(options.allToggle).prop("checked", false);
  84. clearAcross();
  85. checker(0);
  86. updateCounter();
  87. });
  88. lastChecked = null;
  89. $(actionCheckboxes).click(function(event) {
  90. if (!event) { event = window.event; }
  91. var target = event.target ? event.target : event.srcElement;
  92. if (lastChecked && $.data(lastChecked) !== $.data(target) && event.shiftKey === true) {
  93. var inrange = false;
  94. $(lastChecked).prop("checked", target.checked)
  95. .parent().parent().toggleClass(options.selectedClass, target.checked);
  96. $(actionCheckboxes).each(function() {
  97. if ($.data(this) === $.data(lastChecked) || $.data(this) === $.data(target)) {
  98. inrange = (inrange) ? false : true;
  99. }
  100. if (inrange) {
  101. $(this).prop("checked", target.checked)
  102. .parent().parent().toggleClass(options.selectedClass, target.checked);
  103. }
  104. });
  105. }
  106. $(target).parent().parent().toggleClass(options.selectedClass, target.checked);
  107. lastChecked = target;
  108. updateCounter();
  109. });
  110. $('form#changelist-form table#result_list tr').find('td:gt(0) :input').change(function() {
  111. list_editable_changed = true;
  112. });
  113. $('form#changelist-form button[name="index"]').click(function(event) {
  114. if (list_editable_changed) {
  115. return confirm(gettext("You have unsaved changes on individual editable fields. If you run an action, your unsaved changes will be lost."));
  116. }
  117. });
  118. $('form#changelist-form input[name="_save"]').click(function(event) {
  119. var action_changed = false;
  120. $('select option:selected', options.actionContainer).each(function() {
  121. if ($(this).val()) {
  122. action_changed = true;
  123. }
  124. });
  125. if (action_changed) {
  126. if (list_editable_changed) {
  127. return confirm(gettext("You have selected an action, but you haven't saved your changes to individual fields yet. Please click OK to save. You'll need to re-run the action."));
  128. } else {
  129. return confirm(gettext("You have selected an action, and you haven't made any changes on individual fields. You're probably looking for the Go button rather than the Save button."));
  130. }
  131. }
  132. });
  133. };
  134. /* Setup plugin defaults */
  135. $.fn.actions.defaults = {
  136. actionContainer: "div.actions",
  137. counterContainer: "span.action-counter",
  138. allContainer: "div.actions span.all",
  139. acrossInput: "div.actions input.select-across",
  140. acrossQuestions: "div.actions span.question",
  141. acrossClears: "div.actions span.clear",
  142. allToggle: "#action-toggle",
  143. selectedClass: "selected"
  144. };
  145. })(django.jQuery);