Target tabed inline content using external links fancybox - javascript

I have a fancy box with tabbed inline content (multiple divs) the user can navigate different "views" by clicking on the tab name once already in the fancybox.
I would like the tabbed content to be accessible when a user clicks the link in the navigation to launch the fancybox.
So for instance if the user clicks the news link (or any link in the .nav-primary or .nav-secondary menu) it will take them directly to the news (or related link) inline content (view) in the fancybox instead of the default view.
How would I target an id i.e. #news within the main fancybox id #menu? How do I achieve this?
HTML
<nav class="navigation">
<ul class="nav-primary">
<li class="nav-primary-item"><a class="menu" href="#menu"><i class="ico plus-yellow">+</i> Sources</a></li>
<li class="nav-primary-item"><a class="menu" href="#menu"><i class="ico plus-yellow">+</i> Topics</a></li>
<li class="nav-primary-item"><a class="menu" href="#menu"><i class="ico plus-yellow">+</i> Geography</a></li>
</ul>
<ul class="nav-secondary">
<li class="nav-secondary-item"><a class="menu" href="#menu"><i class="ico plus-greyishblue">+</i> Tools</a></li>
<li class="nav-secondary-item"><a class="menu" href="#menu"><i class="ico plus-greyishblue">+</i> Learn</a></li>
<li class="nav-secondary-item"><a class="menu" href="#menu"><i class="ico plus-greyishblue">+</i> News</a></li>
</ul>
<div class="nav-menu" style="display: none">
<div class="nav-tabs page_tabs" id="menu">
<ul class="ui-tabs-nav" role="tablist">
<li role="tab">Sources</li>
<li role="tab">Topics</li>
<li role="tab">Geography</li>
<li role="tab">Tools</li>
<li role="tab">Learn</li>
<li role="tab">News</li>
</ul>
<!--Sources and Uses-->
<div id="sources">
Content here
</div>
<!--Topics-->
<div id="topics">
Content Here
</div>
<!--Geography-->
<div id="geography">
Content Here
</div>
<!--Tools-->
<div id="tools">
Content Here
</div>
<!--Learn-->
<div id="learn">
Content Here
</div>
<!--News-->
<div id="news">
Content Here
</div>
</div>
</div>
</div>
JS
<script type="text/javascript">
$('.menu').fancybox({
type: 'inline',
scrolling: 'auto',
width: 940,
height: 'auto',
padding: 0,
autoSize: false,
tpl: {
closeBtn: '<a title="Close" class="fancybox-item fancybox-close fancyboxBtn" href="javascript:;"></a>'
},
helpers: {
overlay: {
locked: false
}
}
});
EDIT
I think the solution lies with changing the hashes on click I can change one broadly by targeting a class and giving it a target hash. How would I be able to apply the sources link to #sources, topics link to #topics etc.
This is my general attempt
$('ul.nav-primary li a').click(function(e){
event.preventDefault();
window.location.hash = '#sources'
});
EDIT 2
On click is there a way I can target the tab index so that that tab is active?

I got the desired results by combining data-target and selecting the tabs directly.
Here is the script
$(document).on("click", ".menu", function() {
var target = $(this).data("target");
if (target == 'sources') {
jQuery('.page_tabs').tabs({ active: 0 });
}
if (target == 'topics') {
jQuery('.page_tabs').tabs({ active: 1 });
}
if (target == 'geography') {
jQuery('.page_tabs').tabs({ active: 2 });
}
if (target == 'tools') {
jQuery('.page_tabs').tabs({ active: 3 });
}
if (target == 'learn') {
jQuery('.page_tabs').tabs({ active: 4 });
}
if (target == 'news') {
jQuery('.page_tabs').tabs({ active: 5 });
}
});

Related

Materialize tabs persist active tab on page refresh

