jqueryui accordion disable specific according tab - javascript

hi i am trying to make a wizard for first time i want to disable all accordion tabs when i click on the link it enable next tab and open it..
i hve this code but it disable all tabs :(
thanks
$(function() {
$("#list1a").accordion({
autoHeight: false,
navigation: false
});
});
$("#list1a").accordion("disable");
$("#list1a").accordion("activate", 2 );

Don't use the accordion for that, it's not intended for wizardry. And since there's no wizard component available in jquery UI, lets make our own ;)
html:
<ul class="ui-wizard">
<li class="ui-wizard-panel">
<h3 class="ui-wizard-header">panel 1</h3>
<div class="ui-wizard-content">
Panel content
<span class="ui-wizard-next">Goto next</span>
</div>
</li>
<li class="ui-wizard-panel">
<h3 class="ui-wizard-header">panel 1</h3>
<div class="ui-wizard-content">
Panel content
<span class="ui-wizard-next">Goto next</span>
</div>
</li>
</ul>
javascript plugin:
$.fn.wizard = function(){
this.find('.ui-wizard-content').hide();
this.find('.ui-wizard-content:first').show();
this.find('.ui-wizard-content:last .ui-wizard-next').hide(); // just in case
this.delegate('.ui-wizard-next', 'click', function(){
// very long jquery chain...
$(this).closest('.ui-wizard-content')
.hide('fast')
.closest('.ui-wizard-panel')
.next()
.find('.ui-wizard-content')
.show('fast');
});
}
javascript impl:
$(".ui-wizard").wizard();
Ofcourse.. you'd have to theme it yourself, though copy/pasting and renaming accordion styles gets you a long way. A nicer way would be to make an official wizard widget out of this.

Can also check out this code: http://github.com/desdev/jWizard/
Think it's exactly what you need.

Try ui-state-disabled class: http://api.jqueryui.com/theming/css-framework/
Consider this piece of code that allows user go back, but not go to next accordion tab:
function disableAccordionNextTabs () {
var $accordion = $(".accordion");
var active = $accordion.accordion('option', 'active');
var $headers = $accordion.find($accordion.accordion('option', 'header'));
$headers.addClass('ui-state-disabled');
for (var i = active; i >= 0; i--) {
$headers.eq(i).removeClass('ui-state-disabled');
}
}

Related

Openness default the first tab accordion

I have an accordion that works really well, it looks good on the site and works as it should. However, I'm trying to add some more JavaScript functionality to it, to make it more it look more professional.
i want to make first accordion tab open by using JavaScript. thanks in advance.
HTML Code
<div class="accordion"><b>Heading 1</b></div>
<div class="panel">
<p class="text-light">Text 1</p>
</div>
<div class="accordion"><b>Heading 2</b></div>
<div class="panel">
<p class="text-light">Text 2</p>
</div>
JS Code
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function() {
var active = document.querySelector(".accordion.active");
if (active && active != this) {
active.classList.remove("active");
active.nextElementSibling.classList.remove("show");
}
this.classList.toggle("active");
this.nextElementSibling.classList.toggle("show");
}
}
I think Jquery UI's accordion has the first tab open by default and never allows you to have all tabs closed at once.
Check your .js file to see if it's being overridden by active: false. If active: false is there either delete it or change it to active: 0; (0 is first tab (zero based indexing))
Active: false will require the setting collapsible: true, which allows for closing a tab by clicking it so you may also see that in there.

Bootstrap tabs with CodeMirror

