Commit b25e653c authored by Bas Lijnse's avatar Bas Lijnse

Added a generic way to trigger itask component events from html fragments....

Added a generic way to trigger itask component events from html fragments. Used it in leaflet maps to trigger events from map windows
parent cebaf402
Pipeline #25724 failed with stage
in 1 minute and 16 seconds
...@@ -13,8 +13,13 @@ playWithMaps = withShared ({defaultValue & icons = shipIcons, tilesUrls = ["/til ...@@ -13,8 +13,13 @@ playWithMaps = withShared ({defaultValue & icons = shipIcons, tilesUrls = ["/til
) <<@ ArrangeWithSideBar 0 LeftSide True @! () ) <<@ ArrangeWithSideBar 0 LeftSide True @! ()
manipulateMap :: (Shared sds (LeafletMap,LeafletSimpleState)) -> Task () | RWShared sds manipulateMap :: (Shared sds (LeafletMap,LeafletSimpleState)) -> Task () | RWShared sds
manipulateMap m = updateSharedInformation () [UpdateUsing id (flip const) (customLeafletEditor simpleStateEventHandlers)] m manipulateMap m = updateSharedInformation () [UpdateUsing id (flip const) (customLeafletEditor eventHandlers)] m
<<@ ApplyLayout (layoutSubUIs (SelectByPath [1]) (setUIAttributes (sizeAttr FlexSize FlexSize))) @! () <<@ ApplyLayout (layoutSubUIs (SelectByPath [1]) (setUIAttributes (sizeAttr FlexSize FlexSize))) @! ()
where
eventHandlers = {simpleStateEventHandlers & onHtmlEvent = onHtmlEvent}
onHtmlEvent "closewindows" (l,s) = ({LeafletMap|l & objects = [o \\ o <- l.LeafletMap.objects | not (o =: (Window _))]},s)
onHtmlEvent _ (l,s) = (l,s)
managePerspective :: (Shared sds (LeafletMap,LeafletSimpleState)) -> Task () | RWShared sds managePerspective :: (Shared sds (LeafletMap,LeafletSimpleState)) -> Task () | RWShared sds
managePerspective m = updateSharedInformation (Title "Perspective") [] managePerspective m = updateSharedInformation (Title "Perspective") []
...@@ -106,7 +111,10 @@ where ...@@ -106,7 +111,10 @@ where
{ windowId = LeafletObjectID "WINDOW" { windowId = LeafletObjectID "WINDOW"
, initPosition = {x = 100, y = 100} , initPosition = {x = 100, y = 100}
, title = "Test Window" , title = "Test Window"
, content = H1Tag [] [Text "This is test content!"] , content = DivTag []
[H1Tag [] [Text "This is test content!"]
,ATag [HrefAttr "#",OnclickAttr "itasks.htmlEvent('closewindows')"] [Text "Close windows"]
]
, relatedMarkers = [(LeafletObjectID "home", [])] , relatedMarkers = [(LeafletObjectID "home", [])]
} }
......
...@@ -121,6 +121,7 @@ leafletObjectIdOf :: !LeafletObject -> LeafletObjectID ...@@ -121,6 +121,7 @@ leafletObjectIdOf :: !LeafletObject -> LeafletObjectID
:: LeafletEventHandlers s = :: LeafletEventHandlers s =
{ onMapClick :: LeafletLatLng (LeafletMap,s) -> (LeafletMap,s) { onMapClick :: LeafletLatLng (LeafletMap,s) -> (LeafletMap,s)
, onMarkerClick :: LeafletObjectID (LeafletMap,s) -> (LeafletMap,s) , onMarkerClick :: LeafletObjectID (LeafletMap,s) -> (LeafletMap,s)
, onHtmlEvent :: String (LeafletMap,s) -> (LeafletMap,s)
} }
//A minimal state for tracking a set of selected markers //A minimal state for tracking a set of selected markers
......
...@@ -52,6 +52,7 @@ leafletObjectIdOf (Window w) = w.windowId ...@@ -52,6 +52,7 @@ leafletObjectIdOf (Window w) = w.windowId
//Events //Events
| LDMapClick !LeafletLatLng | LDMapClick !LeafletLatLng
| LDMarkerClick !LeafletObjectID | LDMarkerClick !LeafletObjectID
| LDHtmlEvent !String
:: LeafletObjectUpdate :: LeafletObjectUpdate
= UpdatePolyline ![LeafletLatLng] = UpdatePolyline ![LeafletLatLng]
...@@ -179,6 +180,8 @@ where ...@@ -179,6 +180,8 @@ where
# world = (vp .# "addChangeListener" .$! me) world # world = (vp .# "addChangeListener" .$! me) world
# (cb,world) = jsWrapFun (\a w -> beforeRemove me w) me world # (cb,world) = jsWrapFun (\a w -> beforeRemove me w) me world
# world = (me .# "beforeRemove" .= cb) world # world = (me .# "beforeRemove" .= cb) world
# (cb,world) = jsWrapFun (\a w -> onHtmlEvent me a w) me world
# world = (me .# "onHtmlEvent" .= cb) world
# world = case viewMode of # world = case viewMode of
True True
= world = world
...@@ -247,6 +250,17 @@ where ...@@ -247,6 +250,17 @@ where
Just "icons" = setMapIcons me mapObj args.[1] world Just "icons" = setMapIcons me mapObj args.[1] world
_ = world _ = world
onHtmlEvent me args world
# (taskId,world) = me .# "attributes.taskId" .? world
# (editorId,world) = me .# "attributes.editorId" .? world
= case (jsValToString args.[0]) of
Just event
# edit = toJSON [LDHtmlEvent event]
# world = (me .# "doEditEvent" .$! (taskId,editorId,edit)) world
= world
_ = world
onAfterChildInsert viewMode me args world onAfterChildInsert viewMode me args world
# (l, world) = jsGlobal "L" .? world # (l, world) = jsGlobal "L" .? world
# (mapObj,world) = me .# "map" .? world # (mapObj,world) = me .# "map" .? world
...@@ -691,6 +705,7 @@ simpleStateEventHandlers :: LeafletEventHandlers LeafletSimpleState ...@@ -691,6 +705,7 @@ simpleStateEventHandlers :: LeafletEventHandlers LeafletSimpleState
simpleStateEventHandlers = simpleStateEventHandlers =
{ onMapClick = \position (l,s) -> (addCursorMarker position l,{LeafletSimpleState|s & cursor = Just position}) { onMapClick = \position (l,s) -> (addCursorMarker position l,{LeafletSimpleState|s & cursor = Just position})
, onMarkerClick = \markerId (l,s) -> (l,{LeafletSimpleState|s & selection = toggle markerId s.LeafletSimpleState.selection}) , onMarkerClick = \markerId (l,s) -> (l,{LeafletSimpleState|s & selection = toggle markerId s.LeafletSimpleState.selection})
, onHtmlEvent = \msg (l,s) -> (l,s)
} }
where where
addCursorMarker position l=:{LeafletMap|objects,icons} = {l & objects = addCursorObject objects, icons=addCursorIcon icons} addCursorMarker position l=:{LeafletMap|objects,icons} = {l & objects = addCursorObject objects, icons=addCursorIcon icons}
...@@ -749,12 +764,13 @@ where ...@@ -749,12 +764,13 @@ where
valueFromState s = Just s valueFromState s = Just s
updateCustomState {onMapClick,onMarkerClick} datapath (target,edits) state updateCustomState {onMapClick,onMarkerClick,onHtmlEvent} datapath (target,edits) state
| target <> datapath = state | target <> datapath = state
| otherwise = foldl update state edits | otherwise = foldl update state edits
where where
update state (LDMapClick position) = onMapClick position state update state (LDMapClick position) = onMapClick position state
update state (LDMarkerClick markerId) = onMarkerClick markerId state update state (LDMarkerClick markerId) = onMarkerClick markerId state
update state (LDHtmlEvent event) = onHtmlEvent event state
update state _ = state update state _ = state
instance == LeafletObjectID where (==) (LeafletObjectID x) (LeafletObjectID y) = x == y instance == LeafletObjectID where (==) (LeafletObjectID x) (LeafletObjectID y) = x == y
......
//Test script for new itasks embedding style //Global itasks namespace
itasks = {}; itasks = {};
//auxiliary definitions for sending Maybe values to server //Auxiliary definitions for sending Maybe values to server
const Nothing = ["Nothing"]; const Nothing = ["Nothing"];
function Just(x) { return["Just", x]; } function Just(x) { return["Just", x]; }
//Global lookup table of itask components indexed by their dom element.
//This makes it possible to find the managing itask component object for arbitrary dom elements.
//Because it is a WeakMap, we can register components without having to unregister them.
itasks.components = new WeakMap();
//Core behavior //Core behavior
itasks.Component = { itasks.Component = {
...@@ -32,6 +37,7 @@ itasks.Component = { ...@@ -32,6 +37,7 @@ itasks.Component = {
.then(me.initComponent.bind(me)) .then(me.initComponent.bind(me))
.then(me.initChildren.bind(me)) .then(me.initChildren.bind(me))
.then(me.renderComponent.bind(me)) .then(me.renderComponent.bind(me))
.then(me.registerComponent.bind(me))
.then(function(){ me.initialized=true; }); .then(function(){ me.initialized=true; });
}, },
initUI: function() { initUI: function() {
...@@ -92,6 +98,11 @@ itasks.Component = { ...@@ -92,6 +98,11 @@ itasks.Component = {
} }
}); });
}, },
registerComponent: function() {
if(this.domEl !== null) {
itasks.components.set(this.domEl,this);
}
},
initDOMEl: function() {}, initDOMEl: function() {},
initDOMElSize: function() { initDOMElSize: function() {
...@@ -330,6 +341,8 @@ itasks.Component = { ...@@ -330,6 +341,8 @@ itasks.Component = {
onResize: function() { onResize: function() {
this.children.forEach(function(child) { if(child.onResize) {child.onResize();}}); this.children.forEach(function(child) { if(child.onResize) {child.onResize();}});
}, },
onHtmlEvent: function(msg) { //Abstract
},
getViewport: function() { getViewport: function() {
var me = this, vp = me.parentCmp; var me = this, vp = me.parentCmp;
while(vp) { while(vp) {
...@@ -674,3 +687,17 @@ itasks.ConnectionPool = { ...@@ -674,3 +687,17 @@ itasks.ConnectionPool = {
} }
}; };
//Global functions that you can use to trigger edit events from pieces of html code displayed by components
itasks.htmlEvent = function(msg) {
var domEl = event.target;
var component = null;
event.preventDefault();
while(domEl !== null && (component = itasks.components.get(domEl)) == null) {
domEl = domEl.parentElement;
}
if(component !== null) {
component.onHtmlEvent(msg);
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment