1!function ($) { 2 3 // Namespace 4 if (!$.jalios) { $.jalios = {}; } 5 if (!$.jalios.ui) { $.jalios.ui = {}; } 6 7 8 // ------------------------------------------ 9 // PRIVATE 10 // ------------------------------------------ 11 12 var register = function(){ 13 14 // Activate click on tabs 15 $(document).on('click', '.nav-tabs > LI > A, .nav-tabs .tabdrop .dropdown-menu > LI > A', click); 16 $(document).on('click', '.widget .nav-pills > LI > A, .widget .nav-pills .tabdrop .dropdown-menu > LI > A', clickFieldGroup); 17 18 // Register on Ajax-Refresh 19 $(document).on('jalios:refresh', refresh); 20 21 // Upgrade old tabpane 22 upgrade(); 23 24 $(document).on("jalios:field", addedFieldHandler); 25 } 26 27 /** 28 * Perform upgrade with an Ajax-Refresh 29 */ 30 var refresh = function(event){ 31 32 var refresh = $.jalios.Event.match(event, 'refresh', 'after') 33 if (!refresh){ return; } 34 if (!refresh.target){ return; } 35 36 refresh.target.each(function(){ 37 upgrade(this); 38 }); 39 }; 40 41 /** 42 * Handle click on tabpane 43 */ 44 var click = function(evt){ 45 var $e = $(evt.currentTarget); 46 if ($e.attr('href') 47 && ($e.attr('href').indexOf('#') < 0 || $e.attr('href') === "#")){ // Should test base# ? 48 return; 49 } 50 51 52 if($e.is('button, [role=button]')){ 53 return; 54 } 55 56 // Handle nav-static 57 var $nav = $e.closest('.nav-tabs'); 58 if ($nav.hasClass('nav-static')){ 59 return; 60 } 61 62 evt.preventDefault(); 63 $e.tab('show'); 64 65 // Fast hack to retrieve target 66 var selector = $e.attr('href'); // JsChecker.authorize(".attr('href')") 67 selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 68 69 // Fire an event 70 var event = jQuery.Event("jalios:tab"); 71 event.tab = { 72 trigger : $e, 73 pane : $(selector) 74 }; 75 $(document).trigger(event); 76 } 77 78 const addedFieldHandler = function(event){ 79 if(!event.field || !event.field.type){ 80 return; 81 } 82 if(event.field.type !== "addedField"){ 83 return; 84 } 85 86 if(event.field && event.field.clones && event.field.clones[1]){ 87 displayFieldGroupDeleteTabButton($(event.field.clones[1])); 88 89 90 91 92 } 93 } 94 95 96 97 98 99 const deleteTabGroupListItemClickHandler = function(event){ 100 if($(event.currentTarget).closest(".ui-sortable-helper").length > 0){ 101 return; 102 } 103 // Remove all tabs with same fieldGroup 104 const fieldGroup = $(event.currentTarget).closest(".tab-group-list-item >a").data("jalios-fieldgroup"); 105 if(!fieldGroup){ 106 return; 107 } 108 109 // Remove all active element of this fieldGroup 110 let futureGroupFieldToActivate = undefined; 111 $("A[data-jalios-fieldgroup=" + fieldGroup + "]").each(function(index, element){ 112 const $tabGroupList = $(element).closest(".tab-group-list"); 113 114 // Retrieve input list 115 const $inputList = $(element).closest(".widget-content").find(".input-group-list"); 116 117 // Get active tab & input 118 const $activeTabAndInput = $(element).closest(".widget-content").find("li.active"); 119 // Calculate next tab to focus (next if any, otherwhise previous one) 120 if(!futureGroupFieldToActivate){ 121 let $futureTabToActivate = $activeTabAndInput.next(); 122 123 if($futureTabToActivate.length === 0){ 124 $futureTabToActivate = $activeTabAndInput.prev().first(); 125 futureGroupFieldToActivate = $futureTabToActivate.find(" >a").data("jalios-fieldgroup"); 126 }else{ 127 futureGroupFieldToActivate = fieldGroup; 128 } 129 } 130 // Now remove active tab 131 $activeTabAndInput.remove(); 132 $.jalios.ui.renumberTabs($tabGroupList, $inputList); 133 134 135 }); 136 137 showAllFieldGroupTabs(futureGroupFieldToActivate); 138 139 } 140 141 $.jalios.ui.renumberTabs = function($tabList, $inputList){ 142 /* RENUMBER */ 143 144 // Renumber in tab elements 145 $tabList.find('.tab-group-list-item').each(function(index, element) { 146 const $this = $(this); 147 148 // href attribute 149 const $link = $this.children(); 150 const href = $link.attr('href'); // JsChecker.authorize(".attr('href')") 151 const newId = href.substring(0, href.lastIndexOf('_') + 1) + index; 152 $link.attr('href', newId).html(index + 1); 153 154 // 'data-jalios-fieldgroup' attribute 155 const fieldGroup = $link.data('jalios-fieldgroup'); 156 if(fieldGroup) { 157 const fieldGroupId = fieldGroup.substring(0, fieldGroup.lastIndexOf('_') + 1) + index; 158 $link.data('jalios-fieldgroup', fieldGroupId); 159 $link.attr('data-jalios-fieldgroup', fieldGroupId); 160 } 161 }); 162 displayFieldGroupDeleteTabButton($tabList.find(".tab-group-list-item.active")); 163 164 // Renumber in input list 165 $inputList.find('.input-group-list-item').each(function(index) { 166 const $this = $(this); 167 const id = $this.attr('id'); 168 const newId = id.substring(0, id.lastIndexOf('_') + 1) + index; 169 $this.attr('id', newId); 170 }); 171 } 172 173 const displayFieldGroupDeleteTabButton = function($tabGroupListItem){ 174 // Prevent to display delete button if only one item is left 175 if($tabGroupListItem.closest(".tab-group-list").find(">li").length === 1){ 176 return; 177 } 178 179 const fieldGroup = $tabGroupListItem.find(" >a").data("jalios-fieldgroup"); 180 if(!fieldGroup){ 181 return; 182 } 183 184 const $tabGroupList = $tabGroupListItem.closest(".tab-group-list"); 185 if($tabGroupList.length === 0){ 186 return; 187 } 188 189 $tabGroupList.find(".tab-group-list-item__delete").remove(); 190 if($("#hb-tab-group-list-item__delete").length > 0){ 191 const btnDeleteTemplate = Handlebars.compile($("#hb-tab-group-list-item__delete").html()); 192 const $btnDelete = $(btnDeleteTemplate()); 193 $tabGroupList.find(".tab-group-list-item.active > a").append($btnDelete); 194 $btnDelete.on("click", deleteTabGroupListItemClickHandler); 195 } 196 } 197 198
199 const showAllFieldGroupTabs = function(fieldGroup){ 200 $("A[data-jalios-fieldgroup=" + fieldGroup + "]").each(function(index, element){ 201 $(element).tab("show"); 202 displayFieldGroupDeleteTabButton($(element).closest(".tab-group-list-item")); 203 }); 204 } 205 206 /** 207 * Handle click on fieldgroup tab 208 */ 209 const clickFieldGroup = function(evt) { 210 evt.preventDefault(); 211 212 const $e = $(evt.currentTarget); 213 const fieldGroup = $e.data("jalios-fieldgroup"); 214 215 if (fieldGroup) { 216 showAllFieldGroupTabs(fieldGroup); 217 }else{ 218 $e.tab("show"); 219 } 220 } 221 222 /** 223 * DuckTape for old tabpane 224 */ 225 var upgrade = function(context){ 226 227 // Tabdrop 228 $(context || document).find('.nav-pills, .nav-tabs').not('.no-tab-drop').tabdrop({'text' : '<span class="fa fa-bars"></span>'}); 229 230 // Replace old tab layout by bootstrap tabs 231 $(context || document).find('.tab-pane').each(function(){ 232 233 var $this = $(this); 234 235 // Retrieve all tabs 236 var $tab = $(this).children('.tab-page').children('.tab'); 237 if (!$tab.exists()){ return; } 238 239 // CSS: .tab-pane => .tab-content 240 $this.addClass('tab-content').removeClass('tab-pane'); 241 242 // Set an id to each tabs 243 $tab.each(function(idx){ 244 245 var active = idx == 0 ? ' active' : ''; 246 247 // CSS: .tab-page => .tab-pane + id 248 var id = $(this).closest('.tab-page').addClass('tab-pane').addClass(active).removeClass('tab-page').identify().attr('id'); 249 250 // Wrap innerHTML into a link 251 var html = '<a href="#'+id+'">'+this.innerHTML+'</a>'; 252 253 254 // Check if it has already link 255 var $ahref = $(this).find('A').first(); 256 if ($ahref.exists()){ 257 $ahref.attr('href','#'+id); 258 html = this.innerHTML; 259 } 260 261 // Convert to LI 262 $(this).replaceWith($('<li class="tab'+active+'">'+html+'</li>')); 263 }); 264 265 // Insert UL before component and append $tab 266 if ($this.hasClass("tab-old-style")) { 267 $tab = $('<ul class="nav nav-tabs br"></ul>').insertBefore($this).append($('.tab-pane > .tab', this)); 268 } else { 269 $tab = $('<ul class="nav nav-tabs nav-tabs-underlined is-left-aligned br"></ul>').insertBefore($this).append($('.tab-pane > .tab', this)); 270 } 271 272 // Hook: Insert into tab-pane-anchor the Ul of .mainTab 273 if ($this.attr('id') == 'mainTab' && $('#tab-pane-anchor').exists()){ 274 $('#tab-pane-anchor').append($tab); 275 } 276 }); 277 278 // Add Bootstrap classes for inner-tabs 279 $('.inner-tabs', context || document).each(function(){ 280 $(this).find('> UL').addClass('nav nav-tabs nav-static').find('LI').addClass('tab').filter('.enabled').removeClass('enabled').addClass('active'); 281 }); 282 283 $(".tab-group-list-item.active").each(function(index, element){ 284 displayFieldGroupDeleteTabButton($(element)); 285 }); 286 } 287 288 // ------------------------------------------ 289 // PUBLIC 290 // ------------------------------------------ 291 292 /** 293 * <p> 294 * Convenient library to transform 295 * <ul> 296 * <li>old Jalios Tabs (tabpane.js) to new Bootstrap tabs.</li> 297 * <li>old inner-tabs to new Bootstrap tabs.</li> 298 * </ul> 299 * Fires an event <code>jalios:tab</code> when a tab is opened. 300 * </p> 301 * 302 * <h5>Deprecated</h5> 303 * 304 * The function setSelectedTab() is deprecated. Users should relies on Bootstrap functions:<br/> 305 * <code>$('#id A:nth-child(2)').tab('show');</code> 306 * 307 * @namespace $.jalios.ui.Tab 308 * @copyright Jalios SA 309 * 310 * @unittest js/tests/jalios/core/jalios-tab.html 311 * 312 */ 313 $.jalios.ui.Tab = { 314 315 /** 316 * Upgrade old <code>tabpane</code> to new bootstrap tabs. 317 * 318 * @param {element} context the page context to upgrade (optional) 319 */ 320 'upgrade': upgrade, 321 }; 322 323 // Plugin initialization on DOM ready 324 $(document).ready(function($) { 325 register(); 326 }); 327 328}(window.jQuery); 329 330 331// ------------------------------------------ 332// DEPRECATED 333// ------------------------------------------ 334 335 336// Backward compatibility with tabpane.js 337// @param tabPaneId the tabpane id 338// @param index the tab index 339// 340// @deprecated use $selector.tab('show') instead 341 342function setSelectedTab(tabPaneId, index) { 343 var $elm = jQuery("#"+tabPaneId); 344 var $navTabs; 345 // manage old tab legacy 346 if($elm.hasClass("tab-content")){ 347 $navTabs = $elm.parent().find('> UL.nav-tabs'); 348 } 349 else{ 350 $navTabs = $elm.find('UL.nav-tabs') 351 } 352 if(!$navTabs.exists()){ 353 $navTabs = $elm.closest('FORM').find('UL.nav-tabs'); 354 } 355 availableLi = $navTabs.find('>LI'); 356 availableLi.filter(function( tmpIndex ) { 357 return !(jQuery(this).hasClass("dropdown")); 358 }).filter(function( tmpIndex ) { 359 return tmpIndex===index; 360 }).find('A').tab('show'); 361} 362 363// Deprecated fallback for Prototype ajax-refresh 364if (Event.observe){ 365 Event.observe(document, 'refresh:after', function(event){ 366 if (event && event.memo && event.memo.wrapper){ 367 var elm = document.getElementById(event.memo.wrapper); 368 jQuery.jalios.ui.Tab.upgrade(elm); 369 } 370 }) 371} 372 373// Deprecated fallback for Prototype tabpane:change 374jQuery(document).on('jalios:tab', function(event){ 375 document.fire('tabpane:change', { tabPage: event.tab.trigger.identify().attr('id') }); 376}); 377 378
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.