Nessuna descrizione
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.js 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718
  1. /**
  2. * Main
  3. */
  4. 'use strict';
  5. var separator_element = '<div class="separator" ondrop="drop(event)" ondragover="allowDrop(event)"></div>';
  6. function allowDrop(ev) {
  7. ev.preventDefault();
  8. }
  9. $.each($('.toolkit'),function(index){
  10. $(this).on('dragstart',function(ev){
  11. console.log($(this).attr('act'));
  12. ev.originalEvent.dataTransfer.setData("type", $(this).attr('act'));
  13. })
  14. });
  15. function drop(ev) {
  16. ev.preventDefault();
  17. var data = ev.dataTransfer.getData("type");
  18. if(data == 'column1'){
  19. var element = document.createElement('div');
  20. element.innerHTML = '<div class="row"><div class="col-12">'+separator_element+'</div></div>';
  21. element = element.firstChild;
  22. }else if(data == 'column2'){
  23. var element = document.createElement('div');
  24. element.innerHTML = '<div class="row"><div class="col-6">'+separator_element+'</div><div class="col-6">'+separator_element+'</div></div>';
  25. element = element.firstChild;
  26. }else if(data == 'column3'){
  27. var element = document.createElement('div');
  28. element.innerHTML = '<div class="row"><div class="col-4">'+separator_element+'</div><div class="col-4">'+separator_element+'</div><div class="col-4">'+separator_element+'</div></div>';
  29. element = element.firstChild;
  30. }else if(data == 'column4'){
  31. var element = document.createElement('div');
  32. element.innerHTML = '<div class="row"><div class="col-3">'+separator_element+'</div><div class="col-3">'+separator_element+'</div><div class="col-3">'+separator_element+'</div><div class="col-3">'+separator_element+'</div></div>';
  33. element = element.firstChild;
  34. }else if(data == 'textarea'){
  35. var element = document.createElement('div');
  36. element.innerHTML = '<textarea style="width:100%"></textarea>';
  37. element = element.firstChild;
  38. }else if(data == 'text'){
  39. var element = document.createElement('div');
  40. element.innerHTML = '<input style="width:100%"></input>';
  41. element = element.firstChild;
  42. }else if(data == 'picture'){
  43. var element = document.createElement('div');
  44. element.innerHTML = '<input type="file" id="imageInput" accept="image/*" onchange="addImageFromGallery()">';
  45. element = element.firstChild;
  46. }else if(data == 'button'){
  47. var element = document.createElement('div');
  48. element.innerHTML = '<button type="submit" name="submit" class="btn-submit solid"></button>';
  49. element = element.firstChild;
  50. }else{
  51. var element = document.createElement('textarea');
  52. }
  53. if (ev.target.parentNode) {
  54. var condision = document.createElement('div');
  55. condision.innerHTML = separator_element;
  56. const lists = ev.target.parentNode.insertBefore(condision.firstChild, ev.target);
  57. const list = ev.target.parentNode.insertBefore(element, ev.target);
  58. } else {
  59. console.error("parentNode tidak tersedia");
  60. }
  61. // ev.target.appendChild(document.getElementById(data));
  62. // const list = ev.target.parentNode.insertBefore(element,ev.target);
  63. }
  64. window.isRtl = window.Helpers.isRtl();
  65. window.isDarkStyle = window.Helpers.isDarkStyle();
  66. let menu,
  67. animate,
  68. isHorizontalLayout = false;
  69. if (document.getElementById('layout-menu')) {
  70. isHorizontalLayout = document.getElementById('layout-menu').classList.contains('menu-horizontal');
  71. }
  72. (function () {
  73. setTimeout(function () {
  74. window.Helpers.initCustomOptionCheck();
  75. }, 1000);
  76. if (typeof Waves !== 'undefined') {
  77. Waves.init();
  78. Waves.attach(".btn[class*='btn-']:not([class*='btn-outline-']):not([class*='btn-label-'])", ['waves-light']);
  79. Waves.attach("[class*='btn-outline-']");
  80. Waves.attach("[class*='btn-label-']");
  81. Waves.attach('.pagination .page-item .page-link');
  82. }
  83. // Initialize menu
  84. //-----------------
  85. let layoutMenuEl = document.querySelectorAll('#layout-menu');
  86. layoutMenuEl.forEach(function (element) {
  87. menu = new Menu(element, {
  88. orientation: isHorizontalLayout ? 'horizontal' : 'vertical',
  89. closeChildren: isHorizontalLayout ? true : false,
  90. // ? This option only works with Horizontal menu
  91. showDropdownOnHover: localStorage.getItem('templateCustomizer-' + templateName + '--ShowDropdownOnHover') // If value(showDropdownOnHover) is set in local storage
  92. ? localStorage.getItem('templateCustomizer-' + templateName + '--ShowDropdownOnHover') === 'true' // Use the local storage value
  93. : window.templateCustomizer !== undefined // If value is set in config.js
  94. ? window.templateCustomizer.settings.defaultShowDropdownOnHover // Use the config.js value
  95. : true // Use this if you are not using the config.js and want to set value directly from here
  96. });
  97. // Change parameter to true if you want scroll animation
  98. window.Helpers.scrollToActive((animate = false));
  99. window.Helpers.mainMenu = menu;
  100. });
  101. // Initialize menu togglers and bind click on each
  102. let menuToggler = document.querySelectorAll('.layout-menu-toggle');
  103. menuToggler.forEach(item => {
  104. item.addEventListener('click', event => {
  105. event.preventDefault();
  106. window.Helpers.toggleCollapsed();
  107. // Enable menu state with local storage support if enableMenuLocalStorage = true from config.js
  108. if (config.enableMenuLocalStorage && !window.Helpers.isSmallScreen()) {
  109. try {
  110. localStorage.setItem(
  111. 'templateCustomizer-' + templateName + '--LayoutCollapsed',
  112. String(window.Helpers.isCollapsed())
  113. );
  114. // Update customizer checkbox state on click of menu toggler
  115. let layoutCollapsedCustomizerOptions = document.querySelector('.template-customizer-layouts-options');
  116. if (layoutCollapsedCustomizerOptions) {
  117. let layoutCollapsedVal = window.Helpers.isCollapsed() ? 'collapsed' : 'expanded';
  118. layoutCollapsedCustomizerOptions.querySelector(`input[value="${layoutCollapsedVal}"]`).click();
  119. }
  120. } catch (e) {}
  121. }
  122. });
  123. });
  124. // Menu swipe gesture
  125. // Detect swipe gesture on the target element and call swipe In
  126. window.Helpers.swipeIn('.drag-target', function (e) {
  127. window.Helpers.setCollapsed(false);
  128. });
  129. // Detect swipe gesture on the target element and call swipe Out
  130. window.Helpers.swipeOut('#layout-menu', function (e) {
  131. if (window.Helpers.isSmallScreen()) window.Helpers.setCollapsed(true);
  132. });
  133. // Display in main menu when menu scrolls
  134. let menuInnerContainer = document.getElementsByClassName('menu-inner'),
  135. menuInnerShadow = document.getElementsByClassName('menu-inner-shadow')[0];
  136. if (menuInnerContainer.length > 0 && menuInnerShadow) {
  137. menuInnerContainer[0].addEventListener('ps-scroll-y', function () {
  138. if (this.querySelector('.ps__thumb-y').offsetTop) {
  139. menuInnerShadow.style.display = 'block';
  140. } else {
  141. menuInnerShadow.style.display = 'none';
  142. }
  143. });
  144. }
  145. // Update light/dark image based on current style
  146. function switchImage(style) {
  147. if (style === 'system') {
  148. if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
  149. style = 'dark';
  150. } else {
  151. style = 'light';
  152. }
  153. }
  154. const switchImagesList = [].slice.call(document.querySelectorAll('[data-app-' + style + '-img]'));
  155. switchImagesList.map(function (imageEl) {
  156. const setImage = imageEl.getAttribute('data-app-' + style + '-img');
  157. imageEl.src = assetsPath + 'img/' + setImage; // Using window.assetsPath to get the exact relative path
  158. });
  159. }
  160. //Style Switcher (Light/Dark/System Mode)
  161. let styleSwitcher = document.querySelector('.dropdown-style-switcher');
  162. // Get style from local storage or use 'system' as default
  163. let storedStyle =
  164. localStorage.getItem('templateCustomizer-' + templateName + '--Style') || //if no template style then use Customizer style
  165. (window.templateCustomizer?.settings?.defaultStyle ?? 'light'); //!if there is no Customizer then use default style as light
  166. // Set style on click of style switcher item if template customizer is enabled
  167. if (window.templateCustomizer && styleSwitcher) {
  168. let styleSwitcherItems = [].slice.call(styleSwitcher.children[1].querySelectorAll('.dropdown-item'));
  169. styleSwitcherItems.forEach(function (item) {
  170. item.addEventListener('click', function () {
  171. let currentStyle = this.getAttribute('data-theme');
  172. if (currentStyle === 'light') {
  173. window.templateCustomizer.setStyle('light');
  174. } else if (currentStyle === 'dark') {
  175. window.templateCustomizer.setStyle('dark');
  176. } else {
  177. window.templateCustomizer.setStyle('system');
  178. }
  179. });
  180. });
  181. // Update style switcher icon based on the stored style
  182. const styleSwitcherIcon = styleSwitcher.querySelector('i');
  183. if (storedStyle === 'light') {
  184. styleSwitcherIcon.classList.add('ti-sun');
  185. new bootstrap.Tooltip(styleSwitcherIcon, {
  186. title: 'Light Mode',
  187. fallbackPlacements: ['bottom']
  188. });
  189. } else if (storedStyle === 'dark') {
  190. styleSwitcherIcon.classList.add('ti-moon');
  191. new bootstrap.Tooltip(styleSwitcherIcon, {
  192. title: 'Dark Mode',
  193. fallbackPlacements: ['bottom']
  194. });
  195. } else {
  196. styleSwitcherIcon.classList.add('ti-device-desktop');
  197. new bootstrap.Tooltip(styleSwitcherIcon, {
  198. title: 'System Mode',
  199. fallbackPlacements: ['bottom']
  200. });
  201. }
  202. }
  203. // Run switchImage function based on the stored style
  204. switchImage(storedStyle);
  205. // Internationalization (Language Dropdown)
  206. // ---------------------------------------
  207. if (typeof i18next !== 'undefined' && typeof i18NextHttpBackend !== 'undefined') {
  208. i18next
  209. .use(i18NextHttpBackend)
  210. .init({
  211. lng: window.templateCustomizer ? window.templateCustomizer.settings.lang : 'en',
  212. debug: false,
  213. fallbackLng: 'en',
  214. backend: {
  215. loadPath: assetsPath + 'json/locales/{{lng}}.json'
  216. },
  217. returnObjects: true
  218. })
  219. .then(function (t) {
  220. localize();
  221. });
  222. }
  223. let languageDropdown = document.getElementsByClassName('dropdown-language');
  224. if (languageDropdown.length) {
  225. let dropdownItems = languageDropdown[0].querySelectorAll('.dropdown-item');
  226. for (let i = 0; i < dropdownItems.length; i++) {
  227. dropdownItems[i].addEventListener('click', function () {
  228. let currentLanguage = this.getAttribute('data-language');
  229. let textDirection = this.getAttribute('data-text-direction');
  230. for (let sibling of this.parentNode.children) {
  231. var siblingEle = sibling.parentElement.parentNode.firstChild;
  232. // Loop through each sibling and push to the array
  233. while (siblingEle) {
  234. if (siblingEle.nodeType === 1 && siblingEle !== siblingEle.parentElement) {
  235. siblingEle.querySelector('.dropdown-item').classList.remove('active');
  236. }
  237. siblingEle = siblingEle.nextSibling;
  238. }
  239. }
  240. this.classList.add('active');
  241. i18next.changeLanguage(currentLanguage, (err, t) => {
  242. window.templateCustomizer ? window.templateCustomizer.setLang(currentLanguage) : '';
  243. directionChange(textDirection);
  244. if (err) return console.log('something went wrong loading', err);
  245. localize();
  246. });
  247. });
  248. }
  249. function directionChange(textDirection) {
  250. if (textDirection === 'rtl') {
  251. if (localStorage.getItem('templateCustomizer-' + templateName + '--Rtl') !== 'true')
  252. window.templateCustomizer ? window.templateCustomizer.setRtl(true) : '';
  253. } else {
  254. if (localStorage.getItem('templateCustomizer-' + templateName + '--Rtl') === 'true')
  255. window.templateCustomizer ? window.templateCustomizer.setRtl(false) : '';
  256. }
  257. }
  258. }
  259. function localize() {
  260. let i18nList = document.querySelectorAll('[data-i18n]');
  261. // Set the current language in dd
  262. let currentLanguageEle = document.querySelector('.dropdown-item[data-language="' + i18next.language + '"]');
  263. if (currentLanguageEle) {
  264. currentLanguageEle.click();
  265. }
  266. i18nList.forEach(function (item) {
  267. item.innerHTML = i18next.t(item.dataset.i18n);
  268. });
  269. }
  270. // Notification
  271. // ------------
  272. const notificationMarkAsReadAll = document.querySelector('.dropdown-notifications-all');
  273. const notificationMarkAsReadList = document.querySelectorAll('.dropdown-notifications-read');
  274. // Notification: Mark as all as read
  275. if (notificationMarkAsReadAll) {
  276. notificationMarkAsReadAll.addEventListener('click', event => {
  277. notificationMarkAsReadList.forEach(item => {
  278. item.closest('.dropdown-notifications-item').classList.add('marked-as-read');
  279. });
  280. });
  281. }
  282. // Notification: Mark as read/unread onclick of dot
  283. if (notificationMarkAsReadList) {
  284. notificationMarkAsReadList.forEach(item => {
  285. item.addEventListener('click', event => {
  286. item.closest('.dropdown-notifications-item').classList.toggle('marked-as-read');
  287. });
  288. });
  289. }
  290. // Notification: Mark as read/unread onclick of dot
  291. const notificationArchiveMessageList = document.querySelectorAll('.dropdown-notifications-archive');
  292. notificationArchiveMessageList.forEach(item => {
  293. item.addEventListener('click', event => {
  294. item.closest('.dropdown-notifications-item').remove();
  295. });
  296. });
  297. // Init helpers & misc
  298. // --------------------
  299. // Init BS Tooltip
  300. const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
  301. tooltipTriggerList.map(function (tooltipTriggerEl) {
  302. return new bootstrap.Tooltip(tooltipTriggerEl);
  303. });
  304. // Accordion active class
  305. const accordionActiveFunction = function (e) {
  306. if (e.type == 'show.bs.collapse' || e.type == 'show.bs.collapse') {
  307. e.target.closest('.accordion-item').classList.add('active');
  308. } else {
  309. e.target.closest('.accordion-item').classList.remove('active');
  310. }
  311. };
  312. const accordionTriggerList = [].slice.call(document.querySelectorAll('.accordion'));
  313. const accordionList = accordionTriggerList.map(function (accordionTriggerEl) {
  314. accordionTriggerEl.addEventListener('show.bs.collapse', accordionActiveFunction);
  315. accordionTriggerEl.addEventListener('hide.bs.collapse', accordionActiveFunction);
  316. });
  317. // If layout is RTL add .dropdown-menu-end class to .dropdown-menu
  318. // if (isRtl) {
  319. // Helpers._addClass('dropdown-menu-end', document.querySelectorAll('#layout-navbar .dropdown-menu'));
  320. // }
  321. // Auto update layout based on screen size
  322. window.Helpers.setAutoUpdate(true);
  323. // Toggle Password Visibility
  324. window.Helpers.initPasswordToggle();
  325. // Speech To Text
  326. window.Helpers.initSpeechToText();
  327. // Init PerfectScrollbar in Navbar Dropdown (i.e notification)
  328. window.Helpers.initNavbarDropdownScrollbar();
  329. let horizontalMenuTemplate = document.querySelector("[data-template^='horizontal-menu']");
  330. if (horizontalMenuTemplate) {
  331. // if screen size is small then set navbar fixed
  332. if (window.innerWidth < window.Helpers.LAYOUT_BREAKPOINT) {
  333. window.Helpers.setNavbarFixed('fixed');
  334. } else {
  335. window.Helpers.setNavbarFixed('');
  336. }
  337. }
  338. // On window resize listener
  339. // -------------------------
  340. window.addEventListener(
  341. 'resize',
  342. function (event) {
  343. // Hide open search input and set value blank
  344. if (window.innerWidth >= window.Helpers.LAYOUT_BREAKPOINT) {
  345. if (document.querySelector('.search-input-wrapper')) {
  346. document.querySelector('.search-input-wrapper').classList.add('d-none');
  347. document.querySelector('.search-input').value = '';
  348. }
  349. }
  350. // Horizontal Layout : Update menu based on window size
  351. if (horizontalMenuTemplate) {
  352. // if screen size is small then set navbar fixed
  353. if (window.innerWidth < window.Helpers.LAYOUT_BREAKPOINT) {
  354. window.Helpers.setNavbarFixed('fixed');
  355. } else {
  356. window.Helpers.setNavbarFixed('');
  357. }
  358. setTimeout(function () {
  359. if (window.innerWidth < window.Helpers.LAYOUT_BREAKPOINT) {
  360. if (document.getElementById('layout-menu')) {
  361. if (document.getElementById('layout-menu').classList.contains('menu-horizontal')) {
  362. menu.switchMenu('vertical');
  363. }
  364. }
  365. } else {
  366. if (document.getElementById('layout-menu')) {
  367. if (document.getElementById('layout-menu').classList.contains('menu-vertical')) {
  368. menu.switchMenu('horizontal');
  369. }
  370. }
  371. }
  372. }, 100);
  373. }
  374. },
  375. true
  376. );
  377. // Manage menu expanded/collapsed with templateCustomizer & local storage
  378. //------------------------------------------------------------------
  379. // If current layout is horizontal OR current window screen is small (overlay menu) than return from here
  380. if (isHorizontalLayout || window.Helpers.isSmallScreen()) {
  381. return;
  382. }
  383. // If current layout is vertical and current window screen is > small
  384. // Auto update menu collapsed/expanded based on the themeConfig
  385. if (typeof TemplateCustomizer !== 'undefined') {
  386. if (window.templateCustomizer.settings.defaultMenuCollapsed) {
  387. window.Helpers.setCollapsed(true, false);
  388. } else {
  389. window.Helpers.setCollapsed(false, false);
  390. }
  391. }
  392. // Manage menu expanded/collapsed state with local storage support If enableMenuLocalStorage = true in config.js
  393. if (typeof config !== 'undefined') {
  394. if (config.enableMenuLocalStorage) {
  395. try {
  396. if (localStorage.getItem('templateCustomizer-' + templateName + '--LayoutCollapsed') !== null)
  397. window.Helpers.setCollapsed(
  398. localStorage.getItem('templateCustomizer-' + templateName + '--LayoutCollapsed') === 'true',
  399. false
  400. );
  401. } catch (e) {}
  402. }
  403. }
  404. })();
  405. // ! Removed following code if you do't wish to use jQuery. Remember that navbar search functionality will stop working on removal.
  406. if (typeof $ !== 'undefined') {
  407. $(function () {
  408. // ! TODO: Required to load after DOM is ready, did this now with jQuery ready.
  409. window.Helpers.initSidebarToggle();
  410. // Toggle Universal Sidebar
  411. // Navbar Search with autosuggest (typeahead)
  412. // ? You can remove the following JS if you don't want to use search functionality.
  413. //----------------------------------------------------------------------------------
  414. var searchToggler = $('.search-toggler'),
  415. searchInputWrapper = $('.search-input-wrapper'),
  416. searchInput = $('.search-input'),
  417. contentBackdrop = $('.content-backdrop');
  418. // Open search input on click of search icon
  419. if (searchToggler.length) {
  420. searchToggler.on('click', function () {
  421. if (searchInputWrapper.length) {
  422. searchInputWrapper.toggleClass('d-none');
  423. searchInput.focus();
  424. }
  425. });
  426. }
  427. // Open search on 'CTRL+/'
  428. $(document).on('keydown', function (event) {
  429. let ctrlKey = event.ctrlKey,
  430. slashKey = event.which === 191;
  431. if (ctrlKey && slashKey) {
  432. if (searchInputWrapper.length) {
  433. searchInputWrapper.toggleClass('d-none');
  434. searchInput.focus();
  435. }
  436. }
  437. });
  438. // Note: Following code is required to update container class of typeahead dropdown width on focus of search input. setTimeout is required to allow time to initiate Typeahead UI.
  439. setTimeout(function () {
  440. var twitterTypeahead = $('.twitter-typeahead');
  441. searchInput.on('focus', function () {
  442. if (searchInputWrapper.hasClass('container-xxl')) {
  443. searchInputWrapper.find(twitterTypeahead).addClass('container-xxl');
  444. twitterTypeahead.removeClass('container-fluid');
  445. } else if (searchInputWrapper.hasClass('container-fluid')) {
  446. searchInputWrapper.find(twitterTypeahead).addClass('container-fluid');
  447. twitterTypeahead.removeClass('container-xxl');
  448. }
  449. });
  450. }, 10);
  451. if (searchInput.length) {
  452. // Filter config
  453. var filterConfig = function (data) {
  454. return function findMatches(q, cb) {
  455. let matches;
  456. matches = [];
  457. data.filter(function (i) {
  458. if (i.name.toLowerCase().startsWith(q.toLowerCase())) {
  459. matches.push(i);
  460. } else if (
  461. !i.name.toLowerCase().startsWith(q.toLowerCase()) &&
  462. i.name.toLowerCase().includes(q.toLowerCase())
  463. ) {
  464. matches.push(i);
  465. matches.sort(function (a, b) {
  466. return b.name < a.name ? 1 : -1;
  467. });
  468. } else {
  469. return [];
  470. }
  471. });
  472. cb(matches);
  473. };
  474. };
  475. // Search JSON
  476. var searchJson = 'search-vertical.json'; // For vertical layout
  477. if ($('#layout-menu').hasClass('menu-horizontal')) {
  478. var searchJson = 'search-horizontal.json'; // For vertical layout
  479. }
  480. // Search API AJAX call
  481. var searchData = $.ajax({
  482. url: assetsPath + 'json/' + searchJson, //? Use your own search api instead
  483. dataType: 'json',
  484. async: false
  485. }).responseJSON;
  486. // Init typeahead on searchInput
  487. searchInput.each(function () {
  488. var $this = $(this);
  489. searchInput
  490. .typeahead(
  491. {
  492. hint: false,
  493. classNames: {
  494. menu: 'tt-menu navbar-search-suggestion',
  495. cursor: 'active',
  496. suggestion: 'suggestion d-flex justify-content-between px-3 py-2 w-100'
  497. }
  498. },
  499. // ? Add/Update blocks as per need
  500. // Pages
  501. {
  502. name: 'pages',
  503. display: 'name',
  504. limit: 5,
  505. source: filterConfig(searchData.pages),
  506. templates: {
  507. header: '<h6 class="suggestions-header text-primary mb-0 mx-3 mt-3 pb-2">Pages</h6>',
  508. suggestion: function ({ url, icon, name }) {
  509. return (
  510. '<a href="' +
  511. url +
  512. '">' +
  513. '<div>' +
  514. '<i class="ti ' +
  515. icon +
  516. ' me-2"></i>' +
  517. '<span class="align-middle">' +
  518. name +
  519. '</span>' +
  520. '</div>' +
  521. '</a>'
  522. );
  523. },
  524. notFound:
  525. '<div class="not-found px-3 py-2">' +
  526. '<h6 class="suggestions-header text-primary mb-2">Pages</h6>' +
  527. '<p class="py-2 mb-0"><i class="ti ti-alert-circle ti-xs me-2"></i> No Results Found</p>' +
  528. '</div>'
  529. }
  530. },
  531. // Files
  532. {
  533. name: 'files',
  534. display: 'name',
  535. limit: 4,
  536. source: filterConfig(searchData.files),
  537. templates: {
  538. header: '<h6 class="suggestions-header text-primary mb-0 mx-3 mt-3 pb-2">Files</h6>',
  539. suggestion: function ({ src, name, subtitle, meta }) {
  540. return (
  541. '<a href="javascript:;">' +
  542. '<div class="d-flex w-50">' +
  543. '<img class="me-3" src="' +
  544. assetsPath +
  545. src +
  546. '" alt="' +
  547. name +
  548. '" height="32">' +
  549. '<div class="w-75">' +
  550. '<h6 class="mb-0">' +
  551. name +
  552. '</h6>' +
  553. '<small class="text-muted">' +
  554. subtitle +
  555. '</small>' +
  556. '</div>' +
  557. '</div>' +
  558. '<small class="text-muted">' +
  559. meta +
  560. '</small>' +
  561. '</a>'
  562. );
  563. },
  564. notFound:
  565. '<div class="not-found px-3 py-2">' +
  566. '<h6 class="suggestions-header text-primary mb-2">Files</h6>' +
  567. '<p class="py-2 mb-0"><i class="ti ti-alert-circle ti-xs me-2"></i> No Results Found</p>' +
  568. '</div>'
  569. }
  570. },
  571. // Members
  572. {
  573. name: 'members',
  574. display: 'name',
  575. limit: 4,
  576. source: filterConfig(searchData.members),
  577. templates: {
  578. header: '<h6 class="suggestions-header text-primary mb-0 mx-3 mt-3 pb-2">Members</h6>',
  579. suggestion: function ({ name, src, subtitle }) {
  580. return (
  581. '<a href="app-user-view-account.html">' +
  582. '<div class="d-flex align-items-center">' +
  583. '<img class="rounded-circle me-3" src="' +
  584. assetsPath +
  585. src +
  586. '" alt="' +
  587. name +
  588. '" height="32">' +
  589. '<div class="user-info">' +
  590. '<h6 class="mb-0">' +
  591. name +
  592. '</h6>' +
  593. '<small class="text-muted">' +
  594. subtitle +
  595. '</small>' +
  596. '</div>' +
  597. '</div>' +
  598. '</a>'
  599. );
  600. },
  601. notFound:
  602. '<div class="not-found px-3 py-2">' +
  603. '<h6 class="suggestions-header text-primary mb-2">Members</h6>' +
  604. '<p class="py-2 mb-0"><i class="ti ti-alert-circle ti-xs me-2"></i> No Results Found</p>' +
  605. '</div>'
  606. }
  607. }
  608. )
  609. //On typeahead result render.
  610. .bind('typeahead:render', function () {
  611. // Show content backdrop,
  612. contentBackdrop.addClass('show').removeClass('fade');
  613. })
  614. // On typeahead select
  615. .bind('typeahead:select', function (ev, suggestion) {
  616. // Open selected page
  617. if (suggestion.url) {
  618. window.location = suggestion.url;
  619. }
  620. })
  621. // On typeahead close
  622. .bind('typeahead:close', function () {
  623. // Clear search
  624. searchInput.val('');
  625. $this.typeahead('val', '');
  626. // Hide search input wrapper
  627. searchInputWrapper.addClass('d-none');
  628. // Fade content backdrop
  629. contentBackdrop.addClass('fade').removeClass('show');
  630. });
  631. // On searchInput keyup, Fade content backdrop if search input is blank
  632. searchInput.on('keyup', function () {
  633. if (searchInput.val() == '') {
  634. contentBackdrop.addClass('fade').removeClass('show');
  635. }
  636. });
  637. });
  638. // Init PerfectScrollbar in search result
  639. var psSearch;
  640. $('.navbar-search-suggestion').each(function () {
  641. psSearch = new PerfectScrollbar($(this)[0], {
  642. wheelPropagation: false,
  643. suppressScrollX: true
  644. });
  645. });
  646. searchInput.on('keyup', function () {
  647. psSearch.update();
  648. });
  649. }
  650. });
  651. }