jQuery UI Tabs: URL instead of AJAX does not work properly - jquery-ui

I wrote like there: http://jqueryui.com/demos/tabs/#...follow_a_tab.27s_URL_instead_of_loading_its_content_via_ajax
<script type="text/javascript">
$(function(){
$("#tabs").tabs({
select: function(event, ui) {
var url = $.data(ui.tab, 'load.tabs');
if( url ) {
location.href = url;
return false;
}
return true;
}
});
});
</script>
<div id="tabs">
<ul>
<li>
Home
</li>
<li>
About
</li>
</ul>
</div>
Tabs are created, but initial list (div, ul, li) is visible as well. Another problem: when I hover over tab, I see URL kind of /default.htm#ui-tabs-1, /default.htm#ui-tabs-2 etc. But I want to see URL "/default.htm" over the 1st tab and URL "/about.htm" over the 2nd tab.
What could I do to solve my problem?
UPDATE
In version 1.9 there is powerful widget "menu".

You are miss interpreting the jQuery UI Tabs.
This Tabs are for having content hide/show and if using ajax pull the page info and show it on demand.
if you want those tabs to act as a menu ... then you need a menu, not the jQuery UI Tabs.
If your idea if to use this tabs but to fetch the /about.htm as a new content, then you can use the ajax example
http://jqueryui.com/demos/tabs/#ajax
keep in mind that it will fetch the entire content, so the /about.htm page should not have <html> neither <body> tags

I don't want to encourage you to do this, but the solution is currently available on jQuery UI's website: http://jqueryui.com/demos/tabs/#...follow_a_tab.27s_URL_instead_of_loading_its_content_via_ajax
You may extend it a bit to follow only certain URLs:
select: function(e, ui)
{
var tab = $(ui.tab);
var url = $.data(ui.tab, 'load.tabs');
if(url && tab.attr('data-ajax') == 'false')
{
location.href = url;
return false;
}
return true;
}
Then, when defining tabs:
<li>...</li>

Related

Adding a reload button to an Ajax page with jQuery Mobile

In a jQuery Mobile application, I'm using Ajax to load a page with dynamic content. Now, I want to add a "reload" button to that page.
Consider index.html:
<div data-role="page" id="home">
<div data-role="header"><h1>Home</h1></div>
<div data-role="content">Time</div>
</div>
And time.php:
<div data-role="page" data-add-back-btn="true" id="time">
<div data-role="header"><h1>Time</h1></div>
<div data-role="content">
<p><?= date(DATE_RFC822)?></p>
Reload
</div>
</div>
I can now navigate back and forth between the "home" and "time" pages, and the time will be updated when arriving on the "time" page, but I would like the "Reload" button to reload the "time" page. That is: it should do an Ajax request for time.php, and recreate the "time" page from the response (and meanwhile show the "page loading" indicator).
How can I do that?
After looking at the code of changePage and loadPage I came up with a simpler solution:
$('.reload').live('click', function(e) {
$.mobile.changePage($.mobile.activePage.jqmData('url'), {
reloadPage: true,
changeHash: false,
transition: 'none'
});
e.preventDefault();
});
Note that JQM will still transition between the old version of the page and the new version; it is best not to use a transition that has a stronge sense of direction (like 'slide').
The preventDefault does not seem strictly necessary, but I added it for good measure.
This does not seem to be possible when using the hijax-style links. You can however use a multi-page HTML document and load the dynamic page content yourself in the pagebeforechange event.
So in index.html, I already add the "time" page with empty content:
<div data-role="page" id="home">
<div data-role="header"><h1>Home</h1></div>
<div data-role="content">Time</div>
</div>
<div data-role="page" data-add-back-btn="true" id="time">
<div data-role="header">
<h1>Time</h1>
Reload
</div>
<div data-role="content"></div>
</div>
Next, I intercept the pagebeforechange event: in case of the "time" page, we will load the page content from URL time.php.
$(document).bind('pagebeforechange', function(e, data) {
if(typeof data.toPage == 'string') {
var u = $.mobile.path.parseUrl(data.toPage);
if(u.hash == "#time") {
loadPageContent($('#time'), 'time.php', data.options);
e.preventDefault();
}
}
});
Since I want to wait for the Ajax request to come back before changing the page, I prevent the page change; loadPageContent will have to do this.
I can do a similar loadPageContent for the "Reload" button:
$(document).ready(function() {
$('#time .reload').bind('click', function(e) {
loadPageContent($('#time'), 'time.php', undefined, $(e.target).closest(".ui-btn"));
});
});
This is the code of loadPageContent:
function loadPageContent(page, url, options, button) {
if(typeof button != "undefined")
button.addClass($.mobile.activeBtnClass);
$.mobile.showPageLoadingMsg($.mobile.loadingMessageTheme, $.mobile.loadingMessage, $.mobile.loadingMessageTextVisible);
var content = page.children(':jqmData(role=content)');
content.load(url, function(response, status, xhr) {
if(status == "success") {
page.page();
content.trigger('create');
$.mobile.hidePageLoadingMsg();
if(typeof button != "undefined")
button.removeClass($.mobile.activeBtnClass);
$.mobile.changePage(page, options);
} else {
$.mobile.hidePageLoadingMsg();
$.mobile.showPageLoadingMsg($.mobile.pageLoadErrorMessageTheme, $.mobile.pageLoadErrorMessage, true);
setTimeout(function() {
$.mobile.hidePageLoadingMsg();
if(typeof button != "undefined")
button.removeClass($.mobile.activeBtnClass);
}, 1000);
}
});
}
This is already quite an elaborate version: it will display the page loading message, and it will display an error message for 1s when the request fails. At the end of a successful request, it will enhance the content with the create trigger, and it will do the page change. If the reload button is passed along, it will mark this button as active while the operation is in progress.

