Skip to content

Commit

Permalink
Fix URL anchors not selecting tabs
Browse files Browse the repository at this point in the history
For example `/admin/security/EditForm/field/Members/item/1/edit#Root_Permissions` should open the Permissions tab.

Resolves #911 - #911
  • Loading branch information
bergice authored and emteknetnz committed Sep 3, 2020
1 parent d8ab245 commit 0e89d48
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 76 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

161 changes: 86 additions & 75 deletions client/src/legacy/TabSet.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,100 +8,111 @@ require('../../../thirdparty/jquery-entwine/dist/jquery.entwine-dist.js');
// require('../../../thirdparty/jquery-ui-themes/smoothness/jquery-ui.css');

$.entwine('ss', function($){
/**
* Lightweight wrapper around jQuery UI tabs for generic tab set-up
*/
$('.ss-tabset').entwine({
IgnoreTabState: false,

onadd: function() {
var hash = window.location.hash;

this.on("tabsactivate", (function (event, {newPanel}) {
this.lazyLoadGridFields(newPanel);
}).bind(this))
$('.ss-tabset, .cms-tabset').entwine({
onmatch: function () {
var hash = window.location.hash;
if (hash !== '') {
this.openTabFromURL(hash);
}

this._super();
},

/**
* @func openTabFromURL
* @param {string} hash
* @desc Allows linking to a specific tab.
*/
openTabFromURL: function (hash) {
var $trigger;

// Make sure the hash relates to a valid tab.
$.each(this.find('.ui-tabs-anchor'), function () {
// The hash in in the button's href and there is exactly one tab with that id.
if (this.href.indexOf(hash) !== -1 && $(hash).length === 1) {
$trigger = $(this);
return false; // break the loop
}
});

// If there's no tab, it means the hash is invalid, so do nothing.
if ($trigger === void 0) {
return;
}

// Switch to the correct tab when the page is loaded
$(() => {
$trigger.click();
});
},

}),

/**
* Lightweight wrapper around jQuery UI tabs for generic tab set-up
*/
$('.ss-tabset').entwine({
IgnoreTabState: false,

onadd: function() {
this.on("tabsactivate", (function (event, {newPanel}) {
this.lazyLoadGridFields(newPanel);
}).bind(this));
this.on("tabscreate", (function(event, {panel}) {
this.lazyLoadGridFields(panel);
}).bind(this));

// Can't name redraw() as it clashes with other CMS entwine classes
this.redrawTabs();

if (hash !== '') {
this.openTabFromURL(hash);
}

this._super();
},
// Can't name redraw() as it clashes with other CMS entwine classes
this.redrawTabs();
this._super();
},

onremove: function() {
if(this.data('tabs')) this.tabs('destroy');
this._super();
},
onremove: function() {
if(this.data('tabs')) this.tabs('destroy');
this._super();
},

redrawTabs: function() {
this.rewriteHashlinks();
this.tabs();
// If accessing a tabset from a page in the CMS module
// alter how the tabs are rendered
if ($(this).hasClass('ss-tabset')) {
this.rewriteHashlinks();
this.tabs()
} else {
this._super();
}
},

/**
* @func openTabFromURL
* @param {string} hash
* @desc Allows linking to a specific tab.
*/
openTabFromURL: function (hash) {
var $trigger;

// Make sure the hash relates to a valid tab.
$.each(this.find('.ui-tabs-anchor'), function () {
// The hash in in the button's href and there is exactly one tab with that id.
if (this.href.indexOf(hash) !== -1 && $(hash).length === 1) {
$trigger = $(this);
return false; // break the loop
}
});

// If there's no tab, it means the hash is invalid, so do nothing.
if ($trigger === void 0) {
return;
}

// Switch to the correct tab when AJAX loading completes.
$(document).ready('ajaxComplete', function () {
$trigger.click();
});
},

/**
* @func rewriteHashlinks
* @desc Ensure hash links are prefixed with the current page URL, otherwise jQuery interprets them as being external.
*/
rewriteHashlinks: function() {
$(this).find('ul a').each(function() {
if (!$(this).attr('href')) return;

var matches = $(this).attr('href').match(/#.*/);
if(!matches) return;
$(this).attr('href', document.location.href.replace(/#.*/, '') + matches[0]);
});
},
/**
* @func rewriteHashlinks
* @desc Ensure hash links are prefixed with the current page URL, otherwise jQuery interprets them as being external.
*/
rewriteHashlinks: function() {
$(this).find('ul a').each(function() {
if (!$(this).attr('href')) return;

var matches = $(this).attr('href').match(/#.*/);
if(!matches) return;
$(this).attr('href', document.location.href.replace(/#.*/, '') + matches[0]);
});
},

/**
* @func lazyLoadGridFields
* @desc Find all the lazy loadable gridfield in the panel and trigger their reload.
* @param {Object} panel
*/
lazyLoadGridFields: function(panel) {
panel.find('.grid-field--lazy-loadable').each((i, el) => {
const gridfield = $(el);
// Avoid triggering all gridfields when using nested tabs
if (gridfield.closest('.ss-tabset').is(this)) {
$(el).lazyload();
lazyLoadGridFields: function(panel) {
panel.find('.grid-field--lazy-loadable').each((i, el) => {
const gridfield = $(el);
// Avoid triggering all gridfields when using nested tabs
if (gridfield.closest('.ss-tabset, .cms-tabset').is(this)) {
$(el).lazyload();
}
});
}

});
});

// adding bootstrap theme classes to corresponding jQueryUI elements
$('.ui-tabs-active .ui-tabs-anchor').entwine({
Expand Down

0 comments on commit 0e89d48

Please sign in to comment.