I have a listener for tab selection changes, and want to be able to load content in a div element, everytime I click on a tab:
However, the following works only for the first time. With subsequent clicks on the tabs, the page (or div region) is blank.
tabSelectionHandler = function (event, ui) {
// .... code to get tab that was clicked
//..code to get URL
var nextURL = PAGE_URL[tabName];
$('#' + tabName + 'Content').load(nextURL, function (responseTxt, statusTxt, xhr) {});
}
I want the content to be loaded everytime tab is clicked, as the content may be dynamic.. How do I do that?
How I do this is like this:
Suppose I have the following HTML:
<div id="tabs">
<ul>
<li>abc</li>
<li>xyz</li>
</ul>
<div id="tabs-1"></div>
<div id="tabs-2"></div>
</div>
Then you can access each tab like this:
$('#tabs').tabs({
activate: function (event, ui) {
var active = $("#tabs").tabs("option", "active");
var tabId = $("#tabs ul>li a").eq(active).attr('href');
if (tabId === "#tabs-1") {
//set url here
loadHtml(tabId,url );
} else if (tabId === "#tabs-2") {
//set url here
loadHtml(tabId,url );
}
}
});
And then have a javaScript function that loads the content:
function loadHtml(id,url){
$('#'+id).html("some html here");
//you can place an ajax call here or whatever is suitable
//In your case that would be something like
//$('#' + id).load(url);
}
Hope that helps
Related
The active class isn't working and I've tried body On-load click trigger and obviously show tab using id and many other ways, however nothing seems to be working. I have hashed the URL to enable tabs to be linked individually in the search. Any help is much appreciated.
JS: to hash the URL and jump to tab
// jump to tab if it exists
if (location.hash) {
$('a[href=' + location.hash + ']').tab('show');
}
// add tab hash to url to persist state
$(document.body).on("shown.bs.tab", function(e){
location.hash = e.target.hash;
});
});
JS: To go to tab home (not working)
$("document").ready(function(){
$("#home").trigger("click");
});
HTML:
<div class="col-xs-5 col-md-2 nopadding">
<nav class="nav-sidebar">
<ul class="nav tabs">
<li class="lead3">Home </li>
<li class="lead3">tab1</li>
<li class="lead3"><a href="#tab3" data-toggle="tab" >tab3</a></li>
<li class="lead3"> Contact </li>
</ul>
</nav>
tab-pane:
<div class="tab-pane active fade text-style" id="home"> . .. </div>
What you expect from this line?
$("home").trigger("click");
I suppose Jquery can't find element here $("home"). You could evaluate it in console for check.
if you are going to find element with class 'home' or id 'home' then you should use $(".home") or $("#home") properly.
It looks like your Document Ready event doesn't work.
Try remove the quotes around the $("document").
A shorter method for this event is as follows:
$(function() {
});
I know that this is very late but I'd like to post my solution since this was something that I was stuck on as well. There's an important subtlety that I think is easy to miss. You want to trigger the click on the <a> tag inside the nav, not the actual panel. Remember you click on the tab not on the panel to trigger it into view. So to get the correct tab to show when the user navigates to /my/path#home you want to bind on the hashchange event and click the correct element. See https://stackoverflow.com/a/680865/5262119 for more info on binding to the hashchange event.
$(window).bind('hashchange', function(event){
var hash = window.location.hash;
// get the actual anchor tag that links to the panel
var $matchingAnchor = $('nav a[href^="' + hash + '"');
if ($matchingAnchor) $matchingAnchor.click();
});
And assuming you want to restrict this to trigger only a certain page then you can add a location check:
$(window).bind('hashchange', function(event){
var path = window.location.pathname;
var hash = window.location.hash;
var $matchingAnchor = $('nav a[href^="' + hash + '"');
var contextRegex = /my\/page/;
var correctPage = contextRegex.test(path);
if (correctPage && $matchingAnchor) $matchingAnchor.click();
});
I imagine you also want to make sure that clicks on the tabs update the hash in the URL window so bind to the tabs event:
$('nav a').on('click',function() {
var $a = $(this);
var hash = $a.attr("href");
window.location.hash = hash;
});
This would go inside your ready function. You will also have to make sure that the function that triggers the click happens when the page first loads.
Complete solution:
$(document).ready(function() {
// Declare clickback function
function triggerTabClick() {
var path = window.location.pathname;
var hash = window.location.hash;
var $matchingAnchor = $('nav a[href^="' + hash + '"');
var contextRegex = /my\/page/; // or whatever you want this to be
var correctPage = contextRegex.test(path);
if (correctPage && $matchingAnchor) $matchingAnchor.click();
}
// Trigger it when the hash changes
$(window).bind('hashchange', triggerTabClick);
// Trigger it when the page loads
triggerTabClick();
// Hook into click for tabs to make sure hash is updated on click
$('nav a').on('click',function(event){
event.preventDefault();
var $a = $(this);
var hash = $a.attr("href");
var window.location.hash = hash;
})
})
I'm doing an SPA from scratch and so far I've gotten everything working except the active state off the navigation links will not update according to where user is navigating to.
The funny thing is that when I open up the Developer Tools in Chrome, under "Elements" the DOM is still showing the active class on the original nav element, but under "Console", when I console.log the element, it shows that the class has been removed.
I've tried event.stopPropagation() in a few places and the jQuery.off() function but nothing seems to fix this problem.
Problem: The class list of the active and the former active link doesn't update when clicking on a navigation link, but the console.log function does show an updated classlist off the former active link
Desired Behaviour: That the former active link losses its active class and that the currently active link gets an active class after its navigation link has been clicked and the page renders the new content(the supposedly new page).
UPDATE 1: Updated the code according to suggestions and it got the first part of my problem working. Removing active class from all li elements now works, but making the page render the updated links with active class on currently active link after navigation does not work. See in app.js under generateView() function.
UPDATE 2: Got it working. See on the bottom of this Question. Thank you!
My app.js
(function ($, hbs){
'use strict';
// declare some usefull variables to use throughout the app
var
doc = document,
oldPath = '',
newPath = '',
navParentEl = '';
// 1: Manually trigger a hashchange to start the app.
window.onload = function (e) {
$(window).trigger('hashchange');
};
// 2: Catch clicks on the root-level element for anchor tag clicks.
doc.body.addEventListener('click', function (e) {
//e.stopPropagation();
var tag = e.target;
// check element clicket
if (tag.tagName === 'A' && tag.href && e.button === 0) {
// it's a left-click on an anchor. Lets navigate!
if (tag.origin === window.location.origin) {
// prevent the page from navigating
e.preventDefault();
// it's a link within the site, HURRAY!
oldPath = window.location;
newPath = tag.href,
navParentEl = tag.parentElement;
console.log(navParentEl);
// Update the URL bar! IMPORTANT!
// #TODO: MOVE INTO A FUNCTION OR OBJECT
window.history.pushState(null, '', newPath);
render(window.location.hash, data, e);
}
}
});
// register Handlebars partials
hbs.registerPartial({
'header': hbs.templates.header,
'footer': hbs.templates.footer
});
$(window).on('hashchange', function (e) {
// On every hash change the render function is called with the new hash.
render(window.location.hash, data, e);
});
function render(url, data, evt) {
var temp = url.split('/')[0];
// Hide current page
$('.pages').addClass('hidden');
// remove anchors .active class
//$('.nav-parent').removeClass('active');
var map = {
'': function (data) {
renderPage('home', data);
},
'#home': function (data) {
renderPage('home', data);
},
'#gallery': function (data) {
renderPage('gallery', data);
},
'#about': function (data) {
renderPage('about', data);
}
};
if (map[temp]) {
map[temp](data);
} else {
renderErrorPage(data);
}
}
function renderPage(page, data) {
var tpl = hbs.templates[page](data);
generateView(tpl, page);
}
function renderErrorPage(data) {
renderPage('error', data);
}
function generateView(tpl, page) {
var pageId = '#' + page;
$(pageId).removeClass('hidden');
$('.container').html(tpl);
// this works for removing the active class from all li elements
$('.nav-parent').removeClass('active');
// add .active class to the new active anchor element
// does not work
$(navParentEl).addClass('active');
}
})(jQuery, Handlebars);
My navigation HTML:
<div class="header clearfix">
<nav>
<ul class="nav nav-pills pull-right">
<li role="presentation" class="nav-parent active">Home</li>
<li role="presentation" class="nav-parent">Gallery</li>
<li role="presentation" class="nav-parent">About</li>
<li role="presentation" class="nav-parent">Contact</li>
</ul>
</nav>
<h3 class="text-muted">{{ projectName }}</h3>
</div>
UPDATE 2: Got it working after some tips. I needed to re-think my generateView() function. Here's the final code for that function:
function generateView(tpl, page) {
var pageId = '#' + page;
// remove hidden class from content to be shown
$(pageId).removeClass('hidden');
// add the template to the html
$('.container').html(tpl);
// move the active class from the former active link
$('.nav-parent').removeClass('active');
// get the current hash of the location
var newHash = window.location.hash,
// get all links
_links = document.querySelectorAll('.links'),
currentActiveLink = '';
// iterate over the _links object and find the link with href === newHash
for ( var i = 0; i < _links.length; i++ ) {
if ( _links[i].getAttribute('href') === newHash ) {
// store the link with href == newHash
// inside the currentActiveLink variable
currentActiveLink = _links[i];
}
}
// add active class to current active link
currentActiveLink.parentElement.classList.add('active');
}
Thank you!
isnt it possible that you redraw your navigation? didnt really go through your code but it took me a looong time to discover that in my SPI. I changed some params, but I also ajax-loaded those elements wit default serverside properties...
EDIT: yea I can see that happening in your app
I have this jquery code:
$(document).ready(function() {
$(".tabLink").each(function(){
if(location.hash) {
$(".tabLink").removeClass("activeLink");
$(location.hash+"-1").addClass("activeLink");
$(".tabcontent").addClass("hide")
$(location.hash+"-1").removeClass("hide")
} else {
$(".tablink").click(function(){
$(".tabLink").removeClass("activeLink");
$(this).addClass("activeLink");
$(".tabcontent").addClass("hide")
$(location.hash+"-1").removeClass("hide")
});
}
});
});
to switch between tabs, my html is:
Company
Contacts
<div class="tabcontent" id="companyinfo-1">
</div>
<div class="tabcontent" id="contacts-1">
</div>
when i choose another tab i have to click it twice to make the div show
here is a fiddle with the full code : http://jsfiddle.net/2SRZE/
FIDDLE
Why not keep it simple and grab the target right off the anchor link instead of the page URL?
<div class="tab-box">
Company
Contacts
</div>
<div class="tabcontent" id="companyinfo-1">
Tab 1 Content
</div>
<div class="tabcontent hide" id="contacts-1">
Tab 2 Content
</div>
$(document).ready(function() {
if(location.hash) {
// maybe do a little more validation here
setActiveLink(location.hash);
}
$('.tabLink').click(function(e) {
e.preventDefault();
var target = $(this).attr('href');
document.location.hash = target;
setActiveLink(target);
});
function setActiveLink(target) {
$(".tabLink").removeClass("activeLink");
$('a[href=' + target + ']').addClass("activeLink");
$('.tabcontent').addClass('hide');
$(target).removeClass('hide');
}
});
A comment on why you have to click twice:
When you click the tab and the event is triggered the address of the window still has not changed. On first click that would mean no hash. On subsequent clicks that would mean the hash has the value of previous clicked anchor.
Page enter: hash == ''
Click on Contacts: hash == ''
Hide content. (Company is being hided.)
Show hash + '-1' (no match as hash is empty.)
Event done, window hash changes: hash == '#contacts'
Click on #contacts: hash == '#contacts'
Hide content. (Nothing to hide).
Show hash + '-1': contacts-1 show.
Easier by example. Here the text-box is updated with hash value on each click.
Fiddle
As you can see, the hash changes too late.
So: As noted by Lucky Soni, check the target event's href value.
http://jsfiddle.net/awesome/svP3T/2/
$(document).ready(function () {
$(".tabcontent").addClass("hide");
$($(".activeLink").attr('href') + '-1').removeClass("hide");
$(".tabLink").each(function () {
var _tabLink = $(this);
var _tabLinkAttr = $(_tabLink.attr('href') + '-1');
_tabLink.click(function () {
$(".tabLink").removeClass("activeLink");
_tabLink.addClass("activeLink");
$(".tabcontent").addClass("hide");
_tabLinkAttr.removeClass("hide");
});
});
});
check this out: http://jsfiddle.net/awesome/svP3T/4/
see this too: $(window) bind hashchange how to check part hash changed?
var originalHash = window.location.hash;
$(document).ready(function () {
$(window).bind('hashchange', function () {
// remove all active
$(".tabLink").removeClass("activeLink");
$(".tabcontent").addClass("hide");
// https://stackoverflow.com/questions/7699073/window-bind-hashchange-how-to-check-part-hash-changed
var newHash = window.location.hash;
var _origHash = originalHash;
originalHash = newHash;
// log
console.log('original: ' + _origHash);
console.log('new: ' + newHash);
// update active
$('[href="' + newHash + '"]').addClass("activeLink");
$(newHash + '-1').removeClass("hide");
});
// init
$(".tabcontent").addClass("hide");
$($(".activeLink").attr('href') + '-1').removeClass("hide");
});
I am using jquery to add the class to active css on "li" and also navigate to an html page.but after page navigates the class disappers on "li". I have tried different ways to resolve this but couldn't get the point.
$(document).ready(function(){
$( '#topList ul li' ).click(function() {
alert($(this).attr('id'));
if($(this).attr('id') == "add") {
document.location.href = 'localhost:8080/add';
$(this).attr('id').addClass("active");
}
});
});
here is the menu list, what I want is when I click on li it should call a page add and also add a class on that li.
html code
<ul class="nav">
<li class="" id="add"></i> Add </li>
<ul>
You need to add class for the li in the page you are calling ie, the page will be rendered when you call localhost:8080/add.
Because in your code setting up of active class wont be called since the localhost:8080/add will start loading in the previous line of code (document.location.href = 'localhost:8080/add';)
If the page to be rendered is static page then, add this code in that page.
$(document).ready(function(){
$('#add').addClass("active");
});
Use the following script on the page where you have menu or the links.
<div id="cssmenu">
<a href="blah blah" > Test page</a>
<a href="blah blah" > Test page</a>
</div>
$(document).ready(function () {
var pageTitle = window.location.pathname.replace(/^.*\/([^/]*)/, "$1");
$('#cssmenu a').each(function () {
if ($(this).attr('href').toLowerCase() == pageTitle.toLocaleLowerCase())
$(this).addClass('active');
});
});
I solved this problem on my website by looking at the URL and deciding which of the navigation elements was best to add.
function showContent(target) {
var e = $('#'+target);
$(".content").hide();
$("#nav li.active").removeClass("active");
$("#nav li[target='"+target+"']").addClass("active");
e.toggle();
ga('send','pageview',window.location.pathname+"#"+target);
}
// this looks at the URL (by the #...) and decides which view is active
// this gets called on ready and if the client hits the link
// (which dynamically loads instead of making a trip for a new page to the server)
$(window).hashchange(function() {
var which=window.location.hash.substring(1);
switch( which) {
default:
which="profile";
case "profile":
case "resume":
case "projects":
case "contact":
showContent( which);
}
});
I am using jquery UI tab for my project. Kindly check the html code
<div id="tabs">
<ul>
<li>General</li>
<li>Admin Products</li>
<li>Admin Category</li>
<li>Others(Admin)</li>
</ul>
<div id="tabs-1"></div>
<div id="tabs-2"></div>
<div id="tabs-3"></div>
<div id="tabs-4"></div>
</div>
when I click a tab, I get the form using ajax, which works well. Check the js code below which is taken from phtml file,
<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'); }
);
$('.load_cont').click(function()
{
var groupname;
var id = $(this).attr('rel');
var gnameArr = id.split('||');
groupname = gnameArr[1];
//alert(gnameArr[1]);
var url = <?php echo BASE_URL; ?> + '/admin/settings/getqtips/gname/'+groupname;
//alert(id);
$.ajax({
type:'POST',
dataType:'json',
url:url+'/math/'+Math.random(),
data:'',
success:function(response)
{
if(response.MSG == 'DONE')
{
$("#"+gnameArr[0]).html(response.TPL);
$('div#'+gnameArr[0]+' #gname').val(groupname);
}
}
});
}
);
});
$(function(){
$('a#preload').click();
})
</script>
My requirement is, when ever I click on respective tab, I need to clear the html inside other tab. That is, if I click on tabs-2, the content from other tabs (tabs-1, tabs-3, tabs-4) should be clear. This one saves my validation on zend.
Kindly advice on this.
inside your success function empty all other divs
$('div[id^="tabs-"]').each(function(){ //search for all divs which id starts with 'tabs-'
if (this.id != gnameArr[0]) { //if this is not clicked one
$(this).empty(); //clear its content
}
});
or with falsarella's tip
$('.load_cont').click(function() {
var clickedEl = $('#'+gnameArr[0]);
...
success:functi...
$('div[id^="tabs-"]').not(clickedEl).empty();
...
Alternatively, you can set container elements with the same class, eg .container.
// Clear all container before you set the new one.
$('.container').html('');
how about something like this :
$('.load_cont').click(function(){
$('.load_cont').not($(this)).each(function(i,el){
$($(el).attr('href')).empty();
});
});
Select the divs that aren't the selected one, and clear them all:
$('#tabs > div:not(#' + gnameArr[0] + ')').empty();