0

For some reason I can't activate an accordion panel using data stored in a data-active attribute?

My HTML looks like this (after it's turned to an accordion and has all the classes added):

<div class="gcAccordion  ui-accordion ui-widget ui-helper-reset" style="" data-active="1" role="tablist">
    <h3 class="gcAccordionTitle  ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-accordion-icons" style="display: block;" role="tab" id="ui-accordion-1-header-0" aria-controls="ui-accordion-1-panel-0" aria-selected="false" tabindex="0"><span class="ui-accordion-header-icon ui-icon ui-icon-triangle-1-e"></span>This is a title</h3>
    <div class="gcAccordionContent  ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" style="display: none;" id="ui-accordion-1-panel-0" aria-labelledby="ui-accordion-1-header-0" role="tabpanel" aria-expanded="false" aria-hidden="true">This is some content</div>
    <h3 class="gcAccordionTitle  ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-accordion-icons" style="display: block;" role="tab" id="ui-accordion-1-header-1" aria-controls="ui-accordion-1-panel-1" aria-selected="false" tabindex="-1"><span class="ui-accordion-header-icon ui-icon ui-icon-triangle-1-e"></span>This is a 2nd title</h3>
    <div class="gcAccordionContent  ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" style="display: none;" id="ui-accordion-1-panel-1" aria-labelledby="ui-accordion-1-header-1" role="tabpanel" aria-expanded="false" aria-hidden="true">This is some 2nd content</div>
    <h3 class="gcAccordionTitle  ui-accordion-header ui-helper-reset ui-state-default ui-corner-all ui-accordion-icons" style="display: block;" role="tab" id="ui-accordion-1-header-2" aria-controls="ui-accordion-1-panel-2" aria-selected="false" tabindex="-1"><span class="ui-accordion-header-icon ui-icon ui-icon-triangle-1-e"></span>This is a 3rd title</h3>
    <div class="gcAccordionContent  ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" style="display: none;" id="ui-accordion-1-panel-2" aria-labelledby="ui-accordion-1-header-2" role="tabpanel" aria-expanded="false" aria-hidden="true">This is some 3rd content</div>
</div>

Javascript:

$('.gcAccordion').accordion({
  collapsible: true,
  heightStyle: "content",
  autoHeight: false,
  active: false,
  create: function(event, ui){
    $('.gcAccordion').each(function(){
      console.log($(this).attr('data-active'));
      $(this).accordion( "option", "active", $(this).attr('data-active'));          
    });
  }      
}); 

The console.log call properly outputs a 1 to the log but for some reason it doesn't activate the second panel. If I use this line for line 9 in the javascript it works:

$(this).accordion( "option", "active", 1);

But it won't work with the data-active attributes 1 value. Any ideas what's going on?

edit: removed link as the page is no longer active and all the code is in the question anyway.

UPDATE:

Thanks for the help. I needed to parseInt($(this).attr('data-active'))

tsdexter
  • 2,911
  • 4
  • 36
  • 59
  • 1
    You can access "data-" attributes as `$(this).data("active")` – Pointy Mar 26 '13 at 14:00
  • Thanks - I realized I needed parseInt right after I posted. This works as well though and I was unaware of that feature so thanks. – tsdexter Mar 26 '13 at 14:03
  • @tsdexter Just note that using `.data()` will attempt to convert the value to the right type it looks like it represents. So of course, in your case, that's probably ideal for something like this. But for future reference, it may or may not be the best idea. It's usually useful enough to use though :) `.data()` also gets the current value, not the original (kind of like how `.prop` and `.attr` differ). – Ian Mar 26 '13 at 14:07
  • @Ian thanks, that's good to know indeed. I'm going to stick with parseInt() anyway as it will always return an Int and the data-active attr is output via a WP shortcode so I can rely on it being an Int, plus I have to subtract 1 from it anyway as it's 0 based and my users won't think to subtract 1 themselves. – tsdexter Mar 26 '13 at 14:08
  • @tsdexter I agree, I would've used `parseInt` or `+` too. Just wanted to point out that `.data` is similar to `.prop`, where `.attr` gets the original value set. – Ian Mar 26 '13 at 14:12

1 Answers1

3

The type of value returned by .attr() is a string. I'm betting you need a true/false (0/1) value, so try:

$(this).accordion("option", "active", +$(this).attr('data-active'));

The + unary operator is similar to parseInt, converting strings to numbers, but has less strict parsing, and is faster (I think).

Something that might be better is:

$(this).accordion("option", "active", $(this).attr('data-active') === "1" ? 1 : 0);

This will cause the accordion pane to be active only if the data-active attribute exists and its value is "1". Any other combination of existence/value will not open the pane.

EDIT:

Ignore the second example, as the "active" option accepts a 0-based integer, as the OP pointed out. I assumed it accepted true/false for some reason.

Ian
  • 50,146
  • 13
  • 101
  • 111
  • Thanks, I didn't use your answer but I realized I needed parseInt()... Fresh eyes... – tsdexter Mar 26 '13 at 14:04
  • Thanks for the edit but it actually needs a 0 based index of the active pane not a true/false. – tsdexter Mar 26 '13 at 14:05
  • @tsdexter Haha sounds good. Yeah, that makes more sense as I think about it :) – Ian Mar 26 '13 at 14:07
  • I used and accepted this as the answer as you said the + is faster (and less chars too) so the final code on line 9 (actually 8 now since I removed the console.log()) is $(this).accordion( "option", "active", (+$(this).attr('data-active') - 1)); - thanks again! – tsdexter Mar 26 '13 at 14:18
  • @tsdexter Looks good! So I actually found out its speed depends on which OS/browser you're using. Here's a few things to look at: http://jsperf.com/performance-of-parseint and http://jsperf.com/parseint-vs-unary-operator . Also, some things to read - http://stackoverflow.com/questions/1133770/how-do-i-convert-a-string-into-an-integer-in-javascript and http://stackoverflow.com/questions/4090518/string-to-int-use-parseint-or-number . Your example is so simple, and doesn't seem to occur often (it would be different if you were looping thousands of times) that it's fine to use any of the methods – Ian Mar 26 '13 at 14:32
  • Thanks @Ian, I'll give those a read. And yes, the most it would loop on 1 page is probably about 20 or so accordion panes. – tsdexter Mar 26 '13 at 14:34
  • @tsdexter Also, note that using `parseInt` will ignore trailing characters. So using `parseInt("234px", 10);` would yield `234`. `parseInt("s23", 10);` would yield `NaN`, and so would `+"s23"` or `+"23px"`. Again, for your example, it probably wouldn't matter which one you used. But it's good information in general :) – Ian Mar 26 '13 at 14:34
  • Thanks - looks like + is faster for most browsers - and double the speed for my setup. – tsdexter Mar 26 '13 at 14:40