Ei kuvausta

grappelli.js 9.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /**
  2. * GRAPPELLI UTILS
  3. * functions needed for Grappelli
  4. */
  5. // grp jQuery namespace
  6. var grp = {
  7. jQuery: jQuery.noConflict(true)
  8. };
  9. // django jQuery namespace
  10. var django = {
  11. jQuery: grp.jQuery
  12. };
  13. // general jQuery instance
  14. var jQuery = grp.jQuery;
  15. var inputTypes = [
  16. "[type='search']",
  17. "[type='email']",
  18. "[type='url']",
  19. "[type='tel']",
  20. "[type='number']",
  21. "[type='range']",
  22. "[type='date']",
  23. "[type='month']",
  24. "[type='week']",
  25. "[type='time']",
  26. "[type='datetime']",
  27. "[type='datetime-local']",
  28. "[type='color']"].join(",");
  29. (function($) {
  30. // dateformat
  31. grappelli.getFormat = function(type) {
  32. if (type == "date") {
  33. var format = DATE_FORMAT.toLowerCase().replace(/%\w/g, function(str) {
  34. str = str.replace(/%/, '');
  35. return str + str;
  36. });
  37. return format;
  38. }
  39. };
  40. // remove types: search, email, url, tel, number, range, date
  41. // month, week, time, datetime, datetime-local, color
  42. // because of browser inconsistencies
  43. /*jshint multistr: true */
  44. grappelli.cleanInputTypes = function() {
  45. $("form").each(function(){
  46. $(this).find(':input').filter(inputTypes).each(function(){
  47. $(this).attr("type", "text");
  48. });
  49. });
  50. };
  51. // datepicker, timepicker init
  52. grappelli.initDateAndTimePicker = function() {
  53. // HACK: get rid of text after DateField (hardcoded in django.admin)
  54. $('p.datetime').each(function() {
  55. var text = $(this).html();
  56. text = text.replace(/\w*: /, "");
  57. text = text.replace(/<br>[^<]*: /g, "<br>");
  58. $(this).html(text);
  59. });
  60. var options = {
  61. //appendText: '(mm/dd/yyyy)',
  62. constrainInput: false,
  63. showOn: 'button',
  64. buttonImageOnly: false,
  65. buttonText: '',
  66. dateFormat: grappelli.getFormat('date'),
  67. showButtonPanel: true,
  68. showAnim: '',
  69. // HACK: sets the current instance to a global var.
  70. // needed to actually select today if the today-button is clicked.
  71. // see onClick handler for ".ui-datepicker-current"
  72. beforeShow: function(year, month, inst) {
  73. grappelli.datepicker_instance = this;
  74. }
  75. };
  76. var dateFields = $("input[class*='vDateField']:not([id*='__prefix__'])");
  77. dateFields.datepicker(options);
  78. if (typeof IS_POPUP != "undefined" && IS_POPUP) {
  79. dateFields.datepicker('disable');
  80. }
  81. // HACK: adds an event listener to the today button of datepicker
  82. // if clicked today gets selected and datepicker hides.
  83. // use on() because couldn't find hook after datepicker generates it's complete dom.
  84. $(document).on('click', '.ui-datepicker-current', function() {
  85. $.datepicker._selectDate(grappelli.datepicker_instance);
  86. grappelli.datepicker_instance = null;
  87. });
  88. // init timepicker
  89. $("input[class*='vTimeField']:not([id*='__prefix__'])").grp_timepicker();
  90. };
  91. // changelist: filter
  92. grappelli.initFilter = function(method) {
  93. $("a.grp-pulldown-handler").on("click", function() {
  94. var pulldownContainer = $(this).closest(".grp-pulldown-container");
  95. $(pulldownContainer).toggleClass("grp-pulldown-state-open").children(".grp-pulldown-content").toggle();
  96. });
  97. $("a.grp-pulldown-handler").on('mouseout', function() {
  98. $(this).blur();
  99. });
  100. if (!method) {
  101. $(".grp-filter-choice").change(function(){
  102. location.href = $(this).val();
  103. });
  104. }
  105. if (method === 'confirm') {
  106. // Construct windowQueryDict from current window.location.search
  107. var windowQuery = window.location.search.replace('?', '').split('&');
  108. var windowQueryDict = [];
  109. if (windowQuery[0] !== undefined && windowQuery[0] !== '') {
  110. windowQuery.map(param => {
  111. // Split query param to get the fieldName
  112. var fieldName = param.split('=')[0];
  113. if (fieldName.search('__') != -1) {
  114. fieldName = param.split('__')[0];
  115. }
  116. // Check if fieldName already exists in searchStringDict and add it resp. its values
  117. var fieldNameIndex = windowQueryDict.findIndex(el => el.fieldName === fieldName);
  118. if (fieldNameIndex === -1) {
  119. windowQueryDict.push({
  120. fieldName: fieldName,
  121. values: [param]
  122. });
  123. } else {
  124. windowQueryDict.find(obj => obj.fieldName === fieldName).values.push(param);
  125. }
  126. });
  127. }
  128. // Manipulate windowQueryDict based on changes of filter choices
  129. $(".grp-filter-choice").change(function(){
  130. // Get the choice's fieldName and isolate its distinctive query params
  131. var fieldName = $(this).data('field-name');
  132. var value = $(this).val() !== '?' ? $(this).val().replace('?', '') : false;
  133. var values = value && value.split('&');
  134. var filterQueryParams = values && values.filter(el => el.includes(fieldName));
  135. // Check if fieldName already exists in filterQueryDict and add it resp. its values
  136. var filterWindowIndex = windowQueryDict.findIndex(el => el.fieldName === fieldName);
  137. var isFilterPartOfWindow = filterWindowIndex < 0 ? false : true;
  138. if (isFilterPartOfWindow) {
  139. if (filterQueryParams.length > 0) {
  140. // Update query params
  141. windowQueryDict.find(el => el.fieldName === fieldName).values = filterQueryParams;
  142. } else {
  143. // Remove filter
  144. windowQueryDict.splice(filterWindowIndex, 1);
  145. }
  146. } else {
  147. if (filterQueryParams.length > 0) {
  148. // Add filter
  149. windowQueryDict.push({
  150. fieldName: fieldName,
  151. values: filterQueryParams,
  152. });
  153. }
  154. }
  155. // Construct queryString from windowQueryDict
  156. var queryString = windowQueryDict.flatMap(el => el.values).join('&');
  157. // Assiqn query string to "Apply" button
  158. var applyFilter = $(this).closest('.grp-filter').find('#grp-filter-apply');
  159. applyFilter.attr('href', '?' + queryString);
  160. });
  161. }
  162. };
  163. // changelist: searchbar
  164. grappelli.initSearchbar = function() {
  165. var searchbar = $("input.grp-search-field");
  166. searchbar.trigger("focus");
  167. };
  168. grappelli.updateSelectFilter = function(form) {
  169. if (typeof SelectFilter != "undefined"){
  170. form.find(".selectfilter").each(function(index, value){
  171. var namearr = value.name.split('-');
  172. SelectFilter.init(value.id, namearr[namearr.length-1], false, "{% admin_media_prefix %}");
  173. });
  174. form.find(".selectfilterstacked").each(function(index, value){
  175. var namearr = value.name.split('-');
  176. SelectFilter.init(value.id, namearr[namearr.length-1], true, "{% admin_media_prefix %}");
  177. });
  178. }
  179. };
  180. grappelli.reinitDateTimeFields = function(form) {
  181. form.find(".vDateField").datepicker({
  182. constrainInput: false,
  183. showOn: 'button',
  184. buttonImageOnly: false,
  185. buttonText: '',
  186. dateFormat: grappelli.getFormat('date')
  187. });
  188. form.find(".vTimeField").grp_timepicker();
  189. };
  190. // autocomplete helpers
  191. grappelli.get_app_label = function(elem) {
  192. var link = elem.next("a");
  193. if (link.length > 0) {
  194. var url = link.attr('href').split('?')[0].split('/');
  195. return url[url.length-3];
  196. }
  197. return false;
  198. };
  199. grappelli.get_model_name = function(elem) {
  200. var link = elem.next("a");
  201. if (link.length > 0) {
  202. var url = link.attr('href').split('?')[0].split('/');
  203. return url[url.length-2];
  204. }
  205. return false;
  206. };
  207. grappelli.get_query_string = function(elem) {
  208. var link = elem.next("a");
  209. if (link.length > 0) {
  210. var url = link.attr('href').split('/');
  211. pairs = url[url.length-1].replace('?', '').split("&");
  212. return pairs.join(":");
  213. }
  214. return false;
  215. };
  216. grappelli.get_to_field = function(elem) {
  217. var link = elem.next("a");
  218. if (link.length > 0 && link.attr('href').indexOf("_to_field") !== -1) {
  219. var url = link.attr('href').split('/');
  220. var pairs = url[url.length-1].replace('?', '').split("&");
  221. for (var i = 0; i < pairs.length; i++) {
  222. v = pairs[i].split('=');
  223. if (v[0] == "_to_field") {
  224. return v[1];
  225. }
  226. }
  227. }
  228. return false;
  229. };
  230. })(grp.jQuery);