How to send a file to the server without stopping the client process?

This requires Eliom ≥ 3.1.

Due to security reasons, browsers have limitations on sending files. But if the file is chosen by the user through an input file element, there is a way to send it to the server. You can't use the server_function syntax for this, but you can use Eliom_client.call_caml_service.

Example:

let pic_service =
  post_coservice' ~name:"upload_pic" ~post_params:(file "f") ()

{client{
let upload_pic_form () =
  let file = D.Raw.input ~a:[a_input_type `File] () in
  let submit = D.Raw.input ~a:[a_input_type `Submit; a_value "Send"] () in
  Lwt_js_events.(
    async (fun () ->
      clicks (To_dom.of_input submit)
        (fun _ _ ->
          Js.Optdef.case ((To_dom.of_input file)##files)
            Lwt.return
            (fun files ->
              Js.Opt.case (files##item(0))
                Lwt.return
                (fun file ->
                  Eliom_client.call_caml_service
                    ~service:%pic_service
                    () file)))));
  [pcdata "Upload a picture:";
   file;
   submit]
}}