I am building a single page application using vue.js with materialize and I have a navbar with tabs to navigate to different pages on my website. Materialize's tabs has an active property that displays which tab is currently selected. Every thing this far works perfectly.
This is materialize's tabs reference
The Issue
If you refresh the web page the tabs active property 'resets' to its default position. So I am trying to figure out how to persist the state of the navbar's active property and then reassign it to router-link.
My Code
<ul id="tabs" class="tabs tabs-transparent" :class="{ 'navbar--color': !changeNavColor }">
<li class="tab" id="home">
<router-link
id="home"
class="link"
:class="{ 'navbar--color': !changeNavColor }"
to="/"
>Home</router-link>
</li>
<li class="tab" id="services">
<router-link
id="services"
class="link"
:class="{ 'navbar--color': !changeNavColor }"
to="Services"
>Service</router-link>
</li>
<li class="tab" id="Preapproved">
<router-link
id="Preapproved"
class="link"
:class="{ 'navbar--color': !changeNavColor }"
to="PreApproved"
>Get Pre-Approved</router-link>
</li>
<li class="tab">
<router-link
id="cars"
class="link"
:class="{ 'navbar--color': !changeNavColor }"
to="Cars"
>inventory</router-link>
</li>
<li class="tab">
<router-link
id="testimonials"
class="link"
:class="{ 'navbar--color': !changeNavColor }"
to="Testimonials"
>Testimonals</router-link>
</li>
</ul>
if (localStorage.currentTab) {
this.currentTab = localStorage.currentTab;
var activeTab = document.getElementById(this.currentTab);
activeTab.classList.add("active");
console.log("saved");
}
$(document).ready(function() {
$("a").click(function(event) {
this.currentTab = event.target.id;
console.log(this.currentTab);
});
});
$(document).ready(function() {
$(".tabs").tabs();
});
window.addEventListener("scroll", this.onScroll);
},
beforeDestroy() {
window.removeEventListener("scroll", this.onScroll);
},
watch: {
currentTab(newTab) {
console.log("watch");
localStorage.currentTab = this.currentTab;
}
}
any help is appreciated
So I think you can use hash mechanism by using window.location.hash. You can put the data-toggle attribute in every tag anchor. And just check for location.hash !== ''
But the more Vue way would be through client side storage. Check the link its from vue docs. Although it is for the input field but you will get the idea of how to persist info by keeping a reference in client storage and on reload getting your desired state from there onward. Hope it helps.
Remove the indicator that is nested inside the first li, and the navigation works fine.
<ul id="tabs" class="tabs tabs-transparent">
<li id="tab" class="tab">
Home
<li class="indicator"></li> <!-- THIS RANDOM NESTED INDICATOR IS THE ISSUE -->
</li>
<li id="tab" class="tab">
Service
</li>
<li id="tab" class="tab">
Get Pre-Approved
</li>
<li id="tab" class="tab">
inventory
</li>
<li class="indicator" style="right: 488px; left: 0px;"></li> <!-- CORRECT INDICATOR, AUTOMATICALLY GENERATED BY MATERIALIZE -->
</ul>
This is how I ended up implementing this. First all of your router-links or <a> have to have unique id's
mounted() {
if (localStorage.currentTab) {
this.currentTab = localStorage.currentTab;
var element = document.querySelector(this.currentTab);
element.classList.add("active");
}
$(document).ready(function() {
$(".tabs").tabs();
$("a").click(function(event) {
this.currentTab = "#" + event.target.id;
localStorage.currentTab = this.currentTab;
});
});
},
watch: {
currentTab(newTab) {
localStorage.currentTab = this.currentTab;
}
}

jQuery Tabs, multiple tabs with just ONE panel