I have a pretty complex page where I have a number of instances of CodeMirror in hidden tabs within tabs. To then make it even more complex I remember the last active tabs.
I've manage to get it half working (http://codepen.io/anon/pen/LheaF) the problems are with the Second Editor tabs:
Its loading the Second tabs before the main Code Mirror tabs has been clicked. When you do click the Code Mirror tab it doesn't load the editor correctly either, until you click twice.
I want the second tabs to call the refresh() method if its already been initiated, like I do for the main editor.
Bug where its duplicating the secondary editors
(function($) {
var mainEditor;
function initMainCodeEditor() {
if (mainEditor instanceof CodeMirror) {
mainEditor.refresh();
} else {
// Load main editor
var el = document.getElementById("codifyme");
mainEditor = CodeMirror.fromTextArea(el, {
lineNumbers: true
});
mainEditor.setSize('100%', 50);
}
}
function initSecondaryCodeEditor() {
var $active = $('#code_mirror_editors > .active > a');
var $sec_tab = $($active.data('target'));
CodeMirror.fromTextArea($sec_tab.find('textarea')[0], {
lineNumbers: true
});
}
$(document).ready(function() {
// Only load editors if tab has been clicked
$('#maintabs > li > a[data-target="#codemirror"]').on('shown.bs.tab', function(e) {
initMainCodeEditor();
});
$('#code_mirror_editors > li > a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
initSecondaryCodeEditor();
});
// Remember tabs
var json, tabsState;
$('a[data-toggle="tab"]').on('shown.bs.tab', function(e) {
tabsState = localStorage.getItem("tabs-state");
json = JSON.parse(tabsState || "{}");
json[$(e.target).parents("ul.nav.nav-pills, ul.nav.nav-tabs").attr("id")] = $(e.target).data('target');
localStorage.setItem("tabs-state", JSON.stringify(json));
});
tabsState = localStorage.getItem("tabs-state");
json = JSON.parse(tabsState || "{}");
$.each(json, function(containerId, target) {
return $("#" + containerId + " a[data-target=" + target + "]").tab('show');
});
$("ul.nav.nav-pills, ul.nav.nav-tabs").each(function() {
var $this = $(this);
if (!json[$this.attr("id")]) {
return $this.find("a[data-toggle=tab]:first, a[data-toggle=pill]:first").tab("show");
}
});
}); // doc.ready
})(jQuery);
The problems:
it might happen that you create the CodeMirror on an element which is not visible (one of it's parents has display: none). This breaks various calculations done by CodeMirror
by getting the CodeMirror instance right from the CodeMirror container element enables us to call refresh everytime you want (by finding the .CodeMirror next to your textarea)
fixed as a side effect of 2.
HTML
Here's a bootstrap tab frame, if you use jquery-UI, it's gonna be a little different.
<ul class="nav nav-tabs">
<li class="active">tab1</li>
<li>tab2</li>
</ul>
<div class="tab-content">
<div class="tab-pane fade in active" id="tab1"><textarea type="text" id="tab1Content" name="xxx"></textarea></div>
<div class="tab-pane fade" id="tab2"><textarea type="text" id="tab2Content" name="yyy"></textarea></div>
</div>
JS
var cm1, cm2;
$(document).ready(function () {
//when the bootstrap tab is fully shown, call codemirror's refresh().
//Also, if you use jquery-UI, it's gonna be different here.
$('.nav-tabs a').on('shown.bs.tab', function() {
cm1.refresh();
cm2.refresh();
});
cm1 = CodeMirror.fromTextArea(document.getElementById("tab1Content"), {
lineNumbers: true
});
cm2 = CodeMirror.fromTextArea(document.getElementById("tab2Content"), {
lineNumbers: true
});
});
Working Solution: http://codepen.io/anon/pen/hupwy
I addressed issues 2 and 3 as I could not replicated 1.
I used a hash table to store the second editor CodeMirror objects. Then I modified your existing mainEditor code to refresh the objects if they already exist.
var seccondEditor = new Object();
function initSecondaryCodeEditor(){
var $active = $('#code_mirror_editors > .active > a');
var $sec_tab = $($active.data('target'));
var sec_edi = ($sec_tab.find('textarea')[0]);
if(seccondEditor[sec_edi.id] instanceof CodeMirror){
seccondEditor[sec_edi.id].refresh();
} else {
seccondEditor[sec_edi.id] = CodeMirror.fromTextArea(sec_edi, {lineNumbers: true});
}
}
I'm not well versed in CodeMirror so this might no be the most elegant solution, but it looks like the code above prevents the duplicates you were seeing. Hope this helps.
if the problem occurs when codemirror render content within an hidden div, why not just diplay all the tab-panel div, then call codemirror, then hide unneeded tab ??
HTML:
<div role="tabpanel" class="tab-pane active" id="tp1">
<textarea class="code" data-lang="text/html">
<!--- content #1 here -->
</textarea>
</div>
<div role="tabpanel" class="tab-pane active hideAfterRendering" id="tp2">
<textarea class="code" data-lang="text/html">
<!--- content #2 here -->
</textarea>
</div>
<div role="tabpanel" class="tab-pane active hideAfterRendering" id="tp3">
<textarea class="code" data-lang="text/html">
<!--- content #3 here -->
</textarea>
</div>
SCRIPT:
<script>
$( document ).ready(function() {
//render codeMirror
$('.code').each(function() {
CodeMirror.fromTextArea(this, {
mode: "properties",
lineNumbers: true,
indentUnit: 4,
readOnly: true,
matchBrackets: true
});
});
//hide tab-panel after codeMirror rendering (by removing the extra 'active' class
$('.hideAfterRendering').each( function () {
$(this).removeClass('active')
});
});
</script>
Works well for me !!
Why not just to set timeout?.. just exec that code when tab clicked:
update_mirror = function() {
var codeMirrorContainer = $sec_tab.find(".CodeMirror")[0];
if (codeMirrorContainer && codeMirrorContainer.CodeMirror) {
codeMirrorContainer.CodeMirror.refresh();
}
}
// Attention! magic!
setTimeout(update_mirror, 100);
That helped me a lot while I had a battle against that problem. Thanks to Sekaryo Shin, he saved my time.

Open Expanding List from Href

I'm trying to modify this pen I found on CodePen. I'd like to be able to open a specific list on the page from another page. Clicking the link should open the corresponding section on the next page on page load.
I'm a bit of a newbie when it comes to jQuery, so I appreciate any help I can get. I've tried searching around and have an idea of what I need to target, but I haven't been able to make it happen. Here is my code:
HTML:
<!--Link on Previous Page-->
Click Here
<!--Target List-->
<div class="integration-list">
<ul>
<li class="integration">
<a class="expand" id="list">
<div class="expand_intro"><h3 class="teal_bold">Click Here</h3></div>
<div class="right-arrow">▼</div>
</a>
<div class="detail">
<div><p>Lorem Ipsum Dolor...</p></div>
</div>
</li>
</ul>
</div>
JS:
$(function() {
$(".expand").on( "click", function() {
$(this).next().slideToggle(100);
$expand = $(this).find(">:nth-child(2)");
if($expand.text() == "▼") {
$expand.text("▲");
} else {
$expand.text("▼");
}
var hash = window.location.hash;
var thash = hash.substring(hash.lastIndexOf('#'), hash.length);
$('.expand').find('a[href*='+ thash + ']').trigger('click');
});
});
Few things that I did to get it to work:
The trigger event is probably firing before the handler is actually attached. You can use setTimeout as a way around this.
Also, even with setTimeout around $('.expand').find('a[href*='+ thash + ']').trigger('click'); it didn't work for me. I changed that to simply $(thash).click();.
The complete code of the "expand.js" file:
$(function() {
var hash = window.location.hash;
var thash = hash.substring(hash.lastIndexOf('#'), hash.length);
setTimeout(function() {
$(thash).click();
}, 10);
$(".expand").on( "click", function() {
$(this).next().slideToggle(100);
$expand = $(this).find(">:nth-child(2)");
if($expand.text() == "â–¼") { //If you copy/paste, make sure to fix these arrows
$expand.text("â–²");
} else {
$expand.text("â–¼");
}
});
});
Apparently the arrows don't display properly here, so watch that if you copy/paste this.

JQuery jCarousel with paging dots?

I was using jCarousel plugin to display a series of items. I was following this example from the web site to get external controls and a paging control.
There's two problems with this approach:
i need to add the items for the numbers manually (instead of just calculating the number of items in the carousel with JS), although I can live with this, and
There seems to be no way to highlight (via a class change) the item for the current slide
What I am doing is using bullets as paging dots, as you can see in this fiddle
<div class="carousel-nav cf">
<table>
<tr>
<td>◀</td>
<td>
<div class="jcarousel-control">
•
•
•
</div>
</td>
<td>►</td>
</tr>
</table>
</div>
and would like to set the class to "active" or similar for the current item.
Any ideas? Or is there a better plugin for this? I tried Cycle but I need two have 2 or more items showing at once. Thanks.
html:
<ul class="jcarousel-control"></ul>
script:
$('.jcarousel-control')
.on('jcarouselpagination:active', 'li', function() {
$(this).addClass('active');
})
.on('jcarouselpagination:inactive', 'li', function() {
$(this).removeClass('active');
})
.jcarouselPagination({
'perPage':1,
'item': function(page, carouselItems) {
return '<li class="' + (page == 1 ? "active" : "") + '"></li>';
}
});
$('.mycarousel-prev').jcarouselControl({target:'-=1'});
$('.mycarousel-next').jcarouselControl({target:'+=1'});
actually you can use call back function for higlighting respective to current active carousel element
function highlighttab1(carousel, state, liindex) {
document.getElementById(liindex).className = "selected";}
function removehighlighttab1(carousel, state, liindex) {
document.getElementById(liindex).className = "unselected";}
few days ago i worked with jcarousel where i had menu label panel (as you have dots) and all static hyperlinks which when clicked will scroll to the intendent carousel element

Jquery Expand Collapse all divs on Click

I know this has been asked a thousand times but I'm still having trouble figuring it out. I have a simple according following this tutorial and I'm trying to add an "expand/collapse all" link. I have found a way to expand all but can't figure out how to collapse them. The problem with a slideToggle() solution is if I open one then click the link it will close/open all of them but the one that was previoiusly active.
I set up a jsFiddle here.
Here is an overview of the code:
HTML:
<h2 class="acc_trigger">Div 1</h2>
<div class="acc_container">
<div class="block"> Yay content!</div>
</div>
<h2 class="acc_trigger">Div 2</h2>
<div class="acc_container">
<div class="block">More Content, Score!</div>
</div>
<h2 class="acc_trigger">Div 3</h2>
<div class="acc_container">
<div class="block">Even More Content</div>
</div>
Expand/Collapse All
JS:
jQuery(document).ready(function($) {
//Set default open/close settings
$('.acc_container').hide(); //Hide/close all containers
//On Click
$('.acc_trigger').click(function(){
$('.acc_trigger').removeClass('active').next().slideUp();
//Remove all "active" state and slide up the immediate next container
$(this).toggleClass('active').next().slideDown();
return false; //Prevent the browser jump to the link anchor
});
$('.acc_expand-all').click(function(){
//expand all on click
$('.acc_trigger').addClass('active').next().slideDown();
return false;
});
});
You have to check in your expand/collapse handler to see how many are open, etc., something like this (updated fiddle):
$('.acc_expand-all').click(function(){
var all = $('.acc_trigger'),
active = all.filter('.active');
if (all.length && all.length === active.length) {
// All open; close them
all.removeClass('active').next().slideUp();
}
else {
// At least some are closed, open all
all.not('.active').addClass('active').next().slideDown();
}
return false;
});
Regarding your question in the comments, you can check to see whether you should be in "exclusive" mode or not by checking how many are open and whether the clicked one is open, e.g. (updated fiddle):
$('.acc_trigger').click(function(){
var $this = $(this),
thisActive = $this.hasClass('active'),
active;
// If this one is active, we always just close it.
if (thisActive) {
$this.removeClass('active').next().slideUp();
}
else {
// Is there just one active?
active = $('.acc_trigger.active');
if (active.length === 1) {
// Yes, close it
active.removeClass('active').next().slideUp();
}
// Open this one
$this.addClass('active').next().slideDown();
}
});

Categories