Discussion:
[Ur] calling javascript code in <dyn>
Fabrice Leal
2018-07-04 20:10:57 UTC
Permalink
is it possible to trigger javascript code when calling 'set s ...' ?

as i understand the main usage seems to be regenerating html node trees; i
think i could get away with generating some dummy html node with the
javascript call in onload event, but I'm asking just to make sure I'm not
missing anything.

my goal is, for instance, to update some state on the client side and
trigger a canvas redraw,
since i seem to be unable to call '... <- signal s;' inside a 'transaction
page'
---
Fabrice Leal
Adam Chlipala
2018-07-04 20:17:28 UTC
Permalink
Let me try to disentangle the potential parts of your question.

I hope you are not asking about literally writing code in JavaScript.  I
will proceed as though you are actually asking about /client-side code/,
but let me know if I misunderstood.  (It is a rather nice feature of
Ur/Web that writing Ur/Web programs need not involve JavaScript at all,
anymore than we talk about "transistors" when reading JavaScript code!)

So, then, I conclude that your question is how to add a listener on a
[source], to run arbitrary client-side code whenever the source
changes.  You seem to be on a good track there, with the mention of a
dummy node.  I would create a <dyn> node that generates only a <script>
node, whose 'code' handler will then be run whenever the source changes,
such that this <dyn> node contributes no content to the page.
Post by Fabrice Leal
is it possible to trigger javascript code when calling 'set s ...' ?
as i understand the main usage seems to be regenerating html node
trees; i think i could get away with generating some dummy html node
with the javascript call in onload event, but I'm asking just to make
sure I'm not missing anything.
my goal is, for instance, to update some state on the client side and
trigger a canvas redraw,
since i seem to be unable to call '... <- signal s;' inside a
'transaction page'
Simon Van Casteren
2018-07-05 13:43:14 UTC
Permalink
This is a very cool trick! I happened to need this: I'm making a filtering
page with a ton of checkboxes, and every time I check any one of them, I
want to reload stuff from the server. My first solution was to add my
"reloadStuff" function in every onchange handler of every checkbox. I've
now replaced that with the trick mentioned above: one dyn tag which depends
on the signals of every checkbox source, and it renders a script tag when
something changes. Much cleaner! Have to be a little bit careful that I
don't start abusing this though.

Side note: the <script> tag in basis can only be placed in the <head> part
of an html document, so if you want to apply this you'll need to use the JS
ffi to make a new "bodyscript" tag, as mentioned in the manual in chapter
11.3)
Post by Adam Chlipala
Let me try to disentangle the potential parts of your question.
I hope you are not asking about literally writing code in JavaScript. I
will proceed as though you are actually asking about *client-side code*,
but let me know if I misunderstood. (It is a rather nice feature of Ur/Web
that writing Ur/Web programs need not involve JavaScript at all, anymore
than we talk about "transistors" when reading JavaScript code!)
So, then, I conclude that your question is how to add a listener on a
[source], to run arbitrary client-side code whenever the source changes.
You seem to be on a good track there, with the mention of a dummy node. I
would create a <dyn> node that generates only a <script> node, whose 'code'
handler will then be run whenever the source changes, such that this <dyn>
node contributes no content to the page.
is it possible to trigger javascript code when calling 'set s ...' ?
as i understand the main usage seems to be regenerating html node trees; i
think i could get away with generating some dummy html node with the
javascript call in onload event, but I'm asking just to make sure I'm not
missing anything.
my goal is, for instance, to update some state on the client side and
trigger a canvas redraw,
since i seem to be unable to call '... <- signal s;' inside a 'transaction
page'
_______________________________________________
Ur mailing list
http://www.impredicative.com/cgi-bin/mailman/listinfo/ur
Adam Chlipala
2018-07-05 13:59:25 UTC
Permalink
Oh, right.  The <active> tag should do just as well, in that case. 
You'd need to return an empty XML document explicitly, but that's not hard.
Post by Simon Van Casteren
Side note: the <script> tag in basis can only be placed in the <head>
part of an html document, so if you want to apply this you'll need to
use the JS ffi to make a new "bodyscript" tag, as mentioned in the
manual in chapter 11.3)
Simon Van Casteren
2018-07-05 14:09:19 UTC
Permalink
Active doesn't let you do rpc requests though, but if you don't need that
then active works as well, didn't think about that either...
Oh, right. The <active> tag should do just as well, in that case.
You'd need to return an empty XML document explicitly, but that's not hard.
Post by Simon Van Casteren
Side note: the <script> tag in basis can only be placed in the <head>
part of an html document, so if you want to apply this you'll need to
use the JS ffi to make a new "bodyscript" tag, as mentioned in the
manual in chapter 11.3)
_______________________________________________
Ur mailing list
http://www.impredicative.com/cgi-bin/mailman/listinfo/ur
Fabrice Leal
2018-07-05 17:43:30 UTC
Permalink
I didnt get Chlipala's mail in my inbox, so replying to my own email.
Post by Adam Chlipala
I hope you are not asking about literally writing code in JavaScript
How dare you? :o)

