Bug in extractValueB and manually setting values

11 views
Skip to first unread message

Danny Yoo

unread,
Aug 18, 2009, 1:40:05 PM8/18/09
to Flapjax
The following program shows that when I press the clear button, the
value behavior doesn't follow along. I'm not quite sure how to fix
this yet. Suggestions?




<html>
<head>
<title>Flapjax Demo: Where is the Mouse?</title>
<link rel="stylesheet" href="/demo.css"/>

<script>
function clearMe() {
getObj("field").value = "";
}
</script>
</head>

<body>


<p>The text says:
&lt; {! extractValueB("field") !} &gt;
</p>

<input type="text" id="field">
<input type="button" value="clear" onclick="clearMe()">
</body>

</html>

Arjun Guha

unread,
Aug 18, 2009, 2:10:56 PM8/18/09
to fla...@googlegroups.com
extractValueB doesn't interact well with an imperative update. Try
this:

<html>
<head>
<title>Flapjax Demo: Projections</title>
<script type="text/javascript" src="../fx/flapjax-impl.js"></script>

<script type="text/javascript">

function loader() {
var clearE = $E("mybutton", "click").constantE("");

var valB = mergeE($B("field").changes(), clearE).startsWith("");

insertDomB(valB, "mydiv");
insertValueE(clearE, "field", "value");
}


</script>
</head>

<body onload="javascript:loader()">


<div id="mydiv"></div>

<input type="text" id="field">
<input id="mybutton" type="button" value="clear">
</body>

</html>

Leo Meyerovich

unread,
Aug 18, 2009, 2:41:48 PM8/18/09
to fla...@googlegroups.com
$B extracts values on DOM events; programmatic interaction doesn't
trigger any.

A direct approach is for the clearme call to sendEvent to your echo
node (forcing you to give it a variable name).

A more structured one is to define a programmatic change stream, have
imperative code sendevent to it, and instead of just $B, merge in the
change stream.

At one point, there was a hook in the library encapsulating this
pattern where you could have injected imperative changes, but I think
that's gone. E.g., imagine the $B node getter and an inject(obj, fld,
val) function merging into it, like a cell.

- Leo

Danny Yoo

unread,
Aug 18, 2009, 8:55:21 PM8/18/09
to fla...@googlegroups.com
> A direct approach is for the clearme call to sendEvent to your echo
> node (forcing you to give it a variable name).
>
> A more structured one is to define a programmatic change stream, have
> imperative code sendevent to it, and instead of just $B, merge in the
> change stream.


Got it; thanks. I wrote a utility class to help me manage this.

// A workaround imperative value updates for Flapjax.
// We return an object that has a value behavior,
// but we also have an explicit way to trigger the
// value's change.
function FlapjaxValueHandler(node) {
this.node = node;
this._manualChanger = receiverE();
this.behavior = startsWith(
filterRepeatsE(
mergeE(extractValueB(node).changes(),
this._manualChanger,
// HACK: every 100 miliseconds, check the value manually.
timerE(100).mapE(function(v) { return node.value; } ))),
node.value);
insertValueE(this._manualChanger, this.node);
}

FlapjaxValueHandler.prototype.getValue = function() {
return this.attr("value");
};

FlapjaxValueHandler.prototype.setValue = function(x) {
this.attr("value", x);
};

// Get or set an attribute.
FlapjaxValueHandler.prototype.attr = function() {
if (arguments.length == 2) {
if (arguments[0] == "value") {
this.node.value = arguments[1];
this._manualChanger.sendEvent(arguments[1]);
} else {
this.node.setAttribute(arguments[0], arguments[1]);
}
} else if (arguments.length == 1) {
if (arguments[0] == "value") {
return this.node.value;
} else {
return this.node.getAttribute(arguments[0]);
}
} else {
throw new Error("attr");
}
};

Reply all
Reply to author
Forward
0 new messages