Skip to main content

Search and Top Navigation

#8637 closed bug (notabug)

Opened October 09, 2012 02:02AM UTC

Closed October 09, 2012 12:20PM UTC

Last modified December 05, 2013 03:27PM UTC

ui.tabs with <base> tag

Reported by: rxcheng Owned by:
Priority: minor Milestone: 1.9.1
Component: ui.tabs Version: 1.9.0
Keywords: Cc:
Blocked by: Blocking:
Description

With 1.9.0, if a <base> tag is present in the <head> section, local tabs load the content of the base URL, instead of the content of the referred div.


<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <base href="http://example.com/" />
    <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css" />
    <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
    <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    <script>
    $(function() {
        $('#tabs').tabs();
    });
    </script>
</head>
<body>
  <div id="tabs">
    <ul>
      <li><a href="#tab-1">Tab 1</a></li>
      <li><a href="#tab-2">Tab 2</a></li>
    </ul>
    <div id="tab-1">Content of Tab 1</div>
    <div id="tab-2">Content of Tab 2</div>
  </div>
</body>
</html>

Please note: to reproduce this issue, the href URL needs to be the same domain where this HTML file is located.

This is not an issue with 1.8.x.

Attachments (0)
Change History (13)

Changed October 09, 2012 02:06AM UTC by rxcheng comment:1

FYI, the <base> tag is a common trick for referencing static content for MVC frameworks such as CodeIgniter supporting URL segments like /product/view/id/9

Changed October 09, 2012 12:20PM UTC by scottgonzalez comment:2

resolution: → invalid
status: newclosed

FYI, the base href applies to everything. Those are not local tabs. They're pointing to the base href.

Changed October 18, 2012 04:59PM UTC by webzter comment:3

_comment0: It looks like this might be similar to #4941 (Mishandling of base tag), which was fixed in 1.8a1 \ \ We use the base tag on our site as well. Tabs worked perfectly in 1.8 but broke with the change to 1.9. We're exploring a work-around but this is a new behavior that, for better or worse, wasn't expected.1350581048496509
_comment1: It looks like this might be similar to #4941 (Mishandling of base tag), which was fixed in 1.8a1 \ \ We use the base tag on our site as well. Tabs worked perfectly in 1.8 but broke with the change to 1.9. We're exploring a work-around but this is a new behavior that, for better or worse, wasn't expected. \ \ edit: Our workaround was to append the current page's full url in front of the hash link for each tab. \ \ if base is http://mysite.com/theme then the code becomes \ \ {{{ \ <div id="tabs"> \ <ul> \ <li><a href="http://mysite.com/theme#tab-1">Tab 1</a></li> \ <li><a href="http://mysite.com/theme#tab-2">Tab 2</a></li> \ </ul> \ <div id="tab-1">Content of Tab 1</div> \ <div id="tab-2">Content of Tab 2</div> \ </div> \ }}}1350583552576943

It looks like this might be similar to #4941 (Mishandling of base tag), which was fixed in 1.8a1

We use the base tag on our site as well. Tabs worked perfectly in 1.8 but broke with the change to 1.9. We're exploring a work-around but this is a new behavior that, for better or worse, wasn't expected.

edit: Our workaround was to append the current page's full url in front of the hash link for each tab.

if base is http://mysite.com/theme

and current page is http://mysite.com/site

then the code becomes

<div id="tabs">
    <ul>
      <li><a href="http://mysite.com/site#tab-1">Tab 1</a></li>
      <li><a href="http://mysite.com/site#tab-2">Tab 2</a></li>
    </ul>
    <div id="tab-1">Content of Tab 1</div>
    <div id="tab-2">Content of Tab 2</div>
  </div>

Changed October 25, 2012 11:01AM UTC by oz0ne comment:4