I'm working on a custom solution, so I thought I would ask the community if anyone has use jQuery Tabs for this purpose before.
The idea is this: I have one main panel, a form with inputs. There are multiple tabs which basically identify different records. All the records will use this form, thats why I just want to load it once, instead of for each tab.
I put a basic example of the direction I want to go. As you can see there are 3 tabs but only one panel. I want to dynamically load content into the_input depending on which tab I click. SO i don't even want to switch the panel, just the selected tab on each click.
I was thinking I need to catch the beforeActivate (http://api.jqueryui.com/tabs/#event-beforeActivate) event, identify which tab was selected, and dynamically alter the 1 visual panel accordingly.
The code isn't really working
jQuery(function($){
$("#tabs").tabs({
beforeActivate(event, ui) {
$('#msg').append('<p>'+ui.newPanel+'</p>');
//I figure what I want to do here is catch the ID of the selected tab, and use that to dynamically load content to the tab.
}
});
function fill_input(selector){
if ( selector == 1 ) {
$('#the_input').val(1);
}else if ( selector == 2 ) {
$('#the_input').val(2);
}else{
$('#the_input').val();
}
}
})
<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
<link href="https://code.jquery.com/ui/1.12.0/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
<div id="tabs">
<ul>
<li>New</li>
<li>record 1</li>
<li>record 2</li>
</ul>
<div id="bol_new">
<form>
<input id="the_input">
</form>
</div>
</div>
<div id="msg">
</div>
You could set the href for each hyperlink to bol_new as under
<ul>
<li>New</li>
<li>record 1</li>
<li>record 2</li>
</ul>
This will set the panel for each tab to the same div with id="bol_new"
Test: https://plnkr.co/edit/EGtCnmNr0c28AaT647SP?p=preview
I would advise just mocking up the tabs with CSS. You can then manipulate the form as needed.
Working example: https://jsfiddle.net/Twisty/j63uvk4q/
HTML
<div id="tabs" class="ui-tabs ui-corner-all ui-widget ui-widget-content">
<ul class="ui-tabs-nav ui-corner-all ui-helper-reset ui-helper-clearfix ui-widget-header">
<li class="ui-tabs-tab ui-corner-top ui-state-default ui-tab ui-tabs-active ui-state-active">
New
</li>
<li class="ui-tabs-tab ui-corner-top ui-state-default ui-tab">
Record 1
</li>
<li class="ui-tabs-tab ui-corner-top ui-state-default ui-tab">
Record 2
</li>
</ul>
<div id="bol_new" class="ui-tabs-panel ui-corner-bottom ui-widget-content">
<form>
Record:
<input id="the_input">
</form>
</div>
</div>
<div id="msg">
</div>
JavaScript
var myData = {
records: {
bol_1: "Homer Simpson",
bol_2: "Marge Simpson"
}
}
$(function() {
$("#tabs .ui-tabs-nav li").click(function(e) {
e.preventDefault();
$("#tabs li.ui-state-active").toggleClass("ui-tabs-active ui-state-active");
$(e.target).parent().addClass("ui-tabs-active ui-state-active");
var id = $(e.target).attr("href").substring(1);
$("#the_input").val(myData.records[id]);
});
$("#tabs .ui-tabs-nav .ui-tabs-tab").hover(function(e) {
$(this).toggleClass("ui-state-hover");
}, function(e) {
$(this).toggleClass("ui-state-hover");
});
});

JQuery LightSlider inside Bootstrap pills

I'm using jQuery lightSlider as image slider. I want to have sliders inside bootstrap pills (one slider per pill). Nevertheless, I have found the following situation: In the first pill the slider is OK. In the second pill the slider content is not displayed (resizing the window brings up the slider content!). I don't see how to solve this problem. Any help will be sincerely appreciated.
My (simplified) html:
<div>
<ul class="nav nav-pills">
<li class="active"> <a data-toggle="pill" id="pill1" href="#s1">Pill 1</a>
</li>
<li> <a data-toggle="pill" id="pill2" href="#s2">Pill 2</a>
</li>
</ul>
</div>
<div class="tab-content">
<div class="col-md-12 tab-pane fade in active" id="s1">
<ul id="slider-1">
<li>
<p>one</p>
</li>
<li>
<p>two</p>
</li>
<li>
<p>tree</p>
</li>
</ul>
</div>
<div class="col-md-12 tab-pane fade active" id="s2">
<ul id="slider-2">
<li>
<p>uno</p>
</li>
<li>
<p>dos</p>
</li>
<li>
<p>tres</p>
</li>
</ul>
</div>
</div>
The javascript:
function initSlider(sliderId) {
$('#'+sliderId).lightSlider({
item:2,
loop:false,
slideMove:1
});
}
initSlider('slider-1');
initSlider('slider-2');
And the Jsfiddle reproducing the problem: https://jsfiddle.net/sedtjchs/4/
Thank you for your help!
Problem: You are trying to call lightSlider on the content(#s2) which was already hidden so plugin can not calculate height, width(and etc) on that element.
Add active class to the second .panel-pane.
Jsfiddle
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
$('#slider-2').lightSlider({
item:4,
loop:false,
slideMove:2,
pager: false,
easing: 'cubic-bezier(0.25, 0, 0.25, 1)',
speed:600,
responsive : [
{
breakpoint:480,
settings: {
item:2,
slideMove:1
}
}
]
}).refresh();
});
I have the same problem, but the Alex's solution doesn't work for me as my tab wrapper doesn't have a fixed height so it will show blank gap under the 1st tab at the first load.
The Thành Nguyễn's solution is working for me. Basically it's refreshing the slider everytime you click on the tab navigation, so then LightSlider will be able to calculate the active container height.
Here's the complete script :
$(document).ready(function() {
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
$('#slider-2').lightSlider({
item:4,
loop:false,
slideMove:2,
pager: false,
easing: 'cubic-bezier(0.25, 0, 0.25, 1)',
speed:600,
responsive : [
{
breakpoint:480,
settings: {
item:2,
slideMove:1
}
}
]
}).refresh();
});
});

