There are a couple of ways to do this, but the way that immediately stands out to me is the following:
- Add the indexes to the array elements for the Mustache render function
- Render out the indexes as
data-
attributes in the HTML
- Retrieve this data in the click listener
- Modify the original
info
array using this data
Let's run through this.
Step 1: Add the indexes to the array elements for the Mustache render function
First things first, we want to retrieve the array indexes in the HTML. This data isn't available by default when rendering with Mustache, so we need to add it in ourselves. This can't be a permanent addition to the array objects. The actual indexes can change at any time (say, if an element is removed). Instead, we only want to render out the indexes for the HTML and nowhere else.
Create the following addIndexes()
function:
function addIndexes(object) {
object = JSON.parse(JSON.stringify(object));
var info = object.info;
for (var i = 0; i < info.length; i++) {
info[i].index = i;
}
return object;
}
- The first line clones the object. Remember, we don't want to modify the original object or array. This allows us to work on a copy that doesn't affect the original.
- We run through the array and add the index of that array to a property called
index
.
var object = {
info : [
{date: "14, July", day: "Saturday", item: "Lunch", price: 40},
{date: "15, July", day: "Sunday", item: "Airport", price: 80},
{date: "14, July", day: "Saturday", item: "Snacks", price: 25}
],
withdrew: 0
};
function addIndexes(object) {
object = JSON.parse(JSON.stringify(object));
var info = object.info;
for (var i = 0; i < info.length; i++) {
info[i].index = i;
}
return object;
}
console.log("--- The object AFTER addIndexes() ---");
console.log(addIndexes(object));
console.log("--- The object BEFORE addIndexes() ---");
console.log(object);
Now, simply modify the Mustache.render()
method to use our new addIndexes()
function:
function refreshDOM() {
var outputBody = Mustache.render(template, addIndexes(object));
...
}
Step 2: Render out the indexes as data-
attributes in the HTML
Now we need to attach those indexes in our HTML template. In your main index.html
, go to the render function and change the button code to read this:
<td><a href="#" id="editInfo" data-index="{{index}}">Edit</a> | <a href="#" id="deleteInfo" data-index="{{index}}">Delete</a></td>
Now we are outputting the index to the data-index
attribute, which we can retrieve later. This renders out each button element to look something like this:
<td><a href="#" id="editInfo" data-index="0">Edit</a> | <a href="#" id="deleteInfo" data-index="0">Delete</a></td>
<td><a href="#" id="editInfo" data-index="1">Edit</a> | <a href="#" id="deleteInfo" data-index="1">Delete</a></td>
And so on, for each row.
Step 3: Retrieve this data in the click listener
We can now actually handle this data. Change your modifyBtn
click event listener to be the following:
var modifyBtn = document.querySelector('table');
modifyBtn.addEventListener('click', function(e){
var el = e.target;
var action = el.id;
var index = parseInt(el.dataset.index);
switch (action) {
case "editInfo": editInfo(index); break;
case "deleteInfo": deleteInfo(index); break;
}
});
- We're now getting the
el
(which is just the element) from event.target
.
- We can get a string with the action (like "editInfo") from your
el.id
.
- The index value is
data-index
which can be retrieved with el.dataset.index
. Note that this gets placed in HTML as a string (which we can't use), so we have to run parseInt()
on it to get an integer from the string.
- With a switch statement, we can now perform an action depending on the ID.
Neither of these handler functions (editInfo()
nor deleteInfo()
) are currently declared, so on to the final step!
Step 4: Modify the original info
array using this data
I don't know what you want to do with the editInfo
ID, so I'll leave that one up to you. I've created a simple deleteInfo
function directly above the click listener:
function deleteInfo(index) {
object.info.splice(index, 1);
refreshDOM();
}
This will remove the specified index from the global object.info
array and then call refreshDOM()
to update.
We're now complete! Sorry this was such a long-winded answer, I wanted to break down each step as we went along. Let me know if this all made sense and if you have any questions!