How do I change the theme of my jQuery Mobile application using javascript?

Here is some javascript that I wrote that attempts to change the theme of the header of my jQuery Mobile application. It is in the head element of my web page after jQuery mobile javascript and CSS has loaded.
$(function() {
$("[data-role='header']").attr('data-theme', 'b');
});
Why is it having no effect?
As it turns out, dynamically changing the theme of a header is easy since there is only a single class to change, that goes for buttons as well (if you have buttons in your header).
//store all the classes to remove from elements when swapping their theme
var removeClasses = 'ui-bar-a ui-bar-b ui-bar-c ui-bar-d ui-bar-e ui-btn-up-a ui-btn-up-b ui-btn-up-c ui-btn-up-d ui-btn-up-e';
//when a specific page initializes, find links in the body and add an event
//handler to the click event for them to update the header's theme
$(document).delegate('#my-page', 'pageinit', function () {
$(this).find('a').bind('click', function (event) {
//get the new theme letter, stored in the HREF attribute of the link
var newTheme = $(this).attr('href');
//change the header's class/attr to relfect the new theme letter
$.mobile.activePage.children('.ui-header').attr('data-theme', newTheme).removeClass(removeClasses).addClass('ui-bar-' + newTheme).children('h1').text('My Header (' + newTheme + ')');
//change the header button's classes/attr to reflect the new theme letter
$.mobile.activePage.children('.ui-header').children('a').removeClass(removeClasses).addClass('ui-btn-up-' + newTheme);
return false;
});
});​
Here is a demo: http://jsfiddle.net/jUgLr/1/
After all that I guess I should make sure you know you can just add a data-theme attribute to any element to change it's theme:
<div data-role="page">
<div data-role="header" data-theme="e">
...
</div>
<div data-role="content" data-theme="d">
...
</div>
</div>
This would work
$(document).delegate('[data-role=page]','pageinit',function(){
$('[data-role=header]').attr('data-theme','b').removeClass().addClass('ui-header ui-bar-b');
});

how do i create a function to change header banner when using jquery tabs

