Accordion card issue when inside JS array

Issue

I currently have this list that properly displays each row of the database. The issue is that the accordion feature doesn’t work when put into the JS array, however, it works when directly put in HTML. I’m confused as to what I’m doing wrong here to cause it to fail to execute the accordion feature. Would like to understand why this isn’t working and how to fix it. Thanks.

Here is the JS:

<script>
    var acc = document.getElementsByClassName("accordionList");
    var i;

    for (i = 0; i < acc.length; i++) {
    acc[i].addEventListener("click", function() {
        this.classList.toggle("activeLink");
        var panel = this.nextElementSibling;
        if (panel.style.maxHeight) {
        panel.style.maxHeight = null;
        } else {
        panel.style.maxHeight = panel.scrollHeight + "px";
        } 
    });
    }

    $(function() {
        var records = [];
        $.getJSON('https://v1.nocodeapi.com/devmarq/airtable/RiBnzHulmTPHkgnD?tableName=JobListings&fields=company,logo,img,companyDescription,role,roleDescription,location,link,dateAdded&view=AllListings', function(data) {
            $.each(data.records, function parseJSON(i, { fields: f }) {
                var tblRow = "<tr>" + "<td>" + "<div style='padding-top: 1%; padding-bottom: 1%;'>" + "<div style='border: 1px solid black;'>" + "<button class='accordionList' style='font-size: large; outline: none;'>" + "<span style='padding-top: 2.5%; padding-bottom: 3%;'>" + "<img src='" + f.logo + "' height='30px'>" + "</span> &nbsp;<span style='padding-top: 3%; padding-bottom: 3%;'>&nbsp;&nbsp; " + f.company + " &nbsp; | &nbsp; " + f.role + " &nbsp;&nbsp; <span style='color: #2b2b2b;''><span class='iconify-inline' data-icon='eva:pin-outline' style='color: #2b2b2b;'></span> " + f.location +"</span></span>" + "</td>" + "</tr>" + "</button>" + "<div class='panel'>" + "<br>" + "<p style='color: #505050;'>Posted: " + f.dateCreated + " &nbsp; | &nbsp; Status: " + f.status + "</p>" + "<h4>About this role:</h4>" + "<p>" + f.roleDescription + "</p>" + "<h4>About " + f.company + ":</h4>" + "<p>" + f.companyDescription + "</p>" + "<br>" + "<a href='pricing.html' class='button btn btn-lg btn-block btn-sm button-black' style='padding-top: 1%; padding-bottom: 1%; width: 200px;'>Apply &nbsp; <span class='iconify-inline' data-icon='bi:arrow-right-circle' data-width='15' style='color: white;'></span></a>" + "<br>" + "</div>" + "</div>" + "</div>" + "</td>" + "</tr>"

                $(tblRow).appendTo("#userdata tbody");
            });
        });
    });
</script>

HTML:

<table id="userdata" style="width: 100%;">
    <tbody id="jobsData">
        <tr>
            <td>
                <div style="padding-top: 1%; padding-bottom: 1%;">
                    <div style="border: 1px solid black;">
                        <button class="accordionList" style="font-size: large; outline: none;">
                            <span style="padding-top: 2.5%; padding-bottom: 3%;"><img src="[LOGO]" height="30px"></span>&nbsp;<span style="padding-top: 3%; padding-bottom: 3%;">&nbsp;&nbsp; [COMPANY] &nbsp; | &nbsp; [ROLE] &nbsp;&nbsp; <span style="color: #2b2b2b;"><span class="iconify-inline" data-icon="eva:pin-outline" style="color: #2b2b2b;"></span> [LOCATION]</span></span>
                        </button>
                        <div class="panel">
                            <br>
                            <p style="color: #505050;">Posted: [DATEPOSTED] &nbsp; | &nbsp; Status: [POSTSTATUS]</p>
                            <h4>About this role:</h4>
                            <p>[ROLEDESCRIPTION]</p>

                            <h4>About [COMPANYNAME]:</h4>
                            <p>[COMPANYDESCRIPTION]</p>

                            <br>
                            <a href="pricing.html" class="button btn btn-lg btn-block btn-sm button-black" style="padding-top: 1%; padding-bottom: 1%; width: 200px;">Apply&nbsp; <span class="iconify-inline" data-icon="bi:arrow-right-circle" data-width="15" style="color: white;"></span></a>
                            <br>
                        </div>
                    </div>
                </div>
            </td>
        </tr>
    </tbody>
</table>

And CSS:

/* LIST STYLES */
    .accordionList {
        background-color: rgb(255, 255, 255);
        color: rgb(0, 0, 0);
        cursor: pointer;
        padding: 18px;
        width: 100%;
        border: none;
        text-align: left;
        outline: none;
        font-size: 15px;
        transition: 0.4s;
    }

    input:focus {
        outline:none !important;
    }
    
    .accordionList:hover {
        background-color: #f2f2f2;
    }
    
    .accordionList:after {
        content: url("img/expand.svg");
        font-size: 10px;
        height: 15px;
        float: right;
        margin-left: 5px;
    }
    
    .activeLink:after {
        content: url("img/close.svg");
    }
    
    .panel {
        padding: 0 18px;
        background-color: white;
        max-height: 0;
        overflow: hidden;
        transition: max-height 0.2s ease-out;
    }