How to create a tab section in another tab?

i want to run tabs within tabs. this is the first tab section which is running without problems.
<div id="tabs2" class="tabs">
<ul>
<li class="skew-25 active">
<a class="skew25" href="#"> 1 tab</a>
</li>
<li class="skew-25"></li>
<li class="skew-25"></li>
</ul>
<div class="tabs-pane">
<div class="tab-panel active" style="display: block;"> 1 tab output</div>
<div class="tab-panel" style="display: none;">2 tab output</div>
<div class="tab-panel" style="display: none;">3 tab output</div>
</div>
</div>
Now I include another tab within the sections (called 'tab output') of the above:
<div id="tabs4" class="tabs tabs-vertical">
<ul>
<li class="skew-25 active">tab within tab section</li>
<li class="skew-25">
<a class="skew25" href="#"></a>
</li>
<li class="skew-25"></li>
</ul>
<div class="tabs-pane">
<div class="tab-panel active" style="display: block;">content</div>
<div class="tab-panel" style="display: none;"></div>
<div class="tab-panel" style="display: none;"></div>
</div>
</div>
this second code i include in '1 tab output' '2 tab output' and '3 tab output'
Problem is they will ether not send output, not available to choose or not active when apply to a tab in first tab. How to fix this?
Javascripts are:
function(e) {
if (!$(this).parent().hasClass('active')) {
e.preventDefault();
var ind = $(this).parent().index();
tabsUl.find('li').removeClass('active');
$(this).parent().addClass('active');
tabsPane.find('.tab-panel').fadeOut(0).removeClass('active');
tabsPane.find('.tab-panel').eq(ind).fadeIn(350).addClass('active');
return false;
} else {
return false;
}
}
and
f = v.handle = function(e) {
return typeof x === i || e && x.event.triggered === e.type ? t : x.event.dispatch.apply(f.elem, arguments)
}
normal
/* ================ Tabs. ================ */
$.fn.tabs = function(options) {
var defaults = {
direction: ''
};
var options = $.extend({}, defaults, options);
if(options.direction == "vertical"){
$(this).addClass('tabs-vertical');
}
var tabsUl = $(this).find(' > ul'),
activeTab = tabsUl.find('li.active').index(),
tabsPane = $(this).find('.tabs-pane');
tabsPane.find('.tab-panel').fadeOut();
tabsPane.find('.tab-panel').eq(activeTab).fadeIn();
tabsUl.find('li').find('a').click(function(e){
if(!$(this).parent().hasClass('active')){
e.preventDefault();
var ind = $(this).parent().index();
tabsUl.find('li').removeClass('active');
$(this).parent().addClass('active');
tabsPane.find('.tab-panel').fadeOut(0).removeClass('active');
tabsPane.find('.tab-panel').eq(ind).fadeIn(350).addClass('active');
return false;
}else{
return false;
}
});
}
Disable the div and all its contents with jQuery like so:
How to disable all div content
Also, instead of all that js code you can use jQueryUI Tabs or Bootstrap tabs (also explained here scroll down to the Toggable Tabs section at the bottom of the page).

