Comments (5)
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:
- the payload should be a Record of
{detail :: String}
and - 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:
from purescript-flame.
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:
- Use a managed element (see here https://flame.asafe.dev/views)
- Using some custom event/subscription to call into flame from your foreign code (see here https://flame.asafe.dev/events#subscriptions)
- Create some light wrapper for your JavaScript code using foreign definitions
I don't think server side rendering will help here. Does any of this help?
from purescript-flame.
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.
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.
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)
- Move CI to Github Actions HOT 1
- `lazy` with mutliple html composition layers appears to cause runtime errors / other odd behavior HOT 6
- Doctype HOT 2
- Monoid instance for Html a HOT 5
- Make Flame.Types.Html a real type HOT 1
- Internationalisation HOT 6
- Grouping elements in SVG
- No <kbd> tag
- Conditional rendering of fragments
- impossible to execute the ssr example HOT 6
- impossible to build examples HOT 2
- The `tabindex` attribute does not work due to capitalization HOT 3
- Why not use /\ instead of :> for Tuple operator? HOT 1
- Question about Stale model in `AffUpdate` HOT 1
- Bug when using a function as the type of a message HOT 2
- `ReferenceError: document is not defined` on `spago run` HOT 1
- friction at running examples
- HTML elements with empty array of attributes and/or children
- Trivial ToClassList instance HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from purescript-flame.