Creating and adding node/elements to a document


#1

Perhaps because I’m not an experienced JS developer I’m having a hard time understanding how to do something like create an element or node.

In JS I know there is the global ‘document’ variable, which has methods you can create to create or append nodes or elements. I’m looking at Web.DOM and I don’t know how to obtain a Document in the first place so that I can use any other routine.


#2

Here’s an example I made several months ago.

createCanvasElement :: Eff _ HTMLCanvasElement
createCanvasElement = do
  document <- htmlDocumentToDocument <$> (document =<< window)
  bodyEl :: Maybe Element <- getElementById (ElementId "body") $ documentToNonElementParentNode document
  let body' = unsafePartial fromJust bodyEl
  canvasEl :: Maybe HTMLCanvasElement <- toCanvasElement <$> (createElement "canvas" document)
  let canvasEl' = unsafePartial fromJust canvasEl
  setWidth canvasWidth canvasEl'
  setHeight canvasHeight canvasEl'
  _ <- appendChild
      (elementToNode $ htmlElementToElement $ htmlCanvasElementToHTMLElement canvasEl')
      (elementToNode body')
  pure canvasEl'

Source: https://github.com/chexxor/purescript-pong-example/blob/master/src/Main.purs#L52

The DOM API uses sub-typing or something, which means we need to manually do a type conversion from something like Element to Node sometimes, which is a pain – see my toCanvasElement function for an example of how it’s done. The runtime object’s type can be checked, which lets us do it a little more type-safer, which is what the readHTMLCanvasElement function and other readX functions do.


#3

But I think your use of DOM is not current. DOM has been deprecated. I’m hoping to find help with the current Web libraries. Your example seems very long for what little it does. Surely there must be a better way?


#4

purescript-dom used to come with an explanation of its purpose:

The API isn’t primarily intended for “human consumption”, but instead aims to provide functions and types that match up with the interfaces described in the DOM4, HTML5, and CSSOM specifications, with a minimal amount of additional opinion as to how they should be implemented in PureScript.

After the repos changed, that note was lost. The spirit of purescript-web-dom is the same. Which is to say, it’s not easy to use.

purescript-dom-classy exists to make things easier. It hasn’t been updated to 0.12.0 yet.

Seems like there are two viable options:

  1. Follow @chexxor’s example
  2. Raise an issue with purescript-dom-classy about updating for 0.12.0.

The latter helps everyone :slight_smile:.