module Dom ( onInput , selectElement , selectElementFrom , selectElementsFrom , replaceElement , appendNodes , setValue ) where import Control.Monad.Eff (Eff) import Control.Monad.Except (runExcept) as Except import Data.Array (range, catMaybes) as Array import Data.Either (Either(Right)) import Data.Foreign (toForeign) as Foreign import Data.Maybe (Maybe(Nothing, Just)) import Data.Traversable (sequence) as Traversable import Prelude import DOM (DOM) import DOM.HTML (window) as DOM import DOM.HTML.HTMLInputElement (setValue) as HTMLInputElement import DOM.HTML.Types (htmlDocumentToParentNode, readHTMLInputElement) as DOM import DOM.HTML.Window (document) as DOM import DOM.Node.Node (replaceChild, parentNode, appendChild) as DOM import DOM.Node.NodeList (length, item) as DOM import DOM.Node.ParentNode (QuerySelector) import DOM.Node.ParentNode (querySelector, querySelectorAll) as DOM import DOM.Node.Types (Element, Node) import DOM.Node.Types (elementToParentNode) as DOM foreign import onInput :: forall e. Element -> (String -> Eff (dom :: DOM | e) Unit) -> Eff (dom :: DOM | e) Unit selectElement :: forall e. QuerySelector -> Eff (dom :: DOM | e) (Maybe Element) selectElement query = do document <- DOM.window >>= DOM.document DOM.querySelector query (DOM.htmlDocumentToParentNode document) selectElementFrom :: forall e. Element -> QuerySelector -> Eff (dom :: DOM | e) (Maybe Element) selectElementFrom elem query = DOM.querySelector query (DOM.elementToParentNode elem) selectElementsFrom :: forall e. Element -> QuerySelector -> Eff (dom :: DOM | e) (Array Node) selectElementsFrom elem query = do nodeList <- DOM.querySelectorAll query (DOM.elementToParentNode elem) length <- DOM.length nodeList Array.range 0 length # map (\i -> DOM.item i nodeList) # Traversable.sequence # map Array.catMaybes replaceElement :: forall e. Node -> Node -> Eff (dom :: DOM | e) Unit replaceElement before after = do parent <- DOM.parentNode before case parent of Just n -> do _ <- DOM.replaceChild after before n pure unit Nothing -> pure unit appendNodes :: forall e. Node -> Array Node -> Eff (dom :: DOM | e) Unit appendNodes parent nodes = nodes # map (\n -> DOM.appendChild n parent) # Traversable.sequence # map (const unit) setValue :: forall e. String -> Element -> Eff (dom :: DOM | e) Unit setValue value elem = case Except.runExcept $ DOM.readHTMLInputElement (Foreign.toForeign elem) of Right inputElem -> do HTMLInputElement.setValue value inputElem _ -> pure unit