From 14433a928f7fdf9be3193812cbbed1a5ae49ecd7 Mon Sep 17 00:00:00 2001 From: Joris Date: Mon, 8 May 2017 20:44:45 +0200 Subject: Let the user upgrade an ingredient quantity and adapt other quantities --- js/EditableNumber.purs | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 js/EditableNumber.purs (limited to 'js/EditableNumber.purs') diff --git a/js/EditableNumber.purs b/js/EditableNumber.purs new file mode 100644 index 0000000..eb5ddb0 --- /dev/null +++ b/js/EditableNumber.purs @@ -0,0 +1,72 @@ +module EditableNumber + ( NumberElem + , set + , formatNumber + ) where + +import Control.Monad.Eff (Eff) +import Data.Int (round, toNumber, pow) as Int +import Data.Maybe (Maybe(..)) +import Data.String (Pattern(..), Replacement(..)) +import Data.String (replace) as String +import DOM (DOM) +import DOM.HTML (window) as DOM +import DOM.HTML.Types (htmlDocumentToDocument) as DOM +import DOM.HTML.Window (document) as DOM +import DOM.Node.Document (createElement, createTextNode) as DOM +import DOM.Node.Element (setClassName, setAttribute) as DOM +import DOM.Node.Node (textContent) as DOM +import DOM.Node.Types (Element, Node) +import DOM.Node.Types (elementToNode, textToNode) as DOM +import Math (round) as Math +import Prelude + +import Dom (replaceElement, appendNodes) as Dom +import Parser (TextWithNumber) +import Parser (textWithNumber) as Parser + +type NumberElem = + { elem :: Element + , number :: Number + } + +set :: forall e. { tag :: String, node :: Node } -> Eff (dom :: DOM | e) (Maybe NumberElem) +set { tag, node } = do + content <- DOM.textContent node + case Parser.textWithNumber content of + Just twn -> do + textWithNumber <- textWithNumberElem tag twn + Dom.replaceElement node (DOM.elementToNode textWithNumber) + pure (Just { elem: textWithNumber, number: twn.number }) + Nothing -> + pure Nothing + +textWithNumberElem :: forall e. String -> TextWithNumber -> Eff (dom :: DOM | e) Element +textWithNumberElem tag { begin, number, end } = do + document <- DOM.htmlDocumentToDocument <$> (DOM.window >>= DOM.document) + elem <- DOM.createElement tag document + beginNode <- DOM.textToNode <$> DOM.createTextNode begin document + numberNode <- numberElem number + endNode <- DOM.textToNode <$> DOM.createTextNode end document + Dom.appendNodes (DOM.elementToNode elem) [ beginNode, DOM.elementToNode numberNode, endNode ] + pure elem + +numberElem :: forall e. Number -> Eff (dom :: DOM | e) Element +numberElem number = do + document <- DOM.htmlDocumentToDocument <$> (DOM.window >>= DOM.document) + container <- DOM.createElement "input" document + DOM.setClassName "number" container + DOM.setAttribute "value" (formatNumber number) container + pure container + +formatNumber :: Number -> String +formatNumber number = + if Math.round number == number then + show (Int.round number) + else + String.replace (Pattern ".") (Replacement ",") (show (roundAt 1 number)) + +roundAt :: Int -> Number -> Number +roundAt at n = + let exp = Int.toNumber (Int.pow 10 at) + in Math.round (n * exp) / exp -- cgit v1.2.3