Recently I have written a small article on How to remove a DOM Element with JavaScript. So I was wondering what this code would look like in PureScript since it is type safe and more strict than plain JavaScript code. Let's find out together!
First of all, let's create our HTML file and a simple sample application by running
spago init
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Tutorial</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" type="text/css" media="screen" href="main.css" />
</head>
<body>
<div id="targetElement">This needs to go</div>
<script src="main.js"></script>
</body>
</html>
Your Main.purs file should look something like this:
module Main where
import Prelude
import Effect (Effect)
import Effect.Console (log)
main :: Effect Unit
= do
main log "🍝"
We can not start to write our code to access and element by Id and remove it from the DOM (in my example it will be the div with the id #targetElement.
Obviously we can not just use window or document in PureScript. We need to access it in a monadic way inside en Effect:
import Web.HTML.HTMLDocument (toNonElementParentNode)
import Web.HTML.Window (document)
import Web.HTML (window)
import Web.DOM.NonElementParentNode (getElementById)
main :: Effect Unit
= do
main <- map toNonElementParentNode $ document =<< window
doc <- getElementById "targetElement" doc maybeElement
At this stage we will have the access to an Element (if it exists in the HTML DOM structure). If you are interested in understanding the logic behind getElementById, I advice you reading "How to getElementById in PureScript".
Now let's elaborate a bit on the remove function:
import Web.DOM.Node (Node, removeChild, parentNode)
import Web.HTML.HTMLElement (HTMLElement, toNode, fromElement)
removeHtmlElement :: HTMLElement -> Effect Unit
= do
removeHtmlElement htmlElement <- parentNode nodeToRemove
maybeParent $ \parent' -> do
for_ (maybeParent)
removeChild nodeToRemove parent'pure unit
where
nodeToRemove :: Node
= toNode htmlElement nodeToRemove
We can use the Web.DOM.Node module to work with Nodes (for instance access a parentNode and remove a child from a given Node). As in the plain JavaScript example we will use the removeChild function.
I have created a new function which takes a HTMLElement, fetches its parent and calls removeChild with the child and the parent. For this, we transform the given HTMLElement to a Node to be able to work with parentNode and removeChild.
Let's glue everything together by using the for_ function from the Data.Foldable module:
module Main where
import Prelude
import Data.Foldable (for_)
import Effect (Effect)
import Effect.Console (log)
import Web.DOM.Node (Node, removeChild, parentNode)
import Web.HTML.HTMLElement (HTMLElement, toNode, fromElement)
import Web.HTML.HTMLDocument (toNonElementParentNode)
import Web.HTML.Window (document)
import Web.HTML (window)
import Web.DOM.NonElementParentNode (getElementById)
main :: Effect Unit
= do
main log "🍝 Starting Sample Code"
<- map toNonElementParentNode $ document =<< window
doc <- getElementById "targetElement" doc
maybeElement -- Only remove element if it is found in the DOM
$ \element -> do
for_ (maybeElement) -- Transform an Element to a HTMLElement
$ \htmlElement -> do
for_ (fromElement element)
removeHtmlElement htmlElementpure unit
removeHtmlElement :: HTMLElement -> Effect Unit
= do
removeHtmlElement htmlElement <- parentNode nodeToRemove
maybeParent $ \parent' -> do
for_ (maybeParent)
removeChild nodeToRemove parent'pure unit
where
nodeToRemove :: Node
= toNode htmlElement nodeToRemove
Et voila! Here you have it. If you execute the code in the browser with our HTML, the element with the id #targetElement should completely disappear from the DOM!
Thank you for reading this far! Let’s connect. You can @ me on X (@debilofant) with comments, or feel free to follow. Please like/share this article so that it reaches others as well.