1

[![Firefox Console][1]][1]In my Vue app I am trying to use mdb-datatable, the table reads data() and sets the rows accordingly. I am setting the row data programmatically after my data is loaded with Ajax. In one column I need to add a button and it needs to call a function. I am trying to add onclick function to all buttons with "status-button" class but something weird happens.

When I print HtmlCollection it has a button inside, which is expected but I can't reach proceedButtons[0], it is undefined. proceedButtons.length also prints 0 length but I see the button in console.

I also tried to add onclick function but probably "this" reference changes and I get errors like "proceedStatus is not a function" it does not see anything from outer scope.

<mdb-datatable
                :data="tableData"
                :searching="false"
                :pagination="false"
                :responsive="true"
                striped
                bordered/>
    export default {
        name: "Applications",
        mixins: [ServicesMixin, CommonsMixin],
        components: {
            Navbar,
            Multiselect,
            mdbDatatable
        },
        data () {
            return {
                statusFilter: null,
                searchedWord: '',
                jobRequirements: [],
                applications: [],
                options: ['Awaiting', 'Under review', 'Interview', 'Job Offer', 'Accepted'],
                tableData: {
                    columns: [
                        {
                            label: 'Name',
                            field: 'name',
                            sort: 'asc',
                        },
                        {
                            label: 'Date',
                            field: 'date',
                            sort: 'asc'
                        },
                        {
                            label: 'Compatibility',
                            field: 'compatibility',
                            sort: 'asc'
                        },
                        {
                            label: 'Status',
                            field: 'status',
                            sort: 'asc'
                        },
                        {
                            label: 'Proceed Application Status',
                            field: 'changeStatus',
                        }
                    ],
                        rows: []
                }
            }
        }
            fillTable(applications) {
                let statusButtonId = 0;

                applications.forEach(application => {
                    this.tableData.rows.push({
                        name: application.candidateLinkedIn.fullName,
                        date: this.parseDateFromDateObject(application.applicationDate),
                        compatibility: this.calculateJobCompatibility(application.candidateLinkedIn.linkedInSkillSet),
                        status: application.applicationStatus,
                        changeStatus: '<button type="button" class="btn-indigo btn-sm m-0 status-button"' +
                            ' style="margin-left: 1rem">' +
                            'Proceed Status</button>',
                        candidateSkillSet: application.candidateLinkedIn.linkedInSkillSet
                    });

                    statusButtonId++;
                });
            },
            addEventListenersToButtons() {
                let proceedButtons = document.getElementsByClassName("status-button")
                console.log(proceedButtons);
                console.log(proceedButtons[0])
                console.log(proceedButtons.item(0))
                /*
                proceedButtons.forEach(button => {
                    button.addEventListener("click",this.proceedStatus);
                });
                */
            },


  [1]: https://i.stack.imgur.com/zUplv.png
erinc
  • 266
  • 2
  • 12
  • See https://stackoverflow.com/questions/23429203/weird-behavior-with-objects-console-log – CertainPerformance Jul 14 '19 at 22:48
  • 2
    also, getElementsByClassName returns a "live list" - so what you've logged to the console can change over the lifetime of the page – Jaromanda X Jul 14 '19 at 23:08
  • I still need a way to access these elements and add the function – erinc Jul 14 '19 at 23:11
  • As a general rule of thumb, if you are using a library like react, vue, angular, et al - you should never ever ever do direct dom querying or mutations (eg. `document. getElementsByClassName`). This is a sure sign you are doing things wrong. You should be attaching event handers inside your render functions using the preferred method of the library you are using. – Ryan Wheale Apr 08 '22 at 17:51

1 Answers1

0

From MDN:

Get the first element with a class of 'test', or undefined if there is no matching element:

document.getElementsByClassName('test')[0]

So undefined means no match, even if length is 0...

Since this is not an array, you do not get out-of-bounds exceptions.

https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName

Regarding Arrays

You can't index the list returned from getElementsByClassName.

You can turn it into an array though, and then index it.

ES6

let proceedButtons = document.getElementsByClassName("status-button")
const arr = Array.from(proceedButtons);
console.log(arr[0]);

Old School

const arr = []
Array.prototype.forEach.call(proceedButtons, function(el) {
    arr.push(el);
});
console.log(arr[0]);
Steven Spungin
  • 27,002
  • 5
  • 88
  • 78