How to add an event listener to a target with dashes ( - )
Published: 2023-01-21 04:48:42

MDN describes the addEventListener() method as a function that will be called whenever the specified event is delivered to the target. In order for the code to work, you need to access the target.


Common targets are Element, Document, Window, and any object that supports events (such as XMLHttpRequest). In this article we want to access an element, so that we can assign it as a target for a specified event.


JavaScript will throw an error when you try to add an event listener to a node with a specific element ID, Class, or Name with a dash. JavaScript doesn't like dashes ( - ), it will understand it as a minus. This article provides two solutions to resolve a JavaScript error caused by a dash ( - ) in the name of an element.

To prevent JavaScript from understanding the dash as a minus use an alternative way of selecting that node that takes strings.


## Use querySelector() 
In JavaScript querySelector() takes a string that can include the dashes. The stringification ensures that JavaScript does not understand the dash as a minus. According to MDN, the Document method querySelector() returns the first Element within the document that matches the specified selector, or group of selectors. If no matches are found, then null is returned. 

It allows you to select an element with a specific ID using the ID selector e.g. instead of `e.target.new-task-description` use `e.target.querySelector('#new-task-description')`.
document.addEventListener("DOMContentLoaded", () => {
  let form = document.querySelector('#create-task-form');
 form.addEventListener('submit', (e) => {
   e.preventDefault();
   buildTaskList(e.target.querySelector('#new-task-description').value); 
   form.reset();
 })
});



You can also select an element with a class using the class selector e.g. `e.target.querySelector('.new-task-description')`.

## Rename the node
There is a hack solution that is not recommended but works. Rename the node by replacing the dash in the ID or Class name with an underscore or simply remove the dash in all references to the node, e.g. `e.target.new_task_description.value` and `e.target.newtaskdescription.value`.

document.addEventListener("DOMContentLoaded", () => {
  let form = document.querySelector('#create-task-form');
 form.addEventListener('submit', (e) => {
   e.preventDefault();
   buildTaskList(e.target.new_task_description.value);
   form.reset();
 })
});


Any one of the 2 solutions will fix the JavaScript error; however, using a querySelector is the preferred solution because it is more elegant. 

## Creating a variable
Another solution that I explored involved creating a variable called taskInput, assigning the node to that variable, and then chaining the variable taskInput to the target e.g. `newTextInput = document.getElementById("new-task-description")` but JavaScript did not work as I had expected when I tested it in the DOM.

## Other methods to try
When I tried to chain the getElementByID() method e.g. `e.target.getElementByID(‘new-task-description’)`, JavaScript threw an error. Perhaps there was a syntax error that I made and did not catch.

If I didn’t make a syntax error then in theory that would mean that chaining the getElementByClassName() method wouldn’t work either.

There are other methods that I did not try that you might want to check out depending on the element.

You can use the document.getElementsByTagName() method to select all elements of a specific HTML tag, like this:
`getElementsByTagName(‘li’)`

And you can use the document.getElementsByName() method to select all elements with a specific name attribute, like this:
`getElementsByName(‘new-task’)`

## Testing and learning
I’m enrolled in the Flatiron School Software Engineering flex program and I’ve been working through several labs. I was inspired to write this because I could not find an article to help me identify why JavaScript was throwing me an error.

In order to debug my Javascript code I added a console log `e.target.querySelector('#new-task-description')` to my index.js file, saved it, and opened the index.html in a browser to view the Chrome Dev Tools Console logs. This approach to testing does require a lot of console logs to isolate the unexpected behavior.

Instead of using the Console, you can also use Sources in Chrome Dev tools to test and debug your Javascript code for an event listener. Once you have Sources open, click on the .js tab to view your JS code, choose the event listener type from the menu called Event Listener Breakpoints, then click on the button you want to test. Chrome Dev tools will highlight the line of code in the .js Source. 

Thankfully the Flatiron School has technical coaches that helped me identify that the error was caused by JavaScript interpreting the dash as a minus, which I would have never guessed without their help because my syntax was correct. Hopefully, others learning JavaScript that don’t have access to technical coaches find this article helpful. Happy coding!




Cited resources:
“Document.querySelector() - Web Apis: MDN.” Web APIs | MDN, https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector. 

“ EventTarget.addEventListener() - Web APIs | MDN.” Web APIs | MDN, https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener.