wowchemy-publication.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. /*************************************************
  2. * Wowchemy
  3. * https://github.com/wowchemy/wowchemy-hugo-themes
  4. *
  5. * Wowchemy Publications
  6. **************************************************/
  7. // Active publication filters.
  8. let pubFilters = {};
  9. // Search term.
  10. let searchRegex;
  11. // Filter values (concatenated).
  12. let filterValues;
  13. // Publication container.
  14. let $grid_pubs = $('#container-publications');
  15. // Initialise Isotope publication layout if required.
  16. if ($grid_pubs.length) {
  17. $grid_pubs.isotope({
  18. itemSelector: '.isotope-item',
  19. percentPosition: true,
  20. masonry: {
  21. // Use Bootstrap compatible grid layout.
  22. columnWidth: '.grid-sizer',
  23. },
  24. filter: function () {
  25. let $this = $(this);
  26. let searchResults = searchRegex ? $this.text().match(searchRegex) : true;
  27. let filterResults = filterValues ? $this.is(filterValues) : true;
  28. return searchResults && filterResults;
  29. },
  30. });
  31. // Filter by search term.
  32. let $quickSearch = $('.filter-search').keyup(
  33. debounce(function () {
  34. searchRegex = new RegExp($quickSearch.val(), 'gi');
  35. $grid_pubs.isotope();
  36. }),
  37. );
  38. $('.pub-filters').on('change', function () {
  39. let $this = $(this);
  40. // Get group key.
  41. let filterGroup = $this[0].getAttribute('data-filter-group');
  42. // Set filter for group.
  43. pubFilters[filterGroup] = this.value;
  44. // Combine filters.
  45. filterValues = concatValues(pubFilters);
  46. // Activate filters.
  47. $grid_pubs.isotope();
  48. // If filtering by publication type, update the URL hash to enable direct linking to results.
  49. if (filterGroup === 'pubtype') {
  50. // Set hash URL to current filter.
  51. let url = $(this).val();
  52. if (url.substr(0, 9) === '.pubtype-') {
  53. window.location.hash = url.substr(9);
  54. } else {
  55. window.location.hash = '';
  56. }
  57. }
  58. });
  59. }
  60. // Debounce input to prevent spamming filter requests.
  61. function debounce(fn, threshold) {
  62. let timeout;
  63. threshold = threshold || 100;
  64. return function debounced() {
  65. clearTimeout(timeout);
  66. let args = arguments;
  67. let _this = this;
  68. function delayed() {
  69. fn.apply(_this, args);
  70. }
  71. timeout = setTimeout(delayed, threshold);
  72. };
  73. }
  74. // Flatten object by concatenating values.
  75. function concatValues(obj) {
  76. let value = '';
  77. for (let prop in obj) {
  78. value += obj[prop];
  79. }
  80. return value;
  81. }
  82. // Filter publications according to hash in URL.
  83. function filter_publications() {
  84. // Check for Isotope publication layout.
  85. if (!$grid_pubs.length) return;
  86. let urlHash = window.location.hash.replace('#', '');
  87. let filterValue = '*';
  88. // Check if hash is numeric.
  89. if (urlHash != '' && !isNaN(urlHash)) {
  90. filterValue = '.pubtype-' + urlHash;
  91. }
  92. // Set filter.
  93. let filterGroup = 'pubtype';
  94. pubFilters[filterGroup] = filterValue;
  95. filterValues = concatValues(pubFilters);
  96. // Activate filters.
  97. $grid_pubs.isotope();
  98. // Set selected option.
  99. $('.pubtype-select').val(filterValue);
  100. }
  101. document.addEventListener('DOMContentLoaded', function () {
  102. // Enable publication filter for publication index page.
  103. if ($('.pub-filters-select')) {
  104. filter_publications();
  105. // Useful for changing hash manually (e.g. in development):
  106. // window.addEventListener('hashchange', filter_publications, false);
  107. }
  108. // Load citation modal on 'Cite' click.
  109. $('.js-cite-modal').click(function (e) {
  110. e.preventDefault();
  111. let filename = $(this).attr('data-filename');
  112. let modal = $('#modal');
  113. modal.find('.modal-body code').load(filename, function (response, status, xhr) {
  114. if (status == 'error') {
  115. let msg = 'Error: ';
  116. $('#modal-error').html(msg + xhr.status + ' ' + xhr.statusText);
  117. } else {
  118. $('.js-download-cite').attr('href', filename);
  119. }
  120. });
  121. modal.modal('show');
  122. });
  123. // Copy citation text on 'Copy' click.
  124. $('.js-copy-cite').click(function (e) {
  125. e.preventDefault();
  126. // Get text to copy.
  127. let citation = document.querySelector('#modal .modal-body').innerHTML;
  128. navigator.clipboard
  129. .writeText(citation)
  130. .then(function () {
  131. console.debug('Citation copied!');
  132. })
  133. .catch(function () {
  134. console.error('Citation copy failed!');
  135. });
  136. });
  137. });