Search code examples
scala.jsscalatags

Creating a reusable component with scalatags


I'd like to create a reusable component with scalatags like this one:

<div class="container">
  <button>Delete me</button>
  <div class="actual-content">
    ...
  </div> 
</div>

and I'd like to register an onclick listener to the button which deletes the whole div container when clicked.

I know that I can do something like this (with jQuery):

div(id:="myid")(
  button(onclick:={() => jQuery("#myid").remove()}(Delete me),
  div(...)
)

but the problem with this solution is that I'm generating this element automatically and getting the element by id is cumbersome because I'd have to generate unique ids.

Is there a better way? Is there a way to reference a 'myid' div from inside the div?

Thanks


Solution

  • DOM Event callbacks (e.g. what you pass to onClick := ???) receive an instance of an Event as their first parameter. That event has a target property that contains the Node which the event was triggered on (in your case, that would be the button being clicked). That node has a parentNode property which refers to the parent node (element) of the target element. In your case the button's parentNode is your div, the node you want to remove. So you could provide this kind of callback to remove the div:

    def clickHandler = (event: Event): Unit = {
      val myDiv = event.target.parentNode
      myDiv.parentNode.removeChild(myDiv)
    }
    

    However, you should know that this style of UI programming is very imperative and does not scale well to a bigger codebases. There are better ways to write frontend apps nowadays. For Scala.js for example there are a few libraries for managing DOM state:

    There are more, these are just the ones that I remember right now.