Here is one way to do it:
class myClass {
constructor() {
this.onclick = null;
this.item = null;
// Add delegated click listener
document.addEventListener('click', function (e) {
// Only if click happens in #selectDate, and a click handler was defined:
if (this.onclick && e.target.closest('#selectDate')) {
this.onclick(e, this.item);
}
}.bind(this)); // `this` refers to this myClass object when clickListener is called
}
renderDate(item, onclick) {
if (!item) {
return "";
}
this.item = item;
this.onclick = onclick;
let checked = item.selected ? "checked" : "";
let tmp = `<div class="day-item align-center" id="selectDate" key="${item.name}" >
<div class="checkbox align-center justify-center ${checked}" ${checked}>
<span class="iconfont icon-check"></span>
</div>
<span class="text">${item.name}</span>
</div>`;
return tmp;
}
}
let item = {
selected: true,
name: 'this is my text: click me',
data: [1, 2, 3, 4] // some other data...
},
myObj = new myClass;
function processItem(e, storedItem) {
console.log(
`You clicked element with key = "${e.target.closest('#selectDate').getAttribute('key')}".
Item = ${JSON.stringify(storedItem)}`
);
}
// get the template, provide the onclick handler, and insert the HTML
document.getElementById('container').innerHTML = myObj.renderDate(item, processItem);
<h1>My title</h1>
<div id="container"></div>
When an instance of your class is created, a listener is added to the document. It filters click events that happened on the selectDate
element, or one of its child elements. When this is the case a custom onclick
callback is called, to which the item
object is passed.
The call of renderDate
takes the item object, but also the above mentioned callback. It was not clear to me whether you wanted that callback to be defined within the class, or to be provided by the caller, so I went for that second possibility. To change the code to use the first pattern should not be hard.