tips for updating <h1> elements using ghcjs-dom

My experience with the ghcjs and ghcjs-dom documentation has been quite limited. Here is a simple example with basic HTML code:

h1 { font-family: Helvetica; }

p {font-family: Helvetica; color: blue; }
<h1>
Hello World
</h1>
<p>
This is my test document.
</p>

From what I've gathered, ghcjs essentially compiles Haskell to JavaScript. To manipulate the DOM tree even with this simple document, one needs to use the Foreign Function Interface (FFI) and possibly incorporate ghcjs-dom.

The terminology of calling it the "Foreign Function Interface" is somewhat ironic given that JavaScript is considered "native" to browsers. This leads to a bit of confusion in terms.

In this straightforward case,

Let's attempt a basic DOM manipulation example. I have a plain HTML document and I wish to * change the blue paragraph to red or * toggle between red and blue every second

If these simple tasks are not achievable using the ghcjs toolset, then how can it handle more complex challenges? There seems to be a gap in explaining these very fundamental scenarios. I have raised an issue on Github highlighting this lack of clarity and guidance:

Answer №1

Here is a concise example showcasing the use of reflex-dom to implement red/blue color switching as described. This code snippet, originally shared by epsilonhalbe in this answer to an earlier question, builds upon previous knowledge referenced in your inquiry.