Sorry for the poor wording, thanks for the reply. I was trying to make
<script> work and found out about <active>, will try it laters, thanks.
I found out too late for my own good that onload only works for <body>,
placing it in a <div> as no effect
Post by Adam Chlipala
is it possible to trigger javascript code when calling 'set s ...' ?
as i understand the main usage seems to be regenerating html node trees; i
think i could get away with generating some dummy html node with the
javascript call in onload event, but I'm asking just to make sure I'm not
missing anything.
my goal is, for instance, to update some state on the client side and
trigger a canvas redraw,
since i seem to be unable to call '... <- signal s;' inside a 'transaction
page'
---
Fabrice Leal
--
---
Fabrice Leal
Adam Chlipala
2018-07-05 18:05:33 UTC
Permalink
Post by Fabrice Leal
I found out too late for my own good that onload only works for
<body>, placing it in a <div> as no effect
Oh, I didn't realize that some event attribute was systematically
ignored.  That might qualify as a bug!
Adam Chlipala
2018-10-22 18:40:36 UTC
Permalink
Belated follow-up on this remark: now that I look at the types from the
standard library, I see that 'onload' is statically disallowed for <div>
and indeed most other tags.  Is that what you meant?  It could be
reasonable to add 'onload' more widely, but currently including it for
most tags should not have 'no effect'.  Instead, it should trigger type
error messages!
Post by Adam Chlipala
Post by Fabrice Leal
I found out too late for my own good that onload only works for
<body>, placing it in a <div> as no effect
Oh, I didn't realize that some event attribute was systematically
ignored.  That might qualify as a bug!
Aistis Raulinaitis
2018-10-24 04:05:38 UTC
Permalink
Adam,

Yes, I've noticed ignored `onload` on tags other than `body`.

It would be good to have a type error or allowing it more broadly.

Aistis
Post by Adam Chlipala
Belated follow-up on this remark: now that I look at the types from the
standard library, I see that 'onload' is statically disallowed for <div>
and indeed most other tags. Is that what you meant? It could be
reasonable to add 'onload' more widely, but currently including it for most
tags should not have 'no effect'. Instead, it should trigger type error
messages!
I found out too late for my own good that onload only works for <body>,
placing it in a <div> as no effect
Oh, I didn't realize that some event attribute was systematically
ignored. That might qualify as a bug!
_______________________________________________
Ur mailing list
http://www.impredicative.com/cgi-bin/mailman/listinfo/ur
Adam Chlipala
2018-10-24 12:55:36 UTC
Permalink
Sorry, just to be clear: to the best of my knowledge, type errors are
already generated when trying to use 'onload' with tags other than
<body>!  Is that not the case?
Post by Aistis Raulinaitis
Adam,
Yes, I've noticed ignored `onload` on tags other than `body`.
It would be good to have a type error or allowing it more broadly.
Aistis
Belated follow-up on this remark: now that I look at the types
from the standard library, I see that 'onload' is statically
disallowed for <div> and indeed most other tags.  Is that what you
meant?  It could be reasonable to add 'onload' more widely, but
currently including it for most tags should not have 'no effect'.
Instead, it should trigger type error messages!
Post by Adam Chlipala
Post by Fabrice Leal
I found out too late for my own good that onload only works for
<body>, placing it in a <div> as no effect
Oh, I didn't realize that some event attribute was systematically
ignored.  That might qualify as a bug!
Fabrice Leal
2018-10-22 22:50:18 UTC
Permalink
@AdamChlipala

