Stay on same tab upon refresh (Tabs within Tabs) - javascript

Upon page submit the main tab(Register, lock, unlock etc) stays on the current one but the sub tab(list, locked, checked out etc) goes to default(Search) upon page submit. example if I do a submit on List or Locked tab it defaults to Search tab.
Problem: I have to keep track of both the horizontal tab and the vertical tab and currently I am able to track only the horizontal tab
HTML Main tab(Horizontal):
<div id="tabs">
<ul>
<li>Register<div class="hidden_area">Register a device</div></li>
<li>Lock<div class="hidden_area">Lock a device</div></li>
<li>Unlock<div class="hidden_area">Unlock a device</div></li>
<li>Transfer<div class="hidden_area">Transfer device to a new warehouse</div></li>
<li>Manage Users<div class="hidden_area">Change/Add regions to a user</div></li>
<li>Reporting<div class="hidden_area">Reporting Services</div></li>
</ul>
HTML Sub tab(Vertical):
<div id="tabs1">
<ul>
<li class="first current">Search<div class="hidden_area1">Search a device</div></li>
<li>List<div class="hidden_area1">List all devices</div></li>
<li>Locked<div class="hidden_area1">List locked devices</div></li>
<li>Checked Out<div class="hidden_area1">List checked out devices</div></li>
<li>Repair<div class="hidden_area1">List repair devices</div></li>
<li class="last">No Check In<div class="hidden_area1">Devices checked out but not checked in</div></li>
</ul>
jQuery Main Tab:
var index = 'ui.newTab.index()';
// Define data store name
var dataStore = window.sessionStorage;
var oldIndex = 0;
try {
// getter: Fetch previous value
oldIndex = dataStore.getItem(index);
} catch(e) {}
$( "#tabs" ).tabs({
active: oldIndex,
activate: function(event, ui) {
// Get future value
var newIndex = ui.newTab.parent().children().index(ui.newTab);
// Set future value
try {
dataStore.setItem( index, newIndex );
} catch(e) {}
}
});
jQuery Sub Tab:
$( "#tabs1" ).tabs().addClass( "ui-tabs-vertical ui-helper-clearfix" );
$( "#tabs1 li" ).removeClass( "ui-corner-top" ).addClass( "ui-corner-left" );

I assume that you are using jQuery UI tabs ,
here is an example of using tabs + cookies to save the last clicked tab
http://jqueryui.com/demos/tabs/#cookie
demo : open this link http://jqueryui.com/demos/tabs/cookie.html
the close it and re open it and you will see the same clicked tab
update: after 3 years of this answer jquery ui has deprecated the cookie option : http://jqueryui.com/upgrade-guide/1.9/#deprecated-cookie-option.
but you can still append take a look here if this fits your needs or not https://stackoverflow.com/a/14313315/109217
OR
You could try this
$(function() {
// jQueryUI 1.10 and HTML5 ready
// http://jqueryui.com/upgrade-guide/1.10/#removed-cookie-option
// Documentation
// http://api.jqueryui.com/tabs/#option-active
// http://api.jqueryui.com/tabs/#event-activate
// http://balaarjunan.wordpress.com/2010/11/10/html5-session-storage-key-things-to-consider/
//
// Define friendly index name
var index = 'key';
// Define friendly data store name
var dataStore = window.sessionStorage;
// Start magic!
try {
// getter: Fetch previous value
var oldIndex = dataStore.getItem(index);
} catch(e) {
// getter: Always default to first tab in error state
var oldIndex = 0;
}
$('#tabs').tabs({
// The zero-based index of the panel that is active (open)
active : oldIndex,
// Triggered after a tab has been activated
activate : function( event, ui ){
// Get future value
var newIndex = ui.newTab.parent().children().index(ui.newTab);
// Set future value
dataStore.setItem( index, newIndex )
}
});
});

Solved:
Horizontal tabs worked fine, but for vertical tabs the control was going to the default tab hence had to use ui.oldtab.index()
jQuery:
var index1 = 'ui.oldTab.index()';
// Define data store name
var dataStore = window.sessionStorage;
var oldIndex = 0;
try {
// getter: Fetch previous value
oldIndex1 = dataStore.getItem(index1);
} catch(e) {}
$( "#tabs1" ).tabs({
active: oldIndex1,
activate: function(event, ui) {
// Get future value
var newIndex1 = ui.newTab.parent().children().index(ui.newTab);
// Set future value
try {
dataStore.setItem( index1, newIndex1);
} catch(e) {}
}
});

