1

I have a table

column 1 column 2 colum 3 [buttons]
data data data [Button][Button][Button][Button]

I then convert the HTML Table to a responsive datatable, with the buttons bound using a jQuery selector using the .on('click',fuction () {} ); construct. Now in tables that have not been collapsed due to the length of the table row the events are bound, but where datatables have been wrapped the events are not being bound.

It does not matter if I bind the events before or after the creation of the datatable, yet if I specifically bind to a button it works.

This is how I am binding the buttons, all the other buttons that match the selector are bond:


$('button[data-eh-location]').on('click', function () { alert('Wibble'); }; 

This is the thing I have noticed with the datatabe in that you have to bind things and create tooltips BEFORE your convert the HTLML table to a data table. But in this case it does not seem to be working

How a button is defined in the HTML:

<button type="button" data-eh-location="/@item.UniqueRefenceForLinks/Edit" class="btn btn-edit" title="Edit job application" data-bs-toggle="tooltip"><i class="fa-solid fa-pen-line fa-fw"></i></button>

If the table does not wrap the button is bound correctly

6
  • 2
    Please provide the minimal code needed to reproduce the problem. Try to provide code we can just run to see it happen. Commented Sep 29 at 7:01
  • Looks like you need event delegation. Commented Sep 29 at 10:43
  • @trincot You can view the issue here jobs2-test.emma-harris.co.uk/stackoverflowQuestion.html - you need to load the page in a browser that cuase the table to wrap. I am sure that you don't need all of the JS but it is easier to show. - note some of the destinations will not work but it gives you an indea of what I am trying to acheive TIA Commented Sep 29 at 13:33
  • @tricot I have figured it out the buttons that are in the warpper are copies of the original buttons with the help below I think I can come up with a solution Commented Sep 29 at 13:59
  • 1
    As the answer below helped you, please consider marking it as accepted. Commented Sep 29 at 14:32

1 Answer 1

2

Handling events for dynamically created elements can be achieved by using event delegation.

Using jQuery, you can use something like:

$("table.s-table").on("click", "button[data-eh-location]", [handlerFunction]);
//                              ∟ the designated element(s)

But actually you don't need jQuery for it.

This snippet may give you an idea how it works in plain js:

// add the listener before anything is done
document.addEventListener(`click`, handle);

// a demo handler showing the text of the element clicked
function handle(evt) {
  if (evt.target.dataset.clicktext) {
    console.clear();
    return console.log(`${evt.target.textContent} clicked`);
  }
  
  return true;
}

createTableHeader();

// click the first header
document.querySelector(`[data-clicktext]`).click();

// add a header with a button (and click it) after 2 seconds
setTimeout(() => {
    document.querySelector(`thead tr`)
       .insertAdjacentHTML(`beforeend`, 
         `<th><button data-clicktext="1">button!</button></th>`);
    document.querySelector(`thead th:last-child button`).click();   
  },
  2000
);

// create a table header
function createTableHeader() {
  const table = document.createElement(`table`);
  table.insertAdjacentHTML(`beforeend`, `<caption>Example</caption>`);
  const head = table.insertAdjacentElement(
    `beforeend`, document.createElement(`thead`));
  const headerRow = head.insertAdjacentElement(
    `beforeend`, document.createElement(`tr`));
  
  [...Array(3)].forEach((_, i) => 
    headerRow.insertAdjacentHTML(
      `beforeend`, 
      `<th data-clicktext="1">header ${i+1}</th>`)
  );
  document.body.append(table);
}
table {
  th {
    cursor: pointer;
    font-weight: normal;
    padding: 1px 4px;
    &:hover {
      text-decoration: underline;
    }
    &:not(:first-child) {
      border-left: 1px solid #999;
    }
  }
  caption {
    padding: 2px;
    border-bottom: solid 1px #999;
  }
}

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.