_comment0: I wrote a small solution that helps to fix this bug. Just add this javascript code before any usages of tabs. \ \ {{{ \ // ***** BUGFIX for jQuery Tabs ***** // \ $.fn.__tabs = $.fn.tabs; \ $.fn.tabs = function (a, b, c, d, e, f) { \ var base = location.href.replace(/#.*$/, ''); \ $('ul>li>a[href^="#"]', this).each(function () { \ var href = $(this).attr('href'); \ $(this).attr('href', base + href); \ }); \ $(this).__tabs(a, b, c, d, e, f); \ }; \ }}}1351163000939896
_comment1: I wrote a small solution that helps to fix this bug. Just add this javascript code before any usages of tabs. With this patch you can use tabs as always, without changing anchors to full URL. \ \ {{{ \ // ***** BUGFIX for jQuery Tabs ***** // \ $.fn.__tabs = $.fn.tabs; \ $.fn.tabs = function (a, b, c, d, e, f) { \ var base = location.href.replace(/#.*$/, ''); \ $('ul>li>a[href^="#"]', this).each(function () { \ var href = $(this).attr('href'); \ $(this).attr('href', base + href); \ }); \ $(this).__tabs(a, b, c, d, e, f); \ }; \ }}}1351169565341265
_comment2: I wrote a small solution that helps to avoid this bug. Just add this javascript code before any usages of tabs. With this code you can use tabs as always, without changing anchors to full URL. \ \ {{{ \ // ***** HACK for jQuery Tabs ***** // \ $.fn.__tabs = $.fn.tabs; \ $.fn.tabs = function (a, b, c, d, e, f) { \ var base = location.href.replace(/#.*$/, ''); \ $('ul>li>a[href^="#"]', this).each(function () { \ var href = $(this).attr('href'); \ $(this).attr('href', base + href); \ }); \ $(this).__tabs(a, b, c, d, e, f); \ }; \ }}}1351169586314226

I wrote a small solution that helps to avoid this bug. Just add this javascript code before any usages of tabs. With this code you can use tabs as always, without changing anchors to full URL.

$.fn.__tabs = $.fn.tabs;
$.fn.tabs = function (a, b, c, d, e, f) {
	var base = location.href.replace(/#.*$/, '');
	$('ul>li>a[href^="#"]', this).each(function () {
		var href = $(this).attr('href');
		$(this).attr('href', base + href);
	});
	$(this).__tabs(a, b, c, d, e, f);
};

Changed October 25, 2012 11:12AM UTC by scottgonzalez comment:5

That's not a bug fix, it's a hack to make improper markup bend to your will. You should really fix your markup because right now your pages are broken if the user has JavaScript turned off (or they're on a flaky connection and the JS hasn't loaded yet), or if there's an error in your code which prevents the tabs from being initialized.

Changed October 25, 2012 12:51PM UTC by oz0ne comment:6

Yes, I know this doesn't fix the bug, but only eliminates the need to change hash links.

I made this for my project that won't work without javascript enabled, so I didn't bother about it. I think someone will find this code useful for himself.

Changed November 18, 2012 08:53AM UTC by royshoa comment:7

Replying to [comment:5 scott.gonzalez]:

That's not a bug fix, it's a hack to make improper markup bend to your will. You should really fix your markup because right now your pages are broken if the user has JavaScript turned off (or they're on a flaky connection and the JS hasn't loaded yet), or if there's an error in your code which prevents the tabs from being initialized.

I am having the same problem, Did you find a better solution?

Changed November 18, 2012 06:06PM UTC by scottgonzalez comment:8

Replying to [comment:7 royshoa]:

I am having the same problem, Did you find a better solution?

This is the last time I will say this. There is no bug. The only legitimate solution is to fix your markup.

Changed November 29, 2012 08:33PM UTC by blesh comment:9

_comment0: I'm pretty unimpressed by the handling of this. It may not be a "bug" to you, but there is certainly room for improvement/enhancement. \ \ I've inherited an application that uses <base> to point hrefs, srcs, and AJAX calls to the right locations due to the same app running in multiple locations, often in virtual directories. I'd have to go through and change THOUSANDS of hrefs and src to fix this. It seems that maybe an alternative method of registering local tabs that overrides the other method might be nice for people in my boat. \ \ For example.. \ \ {{{ \ <li><a href="#whatever" data-tabid="whatever">foo</a></li> \ }}}1354221423733583

It may not be a "bug" to you, but there is certainly room for improvement/enhancement.

I've inherited an application that uses <base> to point hrefs, srcs, and AJAX calls to the right locations due to the same app running in multiple locations, often in virtual directories. I'd have to go through and change THOUSANDS of hrefs and src to fix this. It seems that maybe an alternative method of registering local tabs that overrides the other method might be nice for people in my boat.

For example..

<li><a href="#whatever" data-tabid="whatever">foo</a></li>

Changed November 29, 2012 08:48PM UTC by scottgonzalez comment:10

If you want your server to send broken URLs, take 5 minutes and write some JavaScript that fixes your URLs prior to calling .tabs(). It'll only be a few lines of code.

Changed November 29, 2012 10:34PM UTC by blesh comment:11

Replying to [comment:10 scott.gonzalez]:

If you want your server to send broken URLs

I don't *want* that... I'm stuck with what I've inherited.

take 5 minutes and write some JavaScript that fixes your URLs prior to calling .tabs(). It'll only be a few lines of code.

You're clearly a bit annoyed about this particular issue. I'm not trying to bother you, I'm trying to help other people, which is what open source is supposed to be about. I put in a pull request with a workaround: https://github.com/jquery/jquery-ui/pull/853

You've made a great tool, thank you for your work.

Changed November 29, 2012 10:55PM UTC by scottgonzalez comment:12

jQuery is about enforcing standards and best practices over hacks and breaking the web...

Changed December 05, 2013 03:27PM UTC by dwd comment:13

Replying to [comment:4 oz0ne]:

I wrote a small solution that helps to avoid this bug. Just add this javascript code before any usages of tabs. With this code you can use tabs as always, without changing anchors to full URL.
> $.fn.__tabs = $.fn.tabs;
> $.fn.tabs = function (a, b, c, d, e, f) {
> 	var base = location.href.replace(/#.*$/, '');
> 	$('ul>li>a[href^="#"]', this).each(function () {
> 		var href = $(this).attr('href');
> 		$(this).attr('href', base + href);
> 	});
> 	$(this).__tabs(a, b, c, d, e, f);
> };
> 

I use the tabs in a dialog, dynamicly loaded by ajax and location.href returns the location of the ajax call (Firefox).

See http://stackoverflow.com/questions/4709037/window-location-versus-just-location

I recommend you to use window.location

$.fn.__tabs = $.fn.tabs;
$.fn.tabs = function (a, b, c, d, e, f) {
	var base = window.location.href.replace(/#.*$/, '');
	$('ul>li>a[href^="#"]', this).each(function () {
		var href = $(this).attr('href');
		$(this).attr('href', base + href);
	});
	$(this).__tabs(a, b, c, d, e, f);
};