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.

app.min.js 59KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041
  1. /* ______________________________________
  2. ________| |_______
  3. \ | SmartAdmin WebApp | /
  4. \ | Copyright © 2015 MyOrange | /
  5. / |______________________________________| \
  6. /__________) (_________\
  7. * The above copyright notice and this permission notice shall be
  8. * included in all copies or substantial portions of the Software.
  9. * =======================================================================
  10. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  11. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  12. * MERCHANTABILITY, IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  13. * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  14. * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  15. * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. * =======================================================================
  17. * original filename : app.js
  18. * filesize : 62,499~ bytes
  19. * author : Sunny (@bootstraphunt)
  20. * email : info@myorange.ca
  21. * legal notice : This script is part of a theme sold by
  22. * bootstraphunter.com
  23. *
  24. * =======================================================================
  25. * INDEX (Note: line numbers for index items may not be up to date):
  26. *
  27. * 1. APP CONFIGURATION..................................[ app.config.js ]
  28. * 2. APP DOM REFERENCES.................................[ app.config.js ]
  29. * 3. DETECT MOBILE DEVICES...................................[line: 149 ]
  30. * 4. CUSTOM MENU PLUGIN......................................[line: 688 ]
  31. * 5. ELEMENT EXIST OR NOT....................................[line: 778 ]
  32. * 6. INITIALIZE FORMS........................................[line: 788 ]
  33. * 6a. BOOTSTRAP SLIDER PLUGIN...........................[line: 794 ]
  34. * 6b. SELECT2 PLUGIN....................................[line: 803 ]
  35. * 6c. MASKING...........................................[line: 824 ]
  36. * 6d. AUTOCOMPLETE......................................[line: 843 ]
  37. * 6f. JQUERY UI DATE....................................[line: 862 ]
  38. * 6g. AJAX BUTTON LOADING TEXT..........................[line: 884 ]
  39. * 7. INITIALIZE CHARTS.......................................[line: 902 ]
  40. * 7a. SPARKLINES........................................[line: 907 ]
  41. * 7b. LINE CHART........................................[line: 1026]
  42. * 7c. PIE CHART.........................................[line: 1077]
  43. * 7d. BOX PLOT..........................................[line: 1100]
  44. * 7e. BULLET............................................[line: 1145]
  45. * 7f. DISCRETE..........................................[line: 1169]
  46. * 7g. TRISTATE..........................................[line: 1195]
  47. * 7h. COMPOSITE: BAR....................................[line: 1223]
  48. * 7i. COMPOSITE: LINE...................................[line: 1259]
  49. * 7j. EASY PIE CHARTS...................................[line: 1339]
  50. * 8. INITIALIZE JARVIS WIDGETS...............................[line: 1379]
  51. * 8a. SETUP DESKTOP WIDGET..............................[line: 1466]
  52. * 8b. GOOGLE MAPS.......................................[line: 1478]
  53. * 8c. LOAD SCRIPTS......................................[line: 1500]
  54. * 8d. APP AJAX REQUEST SETUP............................[line: 1538]
  55. * 9. CHECK TO SEE IF URL EXISTS..............................[line: 1614]
  56. * 10.LOAD AJAX PAGES.........................................[line: 1669]
  57. * 11.UPDATE BREADCRUMB.......................................[line: 1775]
  58. * 12.PAGE SETUP..............................................[line: 1798]
  59. * 13.POP OVER THEORY.........................................[line: 1852]
  60. * 14.DELETE MODEL DATA ON HIDDEN.............................[line: 1991]
  61. * 15.HELPFUL FUNCTIONS.......................................[line: 2027]
  62. *
  63. * =======================================================================
  64. * IMPORTANT: ALL CONFIG VARS IS NOW MOVED TO APP.CONFIG.JS
  65. * =======================================================================
  66. *
  67. *
  68. * GLOBAL: interval array (to be used with jarviswidget in ajax and
  69. * angular mode) to clear auto fetch interval
  70. */
  71. $.intervalArr = [];
  72. /*
  73. * Calculate nav height
  74. */
  75. var calc_navbar_height = function() {
  76. var height = null;
  77. if ($('#header').length)
  78. height = $('#header').height();
  79. if (height === null)
  80. height = $('<div id="header"></div>').height();
  81. if (height === null)
  82. return 49;
  83. // default
  84. return height;
  85. },
  86. navbar_height = calc_navbar_height,
  87. /*
  88. * APP DOM REFERENCES
  89. * Description: Obj DOM reference, please try to avoid changing these
  90. */
  91. shortcut_dropdown = $('#shortcut'),
  92. bread_crumb = $('#ribbon ol.breadcrumb'),
  93. /*
  94. * Top menu on/off
  95. */
  96. topmenu = false,
  97. /*
  98. * desktop or mobile
  99. */
  100. thisDevice = null,
  101. /*
  102. * DETECT MOBILE DEVICES
  103. * Description: Detects mobile device - if any of the listed device is
  104. * detected a class is inserted to $.root_ and the variable thisDevice
  105. * is decleard. (so far this is covering most hand held devices)
  106. */
  107. ismobile = (/iphone|ipad|ipod|android|blackberry|mini|windows\sce|palm/i.test(navigator.userAgent.toLowerCase())),
  108. /*
  109. * JS ARRAY SCRIPT STORAGE
  110. * Description: used with loadScript to store script path and file name
  111. * so it will not load twice
  112. */
  113. jsArray = {},
  114. /*
  115. * App Initialize
  116. * Description: Initializes the app with intApp();
  117. */
  118. initApp = (function(app) {
  119. /*
  120. * ADD DEVICE TYPE
  121. * Detect if mobile or desktop
  122. */
  123. app.addDeviceType = function() {
  124. if (!ismobile) {
  125. // Desktop
  126. $.root_.addClass("desktop-detected");
  127. thisDevice = "desktop";
  128. return false;
  129. } else {
  130. // Mobile
  131. $.root_.addClass("mobile-detected");
  132. thisDevice = "mobile";
  133. if (fastClick) {
  134. // Removes the tap delay in idevices
  135. // dependency: js/plugin/fastclick/fastclick.js
  136. $.root_.addClass("needsclick");
  137. FastClick.attach(document.body);
  138. return false;
  139. }
  140. }
  141. };
  142. /* ~ END: ADD DEVICE TYPE */
  143. /*
  144. * CHECK FOR MENU POSITION
  145. * Scans localstroage for menu position (vertical or horizontal)
  146. */
  147. app.menuPos = function() {
  148. if ($.root_.hasClass("menu-on-top") || localStorage.getItem('sm-setmenu')=='top' ) {
  149. topmenu = true;
  150. $.root_.addClass("menu-on-top");
  151. }
  152. };
  153. /* ~ END: CHECK MOBILE DEVICE */
  154. /*
  155. * SMART ACTIONS
  156. */
  157. app.SmartActions = function(){
  158. var smartActions = {
  159. // LOGOUT MSG
  160. userLogout: function($this){
  161. // ask verification
  162. $.SmartMessageBox({
  163. title : "<i class='fa fa-sign-out txt-color-orangeDark'></i> Logout <span class='txt-color-orangeDark'><strong>" + $('#show-shortcut').text() + "</strong></span> ?",
  164. content : $this.data('logout-msg') || "You can improve your security further after logging out by closing this opened browser",
  165. buttons : '[No][Yes]'
  166. }, function(ButtonPressed) {
  167. if (ButtonPressed == "Yes") {
  168. $.root_.addClass('animated fadeOutUp');
  169. setTimeout(logout, 1000);
  170. }
  171. });
  172. function logout() {
  173. window.location = $this.attr('href');
  174. }
  175. },
  176. // RESET WIDGETS
  177. resetWidgets: function($this){
  178. $.SmartMessageBox({
  179. title : "<i class='fa fa-refresh' style='color:green'></i> Clear Local Storage",
  180. content : $this.data('reset-msg') || "Would you like to RESET all your saved widgets and clear LocalStorage?1",
  181. buttons : '[No][Yes]'
  182. }, function(ButtonPressed) {
  183. if (ButtonPressed == "Yes" && localStorage) {
  184. localStorage.clear();
  185. location.reload();
  186. }
  187. });
  188. },
  189. // LAUNCH FULLSCREEN
  190. launchFullscreen: function(element){
  191. if (!$.root_.hasClass("full-screen")) {
  192. $.root_.addClass("full-screen");
  193. if (element.requestFullscreen) {
  194. element.requestFullscreen();
  195. } else if (element.mozRequestFullScreen) {
  196. element.mozRequestFullScreen();
  197. } else if (element.webkitRequestFullscreen) {
  198. element.webkitRequestFullscreen();
  199. } else if (element.msRequestFullscreen) {
  200. element.msRequestFullscreen();
  201. }
  202. } else {
  203. $.root_.removeClass("full-screen");
  204. if (document.exitFullscreen) {
  205. document.exitFullscreen();
  206. } else if (document.mozCancelFullScreen) {
  207. document.mozCancelFullScreen();
  208. } else if (document.webkitExitFullscreen) {
  209. document.webkitExitFullscreen();
  210. }
  211. }
  212. },
  213. // MINIFY MENU
  214. minifyMenu: function($this){
  215. if (!$.root_.hasClass("menu-on-top")){
  216. $.root_.toggleClass("minified");
  217. $.root_.removeClass("hidden-menu");
  218. $('html').removeClass("hidden-menu-mobile-lock");
  219. $this.effect("highlight", {}, 500);
  220. }
  221. },
  222. // TOGGLE MENU
  223. toggleMenu: function(){
  224. if (!$.root_.hasClass("menu-on-top")){
  225. $('html').toggleClass("hidden-menu-mobile-lock");
  226. $.root_.toggleClass("hidden-menu");
  227. $.root_.removeClass("minified");
  228. //} else if ( $.root_.hasClass("menu-on-top") && $.root_.hasClass("mobile-view-activated") ) {
  229. // suggested fix from Christian Jäger
  230. } else if ( $.root_.hasClass("menu-on-top") && $(window).width() < 979 ) {
  231. $('html').toggleClass("hidden-menu-mobile-lock");
  232. $.root_.toggleClass("hidden-menu");
  233. $.root_.removeClass("minified");
  234. }
  235. },
  236. // TOGGLE SHORTCUT
  237. toggleShortcut: function(){
  238. if (shortcut_dropdown.is(":visible")) {
  239. shortcut_buttons_hide();
  240. } else {
  241. shortcut_buttons_show();
  242. }
  243. // SHORT CUT (buttons that appear when clicked on user name)
  244. shortcut_dropdown.find('a').click(function(e) {
  245. e.preventDefault();
  246. window.location = $(this).attr('href');
  247. setTimeout(shortcut_buttons_hide, 300);
  248. });
  249. // SHORTCUT buttons goes away if mouse is clicked outside of the area
  250. $(document).mouseup(function(e) {
  251. if (!shortcut_dropdown.is(e.target) && shortcut_dropdown.has(e.target).length === 0) {
  252. shortcut_buttons_hide();
  253. }
  254. });
  255. // SHORTCUT ANIMATE HIDE
  256. function shortcut_buttons_hide() {
  257. shortcut_dropdown.animate({
  258. height : "hide"
  259. }, 300, "easeOutCirc");
  260. $.root_.removeClass('shortcut-on');
  261. }
  262. // SHORTCUT ANIMATE SHOW
  263. function shortcut_buttons_show() {
  264. shortcut_dropdown.animate({
  265. height : "show"
  266. }, 200, "easeOutCirc");
  267. $.root_.addClass('shortcut-on');
  268. }
  269. }
  270. };
  271. $.root_.on('click', '[data-action="userLogout"]', function(e) {
  272. var $this = $(this);
  273. smartActions.userLogout($this);
  274. e.preventDefault();
  275. //clear memory reference
  276. $this = null;
  277. });
  278. /*
  279. * BUTTON ACTIONS
  280. */
  281. $.root_.on('click', '[data-action="resetWidgets"]', function(e) {
  282. var $this = $(this);
  283. smartActions.resetWidgets($this);
  284. e.preventDefault();
  285. //clear memory reference
  286. $this = null;
  287. });
  288. $.root_.on('click', '[data-action="launchFullscreen"]', function(e) {
  289. smartActions.launchFullscreen(document.documentElement);
  290. e.preventDefault();
  291. });
  292. $.root_.on('click', '[data-action="minifyMenu"]', function(e) {
  293. var $this = $(this);
  294. smartActions.minifyMenu($this);
  295. e.preventDefault();
  296. //clear memory reference
  297. $this = null;
  298. });
  299. $.root_.on('click', '[data-action="toggleMenu"]', function(e) {
  300. smartActions.toggleMenu();
  301. e.preventDefault();
  302. });
  303. $.root_.on('click', '[data-action="toggleShortcut"]', function(e) {
  304. smartActions.toggleShortcut();
  305. e.preventDefault();
  306. });
  307. };
  308. /* ~ END: SMART ACTIONS */
  309. /*
  310. * ACTIVATE NAVIGATION
  311. * Description: Activation will fail if top navigation is on
  312. */
  313. app.leftNav = function(){
  314. // INITIALIZE LEFT NAV
  315. if (!topmenu) {
  316. if (!null) {
  317. $('nav ul').jarvismenu({
  318. accordion : menu_accordion || true,
  319. speed : menu_speed || true,
  320. closedSign : '<em class="fa fa-plus-square-o"></em>',
  321. openedSign : '<em class="fa fa-minus-square-o"></em>'
  322. });
  323. } else {
  324. alert("Error - menu anchor does not exist");
  325. }
  326. }
  327. };
  328. /* ~ END: ACTIVATE NAVIGATION */
  329. /*
  330. * MISCELANEOUS DOM READY FUNCTIONS
  331. * Description: fire with jQuery(document).ready...
  332. */
  333. app.domReadyMisc = function() {
  334. /*
  335. * FIRE TOOLTIPS
  336. if ($("[rel=tooltip]").length) {
  337. $("[rel=tooltip]").tooltip();
  338. }*/
  339. // SHOW & HIDE MOBILE SEARCH FIELD
  340. $('#search-mobile').click(function() {
  341. $.root_.addClass('search-mobile');
  342. });
  343. $('#cancel-search-js').click(function() {
  344. $.root_.removeClass('search-mobile');
  345. });
  346. // ACTIVITY
  347. // ajax drop
  348. $('#activity').click(function(e) {
  349. var $this = $(this);
  350. if ($this.find('.badge').hasClass('bg-color-red')) {
  351. $this.find('.badge').removeClassPrefix('bg-color-');
  352. $this.find('.badge').text("0");
  353. }
  354. if (!$this.next('.ajax-dropdown').is(':visible')) {
  355. $this.next('.ajax-dropdown').fadeIn(150);
  356. $this.addClass('active');
  357. } else {
  358. $this.next('.ajax-dropdown').fadeOut(150);
  359. $this.removeClass('active');
  360. }
  361. var theUrlVal = $this.next('.ajax-dropdown').find('.btn-group > .active > input').attr('id');
  362. //clear memory reference
  363. $this = null;
  364. theUrlVal = null;
  365. e.preventDefault();
  366. });
  367. $('input[name="activity"]').change(function() {
  368. var $this = $(this);
  369. url = $this.attr('id');
  370. container = $('.ajax-notifications');
  371. loadURL(url, container);
  372. //clear memory reference
  373. $this = null;
  374. });
  375. // close dropdown if mouse is not inside the area of .ajax-dropdown
  376. $(document).mouseup(function(e) {
  377. if (!$('.ajax-dropdown').is(e.target) && $('.ajax-dropdown').has(e.target).length === 0) {
  378. $('.ajax-dropdown').fadeOut(150);
  379. $('.ajax-dropdown').prev().removeClass("active");
  380. }
  381. });
  382. // loading animation (demo purpose only)
  383. $('button[data-btn-loading]').on('click', function() {
  384. var btn = $(this);
  385. btn.button('loading');
  386. setTimeout(function() {
  387. btn.button('reset');
  388. }, 3000);
  389. });
  390. // NOTIFICATION IS PRESENT
  391. // Change color of lable once notification button is clicked
  392. $this = $('#activity > .badge');
  393. if (parseInt($this.text()) > 0) {
  394. $this.addClass("bg-color-red bounceIn animated");
  395. //clear memory reference
  396. $this = null;
  397. }
  398. };
  399. /* ~ END: MISCELANEOUS DOM */
  400. /*
  401. * MISCELANEOUS DOM READY FUNCTIONS
  402. * Description: fire with jQuery(document).ready...
  403. */
  404. app.mobileCheckActivation = function(){
  405. if ($(window).width() < 979) {
  406. $.root_.addClass('mobile-view-activated');
  407. $.root_.removeClass('minified');
  408. } else if ($.root_.hasClass('mobile-view-activated')) {
  409. $.root_.removeClass('mobile-view-activated');
  410. }
  411. if (debugState){
  412. console.log("mobileCheckActivation");
  413. }
  414. }
  415. /* ~ END: MISCELANEOUS DOM */
  416. return app;
  417. })({});
  418. initApp.addDeviceType();
  419. initApp.menuPos();
  420. /*
  421. * DOCUMENT LOADED EVENT
  422. * Description: Fire when DOM is ready
  423. */
  424. jQuery(document).ready(function() {
  425. initApp.SmartActions();
  426. initApp.leftNav();
  427. initApp.domReadyMisc();
  428. });
  429. /*
  430. * RESIZER WITH THROTTLE
  431. * Source: http://benalman.com/code/projects/jquery-resize/examples/resize/
  432. */
  433. (function ($, window, undefined) {
  434. var elems = $([]),
  435. jq_resize = $.resize = $.extend($.resize, {}),
  436. timeout_id, str_setTimeout = 'setTimeout',
  437. str_resize = 'resize',
  438. str_data = str_resize + '-special-event',
  439. str_delay = 'delay',
  440. str_throttle = 'throttleWindow';
  441. jq_resize[str_delay] = throttle_delay;
  442. jq_resize[str_throttle] = true;
  443. $.event.special[str_resize] = {
  444. setup: function () {
  445. if (!jq_resize[str_throttle] && this[str_setTimeout]) {
  446. return false;
  447. }
  448. var elem = $(this);
  449. elems = elems.add(elem);
  450. try {
  451. $.data(this, str_data, {
  452. w: elem.width(),
  453. h: elem.height()
  454. });
  455. } catch (e) {
  456. $.data(this, str_data, {
  457. w: elem.width, // elem.width();
  458. h: elem.height // elem.height();
  459. });
  460. }
  461. if (elems.length === 1) {
  462. loopy();
  463. }
  464. },
  465. teardown: function () {
  466. if (!jq_resize[str_throttle] && this[str_setTimeout]) {
  467. return false;
  468. }
  469. var elem = $(this);
  470. elems = elems.not(elem);
  471. elem.removeData(str_data);
  472. if (!elems.length) {
  473. clearTimeout(timeout_id);
  474. }
  475. },
  476. add: function (handleObj) {
  477. if (!jq_resize[str_throttle] && this[str_setTimeout]) {
  478. return false;
  479. }
  480. var old_handler;
  481. function new_handler(e, w, h) {
  482. var elem = $(this),
  483. data = $.data(this, str_data);
  484. data.w = w !== undefined ? w : elem.width();
  485. data.h = h !== undefined ? h : elem.height();
  486. old_handler.apply(this, arguments);
  487. }
  488. if ($.isFunction(handleObj)) {
  489. old_handler = handleObj;
  490. return new_handler;
  491. } else {
  492. old_handler = handleObj.handler;
  493. handleObj.handler = new_handler;
  494. }
  495. }
  496. };
  497. function loopy() {
  498. timeout_id = window[str_setTimeout](function () {
  499. elems.each(function () {
  500. var width;
  501. var height;
  502. var elem = $(this),
  503. data = $.data(this, str_data); //width = elem.width(), height = elem.height();
  504. // Highcharts fix
  505. try {
  506. width = elem.width();
  507. } catch (e) {
  508. width = elem.width;
  509. }
  510. try {
  511. height = elem.height();
  512. } catch (e) {
  513. height = elem.height;
  514. }
  515. //fixed bug
  516. if (width !== data.w || height !== data.h) {
  517. elem.trigger(str_resize, [data.w = width, data.h = height]);
  518. }
  519. });
  520. loopy();
  521. }, jq_resize[str_delay]);
  522. }
  523. })(jQuery, this);
  524. /*
  525. * ADD CLASS WHEN BELOW CERTAIN WIDTH (MOBILE MENU)
  526. * Description: tracks the page min-width of #CONTENT and NAV when navigation is resized.
  527. * This is to counter bugs for minimum page width on many desktop and mobile devices.
  528. * Note: This script utilizes JSthrottle script so don't worry about memory/CPU usage
  529. */
  530. $('#main').resize(function() {
  531. initApp.mobileCheckActivation();
  532. });
  533. /* ~ END: NAV OR #LEFT-BAR RESIZE DETECT */
  534. /*
  535. * DETECT IE VERSION
  536. * Description: A short snippet for detecting versions of IE in JavaScript
  537. * without resorting to user-agent sniffing
  538. * RETURNS:
  539. * If you're not in IE (or IE version is less than 5) then:
  540. * //ie === undefined
  541. *
  542. * If you're in IE (>=5) then you can determine which version:
  543. * // ie === 7; // IE7
  544. *
  545. * Thus, to detect IE:
  546. * // if (ie) {}
  547. *
  548. * And to detect the version:
  549. * ie === 6 // IE6
  550. * ie > 7 // IE8, IE9 ...
  551. * ie < 9 // Anything less than IE9
  552. */
  553. // TODO: delete this function later on - no longer needed (?)
  554. var ie = ( function() {
  555. var undef, v = 3, div = document.createElement('div'), all = div.getElementsByTagName('i');
  556. while (div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->', all[0]);
  557. return v > 4 ? v : undef;
  558. }());
  559. /* ~ END: DETECT IE VERSION */
  560. /*
  561. * CUSTOM MENU PLUGIN
  562. */
  563. $.fn.extend({
  564. //pass the options variable to the function
  565. jarvismenu : function(options) {
  566. var defaults = {
  567. accordion : 'true',
  568. speed : 200,
  569. closedSign : '[+]',
  570. openedSign : '[-]'
  571. },
  572. // Extend our default options with those provided.
  573. opts = $.extend(defaults, options),
  574. //Assign current element to variable, in this case is UL element
  575. $this = $(this);
  576. //add a mark [+] to a multilevel menu
  577. $this.find("li").each(function() {
  578. if ($(this).find("ul").length !== 0) {
  579. //add the multilevel sign next to the link
  580. $(this).find("a:first").append("<b class='collapse-sign'>" + opts.closedSign + "</b>");
  581. //avoid jumping to the top of the page when the href is an #
  582. if ($(this).find("a:first").attr('href') == "#") {
  583. $(this).find("a:first").click(function() {
  584. return false;
  585. });
  586. }
  587. }
  588. });
  589. //open active level
  590. $this.find("li.active").each(function() {
  591. $(this).parents("ul").slideDown(opts.speed);
  592. $(this).parents("ul").parent("li").find("b:first").html(opts.openedSign);
  593. $(this).parents("ul").parent("li").addClass("open");
  594. });
  595. $this.find("li a").click(function() {
  596. if ($(this).parent().find("ul").length !== 0) {
  597. if (opts.accordion) {
  598. //Do nothing when the list is open
  599. if (!$(this).parent().find("ul").is(':visible')) {
  600. parents = $(this).parent().parents("ul");
  601. visible = $this.find("ul:visible");
  602. visible.each(function(visibleIndex) {
  603. var close = true;
  604. parents.each(function(parentIndex) {
  605. if (parents[parentIndex] == visible[visibleIndex]) {
  606. close = false;
  607. return false;
  608. }
  609. });
  610. if (close) {
  611. if ($(this).parent().find("ul") != visible[visibleIndex]) {
  612. $(visible[visibleIndex]).slideUp(opts.speed, function() {
  613. $(this).parent("li").find("b:first").html(opts.closedSign);
  614. $(this).parent("li").removeClass("open");
  615. });
  616. }
  617. }
  618. });
  619. }
  620. }// end if
  621. if ($(this).parent().find("ul:first").is(":visible") && !$(this).parent().find("ul:first").hasClass("active")) {
  622. $(this).parent().find("ul:first").slideUp(opts.speed, function() {
  623. $(this).parent("li").removeClass("open");
  624. $(this).parent("li").find("b:first").delay(opts.speed).html(opts.closedSign);
  625. });
  626. } else {
  627. $(this).parent().find("ul:first").slideDown(opts.speed, function() {
  628. /*$(this).effect("highlight", {color : '#616161'}, 500); - disabled due to CPU clocking on phones*/
  629. $(this).parent("li").addClass("open");
  630. $(this).parent("li").find("b:first").delay(opts.speed).html(opts.openedSign);
  631. });
  632. } // end else
  633. } // end if
  634. });
  635. } // end function
  636. });
  637. /* ~ END: CUSTOM MENU PLUGIN */
  638. /*
  639. * ELEMENT EXIST OR NOT
  640. * Description: returns true or false
  641. * Usage: $('#myDiv').doesExist();
  642. */
  643. jQuery.fn.doesExist = function() {
  644. return jQuery(this).length > 0;
  645. };
  646. /* ~ END: ELEMENT EXIST OR NOT */
  647. /*
  648. * INITIALIZE FORMS
  649. * Description: Select2, Masking, Datepicker, Autocomplete
  650. */
  651. function runAllForms() {
  652. /*
  653. * BOOTSTRAP SLIDER PLUGIN
  654. * Usage:
  655. * Dependency: js/plugin/bootstrap-slider
  656. */
  657. if ($.fn.slider) {
  658. $('.slider').slider();
  659. }
  660. /*
  661. * SELECT2 PLUGIN
  662. * Usage:
  663. * Dependency: js/plugin/select2/
  664. */
  665. if ($.fn.select2) {
  666. $('select.select2').each(function() {
  667. var $this = $(this),
  668. width = $this.attr('data-select-width') || '100%';
  669. //, _showSearchInput = $this.attr('data-select-search') === 'true';
  670. $this.select2({
  671. //showSearchInput : _showSearchInput,
  672. allowClear : true,
  673. width : width
  674. });
  675. //clear memory reference
  676. $this = null;
  677. });
  678. }
  679. /*
  680. * MASKING
  681. * Dependency: js/plugin/masked-input/
  682. */
  683. if ($.fn.mask) {
  684. $('[data-mask]').each(function() {
  685. var $this = $(this),
  686. mask = $this.attr('data-mask') || 'error...', mask_placeholder = $this.attr('data-mask-placeholder') || 'X';
  687. $this.mask(mask, {
  688. placeholder : mask_placeholder
  689. });
  690. //clear memory reference
  691. $this = null;
  692. });
  693. }
  694. /*
  695. * AUTOCOMPLETE
  696. * Dependency: js/jqui
  697. */
  698. if ($.fn.autocomplete) {
  699. $('[data-autocomplete]').each(function() {
  700. var $this = $(this),
  701. availableTags = $this.data('autocomplete') || ["The", "Quick", "Brown", "Fox", "Jumps", "Over", "Three", "Lazy", "Dogs"];
  702. $this.autocomplete({
  703. source : availableTags
  704. });
  705. //clear memory reference
  706. $this = null;
  707. });
  708. }
  709. /*
  710. * JQUERY UI DATE
  711. * Dependency: js/libs/jquery-ui-1.10.3.min.js
  712. * Usage: <input class="datepicker" />
  713. */
  714. if ($.fn.datepicker) {
  715. $('.datepicker').each(function() {
  716. var $this = $(this),
  717. dataDateFormat = $this.attr('data-dateformat') || 'dd.mm.yy';
  718. $this.datepicker({
  719. dateFormat : dataDateFormat,
  720. prevText : '<i class="fa fa-chevron-left"></i>',
  721. nextText : '<i class="fa fa-chevron-right"></i>',
  722. });
  723. //clear memory reference
  724. $this = null;
  725. });
  726. }
  727. /*
  728. * AJAX BUTTON LOADING TEXT
  729. * Usage: <button type="button" data-loading-text="Loading..." class="btn btn-xs btn-default ajax-refresh"> .. </button>
  730. */
  731. $('button[data-loading-text]').on('click', function() {
  732. var btn = $(this);
  733. btn.button('loading');
  734. setTimeout(function() {
  735. btn.button('reset');
  736. //clear memory reference
  737. btn = null;
  738. }, 3000);
  739. });
  740. }
  741. /* ~ END: INITIALIZE FORMS */
  742. /*
  743. * INITIALIZE CHARTS
  744. * Description: Sparklines, PieCharts
  745. */
  746. function runAllCharts() {
  747. /*
  748. * SPARKLINES
  749. * DEPENDENCY: js/plugins/sparkline/jquery.sparkline.min.js
  750. * See usage example below...
  751. */
  752. /* Usage:
  753. * <div class="sparkline-line txt-color-blue" data-fill-color="transparent" data-sparkline-height="26px">
  754. * 5,6,7,9,9,5,9,6,5,6,6,7,7,6,7,8,9,7
  755. * </div>
  756. */
  757. if ($.fn.sparkline) {
  758. // variable declearations:
  759. var barColor,
  760. sparklineHeight,
  761. sparklineBarWidth,
  762. sparklineBarSpacing,
  763. sparklineNegBarColor,
  764. sparklineStackedColor,
  765. thisLineColor,
  766. thisLineWidth,
  767. thisFill,
  768. thisSpotColor,
  769. thisMinSpotColor,
  770. thisMaxSpotColor,
  771. thishighlightSpotColor,
  772. thisHighlightLineColor,
  773. thisSpotRadius,
  774. pieColors,
  775. pieWidthHeight,
  776. pieBorderColor,
  777. pieOffset,
  778. thisBoxWidth,
  779. thisBoxHeight,
  780. thisBoxRaw,
  781. thisBoxTarget,
  782. thisBoxMin,
  783. thisBoxMax,
  784. thisShowOutlier,
  785. thisIQR,
  786. thisBoxSpotRadius,
  787. thisBoxLineColor,
  788. thisBoxFillColor,
  789. thisBoxWhisColor,
  790. thisBoxOutlineColor,
  791. thisBoxOutlineFill,
  792. thisBoxMedianColor,
  793. thisBoxTargetColor,
  794. thisBulletHeight,
  795. thisBulletWidth,
  796. thisBulletColor,
  797. thisBulletPerformanceColor,
  798. thisBulletRangeColors,
  799. thisDiscreteHeight,
  800. thisDiscreteWidth,
  801. thisDiscreteLineColor,
  802. thisDiscreteLineHeight,
  803. thisDiscreteThrushold,
  804. thisDiscreteThrusholdColor,
  805. thisTristateHeight,
  806. thisTristatePosBarColor,
  807. thisTristateNegBarColor,
  808. thisTristateZeroBarColor,
  809. thisTristateBarWidth,
  810. thisTristateBarSpacing,
  811. thisZeroAxis,
  812. thisBarColor,
  813. sparklineWidth,
  814. sparklineValue,
  815. sparklineValueSpots1,
  816. sparklineValueSpots2,
  817. thisLineWidth1,
  818. thisLineWidth2,
  819. thisLineColor1,
  820. thisLineColor2,
  821. thisSpotRadius1,
  822. thisSpotRadius2,
  823. thisMinSpotColor1,
  824. thisMaxSpotColor1,
  825. thisMinSpotColor2,
  826. thisMaxSpotColor2,
  827. thishighlightSpotColor1,
  828. thisHighlightLineColor1,
  829. thishighlightSpotColor2,
  830. thisFillColor1,
  831. thisFillColor2;
  832. $('.sparkline:not(:has(>canvas))').each(function() {
  833. var $this = $(this),
  834. sparklineType = $this.data('sparkline-type') || 'bar';
  835. // BAR CHART
  836. if (sparklineType == 'bar') {
  837. barColor = $this.data('sparkline-bar-color') || $this.css('color') || '#0000f0';
  838. sparklineHeight = $this.data('sparkline-height') || '26px';
  839. sparklineBarWidth = $this.data('sparkline-barwidth') || 5;
  840. sparklineBarSpacing = $this.data('sparkline-barspacing') || 2;
  841. sparklineNegBarColor = $this.data('sparkline-negbar-color') || '#A90329';
  842. sparklineStackedColor = $this.data('sparkline-barstacked-color') || ["#A90329", "#0099c6", "#98AA56", "#da532c", "#4490B1", "#6E9461", "#990099", "#B4CAD3"];
  843. $this.sparkline('html', {
  844. barColor : barColor,
  845. type : sparklineType,
  846. height : sparklineHeight,
  847. barWidth : sparklineBarWidth,
  848. barSpacing : sparklineBarSpacing,
  849. stackedBarColor : sparklineStackedColor,
  850. negBarColor : sparklineNegBarColor,
  851. zeroAxis : 'false'
  852. });
  853. $this = null;
  854. }
  855. // LINE CHART
  856. if (sparklineType == 'line') {
  857. sparklineHeight = $this.data('sparkline-height') || '20px';
  858. sparklineWidth = $this.data('sparkline-width') || '90px';
  859. thisLineColor = $this.data('sparkline-line-color') || $this.css('color') || '#0000f0';
  860. thisLineWidth = $this.data('sparkline-line-width') || 1;
  861. thisFill = $this.data('fill-color') || '#c0d0f0';
  862. thisSpotColor = $this.data('sparkline-spot-color') || '#f08000';
  863. thisMinSpotColor = $this.data('sparkline-minspot-color') || '#ed1c24';
  864. thisMaxSpotColor = $this.data('sparkline-maxspot-color') || '#f08000';
  865. thishighlightSpotColor = $this.data('sparkline-highlightspot-color') || '#50f050';
  866. thisHighlightLineColor = $this.data('sparkline-highlightline-color') || 'f02020';
  867. thisSpotRadius = $this.data('sparkline-spotradius') || 1.5;
  868. thisChartMinYRange = $this.data('sparkline-min-y') || 'undefined';
  869. thisChartMaxYRange = $this.data('sparkline-max-y') || 'undefined';
  870. thisChartMinXRange = $this.data('sparkline-min-x') || 'undefined';
  871. thisChartMaxXRange = $this.data('sparkline-max-x') || 'undefined';
  872. thisMinNormValue = $this.data('min-val') || 'undefined';
  873. thisMaxNormValue = $this.data('max-val') || 'undefined';
  874. thisNormColor = $this.data('norm-color') || '#c0c0c0';
  875. thisDrawNormalOnTop = $this.data('draw-normal') || false;
  876. $this.sparkline('html', {
  877. type : 'line',
  878. width : sparklineWidth,
  879. height : sparklineHeight,
  880. lineWidth : thisLineWidth,
  881. lineColor : thisLineColor,
  882. fillColor : thisFill,
  883. spotColor : thisSpotColor,
  884. minSpotColor : thisMinSpotColor,
  885. maxSpotColor : thisMaxSpotColor,
  886. highlightSpotColor : thishighlightSpotColor,
  887. highlightLineColor : thisHighlightLineColor,
  888. spotRadius : thisSpotRadius,
  889. chartRangeMin : thisChartMinYRange,
  890. chartRangeMax : thisChartMaxYRange,
  891. chartRangeMinX : thisChartMinXRange,
  892. chartRangeMaxX : thisChartMaxXRange,
  893. normalRangeMin : thisMinNormValue,
  894. normalRangeMax : thisMaxNormValue,
  895. normalRangeColor : thisNormColor,
  896. drawNormalOnTop : thisDrawNormalOnTop
  897. });
  898. $this = null;
  899. }
  900. // PIE CHART
  901. if (sparklineType == 'pie') {
  902. pieColors = $this.data('sparkline-piecolor') || ["#B4CAD3", "#4490B1", "#98AA56", "#da532c","#6E9461", "#0099c6", "#990099", "#717D8A"];
  903. pieWidthHeight = $this.data('sparkline-piesize') || 90;
  904. pieBorderColor = $this.data('border-color') || '#45494C';
  905. pieOffset = $this.data('sparkline-offset') || 0;
  906. $this.sparkline('html', {
  907. type : 'pie',
  908. width : pieWidthHeight,
  909. height : pieWidthHeight,
  910. tooltipFormat : '<span style="color: {{color}}">&#9679;</span> ({{percent.1}}%)',
  911. sliceColors : pieColors,
  912. borderWidth : 1,
  913. offset : pieOffset,
  914. borderColor : pieBorderColor
  915. });
  916. $this = null;
  917. }
  918. // BOX PLOT
  919. if (sparklineType == 'box') {
  920. thisBoxWidth = $this.data('sparkline-width') || 'auto';
  921. thisBoxHeight = $this.data('sparkline-height') || 'auto';
  922. thisBoxRaw = $this.data('sparkline-boxraw') || false;
  923. thisBoxTarget = $this.data('sparkline-targetval') || 'undefined';
  924. thisBoxMin = $this.data('sparkline-min') || 'undefined';
  925. thisBoxMax = $this.data('sparkline-max') || 'undefined';
  926. thisShowOutlier = $this.data('sparkline-showoutlier') || true;
  927. thisIQR = $this.data('sparkline-outlier-iqr') || 1.5;
  928. thisBoxSpotRadius = $this.data('sparkline-spotradius') || 1.5;
  929. thisBoxLineColor = $this.css('color') || '#000000';
  930. thisBoxFillColor = $this.data('fill-color') || '#c0d0f0';
  931. thisBoxWhisColor = $this.data('sparkline-whis-color') || '#000000';
  932. thisBoxOutlineColor = $this.data('sparkline-outline-color') || '#303030';
  933. thisBoxOutlineFill = $this.data('sparkline-outlinefill-color') || '#f0f0f0';
  934. thisBoxMedianColor = $this.data('sparkline-outlinemedian-color') || '#f00000';
  935. thisBoxTargetColor = $this.data('sparkline-outlinetarget-color') || '#40a020';
  936. $this.sparkline('html', {
  937. type : 'box',
  938. width : thisBoxWidth,
  939. height : thisBoxHeight,
  940. raw : thisBoxRaw,
  941. target : thisBoxTarget,
  942. minValue : thisBoxMin,
  943. maxValue : thisBoxMax,
  944. showOutliers : thisShowOutlier,
  945. outlierIQR : thisIQR,
  946. spotRadius : thisBoxSpotRadius,
  947. boxLineColor : thisBoxLineColor,
  948. boxFillColor : thisBoxFillColor,
  949. whiskerColor : thisBoxWhisColor,
  950. outlierLineColor : thisBoxOutlineColor,
  951. outlierFillColor : thisBoxOutlineFill,
  952. medianColor : thisBoxMedianColor,
  953. targetColor : thisBoxTargetColor
  954. });
  955. $this = null;
  956. }
  957. // BULLET
  958. if (sparklineType == 'bullet') {
  959. var thisBulletHeight = $this.data('sparkline-height') || 'auto';
  960. thisBulletWidth = $this.data('sparkline-width') || 2;
  961. thisBulletColor = $this.data('sparkline-bullet-color') || '#ed1c24';
  962. thisBulletPerformanceColor = $this.data('sparkline-performance-color') || '#3030f0';
  963. thisBulletRangeColors = $this.data('sparkline-bulletrange-color') || ["#d3dafe", "#a8b6ff", "#7f94ff"];
  964. $this.sparkline('html', {
  965. type : 'bullet',
  966. height : thisBulletHeight,
  967. targetWidth : thisBulletWidth,
  968. targetColor : thisBulletColor,
  969. performanceColor : thisBulletPerformanceColor,
  970. rangeColors : thisBulletRangeColors
  971. });
  972. $this = null;
  973. }
  974. // DISCRETE
  975. if (sparklineType == 'discrete') {
  976. thisDiscreteHeight = $this.data('sparkline-height') || 26;
  977. thisDiscreteWidth = $this.data('sparkline-width') || 50;
  978. thisDiscreteLineColor = $this.css('color');
  979. thisDiscreteLineHeight = $this.data('sparkline-line-height') || 5;
  980. thisDiscreteThrushold = $this.data('sparkline-threshold') || 'undefined';
  981. thisDiscreteThrusholdColor = $this.data('sparkline-threshold-color') || '#ed1c24';
  982. $this.sparkline('html', {
  983. type : 'discrete',
  984. width : thisDiscreteWidth,
  985. height : thisDiscreteHeight,
  986. lineColor : thisDiscreteLineColor,
  987. lineHeight : thisDiscreteLineHeight,
  988. thresholdValue : thisDiscreteThrushold,
  989. thresholdColor : thisDiscreteThrusholdColor
  990. });
  991. $this = null;
  992. }
  993. // TRISTATE
  994. if (sparklineType == 'tristate') {
  995. thisTristateHeight = $this.data('sparkline-height') || 26;
  996. thisTristatePosBarColor = $this.data('sparkline-posbar-color') || '#60f060';
  997. thisTristateNegBarColor = $this.data('sparkline-negbar-color') || '#f04040';
  998. thisTristateZeroBarColor = $this.data('sparkline-zerobar-color') || '#909090';
  999. thisTristateBarWidth = $this.data('sparkline-barwidth') || 5;
  1000. thisTristateBarSpacing = $this.data('sparkline-barspacing') || 2;
  1001. thisZeroAxis = $this.data('sparkline-zeroaxis') || false;
  1002. $this.sparkline('html', {
  1003. type : 'tristate',
  1004. height : thisTristateHeight,
  1005. posBarColor : thisBarColor,
  1006. negBarColor : thisTristateNegBarColor,
  1007. zeroBarColor : thisTristateZeroBarColor,
  1008. barWidth : thisTristateBarWidth,
  1009. barSpacing : thisTristateBarSpacing,
  1010. zeroAxis : thisZeroAxis
  1011. });
  1012. $this = null;
  1013. }
  1014. //COMPOSITE: BAR
  1015. if (sparklineType == 'compositebar') {
  1016. sparklineHeight = $this.data('sparkline-height') || '20px';
  1017. sparklineWidth = $this.data('sparkline-width') || '100%';
  1018. sparklineBarWidth = $this.data('sparkline-barwidth') || 3;
  1019. thisLineWidth = $this.data('sparkline-line-width') || 1;
  1020. thisLineColor = $this.data('data-sparkline-linecolor') || '#ed1c24';
  1021. thisBarColor = $this.data('data-sparkline-barcolor') || '#333333';
  1022. $this.sparkline($this.data('sparkline-bar-val'), {
  1023. type : 'bar',
  1024. width : sparklineWidth,
  1025. height : sparklineHeight,
  1026. barColor : thisBarColor,
  1027. barWidth : sparklineBarWidth
  1028. //barSpacing: 5
  1029. });
  1030. $this.sparkline($this.data('sparkline-line-val'), {
  1031. width : sparklineWidth,
  1032. height : sparklineHeight,
  1033. lineColor : thisLineColor,
  1034. lineWidth : thisLineWidth,
  1035. composite : true,
  1036. fillColor : false
  1037. });
  1038. $this = null;
  1039. }
  1040. //COMPOSITE: LINE
  1041. if (sparklineType == 'compositeline') {
  1042. sparklineHeight = $this.data('sparkline-height') || '20px';
  1043. sparklineWidth = $this.data('sparkline-width') || '90px';
  1044. sparklineValue = $this.data('sparkline-bar-val');
  1045. sparklineValueSpots1 = $this.data('sparkline-bar-val-spots-top') || null;
  1046. sparklineValueSpots2 = $this.data('sparkline-bar-val-spots-bottom') || null;
  1047. thisLineWidth1 = $this.data('sparkline-line-width-top') || 1;
  1048. thisLineWidth2 = $this.data('sparkline-line-width-bottom') || 1;
  1049. thisLineColor1 = $this.data('sparkline-color-top') || '#333333';
  1050. thisLineColor2 = $this.data('sparkline-color-bottom') || '#ed1c24';
  1051. thisSpotRadius1 = $this.data('sparkline-spotradius-top') || 1.5;
  1052. thisSpotRadius2 = $this.data('sparkline-spotradius-bottom') || thisSpotRadius1;
  1053. thisSpotColor = $this.data('sparkline-spot-color') || '#f08000';
  1054. thisMinSpotColor1 = $this.data('sparkline-minspot-color-top') || '#ed1c24';
  1055. thisMaxSpotColor1 = $this.data('sparkline-maxspot-color-top') || '#f08000';
  1056. thisMinSpotColor2 = $this.data('sparkline-minspot-color-bottom') || thisMinSpotColor1;
  1057. thisMaxSpotColor2 = $this.data('sparkline-maxspot-color-bottom') || thisMaxSpotColor1;
  1058. thishighlightSpotColor1 = $this.data('sparkline-highlightspot-color-top') || '#50f050';
  1059. thisHighlightLineColor1 = $this.data('sparkline-highlightline-color-top') || '#f02020';
  1060. thishighlightSpotColor2 = $this.data('sparkline-highlightspot-color-bottom') ||
  1061. thishighlightSpotColor1;
  1062. thisHighlightLineColor2 = $this.data('sparkline-highlightline-color-bottom') ||
  1063. thisHighlightLineColor1;
  1064. thisFillColor1 = $this.data('sparkline-fillcolor-top') || 'transparent';
  1065. thisFillColor2 = $this.data('sparkline-fillcolor-bottom') || 'transparent';
  1066. $this.sparkline(sparklineValue, {
  1067. type : 'line',
  1068. spotRadius : thisSpotRadius1,
  1069. spotColor : thisSpotColor,
  1070. minSpotColor : thisMinSpotColor1,
  1071. maxSpotColor : thisMaxSpotColor1,
  1072. highlightSpotColor : thishighlightSpotColor1,
  1073. highlightLineColor : thisHighlightLineColor1,
  1074. valueSpots : sparklineValueSpots1,
  1075. lineWidth : thisLineWidth1,
  1076. width : sparklineWidth,
  1077. height : sparklineHeight,
  1078. lineColor : thisLineColor1,
  1079. fillColor : thisFillColor1
  1080. });
  1081. $this.sparkline($this.data('sparkline-line-val'), {
  1082. type : 'line',
  1083. spotRadius : thisSpotRadius2,
  1084. spotColor : thisSpotColor,
  1085. minSpotColor : thisMinSpotColor2,
  1086. maxSpotColor : thisMaxSpotColor2,
  1087. highlightSpotColor : thishighlightSpotColor2,
  1088. highlightLineColor : thisHighlightLineColor2,
  1089. valueSpots : sparklineValueSpots2,
  1090. lineWidth : thisLineWidth2,
  1091. width : sparklineWidth,
  1092. height : sparklineHeight,
  1093. lineColor : thisLineColor2,
  1094. composite : true,
  1095. fillColor : thisFillColor2
  1096. });
  1097. $this = null;
  1098. }
  1099. });
  1100. }// end if
  1101. /*
  1102. * EASY PIE CHARTS
  1103. * DEPENDENCY: js/plugins/easy-pie-chart/jquery.easy-pie-chart.min.js
  1104. * Usage: <div class="easy-pie-chart txt-color-orangeDark" data-pie-percent="33" data-pie-size="72" data-size="72">
  1105. * <span class="percent percent-sign">35</span>
  1106. * </div>
  1107. */
  1108. if ($.fn.easyPieChart) {
  1109. $('.easy-pie-chart').each(function() {
  1110. var $this = $(this),
  1111. barColor = $this.css('color') || $this.data('pie-color'),
  1112. trackColor = $this.data('pie-track-color') || 'rgba(0,0,0,0.04)',
  1113. size = parseInt($this.data('pie-size')) || 25;
  1114. $this.easyPieChart({
  1115. barColor : barColor,
  1116. trackColor : trackColor,
  1117. scaleColor : false,
  1118. lineCap : 'butt',
  1119. lineWidth : parseInt(size / 8.5),
  1120. animate : 1500,
  1121. rotate : -90,
  1122. size : size,
  1123. onStep: function(from, to, percent) {
  1124. $(this.el).find('.percent').text(Math.round(percent));
  1125. }
  1126. });
  1127. $this = null;
  1128. });
  1129. } // end if
  1130. }
  1131. /* ~ END: INITIALIZE CHARTS */
  1132. /*
  1133. * INITIALIZE JARVIS WIDGETS
  1134. * Setup Desktop Widgets
  1135. */
  1136. function setup_widgets_desktop() {
  1137. if ($.fn.jarvisWidgets && enableJarvisWidgets) {
  1138. $('#widget-grid').jarvisWidgets({
  1139. grid : 'article',
  1140. widgets : '.jarviswidget',
  1141. localStorage : localStorageJarvisWidgets,
  1142. deleteSettingsKey : '#deletesettingskey-options',
  1143. settingsKeyLabel : 'Reset settings?',
  1144. deletePositionKey : '#deletepositionkey-options',
  1145. positionKeyLabel : 'Reset position?',
  1146. sortable : sortableJarvisWidgets,
  1147. buttonsHidden : false,
  1148. // toggle button
  1149. toggleButton : true,
  1150. toggleClass : 'fa fa-minus | fa fa-plus',
  1151. toggleSpeed : 200,
  1152. onToggle : function() {
  1153. },
  1154. // delete btn
  1155. deleteButton : true,
  1156. deleteMsg:'Warning: This action cannot be undone!',
  1157. deleteClass : 'fa fa-times',
  1158. deleteSpeed : 200,
  1159. onDelete : function() {
  1160. },
  1161. // edit btn
  1162. editButton : true,
  1163. editPlaceholder : '.jarviswidget-editbox',
  1164. editClass : 'fa fa-cog | fa fa-save',
  1165. editSpeed : 200,
  1166. onEdit : function() {
  1167. },
  1168. // color button
  1169. colorButton : true,
  1170. // full screen
  1171. fullscreenButton : true,
  1172. fullscreenClass : 'fa fa-expand | fa fa-compress',
  1173. fullscreenDiff : 3,
  1174. onFullscreen : function() {
  1175. },
  1176. // custom btn
  1177. customButton : false,
  1178. customClass : 'folder-10 | next-10',
  1179. customStart : function() {
  1180. alert('Hello you, this is a custom button...');
  1181. },
  1182. customEnd : function() {
  1183. alert('bye, till next time...');
  1184. },
  1185. // order
  1186. buttonOrder : '%refresh% %custom% %edit% %toggle% %fullscreen% %delete%',
  1187. opacity : 1.0,
  1188. dragHandle : '> header',
  1189. placeholderClass : 'jarviswidget-placeholder',
  1190. indicator : true,
  1191. indicatorTime : 600,
  1192. ajax : true,
  1193. timestampPlaceholder : '.jarviswidget-timestamp',
  1194. timestampFormat : 'Last update: %m%/%d%/%y% %h%:%i%:%s%',
  1195. refreshButton : true,
  1196. refreshButtonClass : 'fa fa-refresh',
  1197. labelError : 'Sorry but there was a error:',
  1198. labelUpdated : 'Last Update:',
  1199. labelRefresh : 'Refresh',
  1200. labelDelete : 'Delete widget:',
  1201. afterLoad : function() {
  1202. },
  1203. rtl : false, // best not to toggle this!
  1204. onChange : function() {
  1205. console.log("onChange event");
  1206. },
  1207. onSave : function() {
  1208. console.log("onSave event");
  1209. },
  1210. ajaxnav : $.navAsAjax // declears how the localstorage should be saved (HTML or AJAX Version)
  1211. });
  1212. }
  1213. }
  1214. /*
  1215. * SETUP DESKTOP WIDGET
  1216. */
  1217. function setup_widgets_mobile() {
  1218. if (enableMobileWidgets && enableJarvisWidgets) {
  1219. setup_widgets_desktop();
  1220. }
  1221. }
  1222. /* ~ END: INITIALIZE JARVIS WIDGETS */
  1223. /*
  1224. * GOOGLE MAPS
  1225. * description: Append google maps to head dynamically (only execute for ajax version)
  1226. * Loads at the begining for ajax pages
  1227. */
  1228. if ($.navAsAjax || $(".google_maps")){
  1229. var gMapsLoaded = false;
  1230. window.gMapsCallback = function() {
  1231. gMapsLoaded = true;
  1232. $(window).trigger('gMapsLoaded');
  1233. };
  1234. window.loadGoogleMaps = function() {
  1235. if (gMapsLoaded)
  1236. return window.gMapsCallback();
  1237. var script_tag = document.createElement('script');
  1238. script_tag.setAttribute("type", "text/javascript");
  1239. script_tag.setAttribute("src", "https://maps.google.com/maps/api/js?sensor=false&callback=gMapsCallback");
  1240. (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_tag);
  1241. };
  1242. }
  1243. /* ~ END: GOOGLE MAPS */
  1244. /*
  1245. * LOAD SCRIPTS
  1246. * Usage:
  1247. * Define function = myPrettyCode ()...
  1248. * loadScript("js/my_lovely_script.js", myPrettyCode);
  1249. */
  1250. function loadScript(scriptName, callback) {
  1251. if (!jsArray[scriptName]) {
  1252. var promise = jQuery.Deferred();
  1253. // adding the script tag to the head as suggested before
  1254. var body = document.getElementsByTagName('body')[0],
  1255. script = document.createElement('script');
  1256. script.type = 'text/javascript';
  1257. script.src = scriptName;
  1258. // then bind the event to the callback function
  1259. // there are several events for cross browser compatibility
  1260. script.onload = function() {
  1261. promise.resolve();
  1262. };
  1263. // fire the loading
  1264. body.appendChild(script);
  1265. // clear DOM reference
  1266. //body = null;
  1267. //script = null;
  1268. jsArray[scriptName] = promise.promise();
  1269. } else if (debugState)
  1270. root.root.console.log("This script was already loaded %c: " + scriptName, debugStyle_warning);
  1271. jsArray[scriptName].then(function () {
  1272. if(typeof callback === 'function')
  1273. callback();
  1274. });
  1275. }
  1276. /* ~ END: LOAD SCRIPTS */
  1277. /*
  1278. * APP AJAX REQUEST SETUP
  1279. * Description: Executes and fetches all ajax requests also
  1280. * updates naivgation elements to active
  1281. */
  1282. if($.navAsAjax) {
  1283. // fire this on page load if nav exists
  1284. if ($('nav').length) {
  1285. checkURL();
  1286. }
  1287. $(document).on('click', 'nav a[href!="#"]', function(e) {
  1288. e.preventDefault();
  1289. var $this = $(e.currentTarget);
  1290. // if parent is not active then get hash, or else page is assumed to be loaded
  1291. if (!$this.parent().hasClass("active") && !$this.attr('target')) {
  1292. // update window with hash
  1293. // you could also do here: thisDevice === "mobile" - and save a little more memory
  1294. if ($.root_.hasClass('mobile-view-activated')) {
  1295. $.root_.removeClass('hidden-menu');
  1296. $('html').removeClass("hidden-menu-mobile-lock");
  1297. window.setTimeout(function() {
  1298. if (window.location.search) {
  1299. window.location.href =
  1300. window.location.href.replace(window.location.search, '')
  1301. .replace(window.location.hash, '') + '#' + $this.attr('href');
  1302. } else {
  1303. window.location.hash = $this.attr('href');
  1304. }
  1305. }, 150);
  1306. // it may not need this delay...
  1307. } else {
  1308. if (window.location.search) {
  1309. window.location.href =
  1310. window.location.href.replace(window.location.search, '')
  1311. .replace(window.location.hash, '') + '#' + $this.attr('href');
  1312. } else {
  1313. window.location.hash = $this.attr('href');
  1314. }
  1315. }
  1316. // clear DOM reference
  1317. // $this = null;
  1318. }
  1319. });
  1320. // fire links with targets on different window
  1321. $(document).on('click', 'nav a[target="_blank"]', function(e) {
  1322. e.preventDefault();
  1323. var $this = $(e.currentTarget);
  1324. window.open($this.attr('href'));
  1325. });
  1326. // fire links with targets on same window
  1327. $(document).on('click', 'nav a[target="_top"]', function(e) {
  1328. e.preventDefault();
  1329. var $this = $(e.currentTarget);
  1330. window.location = ($this.attr('href'));
  1331. });
  1332. // all links with hash tags are ignored
  1333. $(document).on('click', 'nav a[href="#"]', function(e) {
  1334. e.preventDefault();
  1335. });
  1336. // DO on hash change
  1337. $(window).on('hashchange', function() {
  1338. checkURL();
  1339. });
  1340. }
  1341. /*
  1342. * CHECK TO SEE IF URL EXISTS
  1343. */
  1344. function checkURL() {
  1345. //get the url by removing the hash
  1346. //var url = location.hash.replace(/^#/, '');
  1347. var url = location.href.split('#').splice(1).join('#');
  1348. //BEGIN: IE11 Work Around
  1349. if (!url) {
  1350. try {
  1351. var documentUrl = window.document.URL;
  1352. if (documentUrl) {
  1353. if (documentUrl.indexOf('#', 0) > 0 && documentUrl.indexOf('#', 0) < (documentUrl.length + 1)) {
  1354. url = documentUrl.substring(documentUrl.indexOf('#', 0) + 1);
  1355. }
  1356. }
  1357. } catch (err) {}
  1358. }
  1359. //END: IE11 Work Around
  1360. container = $('#content');
  1361. // Do this if url exists (for page refresh, etc...)
  1362. if (url) {
  1363. // remove all active class
  1364. $('nav li.active').removeClass("active");
  1365. // match the url and add the active class
  1366. $('nav li:has(a[href="' + url + '"])').addClass("active");
  1367. var title = ($('nav a[href="' + url + '"]').attr('title'));
  1368. // change page title from global var
  1369. document.title = (title || document.title);
  1370. // debugState
  1371. if (debugState){
  1372. root.console.log("Page title: %c " + document.title, debugStyle_green);
  1373. }
  1374. // parse url to jquery
  1375. loadURL(url + location.search, container);
  1376. } else {
  1377. // grab the first URL from nav
  1378. var $this = $('nav > ul > li:first-child > a[href!="#"]');
  1379. //update hash
  1380. window.location.hash = $this.attr('href');
  1381. //clear dom reference
  1382. $this = null;
  1383. }
  1384. }
  1385. /*
  1386. * LOAD AJAX PAGES
  1387. */
  1388. function loadURL(url, container) {
  1389. // debugState
  1390. if (debugState){
  1391. root.root.console.log("Loading URL: %c" + url, debugStyle);
  1392. }
  1393. $.ajax({
  1394. type : "GET",
  1395. url : url,
  1396. dataType : 'html',
  1397. cache : true, // (warning: setting it to false will cause a timestamp and will call the request twice)
  1398. beforeSend : function() {
  1399. //IE11 bug fix for googlemaps (delete all google map instances)
  1400. //check if the page is ajax = true, has google map class and the container is #content
  1401. if ($.navAsAjax && $(".google_maps")[0] && (container[0] == $("#content")[0]) ) {
  1402. // target gmaps if any on page
  1403. var collection = $(".google_maps"),
  1404. i = 0;
  1405. // run for each map
  1406. collection.each(function() {
  1407. i ++;
  1408. // get map id from class elements
  1409. var divDealerMap = document.getElementById(this.id);
  1410. if(i == collection.length + 1) {
  1411. // "callback"
  1412. } else {
  1413. // destroy every map found
  1414. if (divDealerMap) divDealerMap.parentNode.removeChild(divDealerMap);
  1415. // debugState
  1416. if (debugState){
  1417. root.console.log("Destroying maps.........%c" + this.id, debugStyle_warning);
  1418. }
  1419. }
  1420. });
  1421. // debugState
  1422. if (debugState){
  1423. root.console.log("✔ Google map instances nuked!!!");
  1424. }
  1425. } //end fix
  1426. // destroy all datatable instances
  1427. if ( $.navAsAjax && $('.dataTables_wrapper')[0] && (container[0] == $("#content")[0]) ) {
  1428. var tables = $.fn.dataTable.fnTables(true);
  1429. $(tables).each(function () {
  1430. if($(this).find('.details-control').length != 0) {
  1431. $(this).find('*').addBack().off().remove();
  1432. $(this).dataTable().fnDestroy();
  1433. } else {
  1434. $(this).dataTable().fnDestroy();
  1435. }
  1436. });
  1437. // debugState
  1438. if (debugState){
  1439. root.console.log("✔ Datatable instances nuked!!!");
  1440. }
  1441. }
  1442. // end destroy
  1443. // pop intervals (destroys jarviswidget related intervals)
  1444. if ( $.navAsAjax && $.intervalArr.length > 0 && (container[0] == $("#content")[0]) && enableJarvisWidgets ) {
  1445. while($.intervalArr.length > 0)
  1446. clearInterval($.intervalArr.pop());
  1447. // debugState
  1448. if (debugState){
  1449. root.console.log("✔ All JarvisWidget intervals cleared");
  1450. }
  1451. }
  1452. // end pop intervals
  1453. // destroy all widget instances
  1454. if ( $.navAsAjax && (container[0] == $("#content")[0]) && enableJarvisWidgets && $("#widget-grid")[0] ) {
  1455. $("#widget-grid").jarvisWidgets('destroy');
  1456. // debugState
  1457. if (debugState){
  1458. root.console.log("✔ JarvisWidgets destroyed");
  1459. }
  1460. }
  1461. // end destroy all widgets
  1462. // cluster destroy: destroy other instances that could be on the page
  1463. // this runs a script in the current loaded page before fetching the new page
  1464. if ( $.navAsAjax && (container[0] == $("#content")[0]) ) {
  1465. /*
  1466. * The following elements should be removed, if they have been created:
  1467. *
  1468. * colorList
  1469. * icon
  1470. * picker
  1471. * inline
  1472. * And unbind events from elements:
  1473. *
  1474. * icon
  1475. * picker
  1476. * inline
  1477. * especially $(document).on('mousedown')
  1478. * It will be much easier to add namespace to plugin events and then unbind using selected namespace.
  1479. *
  1480. * See also:
  1481. *
  1482. * http://f6design.com/journal/2012/05/06/a-jquery-plugin-boilerplate/
  1483. * http://keith-wood.name/pluginFramework.html
  1484. */
  1485. // this function is below the pagefunction for all pages that has instances
  1486. if (typeof pagedestroy == 'function') {
  1487. try {
  1488. pagedestroy();
  1489. if (debugState){
  1490. root.console.log("✔ Pagedestroy()");
  1491. }
  1492. }
  1493. catch(err) {
  1494. pagedestroy = undefined;
  1495. if (debugState){
  1496. root.console.log("! Pagedestroy() Catch Error");
  1497. }
  1498. }
  1499. }
  1500. // destroy all inline charts
  1501. if ( $.fn.sparkline && $("#content .sparkline")[0] ) {
  1502. $("#content .sparkline").sparkline( 'destroy' );
  1503. if (debugState){
  1504. root.console.log("✔ Sparkline Charts destroyed!");
  1505. }
  1506. }
  1507. if ( $.fn.easyPieChart && $("#content .easy-pie-chart")[0] ) {
  1508. $("#content .easy-pie-chart").easyPieChart( 'destroy' );
  1509. if (debugState){
  1510. root.console.log("✔ EasyPieChart Charts destroyed!");
  1511. }
  1512. }
  1513. // end destory all inline charts
  1514. // destroy form controls: Datepicker, select2, autocomplete, mask, bootstrap slider
  1515. if ( $.fn.select2 && $("#content select.select2")[0] ) {
  1516. $("#content select.select2").select2('destroy');
  1517. if (debugState){
  1518. root.console.log("✔ Select2 destroyed!");
  1519. }
  1520. }
  1521. if ( $.fn.mask && $('#content [data-mask]')[0] ) {
  1522. $('#content [data-mask]').unmask();
  1523. if (debugState){
  1524. root.console.log("✔ Input Mask destroyed!");
  1525. }
  1526. }
  1527. if ( $.fn.datepicker && $('#content .datepicker')[0] ) {
  1528. $('#content .datepicker').off();
  1529. $('#content .datepicker').remove();
  1530. if (debugState){
  1531. root.console.log("✔ Datepicker destroyed!");
  1532. }
  1533. }
  1534. if ( $.fn.slider && $('#content .slider')[0] ) {
  1535. $('#content .slider').off();
  1536. $('#content .slider').remove();
  1537. if (debugState){
  1538. root.console.log("✔ Bootstrap Slider destroyed!");
  1539. }
  1540. }
  1541. // end destroy form controls
  1542. }
  1543. // end cluster destroy
  1544. // empty container and var to start garbage collection (frees memory)
  1545. pagefunction = null;
  1546. container.removeData().html("");
  1547. // place cog
  1548. container.html('<h1 class="ajax-loading-animation"><i class="fa fa-cog fa-spin"></i> Loading...</h1>');
  1549. // Only draw breadcrumb if it is main content material
  1550. if (container[0] == $("#content")[0]) {
  1551. // clear everything else except these key DOM elements
  1552. // we do this because sometime plugins will leave dynamic elements behind
  1553. $('body').find('> *').filter(':not(' + ignore_key_elms + ')').empty().remove();
  1554. // draw breadcrumb
  1555. drawBreadCrumb();
  1556. // scroll up
  1557. $("html").animate({
  1558. scrollTop : 0
  1559. }, "fast");
  1560. }
  1561. // end if
  1562. },
  1563. success : function(data) {
  1564. // dump data to container
  1565. container.css({
  1566. opacity : '0.0'
  1567. }).html(data).delay(50).animate({
  1568. opacity : '1.0'
  1569. }, 300);
  1570. // clear data var
  1571. data = null;
  1572. container = null;
  1573. },
  1574. error : function(xhr, status, thrownError, error) {
  1575. container.html('<h4 class="ajax-loading-error"><i class="fa fa-warning txt-color-orangeDark"></i> Error requesting <span class="txt-color-red">' + url + '</span>: ' + xhr.status + ' <span style="text-transform: capitalize;">' + thrownError + '</span></h4>');
  1576. },
  1577. async : true
  1578. });
  1579. }
  1580. /*
  1581. * UPDATE BREADCRUMB
  1582. */
  1583. function drawBreadCrumb(opt_breadCrumbs) {
  1584. var a = $("nav li.active > a"),
  1585. b = a.length;
  1586. bread_crumb.empty(),
  1587. bread_crumb.append($("<li>Home</li>")), a.each(function() {
  1588. bread_crumb.append($("<li></li>").html($.trim($(this).clone().children(".badge").remove().end().text()))), --b || (document.title = bread_crumb.find("li:last-child").text())
  1589. });
  1590. // Push breadcrumb manually -> drawBreadCrumb(["Users", "John Doe"]);
  1591. // Credits: Philip Whitt | philip.whitt@sbcglobal.net
  1592. if (opt_breadCrumbs != undefined) {
  1593. $.each(opt_breadCrumbs, function(index, value) {
  1594. bread_crumb.append($("<li></li>").html(value));
  1595. document.title = bread_crumb.find("li:last-child").text();
  1596. });
  1597. }
  1598. }
  1599. /* ~ END: APP AJAX REQUEST SETUP */
  1600. /*
  1601. * PAGE SETUP
  1602. * Description: fire certain scripts that run through the page
  1603. * to check for form elements, tooltip activation, popovers, etc...
  1604. */
  1605. function pageSetUp() {
  1606. if (thisDevice === "desktop"){
  1607. // is desktop
  1608. // activate tooltips
  1609. $("[rel=tooltip], [data-rel=tooltip]").tooltip();
  1610. // activate popovers
  1611. $("[rel=popover], [data-rel=popover]").popover();
  1612. // activate popovers with hover states
  1613. $("[rel=popover-hover], [data-rel=popover-hover]").popover({
  1614. trigger : "hover"
  1615. });
  1616. // setup widgets
  1617. setup_widgets_desktop();
  1618. // activate inline charts
  1619. runAllCharts();
  1620. // run form elements
  1621. runAllForms();
  1622. } else {
  1623. // is mobile
  1624. // activate popovers
  1625. $("[rel=popover], [data-rel=popover]").popover();
  1626. // activate popovers with hover states
  1627. $("[rel=popover-hover], [data-rel=popover-hover]").popover({
  1628. trigger : "hover"
  1629. });
  1630. // activate inline charts
  1631. runAllCharts();
  1632. // setup widgets
  1633. setup_widgets_mobile();
  1634. // run form elements
  1635. runAllForms();
  1636. }
  1637. }
  1638. /* ~ END: PAGE SETUP */
  1639. /*
  1640. * ONE POP OVER THEORY
  1641. * Keep only 1 active popover per trigger - also check and hide active popover if user clicks on document
  1642. */
  1643. $('body').on('click', function(e) {
  1644. $('[rel="popover"], [data-rel="popover"]').each(function() {
  1645. //the 'is' for buttons that trigger popups
  1646. //the 'has' for icons within a button that triggers a popup
  1647. if (!$(this).is(e.target) && $(this).has(e.target).length === 0 && $('.popover').has(e.target).length === 0) {
  1648. $(this).popover('hide');
  1649. }
  1650. });
  1651. });
  1652. /* ~ END: ONE POP OVER THEORY */
  1653. /*
  1654. * DELETE MODEL DATA ON HIDDEN
  1655. * Clears the model data once it is hidden, this way you do not create duplicated data on multiple modals
  1656. */
  1657. $('body').on('hidden.bs.modal', '.modal', function () {
  1658. $(this).removeData('bs.modal');
  1659. });
  1660. /* ~ END: DELETE MODEL DATA ON HIDDEN */
  1661. /*
  1662. * HELPFUL FUNCTIONS
  1663. * We have included some functions below that can be resued on various occasions
  1664. *
  1665. * Get param value
  1666. * example: alert( getParam( 'param' ) );
  1667. */
  1668. function getParam(name) {
  1669. name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
  1670. var regexS = "[\\?&]" + name + "=([^&#]*)";
  1671. var regex = new RegExp(regexS);
  1672. var results = regex.exec(window.location.href);
  1673. if (results == null)
  1674. return "";
  1675. else
  1676. return results[1];
  1677. }
  1678. /* ~ END: HELPFUL FUNCTIONS */