4

This is a very simple situation but I am surprised that there is no solution discussed or question asked or may be it is so simple that I am the only one stumped by it.

In any Accordion, in which the panel has menus, there will be situations when the Content panel must not be displayed because the Header itself is the only option (of the menu). The header itself processes the click event and does something without expanding the content panel.

So, I tried the following:

a. All possible ways to have CSS set the div height of the content panel to zero, both static as well as dynamically, in various places, including in the activate and beforeactivate event handlers.

b. Added ui-state-disabled class to the header in the create event handler. Works fine but has two minor issues. First the disabled header gets a different CSS and second when clicking on the header, other panels do not collapse as the disabling of the header stops the click event from propagating further and doing its work of collapsing the currently opened content-panel. There is no collapse method available to be called expressly.

c. Tried the solutions in how to disable certain links of jquery accordion. Does not work.

Can someone suggest any new approach? Problem stated differently, is to implement an Accordion-driven menu. Menu widgets are embedded in panels when there are multiple options. If single, then header of the Accordion itself is the clickable menu item/option.

Community
  • 1
  • 1
Sunny
  • 9,245
  • 10
  • 49
  • 79

2 Answers2

3

you can use the event.toElement in beforeActivate function. first set a id to the h3 tag.

<h3 id="3">Section 3</h3>

now check if event.toElement id is 3. if so, execute event.preventDefault()

$("#accordion").accordion({
    beforeActivate: function (event, ui) {
        if($(event.toElement).attr('id') == 3)        
            event.preventDefault();
    }
});

Demo: JsFiddle

Edit to collapse active accordion when the accordion with only header is selected, use the below code

if($(event.toElement).attr('id') == 3){
    event.preventDefault();
    $("#accordion").accordion( "option", "active", false );
}

Modified Demo: JsFiddle

Edit Fix for icon. though a bit messy, it works

beforeActivate: function (event, ui) {
    var $span = $('#accordion h3#3 span').first();
    if ($(event.toElement).attr('id') == 3) {
        event.preventDefault();
        if ($span.hasClass('ui-icon-minus')) {
            $span.removeClass('ui-icon-minus');
            $span.addClass('ui-icon-plus');
        } else {
            $span.removeClass('ui-icon-plus');
            $span.addClass('ui-icon-minus');
        }
        $("#accordion").accordion("option", "active", false);
    } else if (event.toElement) {
        if ($span.hasClass('ui-icon-minus')) {
            $span.removeClass('ui-icon-minus');
            $span.addClass('ui-icon-plus');
        }
    }
}

Modified Demo: JsFiddle

th1rdey3
  • 4,176
  • 7
  • 30
  • 66
  • Thanks! Two problems still persist. First, the event handler on the icon needs to be handled too. I presume your logic should work there too, just need to identify the element which may be a bit tricky. Second if "collapsible" is set to true, then the collapsing of the previously active content panel does not occur, as expected, because the preventDefault stops it just as it stops the expansion of the current hdr. I think that it would be difficult to handle this in the absence of a collapse method for the widget.Any further suggestion? Getting close though. – Sunny Nov 03 '13 at 08:25
  • 1
    @Samir, updated the answer again, hope it helps. I didn't find any easy way to change the icon. so the code got a bit messy. – th1rdey3 Nov 03 '13 at 10:39
  • Great. All works fine in the demo as needed except for the icons. No change there but I get the hang of it. Overall a great job – Sunny Nov 03 '13 at 10:40
  • I tried the second update of your demo and it does not work with the icons. I mean a click on the icon next to the disabled hdr also expands the content panel. That said, I got the approach and probably can try from here. Will update if I find a fix or if I realize that I was trying/doing something wrong with your demo. Your efforts are greatly appreciated. I am relatively new to this forum. – Sunny Nov 03 '13 at 12:46
0

Actually this should be a comment and not my answer. But I could not squeeze it in the comments section and I am new to this forum. Just wanted to get the solution posted. It is TOTALLY based on directions provided by @th1rdey3 so you need to look at his solution first and then the edit here. The concept is that if the header is not going to have any expandable content, then the icon should be removed in the first place. This simplifies the solution and also makes the UI logical. The active state is added because the CSS changes the background color of the hdr accordingly which will not happen otherwise because of the preventDefault.

 $( "#accordion" ).accordion({collapsible: true, active:false, heightStyle:"content",
     icons: {
             "header": "ui-icon-plus",
             "activeHeader": "ui-icon-minus"
     }, 
     collapsible: true,
     create: function (event, ui) {
        $('#accordion h3#3 span').remove();
     },
     beforeActivate: function (event, ui) {
         $('#3').removeClass("ui-state-active"); //Can be removed conditionally too
         if ($(event.toElement).attr('id') == 3) {
                    event.preventDefault();
         $("#accordion").accordion("option", "active", false);
       } 
     }
 });
$('#3').click(function() {  $(this).addClass("ui-state-active"); /* do stuff here on click */ });
Sunny
  • 9,245
  • 10
  • 49
  • 79
  • @th1rdey3, Sorry I am new to this site. Did not know about upvoting of comments. Just found out and did it now to your earlier comments. – Sunny Nov 04 '13 at 15:36