[Ur] When testing the new wrapper for the Pikaday datepicker, adding another <textbox> makes the tag <body onload={...}> stop working
Stefan Scott Alexander
stefanscottalexx at gmail.com
Sun Aug 9 16:58:27 EDT 2015
Summary:
When testing the new wrapper for the Pikaday datepicker, adding a *second*
(apparently unrelated) <textbox> on the form makes the tag <body
onload={...}> stop working - ie, the datepicker no longer appears in the
Date field.
(1) A test form with only *one* textbox compiles and runs - and the
datepicker appears correctly - ie, the following code works:
https://github.com/StefanScott/urweb-pikaday-test-foo/blob/master/thingDate.ur
<body onload={PikadayControl.init date_nid}>
<form>
<textbox{#DateField} id={date_nid}/>
<submit action={add_thing} value="Add !"/>
</form>
</body>
(2) A test form with a *second* (apparently unrelated) textbox also
compiles and runs - but the datepicker no longer appears - ie, the
following code runs but no datepicker appears on the Date field:
https://github.com/StefanScott/urweb-pikaday-test/blob/master/thingDate.ur
<body onload={PikadayControl.init date_nid}>
<form>
<textbox{#NameField} />
<textbox{#DateField} id={date_nid}/>
<submit action={add_thing} value="Add !"/>
</form>
</body>
In order to make it easy to see this minimal change to the code, I have set
up 2 GitHub repos:
- repo (1) "urweb-pikaday-test-foo";
- repo (2) "urweb-pikaday-test" initally a clone of (1), then adding the
tiny change to the code.
The tiny change to the code is highlighted in the following commit to repo
(2):
https://github.com/StefanScott/urweb-pikaday-test/commit/f5142a31b04341a57a5e335a84390d86ef6b7aa9
This is the *only* thing that was changed between repo (1) and repo (2).
Why does the <body onload={...}> work in (1) - but not work in (2), after
merely adding another (apparently unrelated) <textbox> ?
Details:
In order to provide a minimal test case to help isolate any errors, I am
developing two almost-identical versions of an extremely simplified app
which allows editing a table with two columns:
table thing : { Nam : string , Date : time }
Version (1) - base case
(`Nam` is *always* "foo" - this compiles and runs, and the datepicker
appears):
https://github.com/StefanScott/urweb-pikaday-test-foo
This "base case" version of the app works correctly. For simplicity during
testing, Version (1) does *not* include a <textbox> for the `Nam` column -
it simply sets `Nam` to always be "foo" in the SQL INSERT. Version (1)
behaves correctly, ie:
- it displays a form containing *one* field: a Date field (with a
datepicker, which displays when clicking the Date field)
- when the user clicks the "Add!" button, the app INSERTs a record (with
the Date entered by the user, and Nam always "foo")
Version (2) - slightly extended case
(`Nam` is set by user via a <textbox> - this also compiles and runs, but
*no* datepicker appears):
https://github.com/StefanScott/urweb-pikaday-test
Version (2) is almost identical to version (1). Version (2) should:
- display a form containing *two* fields: a Nam field, and a Date field (a
datepicker should appear - but actually, it doesn't!)
- when the user clicks the "Add!" button, the app INSERTs a record (with
the Nam and Date entered by the user)
Version (2) doesn't behave correctly: it fails to display a datepicker on
the Date field.
Remark:
Somehow, adding an additional <textbox> for the (second, unrelated) `Nam`
column seems to prevent the Date field from displaying its datepicker.
Comparison of approaches:
(a) The current approach uses `<body onload={...}>` as implemented in
Istvan Chung's Pull Request, which was merged into the GitHub repo below:
https://github.com/StefanScott/urweb-pikaday
That approach worked in the above repo (which, like Version (1) here,
involved only a *single* field on the form).
(b) Previously, Ziv Scully had suggested a different approach - involving
<active code={...}> :
http://www.impredicative.com/pipermail/ur/2015-August/002143.html
http://www.impredicative.com/pipermail/ur/2015-August/002162.html
<textbox{#DateField} id={date_nid}/>
<active code={PikadayControl.init date_nid; return <xml/>}/>
I have tried doing (b) (putting the <active> tag in 3 different locations:
just inside the <xml>, just inside the <body>, just inside the <form>) but
it always gave a compile error about a conflict between a field `Form` and
a field `DynForm` - so I used (a) instead.
(c) Ziv also stated:
http://www.impredicative.com/pipermail/ur/2015-August/002162.html
> More generally, we have the question of how best to interface with
mutation-heavy JS libraries. You can make this seem a bit more declarative
by writing a wrapper function (see [activate] in Logitext), but maybe there
are other approaches that are nicer in some ways (e.g. could the FFI be
just a value of type [transaction xbody]?).
This approach sounds interesting, but I was unsure how to get started with
it, so I haven't tried it yet.
Discussion:
(a) It seems strange that <body onload={...}> works when there is only
*one* field in the form (ie, the Date field shows a datepicker), but stops
working when a *second*, apparently unrelated field for `Nam` is added (ie,
the Date field does not show a datepicker).
(b) The JavaScript code which adds the datepicker to the Date field is
fairly short, and can be seen here:
https://github.com/StefanScott/urweb-pikaday-test/blob/master/pikadayControl.js
function init ( nodeId ) {
var picker = new Pikaday ( {
field: document.getElementById(nodeId),
firstDay: 1,
format: 'YYYY-MM-DD',
minDate: new Date('2000-01-01'),
maxDate: new Date('2030-12-31'),
yearRange: [2000,2030]
} ) ;
}
This behaves correctly when the Date field is the *only* field in the form.
As far as I understand, it doesn't return anything - it merely adds a
datepicker to the field identified by `nodeId`. Hence its JS FFI
declaration has result type `transaction unit`:
https://github.com/StefanScott/urweb-pikaday/blob/master/pikadayControl.urs
It might be interesting to explore various alternative ways of calling this
code - perhaps not involving:
<body onload={PikadayControl.init date_nid} />
(c) In the interest of "modularity", it might also be interesting if the
code which adds the datepicker to the Date field were as "close" as
possible to the Date field itself - ie, this code could perhaps not be
located "far away" in a <body> tag, but perhaps could be located "closer"
to where it gets used - say, in the <form> - or even somehow in or "next
to" the <textbox> itself.
---
Thanks for any help!
###
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.impredicative.com/pipermail/ur/attachments/20150809/172cf1a5/attachment.html>
More information about the Ur
mailing list