Ticket #8637 (closed bug: notabug)

Opened 2 years ago

Last modified 11 months ago

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:
Blocking: Blocked by:

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

comment:1 Changed 2 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 2 years ago by scott.gonzalez

  • Status changed from new to closed
  • Resolution set to invalid

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

comment:3 Changed 2 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.

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

comment:4 follow-up: ↓ 13 Changed 2 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 2 years ago by oz0ne (previous) (diff)

comment:5 follow-up: ↓ 7 Changed 2 years ago by 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.

comment:6 Changed 2 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 ; follow-up: ↓ 8 Changed 2 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 2 years ago by scott.gonzalez

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 23 months 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 23 months ago by blesh (previous) (diff)

comment:10 follow-up: ↓ 11 Changed 23 months ago by scott.gonzalez

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 ; follow-up: ↓ 12 Changed 23 months 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 23 months ago by scott.gonzalez

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

comment:13 in reply to: ↑ 4 Changed 11 months 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.