Veli Gebrev
Veli Gebrev

Reputation: 2521

jQuery accordion: prevent pane from opening/cancel changestart event

I've got the following markup:

<div id="accordion" class="leftaligned">
    <div>
        <h3><a href="#">Stakeholder</a></h3>
        <div>Content</div>
    </div>
    <div>
        <h3><a href="#">Relationships</a></h3>
        <div>Blah blah</div>
    </div>
    <div>
        <h3><a href="#">Address</a></h3>
        <div>Yada yada</div>
    </div>
    <div>
        <h3><a href="#">Contact Details</a></h3>
        <div>Foo bar</div>
    </div>
</div>

I create an accordion as follows:

$("#accordion").accordion({
    header: "h3",
    fillSpace: true,
    changestart: function(event, ui) {
        if (someConditionIsTrue()) {
            event.stopPropagation();
            event.preventDefault();
            return (false);
        }
    }
});

The idea is that there are some use cases which would prevent the user from changing panes, however the above cancelling of the event has no effect and the panes can still be changed.

Is there a way to prevent the changing of panes? I also tried activating the current pane programmatically in order to prevent the change, but that fires another changestart event and all hell breaks loose (the accordion actually breaks)

Upvotes: 11

Views: 14415

Answers (10)

Borbea
Borbea

Reputation: 422

Maybe it's available in older jQueryUIs but if you use jQuery-UI 1.9.2 or newer you can disable accordion collapsing in beforeActivate event;

beforeActivate: function (event, ui) {
    event.preventDefault();
}

Upvotes: 0

Annabel
Annabel

Reputation: 1414

It's a few years after the question was originally asked and I'm using jQuery-UI 1.11.2 so this might not have been a valid answer then.

But this is what I found to work the best:

  1. First give the header you want to disable the id disable_this, or find some other way you can select the relevant header(s).
  2. Then add this line of code

    $('h3#disable_this').addClass('ui-state-disabled');
    

Some of the methods mentioned in earlier answers (unbind("click") and e.stopImmediatePropogation()) worked for me in the limited sense that they prevented the opening of the panel when the header was clicked. But my method has 2 additional benefits:

  • Stops the header taking on a highlighted style when clicked.

  • Gives the header a disabled style.

A lot more user-friendly.

Upvotes: 2

Adam Seabridge
Adam Seabridge

Reputation: 2044

$("#accordion .h3").unbind("click");

works for me.

Upvotes: 10

Aravind
Aravind

Reputation: 2198

$("#accordion h3").unbind("click");

Refer jsFiddle-accordion

Upvotes: 0

Abhishek
Abhishek

Reputation: 433

I am creating the contents of accordion dynamically, so binding the event call before accordion is generated is not working for me. So I tried out binding the stopImmediatePropagation after accordion is created and that worked out for me.

Upvotes: 0

Matt S
Matt S

Reputation: 1882

I needed a derivation of this behavior because I was chaining draggable and accordion. I'm putting my solution here for anyone looking for the same solution.

The behavior I was trying to avoid was triggering an accordion change after dragging when the headers are the handle for both accordion and draggable. So, every time you drag, it collapses the content section currently expanded.

HTML:

var $container = ('<div id="accordion">');
var $content = ('<div>');
$content.append(
    '<h1>Header 1</h1>' +
    '<div>Content 1</div>' +
    '<h1>Header 2</div>' +
    '<div>Content 2</div>'
);

JS:

$container.append($controls)
.draggable({
    handle: ':header',
    start: function(event, ui) {
        $(event.toElement).addClass('ui-dragging');
    }

});
$container.find(':header').click(function (event) {
    var $this = $(this);
    if ($(this).hasClass('ui-dragging')) {
        event.stopImmediatePropagation();
        $this.removeClass('ui-dragging');
    }
});
$container.accordion({
    collapsible: true,
    header: ':header'
});

Upvotes: 0

Serj Sagan
Serj Sagan

Reputation: 30208

Although there is a similar answer by user438316, it has too much unnecessary code, return false being a jarring obvious... how about just:

$('#accordion .deleted').click(function(e) {      
    e.stopImmediatePropagation();
});    
$('#accordion').accordion();

Upvotes: -1

user438316
user438316

Reputation: 249

Before initing accordion add your custom click handler with your logic. stopImmediatePropagation will stop event before accordion handler will be called.

$('.quiz-qa h3').click(function(e) {      
  if ($(this).hasClass("deleted")) {
    e.stopImmediatePropagation();
    return false;      
   }   
});    
$('.quiz-qa').accordion();

Upvotes: 7

Raphael Schweikert
Raphael Schweikert

Reputation: 18556

I filed an enhancement request for this: Ticket 6651.

Upvotes: 3

Veli Gebrev
Veli Gebrev

Reputation: 2521

I found a workaround which works in my context - I avoid having to cancel the event altogether by simply disabling the h3 headers (after giving them an id) when necessary:

html:

<div>
    <h3 id="relationshipsHeader"><a href="#">Relationships</a></h3>
    <div>Blah blah</div>
</div>

script:

if (someConditionIsTrue()) {
    $("#relationshipsHeader").attr("disabled", "disabled");
    // and so on...
}

Upvotes: 1

Related Questions