I was writing a small file browser in Flapjax and have encountered
a problem with tagRec: there seems to be no way to make one
dynamically created tag to depend on another dynamically created
tag's events.
What I would like to achieve is a tree with branches that
can be shown or hidden.
The tree (or rather, a forest) for testing is the parse tree of an expression
a + b * c, which is translated to JS as follows:
> [{label: 'plus', children: [
> {label: 'a', children: []},
> {label: 'multiply', children: [
> {label: 'b',children: []},
> {label: 'c',children: []}]}]}]
Here's how it is converted to HTML:
> // fun :: Forest * Maybe Hash -> Dom
> function fun(y,vis) {
> return UL(vis || {}, map(function(x) {
> return tagRec(['click'],
> function(e) {
> var db = toggleE('block','none',e).startsWith('block');
> return LI(A({href:'#'+x.label},x.label),
> fun(x.children, {style: {display: db}}));
> });
> }, y));
> }
toggleE is defined as follows:
> function toggleE(a,b,e) {
> return e.collectE(true, function(_,y) {
> return !y;
> }).mapE(function(x) {return x? a : b;});
> }
The tree behaves unexpectedly, because tagRec reacts to *all*
events happening inside a LI, while it should only react to events
of A.
I think I can come up with a hack but would like to write in the
most obvious (and declarative :-)) way possible.
Could anybody help me, please?
Cheers,
Artyom Shalkhakov.
PS here's a demo: http://www.sound-city.kz/fj/tree.html
Suddenly I've found a solution which works okay and is still very nice.
Here it is:
> function fun(y,vis) {
> return UL(vis || {}, map(function(x) {
> var a = A({href:'#'+x.label},x.label);
> var db = toggleE('block','none',clicksE(a)).startsWith('block');
> return LI(a, fun(x.children,{style:{display:db}}));
> }, y));
> }
Strangely enough I got it working without any debugging at all, woot! :)
Cheers,
Artyom Shalkhakov.
Sorry for the delay.
2009/6/5 Arjun Guha <arjun...@gmail.com>:
> Looking at your solution, you didn't actually need a generalized
> tagRec since you had a 1-way dependency. However, there are cases
> when you want a pair of tags to depend on events from each other. For
> that, a generalized tagRec would be great.
I have found a simple example where you need a generalized tagRec.
(Actually, I need to solve this problem to continue with my current
project.)
Let's say we have two links (buttons, tabs...) "A" and "B" and we want
one of them to be "focused" (or "selected"). Focusing a link, as well as
"unfocusing" it, should change it's color accordingly.
If we had Scheme's letrec in JS, the solution would look as follows:
> letrec a = A({href:'#', style:{color:
> startsWith(mergeE(ev1.constantE('#777'),
> ev2.constantE('#000')),
> '#000')}}, "this is A")
> b = A({href:'#', style:{color:
> startsWith(mergeE(ev1.constantE('#000'),
> ev2.constantE('#777')),
> '#000')}}, "this is B")
> ev1 = clicksE(a)
> ev2 = clicksE(b)
> in UL(LI(a),LI(b))
How to do this in JS? The best solution I found involves tricky assignments
and effectful event streams.
I don't get how a menu (either hierarchical or not), a tabbed navigation,
etc. could be implemented without such cyclic dependencies. We could
do it imperatively, of course...
> Maybe one of the implementors will add it out soon.
Let's hope for the better then. :)
Cheers,
Artyom Shalkhakov.
Simply great. :)
> Make sense?
Yes. Big thanks for the explanation.
Cheers,
Artyom Shalkhakov.