Related

How to get ID of link that opened Fancybox3 within onComplete?

I have seen what looks like it could be the solution to this issue in other questions on stackoverflow, but NONE of them have worked.
I am trying to get the innertext of the link that was clicked to open Fancybox:
$("a.turnDateLink").each(function() {
var that = $(this);
$( "a.turnDateLink" ).fancybox({
'type': 'modal',
'onComplete': function() {
var currentday = $(that).text();
console.log(currentday);
},
'afterClose': clearCurrentDay,
'fullScreen' : false
});
});
It only returns the innerText of the last a.turnDateLink. EVERY TIME! ugh.
Keep in mind that I would like to use the fancybox grouping with this.
See the Fancybox documentation to understand grouping: http://fancyapps.com/fancybox/3/docs/#usage
If you have a group of items, you can use the same attribute
data-fancybox value for each of them to create a gallery. Each group
should have a unique value:
Check documentation about events - http://fancyapps.com/fancybox/3/docs/#events
The first examaple contains useful tips, including how to find clicked element:
onComplete: function( instance, slide ) {
// Tip: Each event passes useful information within the event object:
// Object containing references to interface elements
// (background, buttons, caption, etc)
// console.info( instance.$refs );
// Current slide options
// console.info( slide.opts );
// Clicked element
// console.info( slide.opts.$orig );
// Reference to DOM element of the slide
// console.info( slide.$slide );
}
Try like this.Change $( "a.turnDateLink" ) to that.
$("a.turnDateLink").each(function() {
var that = $(this);
that.fancybox({
'type': 'modal',
'onComplete': function() {
$("#currentday").html('');
var currentday = that.text();
console.log(currentday);
},
'afterClose': clearCurrentDay,
'fullScreen' : false
});
});

How to not Open Accordion by default

Ok I do not know javascript so much, so I have created a accordion by searching in google. but the problem is the first item of the accordion is always open up, even if I do not use "toggle-active" class. The accordion works perfectly though, I mean if I use this "toggle-active" class in item number 3 for an example, then the item number 3 is open up at default.
but my problem is I have only one item & I want to open the accordion item, when it clicks only, not open by default. How can I do it?
here is the code guys:
jQuery(".toggle-item").each(function() {
jQuery(this).find('.toggle-active').siblings('.toggle-inner').slideDown(300);
});
jQuery(".toggle-item").on("click", ".toggle-title", function() {
var thisItem = jQuery(this);
var parentdiv = thisItem.parent('div').parent('div');
var active = thisItem.parent('div').find('.toggle-inner').css('display');
if (jQuery(parentdiv).attr('class') === 'accordion') {
if (active !== 'none' ) {
jQuery(parentdiv).find('.toggle-item .toggle-inner').slideUp(300);
thisItem.toggleClass('toggle-active');
} else {
jQuery(parentdiv).find('.toggle-item .toggle-inner').slideUp(300);
jQuery(parentdiv).find('.toggle-item .toggle-title').removeClass('toggle-active');
thisItem.toggleClass('toggle-active');
thisItem.siblings('.toggle-inner').slideDown(300);
}
} else {
thisItem.toggleClass('toggle-active');
thisItem.siblings('.toggle-inner').slideToggle(300);
}
return false;
});
Use http://api.jqueryui.com/accordion/#option-collapsible
This is a jquery accordion widget that you can use.
$( ".toggle-item" ).accordion("option", {
collapsible: true,
active: false
});

Open specific accordion tab using external link and hash