i have 3 default jquery tabs loading external content.
However i need the following adding/binding and was wondering if someone can help me with this issue;
Aswell as loading each tabs content, i need a different header banner to display (outsude of the tab countainer..so i basically have an id called #bannerAd) when each tab is selected.
the coding should be set so a user can link directly to each tab from outside the page (and each banner should load acordingly.)
I really hope this makes sense, hope someone can help.
<script type="text/javascript">
$(function(){
// Tabs
$('#tabs').tabs();
//hover states on the static widgets
$('#dialog_link, ul#icons li').hover(
function() { $(this).addClass('ui-state-hover'); },
function() { $(this).removeClass('ui-state-hover'); }
);
});
</script>
</head>
<body>
<!-- Tabs -->
<h2 class="demoHeaders"></h2>
<div id="tabs">
<ul>
<li>First</li>
<li>Second</li>
<li>Third</li>
</ul>
<div id="tabs-1">Lorem ipsum dolor</div>
<div id="tabs-2">Phasellus mattis tincidunt nibh.</div>
</div>
You could also put data- attributes one each of your tabs.
<li>First</li>
<li>Second</li>
<li>Third</li>
Then in your jQuery
$("#tabs li a").click(function() {
var bannerUrl = $(this).data().bannerurl;
$("#bannerAd").attr("src", bannerUrl);
});
Live in action here: http://jsbin.com/iquluz/5/edit#javascript,html,live
Something like this might be the easiest thing:
$("#tabs li a").click(function() {
switch($("this").attr("href")) {
case "#tabs-1":
//Load First Banner
break;
case "#tabs-2":
//Load Second Banner
break;
case "#tabs-3":
//Load Third Banner
break;
}
});
This will basically set up a click event on the buttons that will fire whenever any of them get clicked. It will then figure out which button was clicked and change the banner accordingly.
And you'd want to put it in your $(function()

Prevent default on a click within a JQuery tabs in Google Chrome

I would like to prevent the default behaviour of a click on a link. I tried the return false; also javascript:void(0); in the href attribute but it doesn’t seem to work. It works fine in Firefox, but not in Chrome and IE.
I have a single tab that loads via AJAX the content which is a simple link.
<script type="text/javascript">
$(function() {
$("#tabs").tabs({
ajaxOptions: {
error: function(xhr, status, index, anchor) {
$(anchor.hash).html("Couldn't load this tab. We'll try to fix this as soon as possible. If this wouldn't be a demo.");
},
success: function() {
alert('hello');
$('#lk').click(function(event) {
alert('Click Me');
event.preventDefault();
return false;
});
}
},
load: function(event, ui) {
$('a', ui.panel).click(function(event) {
$(ui.panel).load(this.href);
event.preventDefault();
return false;
});
}
});
});
</script>
<body>
<div id="tabs">
<ul>
<li>Link</li>
</ul>
</div>
</body>
The content of linkChild.htm is
Click Me
So basically when the tab content is loaded with success, a click event is attached to the link “lk”. When I click on the link, the alert is displayed but then link disappears. I check the HTML and the element is actually removed from the DOM.
$('#selector').click(function(event) {
event.preventDefault();
});
The event object is passed to your click handler by default - you have to have something there to receive it. Once you have the event, you can use jQuery's .preventDefault() method to cancel the link's behavior.
Edit:
Here's the fragment of your code, corrected:
$('a', ui.panel).click(function(event) {
$(ui.panel).load(this.href);
event.preventDefault();
return false;
});
Notice the addition of the word 'event' when creating the anon function (or you could use just e, or anything else - the name is unimportant, the fact there's a var there is.

jquery-ui .tabs ajax load specific content of page?

I'm trying to use jQuery UI's .tabs() to obtain content via AJAX, but the default behavior is to grab the entire page's content. How would I obtain content from a specific #id and/or multiple #id's?
I have a feeling I will need to use the load: event (http://docs.jquery.com/UI/Tabs#event-load), but I need an assist figuring this out.
Example:
The Page with the tabs that is getting and displaying the tabbed content. I have placed #content after the first #the_tabs link to retrieve in an attempt to obtain that specific region of the content, but the entire page is still loaded.
<div id="tabs">
<div id="tabs_display">
</div>
<ul id="the_tabs">
<li><span>1</span></li>
<li><span>2</span></li>
<li><span>3</span></li>
<li><span>4</span></li>
</ul>
</div><!-- /#tabs -->
The page being retrieved by the previous markup:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Remote HTML Page Example</title>
</head>
<body>
<div id="content">
I want this content
</div>
<div id="other_stuff">
Not this content
</div>
</body>
</html>
the JS (for setup purposes):
$(document).ready(function(){
/* Tabs
--------------------*/
$(function() {
var $tabs = $('#tabs').tabs({
});
});
});
In Jquery-UI 1.9, "ajaxOptions" is depreciated; so instead the code below worked for me:
(ref: http://jqueryui.com/upgrade-guide/1.9/#deprecated-ajaxoptions-and-cache-options-added-beforeload-event)
$(function() {
$( "#the_tabs" ).tabs({
beforeLoad: function( event, ui ) {
ui.ajaxSettings.dataType = 'html';
ui.ajaxSettings.dataFilter = function(data) {
return $(data).filter("#content").html();
};
}
});
});
$(document).ready(function(){
/* Tabs
--------------------*/
var $tabs = $('#the_tabs').tabs({
ajaxOptions: {
dataFilter: function(data, type){
return $(data).filter("#content").html();
}
}
});
});
Solution props to Supavisah in #jquery on irc.freenode.net
I have had luck using .find, rather than .filter. Like this:
$(document).ready(function(){
$('#the_tabs').tabs({
ajaxOptions: {
cache : true,
dataFilter: function(data){
return $(data).find('#content');
},
}
});
});

Resources