At the time I implemented an onload attribute for <div> on basis.ur and
only later found out if was for no good on html/js land: the only onload
that gets triggered is the one defined on <body>, setting onload for any
other child tag has no "side effects"; so I scrapped that.

Sorry for the vagueness :)

I did end up using <active code={...} /> and that worked for me
Adam Chlipala
2018-10-22 22:59:24 UTC
Permalink
Here's a hypothesis: if you return a <div onload={...}> at the top level
of a generated page (after adding the attribute by changing basis.urs),
it will actually do what you expect.  However, if you embed such a <div>
within dynamically generated content, even the /initial value/ of such a
dynamic region, the 'onload' handler is not called.  The reason is that
the dynamically generated <div> actually isn't there at the moment when
the page loads; it is only created by JavaScript code running thereafter.

Does that hypothesis seem to match your prior situation?
Post by Fabrice Leal
@AdamChlipala
At the time I implemented an onload attribute for <div> on basis.ur
and only later found out if was for no good on html/js land: the only
onload that gets triggered is the one defined on <body>, setting
onload for any other child tag has no "side effects"; so I scrapped that.
Sorry for the vagueness :)
I did end up using <active code={...} /> and that worked for me
Fabrice Leal
2018-10-22 22:59:40 UTC
Permalink
Addendum: I never tried the onload on <img> from urweb, but on js land it
works
Post by Fabrice Leal
@AdamChlipala
At the time I implemented an onload attribute for <div> on basis.ur and
only later found out if was for no good on html/js land: the only onload
that gets triggered is the one defined on <body>, setting onload for any
other child tag has no "side effects"; so I scrapped that.
Sorry for the vagueness :)
I did end up using <active code={...} /> and that worked for me
--
---
Fabrice Leal
Fabrice Leal
2018-10-22 23:16:07 UTC
Permalink
@AdamChlipala

Actually that sounds like what was happening to me, but can't be 100% sure
- I can't track the issue on github, I might have skipped a few commits
while working out this issue. At the time I read somewhere what I stated
above and moved on.

The onload of an <img> seems to work regardless of being a top level tag or
being dynamically generated (and here I assume calling "new Image()"
generates an <img>: that's what the chrome console seems to imply)

I'm giving it use in my canvas lib:

https://github.com/fabriceleal/urweb-canvas/blob/master/demos/demos.ur#L292
https://github.com/fabriceleal/urweb-canvas/blob/master/src/canvas.js#L46
Post by Fabrice Leal
Addendum: I never tried the onload on <img> from urweb, but on js land it
works
Post by Fabrice Leal
@AdamChlipala
At the time I implemented an onload attribute for <div> on basis.ur and
only later found out if was for no good on html/js land: the only onload
that gets triggered is the one defined on <body>, setting onload for any
other child tag has no "side effects"; so I scrapped that.
Sorry for the vagueness :)
I did end up using <active code={...} /> and that worked for me
--
---
Fabrice Leal
--
---
Fabrice Leal
Fabrice Leal
2018-10-24 21:35:31 UTC
Permalink
@adamChlipala

I can confirm in my end (urweb master) I get a type error when i try to use
onload on a <div>
--
---
Fabrice Leal
Adam Chlipala
2018-10-25 15:03:07 UTC
Permalink
Good.  I think that's been true all along.  Thanks for confirming!
Post by Fabrice Leal
@adamChlipala
I can confirm in my end (urweb master) I get a type error when i try
to use onload on a <div>
Loading...