hi to all I'm new in js sorry for what I ask here now I know its a basic one, I'm working now with accordion plugin that collects all the article that users want to put in accordion and view it in accordion my question is how to open specific tab when is have dynamic id per article inside a item of accordion.. im trying to hook the item using link, http//:example.com#id to open specific tab in accordion here s the plugin code.
hook inside the code and trigger the click event to open the specific the in the accordion plugin
!(function($){
$.fn.spAccordion = function(options){
var settings = $.extend({
hidefirst: 0
}, options);
return this.each(function(){
var $items = $(this).find('>div');
var $handlers = $items.find('.toggler');
var $panels = $items.find('.sp-accordion-container');
if( settings.hidefirst === 1 )
{
$panels.hide().first();
}
else
{
$handlers.first().addClass('active');
$panels.hide().first().slideDown();
}
$handlers.on('click', function(){
if( $(this).hasClass('active') )
{
$(this).removeClass('active');
$panels.slideUp();
}
else
{
$handlers.removeClass('active');
$panels.slideUp();
$(this).addClass('active').parent().find('.sp-accordion-container').slideDown();
}
event.preventDefault();
});
});
};
})(jQuery);
A little thing is, you can use .children('div') instead of .find('>div').
But if you want to get what the hash is set to you can use window.location.hash. By default this is used to identify element IDs. So ideally you could get the element you want to show by doing
if (window.location.hash) {
var $selected = $('#'+window.location.hash);
if ($selected.length) {
// Do what you need to show this element
}
}

Location.hash returns empty string

