Vdom "select" html element : unable to prevent default

Hi,

I am trying some experiment with Ocaml-vdom (version 0.3).

I am trying to build a HTML selectable list of item that actually never changes the value selected. The list shows a selected value when it appears, and never changes even if the user clicks on an other item of the list.

In this purpose, I implemented the following code :

open Vdom

type model = unit

let update () = function
  | `Unit -> ()

let init = ()

let select ?key  l = elt "select" ?key ~a:[onchange ~prevent_default:() ~stop_propagation:() (fun _ -> (`Unit)) ] l
let option ?(selected=false) txt =
  match selected with
  | true -> elt "option" ~a:[value txt; attr "selected" "selected"] [text txt]
  | _ -> elt "option" ~a:[value txt] [text txt]

let view () =
  select [ option "foo"; option "bar" ~selected:true; option "baz"]

let app = simple_app ~init ~view ~update ()

open Js_browser
let run () = Vdom_blit.run app |> Vdom_blit.dom |> Element.append_child (Document.body document)
let () = Window.set_onload window run

I have settled the attributes "prevent_default” and “stop_propagation” on the select element in order to maintain a “freeze” state.

But it does not work and I don’t get why…

Source code can be found here
The example running can be found here

I think you get this behaviour because the result of the view function never changes, so no “diff”, so ocaml-vdom never refreshes the underlying (“real”) DOM. You can force a refresh by artificially triggering the recreation of the select element, by passing a ~key parameter to select which changes each time the user selects an option (a simple increasing integer suffices).

The most direct way of achieving this is to make the element disabled. Then the user cannot select other options and there is no need for custom logic.

Cheers,
Nicolas

Thank you for your response !
It solve my case. Indeed the vdom refreshes the underlying dom and the select element stays fixed on the value “bar” when I set a “key” parameter.

Then, I have a question about ocaml-vdom :

  • on this example, I have used the "attr” function to set the “selected” attribute on option “bar”. I have try to set the “selected” attribute with the “str_prop” function, leading to the following code :
    | true -> elt "option" ~a:[value txt; str_prop "selected" "selected"] [text txt]
    It looks to work the same as with the “attr” function, Is there a difference between them ?

The difference between properties and attributes comes from the DOM model. Attributes correspond to HTML attributes written in markup and they are always strings. Properties correspond to JavaScript DOM object properties on the element, and are typed (string, int, boolean, etc). Sometimes there are both properties and attributes that ultimately correspond to the same thing (this is the case here I think), sometimes one updates the other, but not vice-versa, etc. The ultimate reference is the HTML standard.

Cheers,
Nicolas

Thank you for your response and the clarification between properties and attributes. After a few researches I understand better the difference between them. I guess that “selected” is a reflected property and hence is shared between the properties and attributes of the “option” html element.