0

I generate an html table using javascript and jquery. One of the row cells has an anchor element, that I append to table as a string var deleteLink = "<a href="#">Delete</a>"

I need to set an event listener to the generated element, but don't know how to select it

I can't pass deleteLink as a string like this

$(deleteLink).on("click", function () {
     //call fucntion
});

I'm trying to set a unique id to the generated links, but I also need to know how to select them first. Please help

This's how I generate the html table. Please note that each delete link should only trigger the row it belongs to.

        function appendToDigitalMapTable(docId) {
            tbl = document.getElementById('digitalMapTable');
            var selectedDigitalMap = $("#DigitalMapTypeId option:selected").text();

            var deleteButton = "<a href='#'>Delete</a>";
            addRow(tbl, selectedDigitalMap, deleteButton, docId); 
        }

        function deleteUploadedDoc(docIdAssociatedToRow) {
            console.log("deleteUploadedDoc function is called. docId = " + docIdAssociatedToRow);
            //ajax call to backend function
        }


        function addCell(tr, val) {
            var td = document.createElement('td');
            td.innerHTML = val;
            tr.appendChild(td)
        }

        function addRow(tbl, val_1, val_2, docId) { 2
            var tr = document.createElement('tr');
            var docIdAssociatedToRow = $(tr).data("documentID", docId)
            //selected digitalMapType text
            addCell(tr, val_1);

            //delete row
            addCell(tr, val_2);
            //val_3 is "<a href='#'>Delete</a>"

            //attach eventListener to this element
            $(val_3).on("click", function () {
                deleteUploadedDoc(docIdAssociatedToRow);
            });

            tbl.appendChild(tr)
        }
  • $('#YOUR-UUID') should be the correct selector – CodeFox May 10 '19 at 13:42
  • 1
    Can you show us how do you append your to the table please ? – Ugo T. May 10 '19 at 13:43
  • You can set onclick on the html code (after the href) with a js function you define – Ehcnalb May 10 '19 at 13:44
  • @CodeFox it's a generated element. how to set id to it? I'm having a table with multiple generated rows, each link in each row has to have an id – Abayomi Nidal May 10 '19 at 13:51
  • @UgoT. I added the code that i generate table with – Abayomi Nidal May 10 '19 at 13:51
  • @Ehcnalb I usually don't use onclick function, but i'll try it – Abayomi Nidal May 10 '19 at 13:53
  • Here, to help you https://www.w3schools.com/tags/ev_onclick.asp – Ehcnalb May 10 '19 at 13:56
  • *"I'm trying to set a unique id to the generated links"* - this is an XY problem - you have a problem, you've tried to solve it (using IDs) and got stuck with that route. There's no need for IDs in this scenario. – freedomn-m May 10 '19 at 14:18
  • *"use onclick"* - don't do this (generally). Among other reasons (including separation of concerns), your method `deleteUploadedDoc` then needs to be globally scoped (which it might be) but looks like it isn't (it's probably in a doc ready or in a namespace). – freedomn-m May 10 '19 at 14:20
  • @freedomn-m if i don't need ids, how shall i select the desired link that the user clicked, knowing there are multiple links? – Abayomi Nidal May 10 '19 at 14:27
  • You use `this` and DOM traversal to find anything else you need, eg `$(this).closest("tr").data("documentID")` – freedomn-m May 10 '19 at 14:35
  • More info on event delegation: https://stackoverflow.com/questions/203198/event-binding-on-dynamically-created-elements – freedomn-m May 10 '19 at 14:36

2 Answers2

0

You can give your anchor element an unique id and later use Jquery's # selector to select that particular element.

var counter = 1;
var deleteLink
for (var a = 0; a < 2; a++) {
  deleteLink = "<a href='#' id='myLink" + counter + "'>Delete </a>";
  document.body.innerHTML += deleteLink;
  counter++;
}
$('#myLink1').on("click", function() {
  console.log("clicked")
});
$('#myLink2').on("click", function() {
  console.log("other clicked")
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
obscure
  • 11,916
  • 2
  • 17
  • 36
0

Option 1: return the row from addRow then find the delete button in that row to add the event handler:

function addRow(...) {
    ...
    return tr;
}

var tr = addRow(...);
var delbutton = $(tr).find("a")

// not clear if you question is for css or event handler, asks both
delbutton.css("color", "red").click(function() { handleRowDeleteEvent(); });

this assumes you only have one button/anchor, mitigated using a class

var delbutton = $(tr).find("a.del-button")

(as an aside, it should be a <button type='button' not <a> as it's an action, not a link, so I've used <button> below)

Option 2: use event delegation

$("#digitalMapTable").on("click", "a", handleRowDeleteEvent);

again, assumes you have a single button for delete, not for edit etc, but this can easily be mitigated by adding a class to your buttons when you create them, eg:

var deleteLink = "<button type='button' class='delete-button'>delete</button>";
$("#digitalMapTable").on("click", "button.delete-button", handleRowDeleteEvent);

Option 3: use onclick=

var deleteLink = "<button type='button' onclick='handleRowDeleteEvent'>delete</button>";

not recommended for numerous reasons that I'll leave you to research


How to ensure your button only works on the row it needs to - use this:

function handleRowDeleteEvent() {
    var btn = $(this);
    var row = btn.closest("tr");
    var docId = row.data("documentID");

    deleteUploadedDoc(docId);
}

or, all in one line:

function handleRowDeleteEvent() {
    deleteUploadedDoc($(this).closest("tr").data("documentID"));
}
freedomn-m
  • 27,664
  • 8
  • 35
  • 57
  • thank you for your thorough answer. yet i have multiple rows with multiple links. how can i solve it – Abayomi Nidal May 10 '19 at 14:23
  • oh, you mean assuming I have one button inside each row? yes currently I have one button, later may have 2 – Abayomi Nidal May 10 '19 at 14:32
  • Using any of the provided options... unless: when you say "multiple rows with multiple links" you mean "each row can have multiple links" - you'd ideally need to expand your question to include how you do that as at the moment you only have one delete button per row. Even if you have multiple buttons per row, just give each one a class that matches what it does, eg `class='delete'` `class='edit'` – freedomn-m May 10 '19 at 14:32
  • 1. returning the `tr` from `addRow` will give you access to just that row and then you can get the buttons for that row and manipulate as required. – freedomn-m May 10 '19 at 14:33
  • 2. using event delegation means it doesn't matter where the rows are / when they are added (as long as you know which is delete, which is edit etc) and is probably your cleanest option – freedomn-m May 10 '19 at 14:34
  • thank you very much for point out the concept of event delegation :) and I solved the issue using .find method on row. Answer is approved. Hats off, sir – Abayomi Nidal May 10 '19 at 14:47