Search code examples
javascripttwitter-bootstrapgrailsgsp

Nested Accordion table icon won't change when class id set programatically


I have nested accordion bootstrap tables in a Grails .gsp page that work fine, except for the icon changing from a "+" to a "-" when collapsing/expanding. I can get it to work if I take out the dynamic id variables and statically set the data target id instead of using data-target="#${orgs.ORGN}" and id="${orgs.ORGN}". The icon won't change when I let the g:each loop create the id's and the data, though they do collapse correctly. Any thoughts? Is there something about setting the id's on the fly that won't work?

<div class="col-lg-8">
<div class="panel panel-default">
    <div class="panel-heading"></div>
        <table class="table table-condensed" style="border-collapse:collapse;">
            <thead>
            <tr>
                <th>&nbsp;</th>
                <th>Org</th>
                <th>Description</th>
                <th>Budget</th>
                <th>YTD</th>
                <th>Remaining</th>
            </tr>
            </thead>
            <tbody>
            <g:each in="${overview}" var="orgs">
                <tr data-toggle="collapse" data-target="#${orgs.ORGN}" class="accordion-toggle" style="cursor:pointer">
                    <td><i class="fa fa-plus-square"></i></td>
                    <td>${orgs.ORGN}</td>
                    <td>${orgs.ORGNTITLE}</td>
                    <td>${orgs.BUDGET}</td>
                    <td>${orgs.YTD}</td>
                    <td>${orgs.REMAINING}</td>
                </tr>
                <td colspan="8" class="hiddenRow">
                    <div class="accordian-body collapse" id="${orgs.ORGN}">
                        <table class="table table-condensed">
                        <thead>
                            <tr><th>Account</th>
                                <th>Title</th>
                                <th>Budgeted</th>
                                <th>YTD</th>
                                <th>Remaining</th>
                            </tr>
                            </thead>
                            <tbody>
                            <g:each in="${orgs.expenses}" var="budget">
                                <tr>
                                    <td>${budget.ACCTCODE}</td>
                                    <td>${budget.ACCTTITLE}</td>
                                    <td>${budget.BUDGETACCEPTED}</td>
                                    <td>${budget.YTDACTIVITY}</td>
                                    <td>${budget.BUDGETREMAINING}</td>
                                </tr>
                            </g:each>
                            </tbody>
                        </table>
                    </div>
                </td>
            </g:each>
            </tbody>
        </table>
</div>
</div>

My JS is

  $('tr').on('shown.bs.collapse', function(){
$(this).prev('tr').find(".fa-plus-square").removeClass("fa-plus-square").addClass("fa-minus-square");
}).on('hidden.bs.collapse', function(){
$(this).prev('tr').find(".fa-minus-square").removeClass("fa-minus-square").addClass("fa-plus-square");
});

Thanks for any help.


Solution

  • It sounds like you are trying to run your jQuery code prior to the DOM being fully loaded. I'd recommend looking at the various ways to do this in the jQuery documentation. Typically this is done using $( document ).ready().