DEV Community


Dynamically Made Button

Arturo Salmeron
・3 min read

For this post, I will try to explain dynamically created buttons as I understand the concept. The implementation of this code is done via an independently created library that is similar to jQuery but was created for the purpose of learning and understanding what a library is and how it can be used in our code.

When you want to create a component that is not part of your original HTML, you manipulate the DOM in order to get that component to display. This component can be created as a result to the user doing a certain action, completing a form, and/or clicking on a certain button. In our example, we will create a button as a result of clicking on another button with the id #add.

alt text

Our DOM initially only has the #add button:
alt text

After we click on the add button, we successfully add our new button on the page:
alt text

Now, lets make a function and run that function when we click on our new button with the id #myNewButton:
alt text
alt text

With the new lines of code, we expect the new button to console a message for us once we click on it. However, nothing shows up in the console:
alt text

Why didn't this work? Our code is written correctly but we did not see a new message in the console. This is a rather hard concept to grasp and it has to do with dynamically changing our DOM and with the concept of Bubbling and Capturing.

The way I think about it is that the new button was not in the initial code thus our function did not have a point of reference to attach our listener (the click event) to our new button. Rephrased: our testMyNewButton function could not be tied to #myNewButton because that button was not part of the initial html that loaded.

So instead, lets add the function to something that was already there. We can association the function to clicking on the document, on the body, or any other component that was in the origin HTML. For this example, we will associate the function to clicking on the div with the .container class as this is the div we appended the new button to.
alt text

Now if we refresh our DOM and click on the new button, we get a new message in the console:
alt text

Seems to work well! But what if I click to the right of our new button?
alt text
Our console logs another message here too. This is consistent with our code. Remember, we associated the function to the entire .container div thus we expect the function to run upon clicking anywhere inside of .container :
alt text

To fine tune and solely associate the click event to our new button, lets add some conditions to our function in order to check on the id of the element the user clicked on. To start, lets create a variable that will store the id of the element we will click on. To do this, we will use our initial "submittedOrClickedEvent" parameter and grab the target. The target will be the inner most element where our click event originated from. If that element has an id, we will want to store it:
alt text

Now that we have a variable with an id of an element, we can use it to compare it with the id of our new button #myNewButton :
alt text

Once we refresh our DOM and click on the new button and only our new button, we will see our function running and printing to the console:
alt text

Discussion (1)

link2twenty profile image
Andrew Bone

Nice first post 😀

Generally, I would probably use createElement to push a new node, rather than appending HTML to the DOM directly. There are several ways to do this, I'm a fan of classes so I'd probably make a class that creates the node and then append that. Like so:

class BasicButton {
  constructor(id, text) {
    this.node = document.createElement('button');
    this.node.setAttribute("id", id);

let button = new BasicButton("form_submit", "Submit");
button.node.addEventListener("click", someFunction);

This has the added bonus of being able to reference button.node to make changes to the element even though it's in the DOM.

Here's an example of it in practice, though I've added a class and some CSS to make it a little fancier 😉