Foundation-sites: [Accordion] Foundation overrides id and aria-labelledby information

Created on 19 Jan 2016  ·  26Comments  ·  Source: foundation/foundation-sites

How can we reproduce this bug?

  1. Create an accordion list with AngularJS ng-repeat
  2. Check the id and aria-labelledby which are overridden by "panelname-label"
  3. Even hardcoding it, doesnt resolve the problem

Code Sample

<div class="row">
  <div class="small-12 columns">
    <br>
    <ul class="accordion" data-accordion role="tablist" data-allow-all-closed="true">
      <li class="accordion-item" ng-repeat=" questions in FAQ ">
        <a href="#{{ questions.answerID }}" role="tab" class="accordion-title" id="{{ questions.questionID }}" aria-controls="{{ questions.answerID }}">
           <h5>{{ questions.question }}</h5>
        </a>
        <div id="{{ questions.answerID }}" class="accordion-content" role="tabpanel" data-tab-content aria-labelledby="{{ questions.questionID }}">
                {{ questions.answer }}
        </div>
      </li>
    </ul>
  </div>
</div>

Is there a known issue with this?

accessibility javascript 🐛bug

Most helpful comment

@Saifadin can you please create a codepen of your working code. I am having the exact same issue and and can't seem to get it working. Thank you so much!

@jmathur5 Sure, the final solution was, that I waited for document.ready and called it out of the controller.

See: http://codepen.io/Saifadin/pen/xqEZXO

All 26 comments

Hi,

We've just been having exactly the same problem.
We need to use the ID attribute for link tracking in Site Catalyst but it's being over written by the Foundation tabs component.

Please can this component use a different attribute. Users shold be able to specify their own id's or at least specify what attribute to use in the config.

Kind regards,
Jason

Oversight on my part, most plugins check for an id, and if none is found, apply one where necessary. The id attribute is required for most aria attributes, which is why the js is applying on in the first place. I'll get this fixed to check first before overwriting any preexisting ids. Looks like tabs and accordion both need the check.

@Saifadin your stuff should be good. The ids being assigned are checked first here:

this.$tabs.each(function(idx, el){
      var $el = $(el),
          $content = $el.find('[data-tab-content]'),
          id = $content[0].id || Foundation.GetYoDigits(6, 'accordion'), // <-- if you already have an id applied, it won't overwrite it.
          linkId = el.id || id + '-label';

So the issue may be initialization order, i.e. waiting for Angular to finish loading that scope and within a digest cycle, calling $(document).foundation()

for tabs: c2cb63f

Thanks @zurbchris for your answer.
I am actually loading foundation in the directive after the code like this:

<script>$('#faqs').foundation();</script> 

but it seems like foundation is being loaded before that, I dont know at which point exactly

You'll probably need to use a DOMContentLoaded event or tap into the $watch/$apply/$digest callback system to wait for NG to finish it's business before you pop $('#foo').foundation().

I see I'll have to try that in the morning at work, but putting that aside, if foundation generates its id-labels, shouldn't it be still working? In the rendered html tha tag has id="panel1-label" and the

Can you create a codepen or fiddle to replicate, or at least a stack trace if there's an error? I can't think of why it wouldn't run, unless NG is swallowing the event listeners.

Fixed: https://codepen.io/zurbchris/pen/GoOzJd
this is the code added to your controller:

window.onload = function(){
    $(document).foundation();
  }

Foundation was never initialized in the example you linked.

Okay I'll try that out and come back to you guys!

Now the id i set is taken, but the accordion is still not working. It's written in the exact same way.

Here I screenshoted the generated output in Google Chrome

http://imgur.com/G3MBEJd

So after some testing with my colleagues we came to this conclusion:

It seems like the accordion is rendered correctly, but somehow the trigger for the opening and closing is not reacting (no error message in the console either).
Could the problem lay in multiple declarations of $(document).foundation();?

multiple calls to $(document).foundation(); shouldn't cause problems, as it just ignores, (and logs a warning to the console), elements with previously initiated plugins.

I'm flummoxed by the thing not working though. Do me a favor in your dev build and drop this in somewhere after ng is done rendering the accordion, if you haven't done something similar already:

$('a', '.accordion').on('click', function(e){
  console.log(e.target, e.currentTarget);
});

I just want to verify the click handlers are firing at all, and since my codepen above works, I'm trying to debug an app remotely. I've updated my codepen to reflect the request, and it works there as well.

The click handlers are not fired at all.

I will have to look at it later, right now we had to take the hardcoding measure in the index.html until I find a permanent solution. It is kinda weird that although i start foundation multiple times it is not triggered at all.

I think I can narrow it down now after some testing.

The issues lays in the ng-repeat function, in a directive of AngularJS. Somehow some functions load faster then others and block each other.
It happens with the Accordion and with the Dropdown Menu. Weirdly tabs don't have this problem. I even load $(document).foundation(); so often that i get a warning, that it is already loaded for some elements. see here: http://imgur.com/2vNNSuM

So it's probably like this:

  • directive is loaded
  • foundation is initialized
  • menu is generated through ng-repeat
  • thats it

Hope this can help clarify

@Saifadin Dunno if you nailed this down but perhaps you could trigger a function (which initialized Foundation) on the $last of ng-repeat ??

<li class="accordion-item" ng-repeat="questions in FAQ " ng-init="$last ? doSomething() : null">

I solved this problem a week ago, when it came up, by writing that part as a directive and using the controller to call $document.foundation();

The controller of a directive is called when the directive is fully loaded, thats why it works. Took a while to solve ^^

On 25.06.2016, at 18:18, Joe Watkins [email protected] wrote:

@Saifadin Dunno if you nailed this down but perhaps you could trigger a function (which initialized Foundation) on the $last of ng-repeat ??



  • You are receiving this because you were mentioned.
    Reply to this email directly, view it on GitHub, or mute the thread.

  • @Saifadin can you please create a codepen of your working code. I am having the exact same issue and and can't seem to get it working. Thank you so much!

    @Saifadin can you please create a codepen of your working code. I am having the exact same issue and and can't seem to get it working. Thank you so much!

    @jmathur5 Sure, the final solution was, that I waited for document.ready and called it out of the controller.

    See: http://codepen.io/Saifadin/pen/xqEZXO

    Thank you!!!!! @Saifadin

    Trying to figure out the state of this issue... it looks like the issue of overriding values was resolved, and the remaining issue was enabling foundation after an angular render, is that correct? Can we close this?

    No response. Closing.

    @Saifadin We are awaiting your reply here
    If you still think there is a bug here, let us know
    we will reopen

    Sorry for not replying. Yes its resolved. The final solution was to wait for angular to render then enabling foundation. Thanks to @zurbchris for his help.

    Was this page helpful?
    0 / 5 - 0 ratings