bjui-navtab.js 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658
  1. /*!
  2. * B-JUI v1.2 (http://b-jui.com)
  3. * Git@OSC (http://git.oschina.net/xknaan/B-JUI)
  4. * Copyright 2014 K'naan (xknaan@163.com).
  5. * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
  6. */
  7. /* ========================================================================
  8. * B-JUI: bjui-navtab.js v1.2
  9. * @author K'naan (xknaan@163.com)
  10. * -- Modified from dwz.navTab.js (author:ZhangHuihua@msn.com)
  11. * http://git.oschina.net/xknaan/B-JUI/blob/master/BJUI/js/bjui-navtab.js
  12. * ========================================================================
  13. * Copyright 2014 K'naan.
  14. * Licensed under Apache (http://www.apache.org/licenses/LICENSE-2.0)
  15. * ======================================================================== */
  16. +function ($) {
  17. 'use strict';
  18. // NAVTAB GLOBAL ELEMENTS
  19. // ======================
  20. var currentIndex, $currentTab, $currentPanel, $box, $tabs, $panels, $prevBtn, $nextBtn, $moreBtn, $moreBox, $main, $mainLi
  21. var autorefreshTimer
  22. $(function() {
  23. var INIT_NAVTAB = function() {
  24. currentIndex = 0
  25. $box = $('#bjui-navtab')
  26. $tabs = $box.find('.navtab-tab')
  27. $panels = $box.find('.navtab-panel')
  28. $prevBtn = $box.find('.tabsLeft')
  29. $nextBtn = $box.find('.tabsRight')
  30. $moreBtn = $box.find('.tabsMore')
  31. $moreBox = $box.find('.tabsMoreList')
  32. $main = $tabs.find('li:first')
  33. $mainLi = $moreBox.find('li:first')
  34. $prevBtn.click(function() { $(this).navtab('scrollPrev') })
  35. $nextBtn.click(function() { $(this).navtab('scrollNext') })
  36. $moreBtn.click(function() { $moreBox.show() })
  37. $(document).on('click.bjui.navtab.switchtab', function(e) {
  38. var $target = e.target.tagName == 'I' ? $(e.target).parent() : $(e.target)
  39. if ($moreBtn[0] != $target[0]) $moreBox.hide()
  40. })
  41. var mainTit, options
  42. $main
  43. .navtab('contextmenu', $main)
  44. .click(function() { $(this).navtab('switchTab', 'main') })
  45. .find('> a > span').html(function(n, c) { return (mainTit = c.replace('#maintab#', BJUI.regional.maintab)) })
  46. options = $.extend({}, Navtab.DEFAULTS, $main.data(), {id:'main', title:mainTit})
  47. $main.data('initOptions', options).data('options', options)
  48. if ($main.attr('data-url')) {
  49. $(document).one(BJUI.eventType.initUI, function(e) {
  50. $main.removeAttr('data-url').navtab('reload', options)
  51. })
  52. }
  53. setTimeout(function() {
  54. $main.navtab('switchTab', 'main')
  55. }, 50)
  56. $mainLi
  57. .click(function() {
  58. if ($(this).hasClass('active')) $moreBox.hide()
  59. else $(this).navtab('switchTab', 'main')
  60. })
  61. .find('> a').html(function(n, c) { return c.replace('#maintab#', BJUI.regional.maintab) })
  62. }
  63. INIT_NAVTAB()
  64. })
  65. // NAVTAB CLASS DEFINITION
  66. // ======================
  67. var Navtab = function(element, options) {
  68. this.$element = $(element)
  69. this.options = options
  70. this.tools = this.TOOLS()
  71. }
  72. Navtab.DEFAULTS = {
  73. id : undefined,
  74. title : 'New tab',
  75. url : undefined,
  76. type : 'GET',
  77. data : {},
  78. loadingmask : true,
  79. fresh : false,
  80. autorefresh : false,
  81. onLoad : null,
  82. beforeClose : null,
  83. onClose : null
  84. }
  85. Navtab.prototype.TOOLS = function() {
  86. var that = this
  87. var tools = {
  88. getDefaults: function() {
  89. return Navtab.DEFAULTS
  90. },
  91. getTabs: function() {
  92. return $tabs.find('> li')
  93. },
  94. getPanels: function() {
  95. return $panels.find('> div')
  96. },
  97. getMoreLi: function() {
  98. return $moreBox.find('> li')
  99. },
  100. getTab: function(tabid) {
  101. var index = this.indexTabId(tabid)
  102. if (index >= 0) return this.getTabs().eq(index)
  103. },
  104. getPanel: function(tabid) {
  105. var index = this.indexTabId(tabid)
  106. if (index >= 0) return this.getPanels().eq(index)
  107. },
  108. getTabsW: function(iStart, iEnd) {
  109. return this.tabsW(this.getTabs().slice(iStart, iEnd))
  110. },
  111. tabsW: function($tabs) {
  112. var iW = 0
  113. $tabs.each(function() {
  114. iW += $(this).outerWidth(true)
  115. })
  116. return iW
  117. },
  118. indexTabId: function(tabid) {
  119. if (!tabid) return -1
  120. var iOpenIndex = -1
  121. this.getTabs().each(function(index) {
  122. if ($(this).data('initOptions').id == tabid) {
  123. iOpenIndex = index
  124. return
  125. }
  126. })
  127. return iOpenIndex
  128. },
  129. getLeft: function() {
  130. return $tabs.position().left
  131. },
  132. getScrollBarW: function() {
  133. return $box.width() - 55
  134. },
  135. visibleStart: function() {
  136. var iLeft = this.getLeft(), iW = 0
  137. var $tabs = this.getTabs()
  138. for (var i = 0; i < $tabs.size(); i++) {
  139. if (iW + iLeft >= 0) return i
  140. iW += $tabs.eq(i).outerWidth(true)
  141. }
  142. return 0
  143. },
  144. visibleEnd: function() {
  145. var iLeft = this.getLeft(), iW = 0
  146. var $tabs = this.getTabs()
  147. for (var i = 0; i < $tabs.size(); i++) {
  148. iW += $tabs.eq(i).outerWidth(true)
  149. if (iW + iLeft > this.getScrollBarW()) return i
  150. }
  151. return $tabs.size()
  152. },
  153. scrollPrev: function() {
  154. var iStart = this.visibleStart()
  155. if (iStart > 0)
  156. this.scrollTab(-this.getTabsW(0, iStart - 1))
  157. },
  158. scrollNext: function() {
  159. var iEnd = this.visibleEnd()
  160. if (iEnd < this.getTabs().size())
  161. this.scrollTab(-this.getTabsW(0, iEnd + 1) + this.getScrollBarW())
  162. },
  163. scrollTab: function(iLeft, isNext) {
  164. $tabs.animate({ left: iLeft }, 200, function() { that.tools.ctrlScrollBtn() })
  165. },
  166. scrollCurrent: function() { // auto scroll current tab
  167. var iW = this.tabsW(this.getTabs()), scrollW = this.getScrollBarW()
  168. if (iW <= scrollW)
  169. this.scrollTab(0)
  170. else if (this.getLeft() < scrollW - iW)
  171. this.scrollTab(scrollW-iW)
  172. else if (currentIndex < this.visibleStart())
  173. this.scrollTab(-this.getTabsW(0, currentIndex))
  174. else if (currentIndex >= this.visibleEnd())
  175. this.scrollTab(scrollW - this.getTabs().eq(currentIndex).outerWidth(true) - this.getTabsW(0, currentIndex))
  176. },
  177. ctrlScrollBtn: function() {
  178. var iW = this.tabsW(this.getTabs())
  179. if (this.getScrollBarW() > iW) {
  180. $prevBtn.hide()
  181. $nextBtn.hide()
  182. $tabs.parent().removeClass('tabsPageHeaderMargin')
  183. } else {
  184. $prevBtn.show().removeClass('tabsLeftDisabled')
  185. $nextBtn.show().removeClass('tabsRightDisabled')
  186. $tabs.parent().addClass('tabsPageHeaderMargin')
  187. if (this.getLeft() >= 0)
  188. $prevBtn.addClass('tabsLeftDisabled')
  189. else if (this.getLeft() <= this.getScrollBarW() - iW)
  190. $nextBtn.addClass('tabsRightDisabled')
  191. }
  192. },
  193. switchTab: function(iTabIndex) {
  194. var $tab = this.getTabs().removeClass('active').eq(iTabIndex).addClass('active'), $panels = this.getPanels(), $panel = $panels.eq(iTabIndex), onSwitch = that.options.onSwitch ? that.options.onSwitch.toFunc() : null
  195. if ($tab.data('reloadFlag')) {
  196. $panels.hide()
  197. $panel.show()
  198. that.refresh($tab.data('initOptions').id)
  199. } else {
  200. $panels.hide()
  201. if ($panel.find('.bjui-ajax-mask').length) {
  202. $panel.show()
  203. } else {
  204. $panel.addClass('fade').removeClass('in').show()
  205. if ($.support.transition)
  206. $panel.one('bsTransitionEnd', function() { $panel.addClass('in') }).emulateTransitionEnd(10)
  207. else
  208. $panel.removeClass('fade')
  209. }
  210. }
  211. this.getMoreLi().removeClass('active').eq(iTabIndex).addClass('active')
  212. currentIndex = iTabIndex
  213. this.scrollCurrent()
  214. $currentTab = $tab
  215. $.CurrentNavtab = $currentPanel = $panel
  216. if (onSwitch) onSwitch.apply(that)
  217. //events
  218. $panel.trigger('bjui.navtab.switch')
  219. },
  220. closeTab: function(index, openTabid) {
  221. var $tab = this.getTabs().eq(index)
  222. var $more = this.getMoreLi().eq(index)
  223. var $panel = this.getPanels().eq(index)
  224. var options = $tab.data('options')
  225. var beforeClose = options.beforeClose ? options.beforeClose.toFunc() : null
  226. var onClose = options.onClose ? options.onClose.toFunc() : null
  227. var canClose = true
  228. if (beforeClose) canClose = beforeClose.apply(that, [$panel])
  229. if (!canClose) {
  230. that.tools.switchTab(index)
  231. return
  232. }
  233. $tab.remove()
  234. $more.remove()
  235. $panel.trigger(BJUI.eventType.beforeCloseNavtab).remove()
  236. if (autorefreshTimer) clearInterval(autorefreshTimer)
  237. if (onClose) onClose.apply(that)
  238. if (currentIndex >= index) currentIndex--
  239. if (openTabid) {
  240. var openIndex = this.indexTabId(openTabid)
  241. if (openIndex > 0) currentIndex = openIndex
  242. }
  243. this.scrollCurrent()
  244. this.switchTab(currentIndex)
  245. },
  246. closeOtherTab: function(index) {
  247. index = index || currentIndex
  248. this.getTabs().each(function(i) {
  249. if (i > 0 && index != i) $(this).find('> .close').trigger('click')
  250. })
  251. },
  252. loadUrlCallback: function($panel) {
  253. $panel.find(':button.btn-close').click(function() { that.closeCurrentTab() })
  254. },
  255. reload: function($tab, flag) {
  256. flag = flag || $tab.data('reloadFlag')
  257. var options = $tab.data('options')
  258. if (flag) {
  259. $tab.data('reloadFlag', false)
  260. var $panel = that.tools.getPanel(options.id)
  261. if ($tab.hasClass('external')) {
  262. that.openExternal(options.url, $panel)
  263. } else {
  264. that.tools.reloadTab($panel, options)
  265. }
  266. }
  267. },
  268. reloadTab: function($panel, options) {
  269. var onLoad = options.onLoad ? options.onLoad.toFunc() : null,
  270. arefre = options.autorefresh && (isNaN(String(options.autorefresh)) ? 15 : options.autorefresh)
  271. $panel
  272. .trigger(BJUI.eventType.beforeLoadNavtab)
  273. .ajaxUrl({
  274. type:(options.type || 'GET'), url:options.url, data:options.data || {}, loadingmask:options.loadingmask, callback:function(response) {
  275. that.tools.loadUrlCallback($panel)
  276. if (onLoad) onLoad.apply(that, [$panel])
  277. if (autorefreshTimer) clearInterval(autorefreshTimer)
  278. if (arefre) autorefreshTimer = setInterval(function() { $panel.navtab('refresh') }, arefre * 1000)
  279. if (BJUI.ui.clientPaging && $panel.data('bjui.clientPaging')) $panel.pagination('setPagingAndOrderby', $panel)
  280. }
  281. })
  282. }
  283. }
  284. return tools
  285. }
  286. Navtab.prototype.contextmenu = function($obj) {
  287. var that = this
  288. $obj.contextmenu({
  289. id: 'navtabCM',
  290. bindings: {
  291. reload: function(t, m) {
  292. that.refresh(t.data('initOptions').id)
  293. },
  294. closeCurrent: function(t, m) {
  295. var tabId = t.data('initOptions').id
  296. if (tabId) that.closeTab(tabId)
  297. else that.closeCurrentTab()
  298. },
  299. closeOther: function(t, m) {
  300. if (t.index() == 0) {
  301. that.closeAllTab()
  302. } else {
  303. var index = that.tools.indexTabId(t.data('initOptions').id)
  304. that.tools.closeOtherTab(index > 0 ? index : currentIndex)
  305. }
  306. },
  307. closeAll: function(t, m) {
  308. that.closeAllTab()
  309. }
  310. },
  311. ctrSub: function(t, m) {
  312. var mReload = m.find('[rel="reload"]')
  313. var mCur = m.find('[rel="closeCurrent"]')
  314. var mOther = m.find('[rel="closeOther"]')
  315. var mAll = m.find('[rel="closeAll"]')
  316. var $tabLi = that.tools.getTabs()
  317. if (t.index() == 0) {
  318. mCur.addClass('disabled')
  319. if (!t.data('url')) mReload.addClass('disabled')
  320. }
  321. }
  322. })
  323. }
  324. // if found tabid replace tab, else create a new tab.
  325. Navtab.prototype.openTab = function() {
  326. var that = this, $element = this.$element, options = this.options, tools = this.tools
  327. if (!options.url && options.href) options.url = options.href
  328. if (!options.url) {
  329. BJUI.debug('Navtab Plugin: Error trying to open a navtab, url is undefined!')
  330. return
  331. } else {
  332. options.url = decodeURI(options.url).replacePlh($element.closest('.unitBox'))
  333. if (!options.url.isFinishedTm()) {
  334. $element.alertmsg('error', (options.warn || FRAG.alertPlhMsg.replace('#plhmsg#', BJUI.regional.plhmsg)))
  335. BJUI.debug('Navtab Plugin: The new navtab\'s url is incorrect, url: '+ options.url)
  336. return
  337. }
  338. options.url = encodeURI(options.url)
  339. }
  340. var iOpenIndex = options.id ? tools.indexTabId(options.id) : currentIndex
  341. if (!options.id && !BJUI.ui.overwriteHomeTab && iOpenIndex == 0) {
  342. options.id = 'navtab'
  343. iOpenIndex = -1
  344. }
  345. if (iOpenIndex >= 0) {
  346. if (!options.id) delete options.id
  347. var $tab = tools.getTabs().eq(iOpenIndex)
  348. var $panel = tools.getPanels().eq(iOpenIndex)
  349. var initOp = $tab.data('initOptions')
  350. var op = $.extend({}, initOp, options)
  351. if (initOp.fresh || options.fresh || initOp.url != options.url) {
  352. that.reload(op)
  353. }
  354. currentIndex = iOpenIndex
  355. } else {
  356. var tabFrag = '<li><a href="javascript:" title="#title#"><span>#title#</span></a><span class="close">&times;</span></li>'
  357. var $tab = $(tabFrag.replaceAll('#title#', options.title))
  358. var $panel = $('<div class="navtabPage unitBox"></div>')
  359. var $more = $('<li><a href="javascript:" title="#title#">#title#</a></li>'.replaceAll('#title#', options.title))
  360. $tab.appendTo($tabs)
  361. $panel.appendTo($panels)
  362. $more.appendTo($moreBox)
  363. $tab.data('options', options).data('initOptions', options)
  364. if (options.external || (options.url && options.url.isExternalUrl())) {
  365. $tab.addClass('external')
  366. this.openExternal(options.url, $panel)
  367. } else {
  368. $tab.removeClass('external')
  369. tools.reloadTab($panel, options)
  370. }
  371. currentIndex = tools.getTabs().length - 1
  372. this.contextmenu($tab)
  373. //events
  374. $tab.on('click', function(e) {
  375. var $target = $(e.target)
  376. if ($target.hasClass('close'))
  377. that.closeTab(options.id)
  378. else if ($target.closest('li').hasClass('active'))
  379. return false
  380. else
  381. that.switchTab(options.id)
  382. })
  383. $more.on('click', function() {
  384. that.switchTab(options.id)
  385. })
  386. }
  387. tools.switchTab(currentIndex)
  388. tools.scrollCurrent()
  389. }
  390. Navtab.prototype.closeTab = function(tabid) {
  391. var index = this.tools.indexTabId(tabid)
  392. if (index > 0)
  393. this.tools.closeTab(index)
  394. }
  395. Navtab.prototype.closeCurrentTab = function(openTabid) { //openTabid can be empty. close current tab by default, and open the last tab
  396. if (currentIndex > 0)
  397. this.tools.closeTab(currentIndex, openTabid)
  398. }
  399. Navtab.prototype.closeAllTab = function() {
  400. this.tools.getTabs().find('> .close').each(function() {
  401. $(this).trigger('click')
  402. })
  403. }
  404. Navtab.prototype.reloadFlag = function(tabids) {
  405. var arr = tabids.split(',')
  406. for (var i = 0; i < arr.length; i++) {
  407. var $tab = this.tools.getTab(arr[i].trim())
  408. if ($tab) {
  409. if (this.tools.indexTabId(arr[i]) == currentIndex) this.tools.reload($tab, true)
  410. else $tab.data('reloadFlag', true)
  411. }
  412. }
  413. }
  414. Navtab.prototype.switchTab = function(tabid) {
  415. var index = this.tools.indexTabId(tabid)
  416. this.tools.switchTab(index)
  417. }
  418. Navtab.prototype.scrollPrev = function() {
  419. this.tools.scrollPrev()
  420. }
  421. Navtab.prototype.scrollNext = function() {
  422. this.tools.scrollNext()
  423. }
  424. Navtab.prototype.refresh = function(tabid) {
  425. var $tab, $panel
  426. if (!tabid) {
  427. $tab = $currentTab
  428. } else if (typeof tabid == 'string') {
  429. $tab = this.tools.getTab(tabid)
  430. } else {
  431. $tab = tabid
  432. }
  433. if ($tab && $tab.length) {
  434. $panel = this.tools.getPanel($tab.data('initOptions').id)
  435. $panel.removeData('bjui.clientPaging')
  436. this.reload($tab.data('initOptions'))
  437. }
  438. }
  439. Navtab.prototype.reload = function(option, initOptionFlag) {
  440. var that = this
  441. var options = $.extend({}, typeof option == 'object' && option)
  442. var $tab = options.id ? this.tools.getTab(options.id) : this.tools.getTabs().eq(currentIndex)
  443. if ($tab) {
  444. var initOptions = $tab.data('initOptions') || {}, op = $.extend({}, initOptions, options)
  445. var _reload = function() {
  446. if (initOptions.title != op.title) $tab.find('> a').attr('title', op.title).find('> span').html(op.title)
  447. if (!initOptionFlag) $tab.data('initOptions', op)
  448. $tab.data('options', op)
  449. that.tools.reload($tab, true)
  450. }
  451. if (options.reloadWarn) {
  452. this.$element.alertmsg('confirm', options.reloadWarn, {
  453. okCall: function() {
  454. _reload()
  455. }
  456. })
  457. } else {
  458. _reload()
  459. }
  460. }
  461. }
  462. Navtab.prototype.reloadForm = function(clearQuery, option) {
  463. var options = $.extend({}, typeof option == 'object' && option)
  464. var $tab, $panel
  465. if (typeof option == 'string') {
  466. $tab = this.tools.getTab(option)
  467. $panel = this.tools.getPanel(option)
  468. } else {
  469. $tab = options.id ? this.tools.getTab(options.id) : this.tools.getTabs().eq(currentIndex)
  470. $panel = options.id ? this.tools.getPanel(options.id) : this.tools.getPanels().eq(currentIndex)
  471. }
  472. if ($tab && $panel) {
  473. if (!$tab.hasClass('external')) {
  474. var $pagerForm = $panel.find('#pagerForm'), data = {}, pageData = {}
  475. if ($pagerForm.attr('action')) options.url = $pagerForm.attr('action')
  476. if ($pagerForm && $pagerForm.length) {
  477. pageData = $pagerForm.serializeJson()
  478. if (!option || !option.type) options.type = $pagerForm.attr('method') || 'POST'
  479. if (clearQuery) {
  480. var pageInfo = BJUI.pageInfo
  481. for (var key in pageInfo) {
  482. data[pageInfo[key]] = pageData[pageInfo[key]]
  483. }
  484. } else {
  485. data = pageData
  486. }
  487. options.data = $.extend({}, options.data || {}, data)
  488. }
  489. }
  490. this.reload(options, true)
  491. }
  492. }
  493. Navtab.prototype.getCurrentPanel = function() {
  494. return this.tools.getPanels().eq(currentIndex)
  495. }
  496. Navtab.prototype.checkTimeout = function() {
  497. var json = JSON.parse($currentPanel.html())
  498. if (json && json[BJUI.keys.statusCode] == BJUI.statusCode.timeout) this.closeCurrentTab()
  499. }
  500. Navtab.prototype.openExternal = function(url, $panel) {
  501. var ih = $panel.closest('.navtab-panel').height()
  502. $panel.html(FRAG.externalFrag.replaceAll('{url}', url).replaceAll('{height}', ih +'px'))
  503. }
  504. // NAVTAB PLUGIN DEFINITION
  505. // =======================
  506. function Plugin(option) {
  507. var args = arguments
  508. var property = option
  509. return this.each(function () {
  510. var $this = $(this)
  511. var options = $.extend({}, Navtab.DEFAULTS, typeof option == 'object' && option)
  512. var data = $this.data('bjui.navtab')
  513. if (!data) $this.data('bjui.navtab', (data = new Navtab(this, options)))
  514. if (typeof property == 'string' && $.isFunction(data[property])) {
  515. [].shift.apply(args)
  516. if (!args) data[property]()
  517. else data[property].apply(data, args)
  518. } else {
  519. data = new Navtab(this, options)
  520. data.openTab()
  521. }
  522. })
  523. }
  524. var old = $.fn.navtab
  525. $.fn.navtab = Plugin
  526. $.fn.navtab.Constructor = Navtab
  527. // NAVTAB NO CONFLICT
  528. // =================
  529. $.fn.navtab.noConflict = function () {
  530. $.fn.navtab = old
  531. return this
  532. }
  533. // NAVTAB DATA-API
  534. // ==============
  535. $(document).on('click.bjui.navtab.data-api', '[data-toggle="navtab"]', function(e) {
  536. var $this = $(this), href = $this.attr('href'), data = $this.data(), options = data.options
  537. if (options) {
  538. if (typeof options == 'string') options = options.toObj()
  539. if (typeof options == 'object')
  540. $.extend(data, options)
  541. }
  542. if (!data.title) data.title = $this.text()
  543. if (href && !data.url) data.url = href
  544. Plugin.call($this, data)
  545. e.preventDefault()
  546. })
  547. }(jQuery);