Some help with these buttons, please

I thought this would work fine, but I cant figure out why it’s not working. What I’m trying to do seems pretty simple-I’m sure I’m overlooking something dumb-I’m trying to get 4 different buttons that when clicked log the button text to cell 1 and the time it is pushed to cell 2 of a table row. If you could tell me why this isn’t doing that and/or how I should better approach this, I would be grateful.

<!DOCTYPE html>
<html>
	<head>
		<title>Action Logger App</title>
	</head>
	<body>
		<button onclick="logAction">Action1</button>
		<button onclick="logAction">Action2</button>
		<button onclick="logAction">Action3</button>
		<button onclick="logAction">Action4</button>
		<br>

		<table id="actionLog">
			<tr>
				<th>Action</th>
				<th>Time</th>
			</tr>
		</table>   
		<script type="text/javascript">
		function logAction() {
			var tbl = document.getElementById("actionLog");
			var row = tbl.insertRow(0);
			var actionCell = row.insertCell(0);
			var timeCell = row.insertCell(1);
			var btn = document.getElementByTag("button");
			actionCell.innerHTML = btn.innerHTML();
			timeCell.innerHTML = Date();
		}
		</script>
	</body>
</html>

You have a few problems. I will get you started by letting you know your onclick=“logAction” will not do anything. You need to execute the funciton with onclick=“logAction()”

Once you do that, you will get an error in the console that you will need to debug. getElementByTag is not a valid function. Research how to use getElementsByTagName.

Thank you for the response. So, I fixed the buttons onClick to call the function. I still dont think I’m approaching the first cell right. I’ve got the 2nd cell to give the time/date, but I get undefined for the first cell. I’m wondering if I should call the onClick in the function instead of in the buttons. I suppose I could just write a function for each button and give them a unique id. I’m not even sure I can call innnerHTML on a button. Though, I don’t see why not.

			var btn = document.getElementsByTagName("button");
			actionCell.innerHTML = btn.innerHTML;

If anyone is curious as to the solution I came up for this, here it is:

<!DOCTYPE html>
<html>
	<head>
		<title>Action Logger App</title>
	</head>
	<body>
		<button class="actionBtn">Action1</button>
		<button class="actionBtn">Action2</button>
		<button class="actionBtn">Action3</button>
		<button class="actionBtn">Action4</button>
		<br>

		<table id="actionLog">
			<tr>
				<th>Action</th>
				<th>Time</th>
			</tr>
		</table>   
		<script type="text/javascript">
		var buttons = document.querySelectorAll('.actionBtn');

		for (var i=0; i<buttons.length; i++) {
			buttons[i].addEventListener('click', logAction)
		}
		function logAction(event) {
			var tbl = document.getElementById("actionLog");
			var row = tbl.insertRow(1);
			var actionCell = row.insertCell(0);
			var timeCell = row.insertCell(1);
			var actionTxt = event.target.innerHTML;
			actionCell.innerHTML = actionTxt;
			timeCell.innerHTML = Date();
		}
		</script>
	</body>
</html>

If there’s a better way, I’d love to hear it. For now, this’ll work. Now I’m going to set up a user login, and a database for users and their tables. I’m hoping to figure out how multiple users can add to a shared table and their user name will be added in the row with it’s own cell. Any advice is more than welcomed.
Cheers!

Glad you figured something out!

I was curious if you intended for the rows to show the data in reverse order as the buttons are clicked.

Example:
If I first click button 3, it shows “Action3” was clicked on the first row of the table.

If the next button I click is button 1, then the first row shows “Action1” and row two shows “Action3” (the first button clicked)

Finally, if I click button 2, then the first row shows “Action2”, row two shows “Action1”, and row three shows “Action3”.

This maybe how you wanted to display the data. I was originally thinking you wanted the last entry in the table to show the most current button clicked.

An alternative which would be very useful if you had let’s say 100 buttons, would be to use event delegation. First, you would wrap your buttons in a div (let’s give it an id of “buttons”).

  <div id="buttons">
    <button class="actionBtn">Action1</button>
    <button class="actionBtn">Action2</button>
    <button class="actionBtn">Action3</button>
    <button class="actionBtn">Action4</button>
  </div>

and then use a slightly modified version of your final JS script above.

  <script type="text/javascript">
    var buttons = document.getElementById("buttons"); // div called buttons
    buttons.addEventListener("click", logAction); // listens for click within div called buttons
    function logAction(event) {
      var tbl = document.getElementById("actionLog");
      var row = tbl.insertRow(1);
      var actionCell = row.insertCell(0);
      var timeCell = row.insertCell(1);
      var actionTxt = event.target.innerHTML;
      actionCell.innerHTML = actionTxt;
      timeCell.innerHTML = Date();
    }
  </script>

This way you are only creating one event listener instead of multiple event listeners (which would consume more browser resources). Just another way of approaching this problem.

1 Like