
# How to write forms?


### To write an HTML form towards an Eliom service

Just as we do for links, we provide form-building functions that call Eliom services in a safe manner. These functions are provided in the module `Eliom_content.Html.D.Form` (and `Eliom_content.Html.F.Form`). The functions `Eliom_content.Html.D.Form.get_form` and `Eliom_content.Html.D.Form.post_form` accept a function (named `create_form` in our example below) which is responsible for generating the content from appropriately-typed parameter names.

Here a complete example.

```ocaml
[%%shared
  open Eliom_parameter
  open Eliom_content.Html.D
]
(* Create the form with some inputs *)
let%server create_form =
  (fun (number_name, (number2_name, string_name)) ->
    [p [txt "Write an int: ";
        Form.input
          ~input_type:`Text ~name:number_name
          Form.int;
        txt "Write another int: ";
        Form.input
          ~input_type:`Text ~name:number2_name
          Form.int;
        txt "Write a string: ";
        Form.input ~input_type:`Text ~name:string_name Form.string;
        Form.input ~input_type:`Submit ~value:"Click" Form.string]])

let%server form_result_service = Eliom_service.create
  ~path:(Eliom_service.Path ["form-result"])
  ~meth:(Eliom_service.Get ((int "number_name") ** ((int "number2_name") ** (string "string_name"))))
  ()

let%server form_result_handler =
  (fun (number_name, (number2_name, string_name)) () ->
     Lwt.return (
       (html
          (head (title (txt "")) [])
          (body [
             p [
               txt "First number: ";
               txt (string_of_int number_name);
             ];
             p [
               txt "Second number: ";
               txt (string_of_int number2_name);
             ];
             p [
               txt "String: ";
               txt string_name
             ]
           ]))))

let%server form_service = Eliom_service.create
  ~path:(Eliom_service.Path ["form"])
  ~meth:(Eliom_service.Get unit)
  ()

let%server form_handler =
  (fun () () ->
     let form = Form.get_form ~service:form_result_service create_form in
     Lwt.return
       (html
         (head (title (txt "Form example")) [])
         (body [form])))

let%server () =
  Eliom_registration.Html.register ~service:form_result_service form_result_handler;
  Eliom_registration.Html.register ~service:form_service form_handler
```
As shown in the example, `Eliom_content.Html.D.Form` provides functions for generating the various widgets, e.g., `Eliom_content.Html.D.Form.input`. These functions need to be called with a "type" argument (e.g., `Eliom_content.Html.D.Form.int`) that matches the type of the corresponding parameter name.

POST forms may also take get parameters, as last argument of function `post_form`:

```ocaml
Eliom_content.Html.D.Form.post_form
  my_service_with_get_and_post
  (fun my_string ->
    p [txt "Write a string: ";
       Form.input ~input_type:`Text ~name:my_string Form.string])
  222
```

### Raw forms

There is also a raw interface to write basic forms without Eliom, using standard tyxml constructors.

Use module [Eliom\_content.Html.D.Raw](https://ocsigen.org/eliom/latest/eliom.server/Eliom/Content/Html/D/Raw/index.html).


### Links

- [How to write a select (or other form element)?](./how-to-add-a-select-or-other-form-element.md)