First time asking question here.
Can someone help me in declaring dynamic onclick function in HTML property inside forEach function using TypeScript ?
By the way, i am new in typescript. hehe.
Here is my old code that i want to convert in TypeScript:
const MyClass = (() =>
{
let this_MyClass = {};
this_MyClass.load = () =>
{
let tr;
$.each(data, function()
{
tr +=
`<tr>
<td><button onclick = "MyClass.set_id(${this.id})">Edit</button></td>
</tr>`;
}
$("#table_id tbody").html(tr);
};
this_MyClass.set_id = (id) =>
{
//my codes here
};
return this_MyClass;
})();
My new code in typescript(but its not working):
class MyClass
{
load()
{
let tr:any;
let iteration = 0;
data.forEach((value:{id: number;}) =>
{
tr +=
`<tr>
<td><button id="btn_edit${iteration}">Edit</button></td>
</tr>`;
document.getElementById(`btn_edit${iteration}`)?.addEventListener("click",
(e: Event) => this.set_id(value.id));
iteration++;
});
$("#table_id tbody").html(tr);
}
set_id(id:number)
{
//my codes here
}
}
can someone help me.
Code Update: location of " set_id " method
In the TS code you are adding event listener on the element which is not present in the DOM yet. First add the element into the DOM
and then add event listener.
Working code:
class MyClass {
load() {
// let data = [{ id: 1 }, { id: 2 }, { id: 3 }] Adding for testing
let tr: any;
let iteration = 0;
let trBtnIds = [];
data.forEach((value: { id: number }) => {
tr +=
`<tr>
<td><button id="btn_edit${iteration}">Edit</button></td>
</tr>`;
trBtnIds.push({
iteration,
value
});
iteration++;
});
$("#table_id tbody").html(tr);
trBtnIds.forEach(item => {
document.getElementById(`btn_edit${item.iteration}`) ?.addEventListener("click", (e: Event) => {
this.set_id(item.value.id);
});
});
}
set_id(id: number) {
console.log(id);
}
}
/* Adding these line for testing */
//let myClassObject = new MyClass();
//myClassObject.load();
Babel compiled working code
"use strict"; function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var MyClass = /*#__PURE__*/ function () { function MyClass() { _classCallCheck(this, MyClass); } _createClass(MyClass, [{ key: "load", value: function load() { var _this = this; var data = [{ id: 1 }, { id: 2 }, { id: 3 }]; //Adding for testing var tr; var iteration = 0; var trBtnIds = []; data.forEach(function (value) { tr += "<tr>\\n <td><button id=\\"btn_edit".concat(iteration, "\\">Edit</button></td>\\n </tr>"); trBtnIds.push({ iteration: iteration, value: value }); iteration++; }); $("#table_id tbody").html(tr); trBtnIds.forEach(function (item) { var _document$getElementB; (_document$getElementB = document.getElementById("btn_edit".concat(item.iteration))) === null || _document$getElementB === void 0 ? void 0 : _document$getElementB.addEventListener("click", function (e) { _this.set_id(item.value.id); }); }); } }, { key: "set_id", value: function set_id(id) { console.log(id); } }]); return MyClass; }(); /* Adding these line for testing */ var myClassObject = new MyClass(); myClassObject.load();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table id="table_id"> <tbody> </tbody> </table>
Alternate approach:
Instead of creating event listener for each td button
. Use javascript event bubbling technique. Listening to event for all td buttons
is expensive.
Here is the example.
Create the event listener on the table or the wrapping element.
HTML
<table id="table_id">
</table>
Script
class MyClass {
load() {
// let data = [{ id: 1 }, { id: 2 }, { id: 3 }] /**Adding for testing */
let tr: any;
let iteration = 0;
let trBtnIds = [];
data.forEach((value: { id: number }) => {
tr +=
`<tr>
<td><button data-id="${value.id}" id="btn_edit${iteration}">Edit</button></td>
</tr>`;
trBtnIds.push({
iteration,
value
});
iteration++;
});
$("#table_id tbody").html(tr);
let ele = document.getElementById('table_id');
ele.addEventListener('click', event => {
console.log(event.target);
let target = event.target;
if (target instanceof HTMLButtonElement && target.dataset && target.dataset.id) {
let id = target.dataset.id;
this.set_id(id);
}
});
}
set_id(id: number) {
console.log(id);
}
}
/**Adding for testing */
//let myClassObject = new MyClass();
//myClassObject.load();
Babel compiled working code
"use strict "; function _instanceof(left, right) { if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) { return !!right[Symbol.hasInstance](left); } else { return left instanceof right; } } function _classCallCheck(instance, Constructor) { if (!_instanceof(instance, Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } var MyClass = /*#__PURE__*/ function() { function MyClass() { _classCallCheck(this, MyClass); } _createClass(MyClass, [{ key: "load", value: function load() { var _this = this; var data = [{ id: 1 }, { id: 2 }, { id: 3 }]; /**Adding for testing */ var tr; var iteration = 0; var trBtnIds = []; data.forEach(function(value) { tr += "<tr>\\n <td><button data-id=\\"".concat(value.id, "\\" id=\\"btn_edit").concat(iteration, "\\">Edit</button></td>\\n </tr>"); trBtnIds.push({ iteration: iteration, value: value }); iteration++; }); $("#table_id tbody").html(tr); var ele = document.getElementById('table_id'); ele.addEventListener('click', function(event) { var target = event.target; if (_instanceof(target, HTMLButtonElement) && target.dataset && target.dataset.id) { var id = target.dataset.id; _this.set_id(id); } }); } }, { key: "set_id", value: function set_id(id) { console.log("ID:", id); } }]); return MyClass; }(); /**Adding for testing */ var myClassObject = new MyClass(); myClassObject.load();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table id="table_id"> <tbody> </tbody> </table>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.