简体   繁体   中英

getElementById in Purescript

I am very new to Purescript so this might be a naive question.

I want to write a Purescript function that reads input from HTML input elements on the browser and writes some output to another HTML input element.

With plain Javascript it's as simple as document.getElementById('output').value = myFun(document.getElementById('input')); . How do I do this with just Purescript?

EDIT:

I've noticed that my answer doesn't meet the requirements - I'm only setting up an element value. If I find more time I probably add also reading from element value piece but you should be able to guess how to do this from the hints provided already:-)


In general when using PureScript you want to use some high level framework to manipulate the DOM like: halogen, react-basic, concur, spork, elmish, flare, hedwig, flame (for sure I've missed some others - sorry about that).

But if you really want to mutate the DOM by hand please don't be surprised that it is not as pleasant experience as in imperative JavaScript. It is on purpose - PureScript has the power to separate effects from pure functions and we have to work with Effect in every step here. On the other hand this gives us an unique ability to reason about the code and be sure where side effects can happen and which parts of our program are pure.

So let's use low level purescript-web-html . This library is low level but provides strict types around DOM API so like I said it requires quite a lot of manual value passing:

module Main where

import Prelude

import Data.Maybe (Maybe(..))
import Effect (Effect)
import Web.DOM.Document (toNonElementParentNode)
import Web.DOM.Element (setAttribute)
import Web.DOM.NonElementParentNode (getElementById)
import Web.HTML (window)
import Web.HTML.HTMLDocument (toDocument)
import Web.HTML.Window (document)

main :: Effect Unit
main = do
  w ← window
  d ← document w
  maybeElement ← getElementById "test-input" $ toNonElementParentNode $ toDocument  d
  case maybeElement of
    Nothing → pure unit
    Just elem → do
      setAttribute "value" "new-value" elem

This can be written a bit shorter using point free style so avoiding intermediate variables:

main :: Effect Unit
main = window >>= document >>= toDocument >>> toNonElementParentNode >>> getElementById "test-input" >>= case _ of
  Nothing → pure unit
  Just elem → setAttribute "value" "new-value" elem

Direct DOM manipulation is probably not the best way to start building a larger project or beginning the adventure with this really wonderful language. On the other hand it can be useful from time to time;-)

I used Foreign Function Interface (FFI) feature of Purescript as follows.

Define your Purescript module with imports of foreign functions you want to use. Here we have imported two functions.

-- Main.purs
foreign import getElementById :: String -> Effect String
foreign import setElementById :: String -> String -> Effect Unit 

Now create a Javascript file with the same name but .js extension. We will export JS functions from here for use in Purescript.

// Main.js
"use strict";

exports.getElementById = function(id) {
    return document.getElementById(id).value;
};

exports.setElementById = function(id) {
    return function(value) {
    document.getElementById(id).value = value;
    };
};

Now we can call getElementById and setElementById functions in our Purescript files.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM