EzDevInfo.com

halogen

A collection of loading spinners with React.js

Monad Transformer for Halogen Components

I'm trying to figure out in which way I can use a transformer on the monad that a Halogen component contains.

I'd like to extend the intro example by a ReaderT that carries a Config record which in this case could be used to make the strings configurable, but I'm a lost when it comes to putting it all together.

Let's say we define our Config like this:

-- | Global configuration
newtype Config = Config { toggleText :: String
                        , onText :: String
                        , offText :: String
                        }

Our ui function would then turn from

forall m eff. (Monad m) => Component m Input Input

to

forall m (Monad m) => Component (ReaderT Config m) Input Input.

To evaluate our main function, we'd then use hoistComponent to turn it back into its previous form:

main = do
  let config = Config { toggleText: "Toggle Button"
                      , onText: "On"
                      , offText: "Off"
                      }
  Tuple node _ <- runUI $ hoistComponent (runReaderT config) ui
  appendToBody node

I'm not sure if this even makes sense so far, but pretending that it does, the next step is where I'm struggling. In an ideal world, my ui function would allow me to do something like this:

ui :: forall m eff. (Monad m) => Component (ReaderT Config m) Input Input
ui = render <$> stateful (State { on: false }) update
  where
  render :: State -> H.HTML (ReaderT Config m Input)
  render (State s) = do
    (Config conf) <- ask
    return $ H.div_ [ H.h1_ [ H.text conf.toggleText ]
                    , H.button [ A.onClick (A.input_ ToggleState) ]
                               [ H.text (if s.on then conf.onText else conf.offText) ]
                    ]

  update :: State -> Input -> State
  update (State s) ToggleState = State { on: not s.on }

But I end up with a long chain of unification errors and don't know where to start. Obviously, the inner use of ask cannot work like this, because I'd need to lift it into the HTML context, but I'm not even sure if that's possible.

It would be great if someone could guide my through the types here and tell me if that general approach is sensible. A full (non-compiling) example is on GitHub. I18n should only serve as a simple example use of the Reader here.


Source: (StackOverflow)

Automatically focus input element after creation in purescript-halogen

I'm using purescript-halogen to build a spreadsheet-like table (similar to Handsontable). If you double-click a cell, an html input element is rendered as a child of the respective table cell (and no such element is rendered for all the other cells).

This works really well with halogen, except that I don't know how to automatically set the focus to the newly created input element.

I tried the autofocus attribute, but this only works for the first cell that is double-clicked. The JavaScript way to do it is by calling the focus() method on the new element, but I don't know how to call it after the DOM has been updated in halogen. Any ideas?


Source: (StackOverflow)

Advertisements

How do I combine effectful event handlers and custom EventUpdates in purescript-halogen?

In my custom Halogen/Purescript project I follow the pattern from the AJAX Example where I split my actions up into pure Inputs and effectful Requests.

I want to change my event handler to use the preventDefault behavior, but don't understand what the consequences for the type of the UI function this entails.

I made the same changes to the AJAX Example by changing the event handler the following way:

Before:

H.button [ A.classes [B.btn, B.btnPrimary]
         , A.disabled busy
         , A.onclick (\_ -> pure (handler code))
         ] [ H.text "Compile" ]

After:

H.a [ A.classes [B.btn, B.btnPrimary]
    , A.href "#compile"
    , A.disabled busy
    , A.onclick (\_ -> E.preventDefault $> pure (handler code))
    ] [ H.text "Compile" ]

(Full diff available here)

I end up with this type error:

Cannot unify type
    Example.Ajax.Input
    with type
        Halogen.HTML.Events.Monad.Event Halogen.HalogenEffects<(http ::
        Example.Ajax.HTTP | u32519)> Example.Ajax.Input

At this point, I'm a bit lost whether I would need to adjust the type signature of the UI function or I apply the preventDefault modifier the wrong way.


Source: (StackOverflow)