{-# LANGUAGE OverloadedStrings #-} 
{-# LANGUAGE ScopedTypeVariables #-} -- allows for local type declarations.
import Reflex
import Reflex.Dom
import Data.Text (Text, pack)
import Data.Map (Map)
import Data.Time.Clock (getCurrentTime)
import Control.Monad.Trans (liftIO)

webPage :: MonadWidget t m => m ()
webPage = do

  -- ticker Event triggers every second.
  ticker :: Event t TickInfo <- tickLossy 1.0 =<< liftIO getCurrentTime  

  -- counter Dynamic increments by one per second.
  counter :: Dynamic t Int <- foldDyn  (\_ n -> n+1) 0 ticker

  -- function mapping integers to red or blue styling.
  let chooseColor :: Int -> (Map Text Text) 
      chooseColor n = "style" =: pack ("color: " ++ if (n `mod` 2) == 0 then "red" else "blue")

  -- redBlueStyle Dynamic changes each second.
  let redBlueStyle :: Dynamic t (Map Text Text) 
      redBlueStyle = fmap chooseColor counter

  -- place an h1 element.
  el "h1" $ text "Hello World!"

  -- add a paragraph with Dynamic red-blue style.
  elDynAttr "p" redBlueStyle $ text "This is my test document"

  return ()


css = "h1 {font-family: Helvetica;} p {font-family: Helvetica;}" 

main :: IO ()
main = mainWidgetWithCss css webPage

It's important to note that reflex-dom brings higher level functionalities compared to ghcjs-dom and introduces concepts like Event, Dynamic, and Behavior that require some familiarity.

The provided example utilizes a Dynamic Map to switch styles between red and blue every second when applied to an element.

To enhance clarity, this demonstration includes certain type declarations that may not be strictly necessary.

You can find this project at: https://github.com/dc25/stackOverflow__how-to-change-h1-tags-with-ghcjs-dom. Explore a browser-based demo here:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to disable the caching feature in Google Chrome

When I am working on CSS and JS around a page, I need to disable the cache mechanism in Google Chrome browser. A trick is to open Chrome DevTools, which automatically disables the cache mechanism (you can configure this in the settings section). Are ther ...

Tips for repairing a button using a JavaScript function in an HTML document

I am currently working on extracting titles from body text. To achieve this, I have created a button and linked my function to it. The issue I am facing is that when I click on the button, it disappears from its original position. I intend to keep it in pl ...

I'm struggling to locate the space that should be between these elements

After accidentally starting in quirks mode without declaring a doctype, I realized my mistake and corrected it by declaring a doctype. However, there is a persistent issue with a space between .car-box-img and car-box that I can't seem to locate in t ...

Tips for creating an inline list in MVC

I have a list in MVC that I want to display inline in blocks. List- <ul> <li> @foreach (var item in Model) { <img src="@item.cardFilePath"/> } </li> </ul> CSS attempted here- li { list-style-type: none; displa ...

How to use CSS to align text at the bottom of Angular Material icons within spans?

Looking for assistance with this code snippet. I am trying to align the text within the spans to the bottom of the stars. <ng-container *ngIf="starCount"> <span>Not Relevant</span> <button mat-icon-button ...

Calculating the dimensions of a CSS element based on its content

Is there a way to achieve this using only CSS, without needing JavaScript? I am working on a project with a lot of relative and absolute positions, where elements must be centered dynamically without specifying static widths. While I have managed to minimi ...

Creating a curved container with CSS styling

I've attempted to create a design resembling the image below, but I'm not achieving the desired result. Can someone provide me with assistance? Any help would be greatly appreciated. https://i.sstatic.net/J4LzC.png <!DOCTYPE ht ...

Change the display, animate the elements within

Currently working on a landing page with a contentSwitcher and everything is functioning properly. However, I am interested in animating the contents sequentially to add some stylish flair. Take a look at the Test Landing Page for reference. If you observ ...

Having trouble with CSS messing up your gridview button display?

Oddly enough, whenever I place buttons inside a gridview, they end up looking very small (as shown in the image below), even though the gridview itself has no CSS applied to it. Is it possible that some other CSS is affecting the buttons? I have too much ...

The H1 tag is mysteriously displaying padding or margin on the bottom, despite not being set

Despite not setting any padding or margin for the H1 tag, it still appears to have some spacing at the bottom. After applying a margin and padding of 0 to both the h1 tag and the text below it, I am still facing an issue where the text doesn't align ...

Spots on a spinning wheel

I created a simple carousel design: .index { background-color: var(--color-blue); } .container { display: flex; overflow: auto; outline: 10px solid black; flex: none; } .container.x { width: 100%; flex-flow: row nowrap; } .x.mandatory-s ...

Achieving a layout of three columns and two rows (1 x 2 x 2) using flexbox

I am looking to achieve a specific layout using Flexbox. While I am comfortable with CSS, I want to challenge myself by learning how to implement this design using Flexbox for more concise and maintainable code. https://i.stack.imgur.com/QDVfT.png .ban ...

Updating the icon of an action column dynamically in Ext JS4

Using the getClass function to display icons in the action column: { xtype: 'actioncolumn', id:'actionColumnGridUsers', width: 30, hideable: false, items: ['->', { getClass: function (v, meta, rec) { ...

Keyframes for CSS3 animations

I've spent the past hour trying to figure out this issue. I rely on Notepad++ as my code editor, and I've been attempting to create a css3 animation without success. The problem lies in Notepad++ not recognizing the "@" symbol in "@-webkit-keyfra ...

In what way does a child's width vary when set to "100%" or "inherit" from its parent element?

Can a Child element, nested within a Parent, have a width that is different from the parent's width when: 1) the Child's Width is set to 100% 2) the Child's Width is set to 'inherit'? I am experiencing both scenarios. It is challe ...

Creating a dropdown in HTML that overlaps another div requires using relative and absolute positioning

Having created a navigation bar with dropdown menu items that reveal on hover, I encountered an issue. Below the navigation bar lies a slideshow of images. Whenever I hover over the dropdowns, the slideshow div obstructs the view, making it impossible to s ...

Adding a line and text as a label to a rectangle in D3: A step-by-step guide

My current bar graph displays values for A, B, and C that fluctuate slightly in the data but follow a consistent trend, all being out of 100. https://i.stack.imgur.com/V8AWQ.png I'm facing issues adding lines with text to the center of each graph. A ...

The shadow effects and color overlays do not seem to be functioning properly in Mozilla Firefox

I have designed a popup registration form using the Bootstrap modal class. To ensure form validation, I have integrated some jQuery validation engine functionality. Additionally, I customized the appearance by adding a box shadow, adjusting the background ...

Show HTML code inside a text box

I have a text box that I populate with data from a Json response like this: <div class="gadget-body" style="height:100px"> <label>{{ textData}}</label> </div> Now, the Json response contains HTML code with <p> and < ...

Change a portion of the CSS background-image URL using vanilla JavaScript for a set of pictures

My current code successfully updates part of an src URL for regular images. let svgz = document.querySelectorAll(".svg"); for (let i = 0; i < svgz.length; i++) { svgz[i].src = svgz[i].src.replace("light", "dark"); } Now, ...