[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