I am currently using jQuery, Twitter Bootstrap and CanJS for my web application. I'm trying to implement routing with CanJS. I'm using Bootstrap's tab, and when I click on a tab, it was supposed to bring #tabSearch, #tabUser or #tabPermissions, but the hash is returned with an empty string.
What am I doing wrong?
I´m using this to change the tabs:
TabControl = can.Control.extend({}, {
init: function (element, options) {
element.find('a[href="' + options.defaultTab + '"]').tab('show');
this.userSearch = null;
this.userForm = null;
}
, 'a[data-toggle="tab"] show': function (e) {
this.options.tabChangeCallback(e);
}
});
UserTab = new TabControl('#tabctrlUser', {
defaultTab: '#tabSearch',
tabChangeCallback: function (e) {
if (e.context.hash == '#tabSearch') {
if (!this.userSearch) {
this.userSearch = new FormUserQuery('#tabSearch', {});
}
} else if (e.context.hash == '#tabUser') {
if (!this.userForm) {
this.userForm = new FormUser('#tabUser', {});
}
this.userForm.renderView(currentUser);
} else if (e.context.hash == '#tabPermissions') {
new FormPermissions('#tabPermissions', {});
}
}
});
Here is the HTML part:
<ul id="tabctrlUser" class="nav nav-tabs">
<li>Pesquisar</li>
<li>Cadastrar/Alterar</li>
<li>Acessos</li>
</ul>
<div class="tab-content">
<div class="tab-pane" id="tabSearch"></div>
<div class="tab-pane" id="tabUser"></div>
<div class="tab-pane" id="tabPermissions"></div>
</div>
You need to use can.route or can.Control.Route, the way you do it is complicated take a look at this question
Also there's 2 good articles about routing
look at this gist
http://jsfiddle.net/Z9Cv5/2/light/
var HistoryTabs = can.Control({
init: function( el ) {
// hide all tabs
var tab = this.tab;
this.element.children( 'li' ).each(function() {
tab( $( this ) ).hide();
});
// activate the first tab
var active = can.route.attr(this.options.attr);
this.activate(active);
},
"{can.route} {attr}" : function(route, ev, newVal, oldVal){
this.activate(newVal, oldVal)
},
// helper function finds the tab for a given li
tab: function( li ) {
return $( li.find( 'a' ).attr( 'href' ) );
},
// helper function finds li for a given id
button : function(id){
// if nothing is active, activate the first
return id ? this.element.find("a[href=#"+id+"]").parent() :
this.element.children( 'li:first' );
},
// activates
activate: function( active, oldActive ){
// deactivate the old active
var oldButton = this.button(oldActive).removeClass('active');
this.tab(oldButton).hide();
// activate new
var newButton = this.button(active).addClass('active');
this.tab(newButton).show();
},
"li click" : function(el, ev){
// prevent the default setting
ev.preventDefault();
// update the route data
can.route.attr(this.options.attr, this.tab(el)[0].id)
}
});
// configure routes
can.route(":component",{
component: "model",
person: "mihael"
});
can.route(":component/:person",{
component: "model",
person: "mihael"
});
// adds the controller to the element
new HistoryTabs( '#components',{attr: 'component'});
new HistoryTabs( '#people',{attr: 'person'});
I am not familiar with CanJS, but this could have something to do that anchor click event happens before navigation, and location.hash is set after. E.g. if (as a test) you define your link as
Pesquisar
And in plain vanilla JS try
function tabChangeCallback() {
alert(location.hash)
}
It will display blank.
But if you try something like
function tabChangeCallback() {
setTimeout(function() {
alert(location.hash)
}, 100)
}
It will display the hash. So in your case either set your code to be executed on timeout after main event or (and I think it's a better option) instead of hash you should read href attribute of the anchor element that caused the event.
Update The plain JS example below shows how to get the hash value without timeout:
function tabChangeCallback(e) {
var elem = e ? e.target : event.srcElement
alert(elem.getAttribute("href"))
}

Ready function called multiple times on click

I am using the following code to convert unoredered html list into a select drop down list:
jQuery(document).ready( function($) {
//build dropdown - main navigation
$("<select />").appendTo(".region-menu-inner nav");
// Create default option "Go to..."
$("<option />", {
"selected": "selected",
"value" : "",
"text" : "Navigate..."
}).appendTo("nav select");
// Populate dropdowns with the first menu items
$(".region-menu-inner li a").each(function() {
var el = $(this);
$("<option />", {
"value" : el.attr("href"),
"text" : el.text()
}).appendTo(".region-menu-inner select");
});
//make responsive dropdown menu actually work
$(".region-menu-inner select").change(function() {
window.location = $(this).find("option:selected").val();
});
});
At the same time, I am using Simple dialog module for Drupal to create modular window. This module comes with only one js file. The code this module is using is below:
/*
#file
Defines the simple modal behavior
*/
(function ($) {
/*
Add the class 'simple-dialog' to open links in a dialog
You also need to specify 'rev="<selector>"' where the <selector>
is the unique id of the container to load from the linked page.
Any additional jquery ui dialog options can be passed through
the rel tag using the format:
rel="<option_name1>:<value1>;<option_name2>:<value2>;"
e.g. <a href="financing/purchasing-options" class="simple-dialog"
rel="width:900;resizable:false;position:[60,center]"
rev="content-area" title="Purchasing Options">Link</a>
NOTE: This method doesn't not bring javascript files over from
the target page. You will need to make sure your javascript is
either inline in the html that's being loaded, or in the head tag
of the page you are on.
ALSO: Make sure the jquery ui.dialog library has been added to the page
*/
Drupal.behaviors.simpleDialog = {
attach: function (context, settings) {
// Create a container div for the modal if one isn't there already
if ($("#simple-dialog-container").length == 0) {
// Add a container to the end of the body tag to hold the dialog
$('body').append('<div id="simple-dialog-container" style="display:none;"></div>');
try {
// Attempt to invoke the simple dialog
$( "#simple-dialog-container", context).dialog({
autoOpen: false,
modal: true,
close: function(event, ui) {
// Clear the dialog on close. Not necessary for your average use
// case, butis useful if you had a video that was playing in the
// dialog so that it clears when it closes
$('#simple-dialog-container').html('');
}
});
var defaultOptions = Drupal.simpleDialog.explodeOptions(settings.simpleDialog.defaults);
$('#simple-dialog-container').dialog('option', defaultOptions);
}
catch (err) {
// Catch any errors and report
Drupal.simpleDialog.log('[error] Simple Dialog: ' + err);
}
}
// Add support for custom classes if necessary
var classes = '';
if (settings.simpleDialog.classes) {
classes = ', .' + settings.simpleDialog.classes;
}
$('a.simple-dialog' + classes, context).each(function(event) {
if (!event.metaKey && !$(this).hasClass('simpleDialogProcessed')) {
// Add a class to show that this link has been processed already
$(this).addClass('simpleDialogProcessed');
$(this).click(function(event) {
// prevent the navigation
event.preventDefault();
// Set up some variables
var url = $(this).attr('href');
// Use default title if not provided
var title = $(this).attr('title') ? $(this).attr('title') : settings.simpleDialog.title;
if (!title) {
title = $(this).text();
}
// Use defaults if not provided
var selector = $(this).attr('name') ? $(this).attr('name') : settings.simpleDialog.selector;
var options = $(this).attr('rel') ? Drupal.simpleDialog.explodeOptions($(this).attr('rel')) : Drupal.simpleDialog.explodeOptions(settings.simpleDialog.defaults);
if (url && title && selector) {
// Set the custom options of the dialog
$('#simple-dialog-container').dialog('option', options);
// Set the title of the dialog
$('#simple-dialog-container').dialog('option', 'title', title);
// Add a little loader into the dialog while data is loaded
$('#simple-dialog-container').html('<div class="simple-dialog-ajax-loader"></div>');
// Change the height if it's set to auto
if (options.height && options.height == 'auto') {
$('#simple-dialog-container').dialog('option', 'height', 200);
}
// Use jQuery .get() to request the target page
$.get(url, function(data) {
// Re-apply the height if it's auto to accomodate the new content
if (options.height && options.height == 'auto') {
$('#simple-dialog-container').dialog('option', 'height', options.height);
}
// Some trickery to make sure any inline javascript gets run.
// Inline javascript gets removed/moved around when passed into
// $() so you have to create a fake div and add the raw data into
// it then find what you need and clone it. Fun.
$('#simple-dialog-container').html( $( '<div></div>' ).html( data ).find( '#' + selector ).clone() );
// Attach any behaviors to the loaded content
Drupal.attachBehaviors($('#simple-dialog-container'));
});
// Open the dialog
$('#simple-dialog-container').dialog('open');
// Return false for good measure
return false;
}
});
}
});
}
}
// Create a namespace for our simple dialog module
Drupal.simpleDialog = {};
// Convert the options to an object
Drupal.simpleDialog.explodeOptions = function (opts) {
var options = opts.split(';');
var explodedOptions = {};
for (var i in options) {
if (options[i]) {
// Parse and Clean the option
var option = Drupal.simpleDialog.cleanOption(options[i].split(':'));
explodedOptions[option[0]] = option[1];
}
}
return explodedOptions;
}
// Function to clean up the option.
Drupal.simpleDialog.cleanOption = function(option) {
// If it's a position option, we may need to parse an array
if (option[0] == 'position' && option[1].match(/\[.*,.*\]/)) {
option[1] = option[1].match(/\[(.*)\]/)[1].split(',');
// Check if positions need be converted to int
if (!isNaN(parseInt(option[1][0]))) {
option[1][0] = parseInt(option[1][0]);
}
if (!isNaN(parseInt(option[1][1]))) {
option[1][1] = parseInt(option[1][1]);
}
}
// Convert text boolean representation to boolean
if (option[1] === 'true') {
option[1]= true;
}
else if (option[1] === 'false') {
option[1] = false;
}
return option;
}
Drupal.simpleDialog.log = function(msg) {
if (window.console) {
window.console.log(msg);
}
}
})(jQuery);
Link that is using this module, in the source looks like this:
<a href='/user' name='user-login' id='user-login' class='simple-dialog' title='Login ' rel='width:400;resizable:false;position:[center,60]'>Log in</a>
The problem is that when you click on that link, it takes a second or two to load the popup and when it actually loads, second set of select dropdown list is being generated. If you click login link one more time, it generates third select list. Basically it duplicates whatever is converted from ul li into select list.
Thanks for help in advance.
jQuery(document).ready( function($) {
$(".region-menu-inner nav").empty(); //empty here
//build dropdown - main navigation
$("<select />").appendTo(".region-menu-inner nav");
// Create default option "Go to..."
$("<option />", {
"selected": "selected",
"value" : "",
"text" : "Navigate..."
}).appendTo("nav select");
// Populate dropdowns with the first menu items
$(".region-menu-inner li a").each(function() {
var el = $(this);
$("<option />", {
"value" : el.attr("href"),
"text" : el.text()
}).appendTo(".region-menu-inner select");
});
//make responsive dropdown menu actually work
$(".region-menu-inner select").change(function() {
window.location = $(this).find("option:selected").val();
});
});

Categories