Opened 11 years ago

Closed 11 years ago

Last modified 9 years ago

#8637 closed bug (notabug)

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.

Change History (13)

comment:1 Changed 11 years ago by rxcheng

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

comment:2 Changed 11 years ago by Scott González

Resolution: invalid
Status: newclosed

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

comment:3 Changed 11 years ago by webzter

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.

Version 0, edited 11 years ago by webzter (next)

comment:4 Changed 11 years ago by 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);
};
Last edited 11 years ago by oz0ne (previous) (diff)

comment:5 Changed 11 years ago by Scott González

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.

comment:6 Changed 11 years ago by oz0ne

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.

comment:7 in reply to:  5 ; Changed 11 years ago by royshoa

Replying to 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?

comment:8 in reply to:  7 Changed 11 years ago by Scott González

Replying to 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.

comment:9 Changed 11 years ago by blesh

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>
Last edited 11 years ago by blesh (previous) (diff)

comment:10 Changed 11 years ago by Scott González

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.

comment:11 in reply to:  10 ; Changed 11 years ago by blesh

Replying to 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.

comment:12 in reply to:  11 Changed 11 years ago by Scott González

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

comment:13 in reply to:  4 Changed 9 years ago by dwd

Replying to 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);
};

Note: See TracTickets for help on using tickets.