Solution

  1. When load page , JS add event click for elements (class name is : accordionList )
  2. When you get data and create new elements ( those do not add event click) and event click of you not working on those elements

You are using Jquery then i suggest you code same as below : (Note : I ‘ve changed stype of .panel and records is data example)

$(document).on('click', '.accordionList', function(){
  $(this).toggleClass('activeLink')
  $(this).next().toggle(200)
})

const records = [
  {
     logo: 'test',
     company : 'company',
     role: 'role',
     location: 'location',
     dateCreated: 'dateCreated',
     status : 'status',
     roleDescription: 'roleDescription',
     companyDescription: 'companyDescription'
  }
]
$.each(records, function (k, f) {
    let tblRow = "<tr>" + 
    "<td>" + 
        "<div style='padding-top: 1%; padding-bottom: 1%;'>" + 
            "<div style='border: 1px solid black;'>" + 
                "<button class='accordionList' style='font-size: large; outline: none;'>" + 
                    "<span style='padding-top: 2.5%; padding-bottom: 3%;'>" + 
                        "<img src='" + f.logo + "' height='30px'>" + 
                    "</span> &nbsp;<span style='padding-top: 3%; padding-bottom: 3%;'>&nbsp;&nbsp; " + 
                        f.company + " &nbsp; | &nbsp; " + f.role + 
                    " &nbsp;&nbsp; <span style='color: #2b2b2b;''><span class='iconify-inline' data-icon='eva:pin-outline' style='color: #2b2b2b;'></span> " + f.location +"</span></span>" + 
                "</button>" + 
                "<div class='panel'>" + "<br>" + 
                    "<p style='color: #505050;'>Posted: " + f.dateCreated + " &nbsp; | &nbsp; Status: " + f.status + "</p>" + 
                    "<h4>About this role:</h4>" + 
                    "<p>" + f.roleDescription + "</p>" + 
                    "<h4>About " + f.company + ":</h4>" + 
                    "<p>" + f.companyDescription + "</p>" + "<br>" + 
                    "<a href='pricing.html' class='button btn btn-lg btn-block btn-sm button-black' style='padding-top: 1%; padding-bottom: 1%; width: 200px;'>Apply &nbsp; <span class='iconify-inline' data-icon='bi:arrow-right-circle' data-width='15' style='color: white;'></span></a>" + 
                    "<br>" + "</div>" + 
                "</div>" + 
            "</div>" + 
        "</div>" + 
    "</td>" + 
"</tr>"
    $(tblRow).appendTo("#userdata tbody")
})
.accordionList {
        background-color: rgb(255, 255, 255);
        color: rgb(0, 0, 0);
        cursor: pointer;
        padding: 18px;
        width: 100%;
        border: none;
        text-align: left;
        outline: none;
        font-size: 15px;
        transition: 0.4s;
    }

    input:focus {
        outline:none !important;
    }
    
    .accordionList:hover {
        background-color: #f2f2f2;
    }
    
    .accordionList:after {
        content: url("img/expand.svg");
        font-size: 10px;
        height: 15px;
        float: right;
        margin-left: 5px;
    }
    
    .activeLink:after {
        content: url("img/close.svg");
    }
    
    .panel {
        padding: 0 18px;
        background-color: white;
        overflow: hidden;
        display: none
    }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="userdata" style="width: 100%;">
    <tbody id="jobsData">
        <tr>
            <td>
                <div style="padding-top: 1%; padding-bottom: 1%;">
                    <div style="border: 1px solid black;">
                        <button class="accordionList" style="font-size: large; outline: none;">
                            <span style="padding-top: 2.5%; padding-bottom: 3%;"><img src="[LOGO]" height="30px"></span>&nbsp;<span style="padding-top: 3%; padding-bottom: 3%;">&nbsp;&nbsp; [COMPANY] &nbsp; | &nbsp; [ROLE] &nbsp;&nbsp; <span style="color: #2b2b2b;"><span class="iconify-inline" data-icon="eva:pin-outline" style="color: #2b2b2b;"></span> [LOCATION]</span></span>
                        </button>
                        <div class="panel">
                            <br>
                            <p style="color: #505050;">Posted: [DATEPOSTED] &nbsp; | &nbsp; Status: [POSTSTATUS]</p>
                            <h4>About this role:</h4>
                            <p>[ROLEDESCRIPTION]</p>

                            <h4>About [COMPANYNAME]:</h4>
                            <p>[COMPANYDESCRIPTION]</p>

                            <br>
                            <a href="pricing.html" class="button btn btn-lg btn-block btn-sm button-black" style="padding-top: 1%; padding-bottom: 1%; width: 200px;">Apply&nbsp; <span class="iconify-inline" data-icon="bi:arrow-right-circle" data-width="15" style="color: white;"></span></a>
                            <br>
                        </div>
                    </div>
                </div>
            </td>
        </tr>
    </tbody>
</table>
$(document).on('click', '.accordionList', function(){
  $(this).toggleClass('activeLink')
  $(this).next().toggle(200)
})

event click refer from document to .accordionList

Update format your html structure : enter image description here

Answered By – Xupitan

Answer Checked By – Marie Seifert (AngularFixing Admin)

Leave a Reply

Your email address will not be published.