GithubHelp home page GithubHelp logo

Comments (5)

hasanalrasyid avatar hasanalrasyid commented on June 18, 2024 1

Great, all solved. Just want to share some results. Here are the minimum working example, combined with examples/SpecialElements due to me being strayed to HE.lazy. However, it helped me to realize which and where should I put the implementations. The code should show us better.

Aim: I want to use the dynamically updated autocomplete input box from jQuery as flame element, and use its value.

index.html : very clean and straightforward

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
       <link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css">
    </head>

    <body>
  <script src="https://code.jquery.com/jquery-3.6.0.js"></script>
  <script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
    <div id="app"></div>

    <script src="./app.js" type="module"></script>
    </div>
    </body>
</html>

src/Main.js : I spent quite some time on the message that I should send by document.dispatchEvent. The error from browser console did not help very much for me. It would be better if we know beforehand that:

  1. the payload should be a Record of {detail :: String} and
  2. then we should JSON.stringify the data first
"use strict"

export function createAutoCompleteJQ(){
  var res = document.createElement("input");
  res.id = "birds";
  $(function(){
    $( "#birds" ).autocomplete({
     source: "search.php",
     minLength: 2,
     select: function( event, ui ) {
      console.log( "Selected: " + ui.item.value + " aka " + ui.item.id );
      var theMessage = {bird : ui.item.value + " aka " + ui.item.id} ;
      document.dispatchEvent(new CustomEvent("birdEvent", {detail: JSON.stringify(theMessage)}))
     }
  });
  });
  return res;
}

src/Main.purs: I did not quite grasp the difference between HE.managed_ and HE.managed. What is nd in HE.managed :: forall arg nd message. ToNode nd message NodeData => NodeRenderer arg -> nd -> arg -> Html message ?

module Main where

import Prelude

import Data.Array ((:))
import Data.Maybe (Maybe(..))
import Data.Tuple (Tuple)
import Effect (Effect)
import Effect.Aff (Aff)
import Effect.Class (liftEffect)
import Effect.Random as ER
import Flame (QuerySelector(..), Html, (:>))
import Flame as F
import Flame.Html.Attribute as HA
import Flame.Html.Element as HE
import Flame.Subscription as FS
import Web.DOM (Node)
import Web.Event.Event (EventType(..))

foreign import createAutoCompleteJQ :: Effect Node

type Model =
      { current ∷ Maybe Int
      , history ∷ Array Int
      , bird :: Array String
      }

init ∷ Model
init =
      { current: Nothing
      , history: []
      , bird: []
      }

data Message = Roll | Update Int | BirdEvent (Array String)

update ∷ Model → Message → Tuple Model (Array (Aff (Maybe Message)))
update model@{ history } = case _ of
      BirdEvent theBird -> model { bird = theBird } :> []
      Roll → model :>
            [ Just <<< Update <$> liftEffect (ER.randomInt 1 6)
            ]
      Update roll →
            model
                  { current = Just roll
                  , history = roll : history
                  } :> []

view ∷ Model → Html Message
view { current, history, bird } = HE.fragment
      [ -- only children elements will be rendered
        HE.text $ show current
      , HE.button [ HA.onClick Roll ] "Roll"
      , HE.br
      , HE.span_ "History"
      , HE.div_ $ map lazyEntry history

 -- this should be updated based on the input picked on the autocomplete textinput, it can even be shown before I do anything on the textbox ;-P
      , HE.text $ show bird

-- Here we use managed element. I do not quite understand the difference with `HE.managed`.
      , HE.div_ $ HE.managed_
          { createNode: const createAutoCompleteJQ
          , updateNode: \n _ _ -> pure n} unit
      ]

lazyEntry :: Int -> Html Message
lazyEntry roll = HE.lazy Nothing toEntry roll -- lazy node will only be recomputed in case the roll changes
      where
      rolled = show roll
      toEntry = const (HE.div (HA.key rolled) rolled) -- keyed rendering for rolls

main ∷ Effect Unit
main = do
  F.mount_ (QuerySelector "#app")
      { init: init :> []
      , subscribe:
        [ FS.onCustomEvent (EventType "birdEvent") birdEventProcessor ]
      , update
      , view
      }
      where
        birdEventProcessor :: { bird :: String} -> Message
        birdEventProcessor {bird} = BirdEvent [bird]

Just a note for myself, it turned out that there are some gems in test/ directory. So I needlessly limit myself on src/ and examples/.

In short, I am very satisfied with this library and will implement it on my real use case. As for the solution, hopefully @easafe can show a more elegant way (means shorter).

Thank you for this beautiful flaming gem.

Reference:

  1. Autocomplete example in jQuery

from purescript-flame.

easafe avatar easafe commented on June 18, 2024

Hello @hasanalrasyid ,

It is a bit hard to tell without seeing code or how you'd use this JavaScript code. But here are some options:

I don't think server side rendering will help here. Does any of this help?

from purescript-flame.

hasanalrasyid avatar hasanalrasyid commented on June 18, 2024

Hello @easafe, thank you for such a fast response.
I am looking into managed element here.

From your advises, I suppose for createNode, I can use an imported foreign to initiate the container div.
as for updateNode, maybe I can tell pureScript not to touch anything inside container because it already managed by the external javascript library, thus updateNode n _ _ = pure n

Is this correct?

I am preparing some minimal working example (or not working ;-) ). I'll send some updates later.

Nonetheless, are there some available example on managed element?

Thank you very much.

from purescript-flame.

easafe avatar easafe commented on June 18, 2024

Is this correct?

It could be, yes. Do you need to pass any data from the node to your model? For example, inputted text or selected option. If so you either need to handle messages events or use subscriptions.

Nonetheless, are there some available example on managed element?

I thought so, but apparently not. Gonna have to fill that gap.

Feel free to post any code samples once you have'em!

from purescript-flame.

easafe avatar easafe commented on June 18, 2024

Thank you for your kind words @hasanalrasyid

I did not quite grasp the difference between HE.managed_ and HE.managed

HE.managed_ won't try to diff attributes/events/properties on that node, whereas HE.managed do.

Other than that, I think you got it about the most straightforward way to consume the external event

from purescript-flame.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.