codebase.js 70 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833
  1. /*
  2. * Document : codebase.js
  3. * Author : pixelcave
  4. * Description: Codebase - UI Framework Custom Functionality
  5. *
  6. */
  7. 'use strict';
  8. var Codebase = function() {
  9. var lHtml,
  10. lBody,
  11. lPage,
  12. lSidebar,
  13. lSidebarScroll,
  14. lSideOverlay,
  15. lSideOverlayScroll,
  16. lHeader,
  17. lHeaderSearch,
  18. lHeaderSearchInput,
  19. lHeaderLoader,
  20. lMain,
  21. lFooter,
  22. windowW;
  23. // Set helper variables
  24. var uiInit = function() {
  25. lHtml = jQuery('html');
  26. lBody = jQuery('body');
  27. lPage = jQuery('#page-container');
  28. lSidebar = jQuery('#sidebar');
  29. lSidebarScroll = jQuery('#sidebar-scroll');
  30. lSideOverlay = jQuery('#side-overlay');
  31. lSideOverlayScroll = jQuery('#side-overlay-scroll');
  32. lHeader = jQuery('#page-header');
  33. lHeaderSearch = jQuery('#page-header-search');
  34. lHeaderSearchInput = jQuery('#page-header-search-input');
  35. lHeaderLoader = jQuery('#page-header-loader');
  36. lMain = jQuery('#main-container');
  37. lFooter = jQuery('#page-footer');
  38. };
  39. /*
  40. ********************************************************************************************
  41. *
  42. * BASE UI FUNCTIONALITY
  43. *
  44. * Functions which handle vital UI functionality such as main navigation and layout
  45. * They are auto initialized
  46. *
  47. *********************************************************************************************
  48. */
  49. // Handles sidebar and side overlay custom scrolling functionality
  50. var uiHandleScroll = function(mode) {
  51. windowW = getWidth();
  52. // Init scrolling
  53. if (mode === 'init') {
  54. var sScrollTimeout;
  55. // Unbind events in case they are already binded
  56. jQuery(window).off('resize.cb.scroll orientationchange.cb.scroll');
  57. // Bind the events
  58. jQuery(window).on('resize.cb.scroll orientationchange.cb.scroll', function(){
  59. clearTimeout(sScrollTimeout);
  60. sScrollTimeout = setTimeout(function(){
  61. uiHandleScroll();
  62. }, 150);
  63. }).triggerHandler('resize.cb.scroll');
  64. } else {
  65. // If screen width is greater than 991 pixels and .side-scroll is added to #page-container
  66. if (windowW > 991 && lPage.hasClass('side-scroll')) {
  67. // Turn scroll lock off (sidebar and side overlay - slimScroll will take care of it)
  68. jQuery(lSidebar).add(lSideOverlay).scrollLock('disable');
  69. // If sidebar scrolling does not exist init it..
  70. if (lSidebarScroll.length && (!lSidebarScroll.parent('.slimScrollDiv').length)) {
  71. lSidebarScroll.slimScroll({
  72. height: lSidebar.outerHeight(),
  73. color: '#cdcdcd',
  74. size: '4px',
  75. opacity : .9,
  76. wheelStep : 15,
  77. distance : '0',
  78. railVisible: false,
  79. railOpacity: 1
  80. });
  81. // Small hack, so that scrolling works if the mouse is over the scrolling area on load and hasn't moved yet
  82. lSidebarScroll.mouseover();
  83. }
  84. else { // ..else resize scrolling height
  85. lSidebarScroll
  86. .add(lSidebarScroll.parent())
  87. .css('height', lSidebar.outerHeight());
  88. // Small hack, so that scrolling works if the mouse is over the scrolling area on load and hasn't moved yet
  89. lSidebarScroll.mouseover();
  90. }
  91. // If side overlay scrolling does not exist init it..
  92. if (lSideOverlayScroll.length && (!lSideOverlayScroll.parent('.slimScrollDiv').length)) {
  93. lSideOverlayScroll.slimScroll({
  94. height: lSideOverlay.outerHeight(),
  95. color: '#cdcdcd',
  96. size: '4px',
  97. opacity : .9,
  98. wheelStep : 15,
  99. distance : '0',
  100. railVisible: false,
  101. railOpacity: 1
  102. });
  103. }
  104. else { // ..else resize scrolling height
  105. lSideOverlayScroll
  106. .add(lSideOverlayScroll.parent())
  107. .css('height', lSideOverlay.outerHeight());
  108. }
  109. } else {
  110. // Turn scroll lock on (sidebar and side overlay)
  111. jQuery(lSidebar).add(lSideOverlay).scrollLock('enable');
  112. // If sidebar scrolling exists destroy it..
  113. if (lSidebarScroll.length && lSidebarScroll.parent('.slimScrollDiv').length) {
  114. lSidebarScroll
  115. .slimScroll({destroy: true});
  116. lSidebarScroll
  117. .attr('style', '');
  118. }
  119. // If side overlay scrolling exists destroy it..
  120. if (lSideOverlayScroll.length && lSideOverlayScroll.parent('.slimScrollDiv').length) {
  121. lSideOverlayScroll
  122. .slimScroll({destroy: true});
  123. lSideOverlayScroll
  124. .attr('style', '');
  125. }
  126. }
  127. }
  128. };
  129. // Resizes #main-container to fill empty space if exists (pushes footer to the bottom) + Adds transition to sidebar (small fix for IE)
  130. var uiHandleMain = function() {
  131. var resizeTimeout;
  132. // Unbind events in case they are already binded
  133. jQuery(window).off('resize.cb.main orientationchange.cb.main');
  134. // If #main-container element exists
  135. if (lMain.length) {
  136. jQuery(window).on('resize.cb.main orientationchange.cb.main', function(){
  137. clearTimeout(resizeTimeout);
  138. resizeTimeout = setTimeout(function(){
  139. var hWindow = jQuery(window).height();
  140. var hHeader = lHeader.outerHeight() || 0;
  141. var hFooter = lFooter.outerHeight() || 0;
  142. // Set #main-container min height accordingly
  143. if (lPage.hasClass('page-header-fixed') || lPage.hasClass('page-header-glass')) {
  144. lMain.css('min-height', hWindow - hFooter);
  145. } else {
  146. lMain.css('min-height', hWindow - hHeader - hFooter);
  147. }
  148. // Show footer's content
  149. lFooter.fadeTo(1000, 1);
  150. }, 150);
  151. }).triggerHandler('resize.cb.main');
  152. }
  153. // Add 'side-trans-enabled' class to #page-container (enables sidebar and side overlay transition on open/close)
  154. // Fixes IE10, IE11 and Edge bug in which animation was executed on each page load - really annoying!
  155. lPage.addClass('side-trans-enabled');
  156. };
  157. // Handles header related classes
  158. var uiHandleHeader = function() {
  159. // Unbind event in case it is already enabled
  160. jQuery(window).off('scroll.cb.header');
  161. // If the header is fixed and has the glass style, add the related class on scrolling to add a background color to the header
  162. if (lPage.hasClass('page-header-glass') && lPage.hasClass('page-header-fixed')) {
  163. jQuery(window).on('scroll.cb.header', function(){
  164. if (jQuery(this).scrollTop() > 60) {
  165. lPage.addClass('page-header-scroll');
  166. } else {
  167. lPage.removeClass('page-header-scroll');
  168. }
  169. }).trigger('scroll.cb.header');
  170. }
  171. };
  172. // Main navigation functionality
  173. var uiHandleNav = function() {
  174. // Unbind event in case it is already enabled
  175. lPage.off('click.cb.menu');
  176. // When a submenu link is clicked
  177. lPage.on('click.cb.menu', '[data-toggle="nav-submenu"]', function(e){
  178. // Get link
  179. var link = jQuery(this);
  180. // Get link's parent
  181. var parentLi = link.parent('li');
  182. if (parentLi.hasClass('open')) { // If submenu is open, close it..
  183. parentLi.removeClass('open');
  184. } else { // .. else if submenu is closed, close all other (same level) submenus first before open it
  185. link
  186. .closest('ul')
  187. .children('li')
  188. .removeClass('open');
  189. parentLi
  190. .addClass('open');
  191. }
  192. // Remove focus from submenu link
  193. if (lHtml.hasClass('no-focus')) {
  194. link.blur();
  195. }
  196. return false;
  197. });
  198. };
  199. // Material form inputs functionality
  200. var uiHandleForms = function() {
  201. jQuery('.form-material.floating > .form-control').each(function(){
  202. var input = jQuery(this);
  203. var parent = input.parent('.form-material');
  204. setTimeout(function() {
  205. if (input.val() ) {
  206. parent.addClass('open');
  207. }
  208. }, 150);
  209. input.off('change.cb.inputs').on('change.cb.inputs', function(){
  210. if (input.val()) {
  211. parent.addClass('open');
  212. } else {
  213. parent.removeClass('open');
  214. }
  215. });
  216. });
  217. };
  218. // Set active color theme functionality
  219. var uiHandleTheme = function() {
  220. var themeEl = jQuery('#css-theme');
  221. var cookies = lPage.hasClass('enable-cookies') ? true : false;
  222. // If cookies are enabled
  223. if (cookies) {
  224. var themeName = Cookies.get('cbThemeName') || false;
  225. // Update color theme
  226. if (themeName) {
  227. uiHandleThemeChange(themeEl, themeName);
  228. }
  229. // Update theme element
  230. themeEl = jQuery('#css-theme');
  231. }
  232. // Set the active color theme link as active
  233. jQuery('[data-toggle="theme"][data-theme="' + (themeEl.length ? themeEl.attr('href') : 'default') + '"]')
  234. .parent('li')
  235. .addClass('active');
  236. // Unbind event in case it is already enabled
  237. lPage.off('click.cb.themes');
  238. // When a color theme link is clicked
  239. lPage.on('click.cb.themes', '[data-toggle="theme"]', function(){
  240. var themeName = jQuery(this).data('theme');
  241. // Set this color theme link as active
  242. jQuery('[data-toggle="theme"]')
  243. .parent('li')
  244. .removeClass('active');
  245. jQuery('[data-toggle="theme"][data-theme="' + themeName + '"]')
  246. .parent('li')
  247. .addClass('active');
  248. // Update color theme
  249. uiHandleThemeChange(themeEl, themeName);
  250. // Update theme element
  251. themeEl = jQuery('#css-theme');
  252. // If cookies are enabled, save the new active color theme
  253. if (cookies) {
  254. Cookies.set('cbThemeName', themeName, { expires: 7 });
  255. }
  256. });
  257. };
  258. // Helper function for changing a theme
  259. var uiHandleThemeChange = function(themeEl, themeName) {
  260. if (themeName === 'default') {
  261. if (themeEl.length) {
  262. themeEl.remove();
  263. }
  264. } else {
  265. if (themeEl.length) {
  266. themeEl.attr('href', themeName);
  267. } else {
  268. jQuery('#css-main')
  269. .after('<link rel="stylesheet" id="css-theme" href="' + themeName + '">');
  270. }
  271. }
  272. };
  273. /*
  274. ********************************************************************************************
  275. *
  276. * API
  277. *
  278. * Functions which handle requests for blocks and layout
  279. *
  280. *********************************************************************************************
  281. */
  282. // Layout API
  283. var uiApiLayout = function(mode) {
  284. windowW = getWidth();
  285. // Mode selection
  286. switch(mode) {
  287. case 'init':
  288. // Unbind event in case it is already enabled
  289. lPage.off('click.cb.layout');
  290. // Call layout API on button click
  291. lPage.on('click.cb.layout', '[data-toggle="layout"]', function(){
  292. var el = jQuery(this);
  293. uiApiLayout(el.data('action'));
  294. if (lHtml.hasClass('no-focus')) {
  295. el.blur();
  296. }
  297. });
  298. break;
  299. case 'sidebar_pos_toggle':
  300. lPage.toggleClass('sidebar-r');
  301. break;
  302. case 'sidebar_pos_left':
  303. lPage.removeClass('sidebar-r');
  304. break;
  305. case 'sidebar_pos_right':
  306. lPage.addClass('sidebar-r');
  307. break;
  308. case 'sidebar_toggle':
  309. if (windowW > 991) {
  310. lPage.toggleClass('sidebar-o');
  311. } else {
  312. lPage.toggleClass('sidebar-o-xs');
  313. }
  314. break;
  315. case 'sidebar_open':
  316. if (windowW > 991) {
  317. lPage.addClass('sidebar-o');
  318. } else {
  319. lPage.addClass('sidebar-o-xs');
  320. }
  321. break;
  322. case 'sidebar_close':
  323. if (windowW > 991) {
  324. lPage.removeClass('sidebar-o');
  325. } else {
  326. lPage.removeClass('sidebar-o-xs');
  327. }
  328. break;
  329. case 'sidebar_mini_toggle':
  330. if (windowW > 991) {
  331. lPage.toggleClass('sidebar-mini');
  332. }
  333. break;
  334. case 'sidebar_mini_on':
  335. if (windowW > 991) {
  336. lPage.addClass('sidebar-mini');
  337. }
  338. break;
  339. case 'sidebar_mini_off':
  340. if (windowW > 991) {
  341. lPage.removeClass('sidebar-mini');
  342. }
  343. break;
  344. case 'sidebar_style_inverse_toggle':
  345. lPage.toggleClass('sidebar-inverse');
  346. break;
  347. case 'sidebar_style_inverse_on':
  348. lPage.addClass('sidebar-inverse');
  349. break;
  350. case 'sidebar_style_inverse_off':
  351. lPage.removeClass('sidebar-inverse');
  352. break;
  353. case 'side_overlay_toggle':
  354. if (lPage.hasClass('side-overlay-o')) {
  355. uiApiLayout('side_overlay_close');
  356. } else {
  357. uiApiLayout('side_overlay_open');
  358. }
  359. break;
  360. case 'side_overlay_open':
  361. // When ESCAPE key is hit close the side overlay
  362. jQuery(document).on('keydown.cb.sideOverlay', function(e){
  363. if (e.which === 27) {
  364. e.preventDefault();
  365. uiApiLayout('side_overlay_close');
  366. }
  367. });
  368. lPage.addClass('side-overlay-o');
  369. break;
  370. case 'side_overlay_close':
  371. // Unbind ESCAPE key
  372. jQuery(document).off('keydown.cb.sideOverlay');
  373. lPage.removeClass('side-overlay-o');
  374. break;
  375. case 'side_overlay_hoverable_toggle':
  376. lPage.toggleClass('side-overlay-hover');
  377. break;
  378. case 'side_overlay_hoverable_on':
  379. lPage.addClass('side-overlay-hover');
  380. break;
  381. case 'side_overlay_hoverable_off':
  382. lPage.removeClass('side-overlay-hover');
  383. break;
  384. case 'header_fixed_toggle':
  385. lPage.toggleClass('page-header-fixed');
  386. uiHandleHeader();
  387. uiHandleMain();
  388. break;
  389. case 'header_fixed_on':
  390. lPage.addClass('page-header-fixed');
  391. uiHandleHeader();
  392. uiHandleMain();
  393. break;
  394. case 'header_fixed_off':
  395. lPage.removeClass('page-header-fixed');
  396. uiHandleHeader();
  397. uiHandleMain();
  398. break;
  399. case 'header_style_modern':
  400. lPage.removeClass('page-header-glass page-header-inverse').addClass('page-header-modern');
  401. uiHandleHeader();
  402. uiHandleMain();
  403. break;
  404. case 'header_style_classic':
  405. lPage.removeClass('page-header-glass page-header-modern');
  406. uiHandleHeader();
  407. uiHandleMain();
  408. break;
  409. case 'header_style_glass':
  410. lPage.removeClass('page-header-modern').addClass('page-header-glass');
  411. uiHandleHeader();
  412. uiHandleMain();
  413. break;
  414. case 'header_style_inverse_toggle':
  415. if (!lPage.hasClass('page-header-modern')) {
  416. lPage.toggleClass('page-header-inverse');
  417. }
  418. break;
  419. case 'header_style_inverse_on':
  420. if (!lPage.hasClass('page-header-modern')) {
  421. lPage.addClass('page-header-inverse');
  422. }
  423. break;
  424. case 'header_style_inverse_off':
  425. if (!lPage.hasClass('page-header-modern')) {
  426. lPage.removeClass('page-header-inverse');
  427. }
  428. break;
  429. case 'header_search_on':
  430. lHeaderSearch.addClass('show');
  431. lHeaderSearchInput.focus();
  432. // When ESCAPE key is hit close the search section
  433. jQuery(document).on('keydown.cb.header.search', function(e){
  434. if (e.which === 27) {
  435. e.preventDefault();
  436. console.log('test');
  437. uiApiLayout('header_search_off');
  438. }
  439. });
  440. break;
  441. case 'header_search_off':
  442. lHeaderSearch.removeClass('show');
  443. lHeaderSearchInput.blur();
  444. // Unbind ESCAPE key
  445. jQuery(document).off('keydown.cb.header.search');
  446. break;
  447. case 'header_loader_on':
  448. lHeaderLoader.addClass('show');
  449. break;
  450. case 'header_loader_off':
  451. lHeaderLoader.removeClass('show');
  452. break;
  453. case 'side_scroll_toggle':
  454. lPage.toggleClass('side-scroll');
  455. uiHandleScroll();
  456. break;
  457. case 'side_scroll_on':
  458. lPage.addClass('side-scroll');
  459. uiHandleScroll();
  460. break;
  461. case 'side_scroll_off':
  462. lPage.removeClass('side-scroll');
  463. uiHandleScroll();
  464. break;
  465. case 'content_layout_toggle':
  466. if (lPage.hasClass('main-content-boxed')) {
  467. uiApiLayout('content_layout_narrow');
  468. } else if (lPage.hasClass('main-content-narrow')) {
  469. uiApiLayout('content_layout_full_width');
  470. } else {
  471. uiApiLayout('content_layout_boxed');
  472. }
  473. break;
  474. case 'content_layout_boxed':
  475. lPage.removeClass('main-content-narrow').addClass('main-content-boxed');
  476. break;
  477. case 'content_layout_narrow':
  478. lPage.removeClass('main-content-boxed').addClass('main-content-narrow');
  479. break;
  480. case 'content_layout_full_width':
  481. lPage.removeClass('main-content-boxed main-content-narrow');
  482. default:
  483. return false;
  484. }
  485. };
  486. // Blocks API
  487. var uiApiBlocks = function(block, mode) {
  488. // Set default icons for fullscreen and content toggle buttons
  489. var iconFullscreen = 'si si-size-fullscreen';
  490. var iconFullscreenActive = 'si si-size-actual';
  491. var iconContent = 'si si-arrow-up';
  492. var iconContentActive = 'si si-arrow-down';
  493. if (mode === 'init') {
  494. // Auto add the default toggle icons to fullscreen and content toggle buttons
  495. jQuery('[data-toggle="block-option"][data-action="fullscreen_toggle"]').each(function(){
  496. var el = jQuery(this);
  497. el.html('<i class="' + (jQuery(el).closest('.block').hasClass('block-mode-fullscreen') ? iconFullscreenActive : iconFullscreen) + '"></i>');
  498. });
  499. jQuery('[data-toggle="block-option"][data-action="content_toggle"]').each(function(){
  500. var el = jQuery(this);
  501. el.html('<i class="' + (el.closest('.block').hasClass('block-mode-hidden') ? iconContentActive : iconContent) + '"></i>');
  502. });
  503. // Unbind event in case it is already enabled
  504. lPage.off('click.cb.blocks');
  505. // Call blocks API on option button click
  506. lPage.on('click.cb.blocks', '[data-toggle="block-option"]', function(){
  507. uiApiBlocks(jQuery(this).closest('.block'), jQuery(this).data('action'));
  508. });
  509. } else {
  510. // Get block element
  511. var elBlock = (block instanceof jQuery) ? block : jQuery(block);
  512. // If element exists, procceed with blocks functionality
  513. if (elBlock.length) {
  514. // Get block option buttons if exist (need them to update their icons)
  515. var btnFullscreen = jQuery('[data-toggle="block-option"][data-action="fullscreen_toggle"]', elBlock);
  516. var btnContentToggle = jQuery('[data-toggle="block-option"][data-action="content_toggle"]', elBlock);
  517. // Mode selection
  518. switch(mode) {
  519. case 'fullscreen_toggle':
  520. elBlock.removeClass('block-mode-pinned').toggleClass('block-mode-fullscreen');
  521. // Enable/disable scroll lock to block
  522. if (elBlock.hasClass('block-mode-fullscreen')) {
  523. jQuery(elBlock).scrollLock('enable');
  524. } else {
  525. jQuery(elBlock).scrollLock('disable');
  526. }
  527. // Update block option icon
  528. if (btnFullscreen.length) {
  529. if (elBlock.hasClass('block-mode-fullscreen')) {
  530. jQuery('i', btnFullscreen)
  531. .removeClass(iconFullscreen)
  532. .addClass(iconFullscreenActive);
  533. } else {
  534. jQuery('i', btnFullscreen)
  535. .removeClass(iconFullscreenActive)
  536. .addClass(iconFullscreen);
  537. }
  538. }
  539. break;
  540. case 'fullscreen_on':
  541. elBlock.removeClass('block-mode-pinned').addClass('block-mode-fullscreen');
  542. // Enable scroll lock to block
  543. jQuery(elBlock).scrollLock('enable');
  544. // Update block option icon
  545. if (btnFullscreen.length) {
  546. jQuery('i', btnFullscreen)
  547. .removeClass(iconFullscreen)
  548. .addClass(iconFullscreenActive);
  549. }
  550. break;
  551. case 'fullscreen_off':
  552. elBlock.removeClass('block-mode-fullscreen');
  553. // Disable scroll lock to block
  554. jQuery(elBlock).scrollLock('disable');
  555. // Update block option icon
  556. if (btnFullscreen.length) {
  557. jQuery('i', btnFullscreen)
  558. .removeClass(iconFullscreenActive)
  559. .addClass(iconFullscreen);
  560. }
  561. break;
  562. case 'content_toggle':
  563. elBlock.toggleClass('block-mode-hidden');
  564. // Update block option icon
  565. if (btnContentToggle.length) {
  566. if (elBlock.hasClass('block-mode-hidden')) {
  567. jQuery('i', btnContentToggle)
  568. .removeClass(iconContent)
  569. .addClass(iconContentActive);
  570. } else {
  571. jQuery('i', btnContentToggle)
  572. .removeClass(iconContentActive)
  573. .addClass(iconContent);
  574. }
  575. }
  576. break;
  577. case 'content_hide':
  578. elBlock.addClass('block-mode-hidden');
  579. // Update block option icon
  580. if (btnContentToggle.length) {
  581. jQuery('i', btnContentToggle)
  582. .removeClass(iconContent)
  583. .addClass(iconContentActive);
  584. }
  585. break;
  586. case 'content_show':
  587. elBlock.removeClass('block-mode-hidden');
  588. // Update block option icon
  589. if (btnContentToggle.length) {
  590. jQuery('i', btnContentToggle)
  591. .removeClass(iconContentActive)
  592. .addClass(iconContent);
  593. }
  594. break;
  595. case 'state_toggle':
  596. elBlock.toggleClass('block-mode-loading');
  597. // Return block to normal state if the demostration mode is on in the refresh option button - data-action-mode="demo"
  598. if (jQuery('[data-toggle="block-option"][data-action="state_toggle"][data-action-mode="demo"]', elBlock).length) {
  599. setTimeout(function(){
  600. elBlock.removeClass('block-mode-loading');
  601. }, 2000);
  602. }
  603. break;
  604. case 'state_loading':
  605. elBlock.addClass('block-mode-loading');
  606. break;
  607. case 'state_normal':
  608. elBlock.removeClass('block-mode-loading');
  609. break;
  610. case 'pinned_toggle':
  611. elBlock.removeClass('block-mode-fullscreen').toggleClass('block-mode-pinned');
  612. break;
  613. case 'pinned_on':
  614. elBlock.removeClass('block-mode-fullscreen').addClass('block-mode-pinned');
  615. break;
  616. case 'pinned_off':
  617. elBlock.removeClass('block-mode-pinned');
  618. break;
  619. case 'close':
  620. elBlock.hide();
  621. break;
  622. case 'open':
  623. elBlock.show();
  624. break;
  625. default:
  626. return false;
  627. }
  628. }
  629. }
  630. };
  631. /*
  632. ********************************************************************************************
  633. *
  634. * PRIVATE HELPERS
  635. *
  636. * Private helper functions
  637. *
  638. *********************************************************************************************
  639. */
  640. // Get window width
  641. var getWidth = function() {
  642. return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
  643. };
  644. /*
  645. ********************************************************************************************
  646. *
  647. * CORE HELPERS
  648. *
  649. * Third party plugin inits or various custom user interface helpers to extend functionality
  650. * They are called by default and can be used right away
  651. *
  652. *********************************************************************************************
  653. */
  654. // Toggle class
  655. var uiHelperCoreToggleClass = function() {
  656. jQuery('[data-toggle="class-toggle"]:not(.js-class-toggle-enabled)').on('click.cb.helpers.core', function(){
  657. var el = jQuery(this);
  658. // Add .js-class-toggle-enabled class to tag it as activated
  659. el.addClass('js-class-toggle-enabled');
  660. jQuery(el.data('target').toString()).toggleClass(el.data('class').toString());
  661. if (lHtml.hasClass('no-focus')) {
  662. el.blur();
  663. }
  664. });
  665. };
  666. // Scroll to element animation
  667. var uiHelperCoreScrollTo = function() {
  668. jQuery('[data-toggle="scroll-to"]:not(.js-scroll-to-enabled)').on('click.cb.helpers.core', function(e){
  669. e.stopPropagation();
  670. // Set variables
  671. var el = jQuery(this);
  672. var elTarget = el.data('target') || el.attr('href');
  673. var elSpeed = el.data('speed') || 1000;
  674. var headerHeight = (lHeader.length && lPage.hasClass('page-header-fixed')) ? lHeader.outerHeight() : 0;
  675. // Add .js-scroll-to-enabled class to tag it as activated
  676. el.addClass('js-scroll-to-enabled');
  677. jQuery('html, body').animate({
  678. scrollTop: jQuery(elTarget).offset().top - headerHeight
  679. }, elSpeed);
  680. });
  681. };
  682. // Add the correct copyright year
  683. var uiHelperCoreYearCopy = function() {
  684. var yearCopy = jQuery('.js-year-copy');
  685. if (yearCopy.length > 0) {
  686. var date = new Date();
  687. var curYear = date.getFullYear();
  688. var baseYear = (yearCopy.html().length > 0) ? yearCopy.html() : curYear;
  689. if (parseInt(baseYear) >= curYear) {
  690. yearCopy.html(curYear);
  691. } else {
  692. yearCopy.html(baseYear + '-' + curYear.toString().substr(2, 2));
  693. }
  694. }
  695. };
  696. // Bootstrap tooltip, for more examples you can check out https://getbootstrap.com/docs/4.0/components/tooltips/
  697. var uiHelperCoreTooltip = function() {
  698. jQuery('[data-toggle="tooltip"]:not(.js-tooltip-enabled)').add('.js-tooltip:not(.js-tooltip-enabled)').each(function(){
  699. var el = jQuery(this);
  700. // Add .js-tooltip-enabled class to tag it as activated
  701. el.addClass('js-tooltip-enabled');
  702. // Init
  703. el.tooltip({
  704. container: el.data('container') || 'body',
  705. animation: el.data('animation') || false
  706. });
  707. });
  708. };
  709. // Bootstrap popover, for more examples you can check out https://getbootstrap.com/docs/4.0/components/popovers/
  710. var uiHelperCorePopover = function() {
  711. jQuery('[data-toggle="popover"]:not(.js-popover-enabled)').add('.js-popover:not(.js-popover-enabled)').each(function(){
  712. var el = jQuery(this);
  713. // Add .js-popover-enabled class to tag it as activated
  714. el.addClass('js-popover-enabled');
  715. // Init
  716. el.popover({
  717. container: el.data('container') || 'body',
  718. animation: el.data('animation') || false,
  719. trigger: el.data('trigger') || 'hover focus'
  720. });
  721. });
  722. };
  723. // Bootstrap tab, for more examples you can check out http://getbootstrap.com/docs/4.0/components/navs/#tabs
  724. var uiHelperCoreTab = function() {
  725. jQuery('[data-toggle="tabs"]:not(.js-tabs-enabled)').add('.js-tabs:not(.js-tabs-enabled)').each(function(){
  726. var el = jQuery(this);
  727. // Add .js-tabs-enabled class to tag it as activated
  728. el.addClass('js-tabs-enabled');
  729. // Init
  730. el.find('a').on('click.cb.helpers.core', function(e){
  731. e.preventDefault();
  732. jQuery(this).tab('show');
  733. });
  734. });
  735. };
  736. // jQuery Appear, for more examples you can check out https://github.com/bas2k/jquery.appear
  737. var uiHelperCoreAppear = function(){
  738. // Add a specific class on elements (when they become visible on scrolling)
  739. jQuery('[data-toggle="appear"]:not(.js-appear-enabled)').each(function(){
  740. windowW = getWidth();
  741. var el = jQuery(this);
  742. var elCssClass = el.data('class') || 'animated fadeIn';
  743. var elOffset = el.data('offset') || 0;
  744. var elTimeout = (lHtml.hasClass('ie9') || windowW < 992) ? 0 : (el.data('timeout') ? el.data('timeout') : 0);
  745. // Add .js-appear-enabled class to tag it as activated
  746. el.addClass('js-appear-enabled');
  747. // Init
  748. el.appear(function() {
  749. setTimeout(function(){
  750. el
  751. .removeClass('invisible')
  752. .addClass(elCssClass);
  753. }, elTimeout);
  754. },{accY: elOffset});
  755. });
  756. };
  757. // jQuery Appear + jQuery countTo, for more examples you can check out https://github.com/bas2k/jquery.appear and https://github.com/mhuggins/jquery-countTo
  758. var uiHelperCoreAppearCountTo = function(){
  759. // Init counter functionality
  760. jQuery('[data-toggle="countTo"]:not(.js-count-to-enabled)').each(function(){
  761. var el = jQuery(this);
  762. var elAfter = el.data('after');
  763. var elBefore = el.data('before');
  764. // Add .js-count-to-enabled class to tag it as activated
  765. el.addClass('js-count-to-enabled');
  766. // Init
  767. el.appear(function() {
  768. el.countTo({
  769. speed: el.data('speed') || 1500,
  770. refreshInterval: el.data('refresh-interval') || 15,
  771. onComplete: function() {
  772. if(elAfter) {
  773. el.html(el.html() + elAfter);
  774. } else if (elBefore) {
  775. el.html(elBefore + el.html());
  776. }
  777. }
  778. });
  779. });
  780. });
  781. };
  782. // jQuery SlimScroll, for more examples you can check out http://rocha.la/jQuery-slimScroll
  783. var uiHelperCoreSlimscroll = function(){
  784. // Init slimScroll functionality
  785. jQuery('[data-toggle="slimscroll"]:not(.js-slimscroll-enabled)').each(function(){
  786. var el = jQuery(this);
  787. // Add .js-slimscroll-enabled class to tag it as activated
  788. el.addClass('js-slimscroll-enabled');
  789. // Init
  790. el.slimScroll({
  791. height: el.data('height') || '200px',
  792. size: el.data('size') || '5px',
  793. position: el.data('position') || 'right',
  794. color: el.data('color') || '#000',
  795. opacity: el.data('opacity') || '.25',
  796. distance: el.data('distance') || '0',
  797. alwaysVisible: el.data('always-visible') ? true : false,
  798. railVisible: el.data('rail-visible') ? true : false,
  799. railColor: el.data('rail-color') ||'#999',
  800. railOpacity: el.data('rail-opacity') || .3
  801. });
  802. });
  803. };
  804. // Manage page loading screen functionality
  805. var uiHelperCorePageLoader = function(mode, colorClass) {
  806. var lpageLoader = jQuery('#page-loader');
  807. if (mode === 'show') {
  808. if (lpageLoader.length) {
  809. if (colorClass) {
  810. lpageLoader.removeClass().addClass(colorClass);
  811. }
  812. lpageLoader.addClass('show');
  813. } else {
  814. if (colorClass) {
  815. lBody.prepend('<div id="page-loader" class="show ' + colorClass + '"></div>');
  816. } else {
  817. lBody.prepend('<div id="page-loader" class="show"></div>');
  818. }
  819. }
  820. } else if (mode === 'hide') {
  821. if (lpageLoader.length) {
  822. lpageLoader.removeClass('show');
  823. }
  824. }
  825. return false;
  826. };
  827. // Ripple effect fuctionality
  828. var uiHelperCoreRipple = function() {
  829. jQuery('[data-toggle="click-ripple"]:not(.js-click-ripple-enabled)').each(function(){
  830. var el = jQuery(this);
  831. // Add .js-click-ripple-enabled class to tag it as activated
  832. el.addClass('js-click-ripple-enabled');
  833. // Add required properties to the element
  834. el.css({
  835. 'overflow': 'hidden',
  836. 'position': 'relative',
  837. 'z-index': 1
  838. });
  839. // On element click
  840. el.on('click.cb.helpers.core', function(e) {
  841. var cssClass = 'click-ripple', ripple, d, x, y;
  842. // If the ripple element doesn't exist in this element, add it..
  843. if (el.children('.' + cssClass).length === 0) {
  844. el.prepend('<span class="' + cssClass + '"></span>');
  845. }
  846. else { // ..else remove .animate class from ripple element
  847. el.children('.' + cssClass).removeClass('animate');
  848. }
  849. // Get the ripple element
  850. var ripple = el.children('.' + cssClass);
  851. // If the ripple element doesn't have dimensions set them accordingly
  852. if(!ripple.height() && !ripple.width()) {
  853. d = Math.max(el.outerWidth(), el.outerHeight());
  854. ripple.css({height: d, width: d});
  855. }
  856. // Get coordinates for our ripple element
  857. x = e.pageX - el.offset().left - ripple.width()/2;
  858. y = e.pageY - el.offset().top - ripple.height()/2;
  859. // Position the ripple element and add the class .animate to it
  860. ripple.css({top: y + 'px', left: x + 'px'}).addClass('animate');
  861. });
  862. });
  863. };
  864. /*
  865. ********************************************************************************************
  866. *
  867. * UI HELPERS (ON DEMAND)
  868. *
  869. * Third party plugin inits or various custom user interface helpers to extend functionality
  870. * They need to be called in a page to be initialized. They are included here to be easy to
  871. * init them on demand on multiple pages (usually repeated init code in common components)
  872. *
  873. ********************************************************************************************
  874. */
  875. /*
  876. * Print Page functionality
  877. *
  878. * Codebase.helper('print-page');
  879. *
  880. */
  881. var uiHelperPrint = function() {
  882. // Store all #page-container classes
  883. var pageCls = lPage.prop('class');
  884. // Remove all classes from #page-container
  885. lPage.prop('class', '');
  886. // Print the page
  887. window.print();
  888. // Restore all #page-container classes
  889. lPage.prop('class', pageCls);
  890. };
  891. /*
  892. * Custom Table functionality such as section toggling or checkable rows
  893. *
  894. * Codebase.helper('table-tools');
  895. *
  896. */
  897. // Table sections functionality
  898. var uiHelperTableToolsSections = function(){
  899. // For each table
  900. jQuery('.js-table-sections:not(.js-table-sections-enabled)').each(function(){
  901. var table = jQuery(this);
  902. // Add .js-table-sections-enabled class to tag it as activated
  903. table.addClass('js-table-sections-enabled');
  904. // When a row is clicked in tbody.js-table-sections-header
  905. jQuery('.js-table-sections-header > tr', table).on('click.cb.helpers', function(e) {
  906. if (e.target.type !== 'checkbox'
  907. && e.target.type !== 'button'
  908. && e.target.tagName.toLowerCase() !== 'a'
  909. && !jQuery(e.target).parent('label').length) {
  910. var row = jQuery(this);
  911. var tbody = row.parent('tbody');
  912. if ( ! tbody.hasClass('show')) {
  913. jQuery('tbody', table).removeClass('show table-active');
  914. }
  915. tbody.toggleClass('show table-active');
  916. }
  917. });
  918. });
  919. };
  920. // Checkable table functionality
  921. var uiHelperTableToolsCheckable = function() {
  922. // For each table
  923. jQuery('.js-table-checkable:not(.js-table-checkable-enabled)').each(function(){
  924. var table = jQuery(this);
  925. // Add .js-table-checkable-enabled class to tag it as activated
  926. table.addClass('js-table-checkable-enabled');
  927. // When a checkbox is clicked in thead
  928. jQuery('thead input:checkbox', table).on('click.cb.helpers', function() {
  929. var checkedStatus = jQuery(this).prop('checked');
  930. // Check or uncheck all checkboxes in tbody
  931. jQuery('tbody input:checkbox', table).each(function() {
  932. var checkbox = jQuery(this);
  933. checkbox.prop('checked', checkedStatus);
  934. uiHelperTableToolscheckRow(checkbox, checkedStatus);
  935. });
  936. });
  937. // When a checkbox is clicked in tbody
  938. jQuery('tbody input:checkbox', table).on('click.cb.helpers', function() {
  939. var checkbox = jQuery(this);
  940. uiHelperTableToolscheckRow(checkbox, checkbox.prop('checked'));
  941. });
  942. // When a row is clicked in tbody
  943. jQuery('tbody > tr', table).on('click.cb.helpers', function(e) {
  944. if (e.target.type !== 'checkbox'
  945. && e.target.type !== 'button'
  946. && e.target.tagName.toLowerCase() !== 'a'
  947. && !jQuery(e.target).parent('label').length) {
  948. var checkbox = jQuery('input:checkbox', this);
  949. var checkedStatus = checkbox.prop('checked');
  950. checkbox.prop('checked', ! checkedStatus);
  951. uiHelperTableToolscheckRow(checkbox, ! checkedStatus);
  952. }
  953. });
  954. });
  955. };
  956. // Checkable table functionality helper - Checks or unchecks table row
  957. var uiHelperTableToolscheckRow = function(checkbox, checkedStatus) {
  958. if (checkedStatus) {
  959. checkbox
  960. .closest('tr')
  961. .addClass('table-active');
  962. } else {
  963. checkbox
  964. .closest('tr')
  965. .removeClass('table-active');
  966. }
  967. };
  968. /*
  969. * Content filtering functionality
  970. *
  971. * Codebase.helper('content-filter');
  972. *
  973. */
  974. var uiHelperContentFilter = function() {
  975. // Content Filtering init
  976. jQuery('.js-filter:not(.js-filter-enabled)').each(function(){
  977. var el = jQuery(this);
  978. var filterNav = jQuery('.nav-pills', el);
  979. var filterLinks = jQuery('a[data-category-link]', el);
  980. var filterItems = jQuery('[data-category]', el);
  981. var filterSpeed = el.data('speed') || 200;
  982. // Add .js-filter-enabled class to tag it as activated
  983. el.addClass('js-filter-enabled');
  984. // If navigation pills are used, make them responsive (stacked on smaller screens)
  985. if (filterNav.length) {
  986. var resizeTimeout, windowW;
  987. jQuery(window).on('resize.cb.helpers', function(){
  988. clearTimeout(resizeTimeout);
  989. resizeTimeout = setTimeout(function(){
  990. windowW = getWidth();
  991. if (windowW < 768) {
  992. filterNav.addClass('flex-column');
  993. } else {
  994. filterNav.removeClass('flex-column');
  995. }
  996. }, 150);
  997. }).trigger('resize.cb.helpers');
  998. }
  999. // Add number of items to the links if enabled by adding data-numbers="true" to the main element
  1000. if (el.data('numbers')) {
  1001. filterLinks.each(function(){
  1002. var filterLink = jQuery(this);
  1003. var filterCat = filterLink.data('category-link');
  1004. // Add number of items to this category link
  1005. if (filterCat === 'all') {
  1006. filterLink.append(' (' + filterItems.length + ')');
  1007. } else {
  1008. filterLink.append(' (' + filterItems.filter('[data-category="' + filterCat + '"]').length + ')');
  1009. }
  1010. });
  1011. }
  1012. // When a filter link is clicked
  1013. filterLinks.on('click.cb.helpers', function() {
  1014. var filterLink = jQuery(this);
  1015. var filterCat;
  1016. // Procceed only if the user clicked on an inactive category
  1017. if ( ! filterLink.hasClass('active')) {
  1018. // Remove active class from all filter links
  1019. filterLinks.removeClass('active');
  1020. // Add the active class to the clicked link
  1021. filterLink.addClass('active');
  1022. // Get its data-category value
  1023. filterCat = filterLink.data('category-link');
  1024. // If the value is 'all' hide current visible items and show them all together, else hide them all and show only from the category we need
  1025. if (filterCat === 'all') {
  1026. if (filterItems.filter(':visible').length) {
  1027. filterItems.filter(':visible').fadeOut(filterSpeed, function(){
  1028. filterItems.fadeIn(filterSpeed);
  1029. });
  1030. } else {
  1031. filterItems.fadeIn(filterSpeed);
  1032. }
  1033. } else {
  1034. if (filterItems.filter(':visible').length) {
  1035. filterItems.filter(':visible').fadeOut(filterSpeed, function(){
  1036. filterItems
  1037. .filter('[data-category="' + filterCat + '"]')
  1038. .fadeIn(filterSpeed);
  1039. });
  1040. } else {
  1041. filterItems
  1042. .filter('[data-category="' + filterCat + '"]')
  1043. .fadeIn(filterSpeed);
  1044. }
  1045. }
  1046. }
  1047. return false;
  1048. });
  1049. });
  1050. };
  1051. /*
  1052. ********************************************************************************************
  1053. *
  1054. * All the following helpers require each plugin's resources (JS, CSS) to be included in order to work
  1055. *
  1056. ********************************************************************************************
  1057. */
  1058. /*
  1059. * Magnific Popup functionality, for more examples you can check out http://dimsemenov.com/plugins/magnific-popup/
  1060. *
  1061. * Codebase.helper('magnific-popup');
  1062. *
  1063. */
  1064. var uiHelperMagnific = function(){
  1065. // Gallery init
  1066. jQuery('.js-gallery:not(.js-gallery-enabled)').each(function(){
  1067. var el = jQuery(this);
  1068. // Add .js-gallery-enabled class to tag it as activated
  1069. el.addClass('js-gallery-enabled');
  1070. // Init
  1071. el.magnificPopup({
  1072. delegate: 'a.img-lightbox',
  1073. type: 'image',
  1074. gallery: {
  1075. enabled: true
  1076. }
  1077. });
  1078. });
  1079. };
  1080. /*
  1081. * CKEditor init, for more examples you can check out http://ckeditor.com/
  1082. *
  1083. * Codebase.helper('ckeditor');
  1084. *
  1085. */
  1086. var uiHelperCkeditor = function(){
  1087. // Init inline text editor
  1088. if (jQuery('#js-ckeditor-inline:not(.js-ckeditor-inline-enabled)').length) {
  1089. jQuery('#js-ckeditor-inline').attr('contenteditable','true');
  1090. CKEDITOR.inline('js-ckeditor-inline');
  1091. // Add .js-ckeditor-inline-enabled class to tag it as activated
  1092. jQuery('#js-ckeditor-inline').addClass('js-ckeditor-inline-enabled');
  1093. }
  1094. // Init full text editor
  1095. if (jQuery('#js-ckeditor:not(.js-ckeditor-enabled)').length) {
  1096. CKEDITOR.replace('js-ckeditor');
  1097. // Add .js-ckeditor-enabled class to tag it as activated
  1098. jQuery('#js-ckeditor').addClass('js-ckeditor-enabled');
  1099. }
  1100. };
  1101. /*
  1102. * SimpleMDE init, for more examples you can check out https://github.com/NextStepWebs/simplemde-markdown-editor
  1103. *
  1104. * Codebase.helper('simplemde');
  1105. *
  1106. */
  1107. var uiHelperSimpleMDE = function(){
  1108. // Init markdown editor (with .js-simplemde class)
  1109. jQuery('.js-simplemde:not(.js-simplemde-enabled)').each(function(){
  1110. var el = jQuery(this);
  1111. // Add .js-simplemde-enabled class to tag it as activated
  1112. el.addClass('js-simplemde-enabled');
  1113. // Init editor
  1114. new SimpleMDE({ element: el[0] });
  1115. });
  1116. };
  1117. /*
  1118. * Slick init, for more examples you can check out http://kenwheeler.github.io/slick/
  1119. *
  1120. * Codebase.helper('slick');
  1121. *
  1122. */
  1123. var uiHelperSlick = function(){
  1124. // Get each slider element (with .js-slider class)
  1125. jQuery('.js-slider:not(.js-slider-enabled)').each(function(){
  1126. var el = jQuery(this);
  1127. // Add .js-slider-enabled class to tag it as activated
  1128. el.addClass('js-slider-enabled');
  1129. // Init slick slider
  1130. el.slick({
  1131. arrows: el.data('arrows') || false,
  1132. dots: el.data('dots') || false,
  1133. slidesToShow: el.data('slides-to-show') || 1,
  1134. slidesToScroll: el.data('slides-to-scroll') || 1,
  1135. centerMode: el.data('center-mode') || false,
  1136. autoplay: el.data('autoplay') || false,
  1137. autoplaySpeed: el.data('autoplay-speed') || 3000
  1138. });
  1139. });
  1140. };
  1141. /*
  1142. * Bootstrap Datepicker init, for more examples you can check out https://github.com/eternicode/bootstrap-datepicker
  1143. *
  1144. * Codebase.helper('datepicker');
  1145. *
  1146. */
  1147. var uiHelperDatepicker = function(){
  1148. // Init datepicker (with .js-datepicker and .input-daterange class)
  1149. jQuery('.js-datepicker:not(.js-datepicker-enabled)').add('.input-daterange:not(.js-datepicker-enabled)').each(function(){
  1150. var el = jQuery(this);
  1151. // Add .js-datepicker-enabled class to tag it as activated
  1152. el.addClass('js-datepicker-enabled');
  1153. // Init
  1154. el.datepicker({
  1155. weekStart: el.data('week-start') || 0,
  1156. autoclose: el.data('autoclose') || false,
  1157. todayHighlight: el.data('today-highlight') || false,
  1158. orientation: 'bottom' // Position issue when using BS4, set it to bottom until officially supported
  1159. });
  1160. });
  1161. };
  1162. /*
  1163. * Bootstrap Colorpicker init, for more examples you can check out https://github.com/itsjavi/bootstrap-colorpicker/
  1164. *
  1165. * Codebase.helper('colorpicker');
  1166. *
  1167. */
  1168. var uiHelperColorpicker = function(){
  1169. // Get each colorpicker element (with .js-colorpicker class)
  1170. jQuery('.js-colorpicker:not(.js-colorpicker-enabled)').each(function(){
  1171. var el = jQuery(this);
  1172. // Add .js-enabled class to tag it as activated
  1173. el.addClass('js-colorpicker-enabled');
  1174. // Init colorpicker
  1175. el.colorpicker();
  1176. });
  1177. };
  1178. /*
  1179. * Masked Inputs, for more examples you can check out http://digitalbush.com/projects/masked-input-plugin/
  1180. *
  1181. * Codebase.helper('masked-inputs');
  1182. *
  1183. */
  1184. var uiHelperMaskedInputs = function(){
  1185. // Init Masked Inputs
  1186. // a - Represents an alpha character (A-Z,a-z)
  1187. // 9 - Represents a numeric character (0-9)
  1188. // * - Represents an alphanumeric character (A-Z,a-z,0-9)
  1189. jQuery('.js-masked-date:not(.js-masked-enabled)').mask('99/99/9999');
  1190. jQuery('.js-masked-date-dash:not(.js-masked-enabled)').mask('99-99-9999');
  1191. jQuery('.js-masked-phone:not(.js-masked-enabled)').mask('(999) 999-9999');
  1192. jQuery('.js-masked-phone-ext:not(.js-masked-enabled)').mask('(999) 999-9999? x99999');
  1193. jQuery('.js-masked-taxid:not(.js-masked-enabled)').mask('99-9999999');
  1194. jQuery('.js-masked-ssn:not(.js-masked-enabled)').mask('999-99-9999');
  1195. jQuery('.js-masked-pkey:not(.js-masked-enabled)').mask('a*-999-a999');
  1196. jQuery('.js-masked-time:not(.js-masked-enabled)').mask('99:99');
  1197. jQuery('.js-masked-date')
  1198. .add('.js-masked-date-dash')
  1199. .add('.js-masked-phone')
  1200. .add('.js-masked-phone-ext')
  1201. .add('.js-masked-taxid')
  1202. .add('.js-masked-ssn')
  1203. .add('.js-masked-pkey')
  1204. .add('.js-masked-time')
  1205. .addClass('js-masked-enabled');
  1206. };
  1207. /*
  1208. * Tags Inputs, for more examples you can check out https://github.com/xoxco/jQuery-Tags-Input
  1209. *
  1210. * Codebase.helper('tags-inputs');
  1211. *
  1212. */
  1213. var uiHelperTagsInputs = function(){
  1214. // Init Tags Inputs (with .js-tags-input class)
  1215. jQuery('.js-tags-input:not(.js-tags-input-enabled)').each(function(){
  1216. var el = jQuery(this);
  1217. // Add .js-tags-input-enabled class to tag it as activated
  1218. el.addClass('js-tags-input-enabled');
  1219. // Init
  1220. el.tagsInput({
  1221. height: el.data('height') || false,
  1222. width: el.data('width') || '100%',
  1223. defaultText: el.data('default-text') || 'Add tag',
  1224. removeWithBackspace: el.data('remove-with-backspace') || true,
  1225. delimiter: [',']
  1226. });
  1227. });
  1228. };
  1229. /*
  1230. * Select2, for more examples you can check out https://github.com/select2/select2
  1231. *
  1232. * Codebase.helper('select2');
  1233. *
  1234. */
  1235. var uiHelperSelect2 = function(){
  1236. // Init Select2 (with .js-select2 class)
  1237. jQuery('.js-select2:not(.js-select2-enabled)').each(function(){
  1238. var el = jQuery(this);
  1239. // Add .js-select2-enabled class to tag it as activated
  1240. el.addClass('js-select2-enabled');
  1241. // Init
  1242. el.select2();
  1243. });
  1244. };
  1245. /*
  1246. * Highlight.js, for more examples you can check out https://highlightjs.org/usage/
  1247. *
  1248. * Codebase.helper('highlightjs');
  1249. *
  1250. */
  1251. var uiHelperHighlightjs = function(){
  1252. // Init Highlight.js
  1253. if ( ! hljs.isHighlighted) {
  1254. hljs.initHighlighting();
  1255. }
  1256. };
  1257. /*
  1258. * Bootstrap Notify, for more examples you can check out http://bootstrap-growl.remabledesigns.com/
  1259. *
  1260. * Codebase.helper('notify');
  1261. *
  1262. */
  1263. var uiHelperNotify = function(){
  1264. // Init notifications (with .js-notify class)
  1265. jQuery('.js-notify:not(.js-notify-enabled)').each(function(){
  1266. var el = jQuery(this);
  1267. // Add .js-notify-enabled class to tag it as activated
  1268. el.addClass('js-notify-enabled');
  1269. // Init on click
  1270. el.on('click.cb.helpers', function(){
  1271. var growl = jQuery(this);
  1272. // Create notification
  1273. jQuery.notify({
  1274. icon: growl.data('icon') || '',
  1275. message: growl.data('message'),
  1276. url: growl.data('url') || ''
  1277. },
  1278. {
  1279. element: 'body',
  1280. type: growl.data('type') || 'info',
  1281. allow_dismiss: true,
  1282. newest_on_top: true,
  1283. showProgressbar: false,
  1284. placement: {
  1285. from: growl.data('from') || 'top',
  1286. align: growl.data('align') || 'right'
  1287. },
  1288. offset: 20,
  1289. spacing: 10,
  1290. z_index: 1033,
  1291. delay: 5000,
  1292. timer: 1000,
  1293. template: '<div data-notify="container" class="col-11 col-sm-3 alert alert-{0}" role="alert">' +
  1294. '<button type="button" aria-hidden="true" class="close" data-notify="dismiss">×</button>' +
  1295. '<span data-notify="icon"></span> ' +
  1296. '<span data-notify="title">{1}</span> ' +
  1297. '<span data-notify="message">{2}</span>' +
  1298. '<div class="progress" data-notify="progressbar">' +
  1299. '<div class="progress-bar progress-bar-{0}" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"></div>' +
  1300. '</div>' +
  1301. '<a href="{3}" target="{4}" data-notify="url"></a>' +
  1302. '</div>',
  1303. animate: {
  1304. enter: 'animated fadeIn',
  1305. exit: 'animated fadeOutDown'
  1306. }
  1307. });
  1308. });
  1309. });
  1310. };
  1311. /*
  1312. * Draggable items with jQuery, for more examples you can check out https://jqueryui.com/sortable/
  1313. *
  1314. * Codebase.helper('draggable-items');
  1315. *
  1316. */
  1317. var uiHelperDraggableItems = function(){
  1318. // Init draggable items functionality (with .js-draggable-items class)
  1319. jQuery('.js-draggable-items:not(.js-draggable-items-enabled)').each(function(){
  1320. var el = jQuery(this);
  1321. // Add .js-draggable-items-enabled class to tag it as activated
  1322. el.addClass('js-draggable-items-enabled');
  1323. // Init
  1324. el.children('.draggable-column').sortable({
  1325. connectWith: '.draggable-column',
  1326. items: '.draggable-item',
  1327. dropOnEmpty: true,
  1328. opacity: .75,
  1329. handle: '.draggable-handler',
  1330. placeholder: 'draggable-placeholder',
  1331. tolerance: 'pointer',
  1332. start: function(e, ui){
  1333. ui.placeholder.css({
  1334. 'height': ui.item.outerHeight(),
  1335. 'margin-bottom': ui.item.css('margin-bottom')
  1336. });
  1337. }
  1338. });
  1339. });
  1340. };
  1341. /*
  1342. * Easy Pie Chart, for more examples you can check out http://rendro.github.io/easy-pie-chart/
  1343. *
  1344. * Codebase.helper('easy-pie-chart');
  1345. *
  1346. */
  1347. var uiHelperEasyPieChart = function(){
  1348. // Init Easy Pie Charts (with .js-pie-chart class)
  1349. jQuery('.js-pie-chart:not(.js-pie-chart-enabled)').each(function(){
  1350. var el = jQuery(this);
  1351. // Add .js-pie-chart-enabled class to tag it as activated
  1352. el.addClass('js-pie-chart-enabled');
  1353. // Init
  1354. el.easyPieChart({
  1355. barColor: el.data('bar-color') || '#777777',
  1356. trackColor: el.data('track-color') || '#eeeeee',
  1357. lineWidth: el.data('line-width') || 3,
  1358. size: el.data('size') || '80',
  1359. animate: el.data('animate') || 750,
  1360. scaleColor: el.data('scale-color') || false
  1361. });
  1362. });
  1363. };
  1364. /*
  1365. * Bootstrap Maxlength, for more examples you can check out https://github.com/mimo84/bootstrap-maxlength
  1366. *
  1367. * Codebase.helper('maxlength');
  1368. *
  1369. */
  1370. var uiHelperMaxlength = function(){
  1371. // Init Bootstrap Maxlength (with .js-maxlength class)
  1372. jQuery('.js-maxlength:not(.js-maxlength-enabled)').each(function(){
  1373. var el = jQuery(this);
  1374. // Add .js-maxlength-enabled class to tag it as activated
  1375. el.addClass('js-maxlength-enabled');
  1376. // Init
  1377. el.maxlength({
  1378. alwaysShow: el.data('always-show') ? true : false,
  1379. threshold: el.data('threshold') || 10,
  1380. warningClass: el.data('warning-class') || 'badge badge-warning',
  1381. limitReachedClass: el.data('limit-reached-class') || 'badge badge-danger',
  1382. placement: el.data('placement') || 'bottom',
  1383. preText: el.data('pre-text') || '',
  1384. separator: el.data('separator') || '/',
  1385. postText: el.data('post-text') || ''
  1386. });
  1387. });
  1388. };
  1389. /*
  1390. * Ion Range Slider, for more examples you can check out https://github.com/IonDen/ion.rangeSlider
  1391. *
  1392. * Codebase.helper('rangeslider');
  1393. *
  1394. */
  1395. var uiHelperRangeslider = function(){
  1396. // Init Ion Range Slider (with .js-rangeslider class)
  1397. jQuery('.js-rangeslider:not(.js-rangeslider-enabled)').each(function(){
  1398. var el = jQuery(this);
  1399. // Add .js-rangeslider-enabled class to tag it as activated
  1400. el.addClass('js-rangeslider-enabled');
  1401. // Init
  1402. el.ionRangeSlider({
  1403. input_values_separator: ';'
  1404. });
  1405. });
  1406. };
  1407. /*
  1408. * Summernote, for more examples you can check out https://github.com/summernote/summernote/
  1409. *
  1410. * Codebase.helper('summernote');
  1411. *
  1412. */
  1413. var uiHelperSummernote = function(){
  1414. // Init text editor in air mode (inline)
  1415. jQuery('.js-summernote-air:not(.js-summernote-air-enabled)').each(function(){
  1416. var el = jQuery(this);
  1417. // Add .js-summernote-air-enabled class to tag it as activated
  1418. el.addClass('js-summernote-air-enabled');
  1419. // Init
  1420. el.summernote({
  1421. airMode: true,
  1422. tooltip: false
  1423. });
  1424. });
  1425. // Init full text editor
  1426. jQuery('.js-summernote:not(.js-summernote-enabled)').each(function(){
  1427. var el = jQuery(this);
  1428. // Add .js-summernote-enabled class to tag it as activated
  1429. el.addClass('js-summernote-enabled');
  1430. // Init
  1431. el.summernote({
  1432. height: 350,
  1433. minHeight: null,
  1434. maxHeight: null
  1435. });
  1436. });
  1437. };
  1438. return {
  1439. init: function() {
  1440. // LAYOUT VARIABLES
  1441. uiInit();
  1442. // BASE UI
  1443. uiHandleScroll('init');
  1444. uiHandleMain();
  1445. uiHandleHeader();
  1446. uiHandleNav();
  1447. uiHandleForms();
  1448. uiHandleTheme();
  1449. // API
  1450. uiApiLayout('init');
  1451. uiApiBlocks(false, 'init');
  1452. // CORE HELPERS
  1453. uiHelperCoreToggleClass();
  1454. uiHelperCoreScrollTo();
  1455. uiHelperCoreYearCopy();
  1456. uiHelperCoreTooltip();
  1457. uiHelperCorePopover();
  1458. uiHelperCoreTab();
  1459. uiHelperCoreAppear();
  1460. uiHelperCoreAppearCountTo();
  1461. uiHelperCoreSlimscroll();
  1462. uiHelperCorePageLoader('hide');
  1463. uiHelperCoreRipple();
  1464. },
  1465. layout: function(mode) {
  1466. uiApiLayout(mode);
  1467. },
  1468. blocks: function(block, mode) {
  1469. uiApiBlocks(block, mode);
  1470. },
  1471. loader: function(mode, colorClass) {
  1472. uiHelperCorePageLoader(mode, colorClass);
  1473. },
  1474. helper: function(helper) {
  1475. switch (helper) {
  1476. case 'core-fn-uiInit':
  1477. uiInit();
  1478. break;
  1479. case 'core-fn-uiHandleScrollInit':
  1480. uiHandleScroll('init');
  1481. break;
  1482. case 'core-fn-uiHandleScroll':
  1483. uiHandleScroll();
  1484. break;
  1485. case 'core-fn-uiHandleMain':
  1486. uiHandleMain();
  1487. break;
  1488. case 'core-fn-uiHandleHeader':
  1489. uiHandleHeader();
  1490. break;
  1491. case 'core-fn-uiHandleNav':
  1492. uiHandleNav();
  1493. break;
  1494. case 'core-fn-uiHandleForms':
  1495. uiHandleForms();
  1496. break;
  1497. case 'core-fn-uiHandleTheme':
  1498. uiHandleTheme();
  1499. break;
  1500. case 'core-fn-uiApiLayout':
  1501. uiApiLayout('init');
  1502. break;
  1503. case 'core-fn-uiApiBlocks':
  1504. uiApiBlocks(false, 'init');
  1505. break;
  1506. case 'core-tooltip':
  1507. uiHelperCoreTooltip();
  1508. break;
  1509. case 'core-popover':
  1510. uiHelperCorePopover();
  1511. break;
  1512. case 'core-tab':
  1513. uiHelperCoreTab();
  1514. break;
  1515. case 'core-scrollTo':
  1516. uiHelperCoreScrollTo();
  1517. break;
  1518. case 'core-toggle-class':
  1519. uiHelperCoreToggleClass();
  1520. break;
  1521. case 'core-year-copy':
  1522. uiHelperCoreYearCopy();
  1523. break;
  1524. case 'core-appear':
  1525. uiHelperCoreAppear();
  1526. break;
  1527. case 'core-appear-countTo':
  1528. uiHelperCoreAppearCountTo();
  1529. break;
  1530. case 'core-slimscroll':
  1531. uiHelperCoreSlimscroll();
  1532. break;
  1533. case 'core-ripple':
  1534. uiHelperCoreRipple();
  1535. break;
  1536. case 'core-page-loader':
  1537. uiHelperCorePageLoader('hide');
  1538. break;
  1539. case 'print-page':
  1540. uiHelperPrint();
  1541. break;
  1542. case 'table-tools':
  1543. uiHelperTableToolsSections();
  1544. uiHelperTableToolsCheckable();
  1545. break;
  1546. case 'content-filter':
  1547. uiHelperContentFilter();
  1548. break;
  1549. case 'slimscroll':
  1550. uiHelperSlimscroll();
  1551. break;
  1552. case 'magnific-popup':
  1553. uiHelperMagnific();
  1554. break;
  1555. case 'ckeditor':
  1556. uiHelperCkeditor();
  1557. break;
  1558. case 'simplemde':
  1559. uiHelperSimpleMDE();
  1560. break;
  1561. case 'slick':
  1562. uiHelperSlick();
  1563. break;
  1564. case 'datepicker':
  1565. uiHelperDatepicker();
  1566. break;
  1567. case 'colorpicker':
  1568. uiHelperColorpicker();
  1569. break;
  1570. case 'tags-inputs':
  1571. uiHelperTagsInputs();
  1572. break;
  1573. case 'masked-inputs':
  1574. uiHelperMaskedInputs();
  1575. break;
  1576. case 'select2':
  1577. uiHelperSelect2();
  1578. break;
  1579. case 'highlightjs':
  1580. uiHelperHighlightjs();
  1581. break;
  1582. case 'notify':
  1583. uiHelperNotify();
  1584. break;
  1585. case 'draggable-items':
  1586. uiHelperDraggableItems();
  1587. break;
  1588. case 'easy-pie-chart':
  1589. uiHelperEasyPieChart();
  1590. break;
  1591. case 'maxlength':
  1592. uiHelperMaxlength();
  1593. break;
  1594. case 'rangeslider':
  1595. uiHelperRangeslider();
  1596. break;
  1597. case 'summernote':
  1598. uiHelperSummernote();
  1599. break;
  1600. default:
  1601. return false;
  1602. }
  1603. },
  1604. helpers: function(helpers) {
  1605. if (helpers instanceof Array) {
  1606. for (var index in helpers) {
  1607. Codebase.helper(helpers[index]);
  1608. }
  1609. } else {
  1610. Codebase.helper(helpers);
  1611. }
  1612. }
  1613. };
  1614. }();
  1615. // Initialize when page loads
  1616. jQuery(function(){
  1617. if (typeof angular === 'undefined') {
  1618. Codebase.init();
  1619. }
  1620. });