Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

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