pages-all.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. $(function(){
  2. var root = window || {};
  3. root = root.GravJS = root.GravJS || {};
  4. //Make it global because used by ./forms/form.js
  5. root.currentValues = getState();
  6. var clickedLink;
  7. // selectize
  8. var pageFilter = $('input.page-filter'),
  9. pageTypes = pageFilter.data('template-types'),
  10. options = [
  11. {flag: 'Modular', key: 'Modular', cat: 'mode'},
  12. {flag: 'Visible', key: 'Visible', cat: 'mode'},
  13. {flag: 'Routable', key: 'Routable', cat: 'mode'},
  14. {flag: 'Published', key: 'Published', cat: 'mode'},
  15. {flag: 'Non-Modular', key: 'NonModular', cat: 'mode'},
  16. {flag: 'Non-Visible', key: 'NonVisible', cat: 'mode'},
  17. {flag: 'Non-Routable', key: 'NonRoutable', cat: 'mode'},
  18. {flag: 'Non-Published', key: 'NonPublished', cat: 'mode'},
  19. ];
  20. if (pageFilter && pageTypes) {
  21. jQuery.each(pageTypes, function(key, name){
  22. options.push({flag: name, key: key, cat: 'type'});
  23. })
  24. pageFilter.selectize({
  25. maxItems: null,
  26. valueField: 'key',
  27. labelField: 'flag',
  28. searchField: ['flag', 'key'],
  29. options: options,
  30. optgroups: [
  31. {id: 'mode', name: 'Page Modes'},
  32. {id: 'type', name: 'Page Types'},
  33. ],
  34. optgroupField: 'cat',
  35. optgroupLabelField: 'name',
  36. optgroupValueField: 'id',
  37. optgroupOrder: ['mode', 'type'],
  38. plugins: ['optgroup_columns']
  39. });
  40. }
  41. var childrenToggles = $('[data-toggle="children"]'),
  42. storage = sessionStorage.getItem('grav:admin:pages'),
  43. collapseAll = function(store) {
  44. childrenToggles.each(function(i, element){
  45. var icon = $(element).find('.page-icon'),
  46. open = icon.hasClass('children-open'),
  47. key = $(element).closest('[data-nav-id]').data('nav-id'),
  48. children = $(element).closest('li.page-item').find('ul:first');
  49. if (open) {
  50. children.hide();
  51. if (store) delete storage[key];
  52. icon.removeClass('children-open').addClass('children-closed');
  53. }
  54. if (store) sessionStorage.setItem('grav:admin:pages', JSON.stringify(storage));
  55. });
  56. },
  57. expandAll = function(store) {
  58. childrenToggles.each(function(i, element){
  59. var icon = $(element).find('.page-icon'),
  60. open = icon.hasClass('children-open'),
  61. key = $(element).closest('[data-nav-id]').data('nav-id'),
  62. children = $(element).closest('li.page-item').find('ul:first');
  63. if (!open) {
  64. children.show();
  65. if (store) storage[key] = 1;
  66. icon.removeClass('children-closed').addClass('children-open');
  67. }
  68. if (store) sessionStorage.setItem('grav:admin:pages', JSON.stringify(storage));
  69. });
  70. },
  71. restoreStates = function() {
  72. collapseAll();
  73. for (var key in storage) {
  74. var element = $('[data-nav-id="' + key + '"]'),
  75. icon = element.find('.page-icon').first(),
  76. open = icon.hasClass('children-open'),
  77. children = element.closest('li.page-item').find('ul:first');
  78. children.show();
  79. icon.removeClass('children-closed').addClass('children-open');
  80. }
  81. };
  82. if (!storage) {
  83. sessionStorage.setItem('grav:admin:pages', (storage = '{}'));
  84. }
  85. storage = JSON.parse(storage);
  86. restoreStates();
  87. var startFilterPages = function () {
  88. var task = 'task' + GravAdmin.config.param_sep;
  89. $('input[name="page-search"]').focus();
  90. var flags = $('input[name="page-filter"]').val(),
  91. query = $('input[name="page-search"]').val();
  92. if (!flags.length && !query.length) {
  93. GravAjax.jqxhr.abort();
  94. return finishFilterPages([], true);
  95. }
  96. GravAjax({
  97. dataType: 'json',
  98. method: 'POST',
  99. url: GravAdmin.config.base_url_relative + '/pages-filter.json/' + task + 'filterPages',
  100. data: {
  101. flags: flags,
  102. query: query
  103. },
  104. toastErrors: true,
  105. success: function (result, status) {
  106. finishFilterPages(result.results);
  107. }
  108. });
  109. };
  110. var finishFilterPages = function (pages, reset) {
  111. var items = $('[data-nav-id]');
  112. items.removeClass('search-match');
  113. if (reset) {
  114. items.addClass('search-match');
  115. restoreStates();
  116. } else {
  117. pages.forEach(function (id) {
  118. var match = items.filter('[data-nav-id="' + id + '"]'),
  119. parents = match.parents('[data-nav-id]');
  120. match.addClass('search-match');
  121. match.find('[data-nav-id]').addClass('search-match');
  122. parents.addClass('search-match');
  123. parents.find('[data-toggle="children"]').each(function(index, element){
  124. var icon = $(this).find('.page-icon'),
  125. open = icon.hasClass('children-open'),
  126. children = $(this).closest('li.page-item').find('ul:first');
  127. if (!open) {
  128. children.show();
  129. icon.removeClass('children-closed').addClass('children-open');
  130. }
  131. });
  132. });
  133. }
  134. items.each(function (key, item) {
  135. if ($(item).hasClass('search-match')) {
  136. $(item).show();
  137. } else {
  138. $(item).hide();
  139. }
  140. });
  141. };
  142. // selectize
  143. $('input[name="page-search"]').on('input', startFilterPages);
  144. $('input[name="page-filter"]').on('change', startFilterPages);
  145. // auto generate folder based on title
  146. // on user input on folder, autogeneration stops
  147. // if user empties the folder, autogeneration restarts
  148. $('input[name="folder"]').on('input', function(){
  149. $(this).data('user-custom-folder', true);
  150. if (!$(this).val()) $(this).data('user-custom-folder', false);
  151. });
  152. $('input[name="title"]').on('input', function(e){
  153. if (!$('input[name="folder"]').data('user-custom-folder')) {
  154. folder = $.slugify($(this).val());
  155. $('input[name="folder"]').val(folder);
  156. }
  157. });
  158. $('#slug-target').slugify('#slug-source');
  159. $('input[name="folder"]').on('input', function(e){
  160. var start = this.selectionStart,
  161. end = this.selectionEnd;
  162. value = $(this).val().toLowerCase().replace(/\s/g, '-').replace(/[^a-z0-9_\-]/g, '');
  163. $(this).val(value);
  164. // restore cursor position
  165. this.setSelectionRange(start, end);
  166. });
  167. childrenToggles.on('click', function () {
  168. var icon = $(this).find('.page-icon'),
  169. open = icon.hasClass('children-open'),
  170. key = $(this).closest('[data-nav-id]').data('nav-id'),
  171. children = $(this).closest('li.page-item').find('ul:first');
  172. if (open) {
  173. children.hide();
  174. delete storage[key];
  175. icon.removeClass('children-open').addClass('children-closed');
  176. } else {
  177. children.show();
  178. storage[key] = true;
  179. icon.removeClass('children-closed').addClass('children-open');
  180. }
  181. sessionStorage.setItem('grav:admin:pages', JSON.stringify(storage));
  182. });
  183. $('[data-page-toggleall]').on('click', function() {
  184. var state = $(this).data('page-toggleall');
  185. if (state == 'collapse') collapseAll(true);
  186. else expandAll(true);
  187. });
  188. $('#admin-main button').on('click', function(){
  189. $(window).off('beforeunload');
  190. });
  191. $('[data-remodal-id] form').on('submit', function(){
  192. $(window).off('beforeunload');
  193. });
  194. $("#admin-mode-toggle input[name=mode-switch]").on('change', function(e){
  195. var value = $(this).val(),
  196. uri = $(this).data('leave-url');
  197. if (root.currentValues == getState()) {
  198. setTimeout(function(){
  199. window.location.href = uri;
  200. }, 200)
  201. return true;
  202. }
  203. e.preventDefault();
  204. var confirm = $.remodal.lookup[$('[data-remodal-id=changes]').data('remodal')],
  205. buttons = $('[data-remodal-id=changes] a.button'),
  206. action;
  207. buttons.on('click', function(e){
  208. e.preventDefault();
  209. action = $(this).data('leave-action');
  210. buttons.off('click');
  211. confirm.close();
  212. if (action == 'continue') {
  213. $(window).off('beforeunload');
  214. window.location.href = $("#admin-mode-toggle input[name=mode-switch]:checked").data('leave-url');
  215. } else {
  216. $('input[name=mode-switch][checked]').prop('checked', true);
  217. }
  218. });
  219. confirm.open();
  220. });
  221. $('a[href]:not([href^=#])').on('click', function(e){
  222. if (root.currentValues != getState()){
  223. e.preventDefault();
  224. clickedLink = $(this).attr('href');
  225. var confirm = $.remodal.lookup[$('[data-remodal-id=changes]').data('remodal')],
  226. buttons = $('[data-remodal-id=changes] a.button'),
  227. action;
  228. buttons.on('click', function(e){
  229. e.preventDefault();
  230. action = $(this).data('leave-action');
  231. buttons.off('click');
  232. confirm.close();
  233. if (action == 'continue') {
  234. $(window).off('beforeunload');
  235. window.location.href = clickedLink;
  236. }
  237. });
  238. confirm.open();
  239. }
  240. });
  241. // deletion
  242. $('[data-remodal-target="delete"]').on('click', function(){
  243. var okdelete = $('[data-remodal-id=delete] a.button');
  244. okdelete.data('delete-action', $(this).data('delete-url'));
  245. });
  246. $('[data-delete-action]').on('click', function(){
  247. var confirm = $.remodal.lookup[$('[data-remodal-id=delete]').data('remodal')],
  248. okdelete = $(this).data('delete-action');
  249. window.location.href = okdelete;
  250. confirm.close();
  251. });
  252. $(window).on('beforeunload', function(){
  253. if (root.currentValues != getState()){
  254. return "You have made changes on this page that you have not yet confirmed. If you navigate away from this page you will lose your unsaved changes";
  255. }
  256. });
  257. // Move dropdown sync (on dropdown change)
  258. /*$('body').on('change', '[data-page-move] select', function(){
  259. var route = jQuery('form#blueprints').first().find('select[name="route"]'),
  260. value = $(this).val();
  261. if (route.length && route.val() !== value) {
  262. route.val(value);
  263. route.data('selectize').setValue(value);
  264. }
  265. });*/
  266. // Move dropdown sync (on continue)
  267. $('[data-page-move] button').on('click', function(){
  268. var route = jQuery('form#blueprints').first().find('select[name="route"]'),
  269. value = $('[data-page-move] select').val();
  270. if (route.length && route.val() !== value) {
  271. var selectize = route.data('selectize');
  272. route.val(value);
  273. if (selectize) selectize.setValue(value);
  274. }
  275. });
  276. });