How to close all elements that are opened with jquery? (Behavior similar to the accordion menu)

I have this html code:
<div id="menu">
<ul id="menuFuncionalidades">
<li>
<div class="menuFuncionalidades_categoria">
Index</div>
</li>
<li>
<div class="menuFuncionalidades_categoria">
Cadastros</div>
<div class="menuFuncionalidades_content_links">
<div class="menuFuncionalidades_content_links_descricao">
<span class="menuFuncionalidades_content_links_descricao_titulo">Descrição</span>
<div class="menuFuncionalidades_content_links_descricao_texto">
Lorem Ipsum...
</div>
</div>
<div class="menuFuncionalidades_content_links_links">
<ul><b>Acesso Usuario</b>
<li>Pesquisar </li>
<li>Incluir </li>
<li>Alterar </li>
<li>Consultar </li>
</ul>
<ul><b>Produto</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
<ul><b>Perfil</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
</div>
</div>
</li>
<li>
<div class="menuFuncionalidades_categoria">
Coletores</div>
<div class="menuFuncionalidades_content_links">
<div class="menuFuncionalidades_content_links_descricao">
<span class="menuFuncionalidades_content_links_descricao_titulo">Descrição</span>
<div class="menuFuncionalidades_content_links_descricao_texto">
Lorem Ipsum...
</div>
</div>
<div class="menuFuncionalidades_content_links_links">
<ul>
<b>Coletor 1</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
<ul>
<b>Coletor 2</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
<ul>
<b>Coletor 3</b>
<li>Pesquisar </li>
<li>Incluir </li>
</ul>
</div>
</div>
</li>
</ul>
</div>
My objective is when i click in a menuFuncionalidades_categoria i close all menuFuncionalidades_content_links that is opened, and opened the right one that is in the same level of the menuFuncionalidades_categoria that i click. So, i try this, but i have no success:
$(document).ready(function () {
$('#menuFuncionalidades > li > .menuFuncionalidades_categoria').click(function () {
$("#menu").children().find('.menuFuncionalidades_content_links').each(function () {
// I need a code here to close only the tags that are opened but is not the current
if ($(this).css('display') == 'block') {
$(this).hide();
}
});
$(this).parent().find('.menuFuncionalidades_content_links').slideToggle('normal').css('width', $('#menu').css('width'));
});
});
What am i missing or doing wrong?
OBS: The behavior that i want, is similar with accordion menu.
DEMO here: http://fiddle.jshell.net/ry9dz/1/
As #karim79 says, you can't check "display" that way - it's a css attribute, not an html attribute.
On the other hand, if you want to close all other entries, then just do that - no need to check if they are visible first! I also suggest you use a more efficient event handler for all your items, instead of binding it to all of them. Using jQuery 1.7, something like this would work:
$(document).ready(function () {
$("#menuFuncionalidades").on("click", ".menuFuncionalidades_categoria", function(event) {
var selectedMenu = $(event.target).parents("li").find(".menuFuncionalidades_content_links")
, visible = selectedMenu.is(":visible");
// Hide all others
$("#menuFuncionalidades .menuFuncionalidades_content_links").hide();
// Show this one unless it was already visible
if(!visible) {
selectedMenu
.slideToggle('normal')
.css('width', $('#menu').css('width'));
}
// Prevent the default action
event.preventDefault();
});
});
You can hide multiple elements without iterating though all of them to see which ones aren't hidden.
Replace;
$("#menu").children().find('.menuFuncionalidades_content_links').each(function () {
if ($(this).attr('display') == 'block') {
$(this).hide();
}
});
with;
$("#menu").find('.menuFuncionalidades_content_links').hide();
$(this).attr('display') is invalid as there are no "display" attribute and instead of using .css('display') == 'block' you could simply use the psuedo selector :visible.
You want the display css property:
if ($(this).css('display') == 'block') {
$(this).hide();
}
or:
if ($(this).is(':visible')) {
$(this).hide();
}

Categories