> For the complete documentation index, see [llms.txt](https://docs.jmapcloud.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.jmapcloud.io/en/jmap-ng/jmap-ng-developer-documentation/examples/create-a-custom-form-in-a-div.md).

# Create a custom form in a div

This example shows how to create a custom form. It instantiates a JMap NG App extension that creates a custom form in a panel.

Form UI is only available in JMap NG App, and not in JMap NG Core.

## Example

Try it out in [Codepen.io](https://codepen.io/k2-dev/pen/mdpyxQW)

```html
<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <meta charset="UTF-8">
    <style>
      #my-custom-app {
        position: relative;
        overflow: hidden;
        width: 850px;
        height: 700px;
        border: 1px solid grey;
      }
    </style>
  </head>
  <body>
    <div id="my-custom-app" class="jmap_wrapper"></div>
    <script type="text/javascript">
      window.JMAP_OPTIONS = {
        projectId: 1,
        restBaseUrl: "https://jmapdoc.jmaponline.net/services/rest/v2.0",
        anonymous: true,
        map: {
          zoom: 9.573700695830425,
          center: {
            x: -73.7219880403544,
            y: 45.53690235213574
          }
        },
        application: {
          containerId: "my-custom-app",
          panel: "test-form-panel",
          extensions: [{
            id: "test-form",
            panelTitle: "Test of form component API",
            initFn: () => {/* nothing to do */},
            onPanelCreation: panelContainerId => {
              document.getElementById(panelContainerId).style.padding = "1rem"
              JMap.Application.Form.render(panelContainerId, {
                id: "search-form",
                schema: {
                  properties: {
                    name: {
                      title: "Office Name",
                      type: "string",
                      isRequired: true,
                      maxLength: 255
                    },
                    type: {
                      title: "Office type",
                      type: "number",
                      // default: 2,
                      enum: [1, 2, 3],
                      enumNames: ["Local", "External", "Mixte"]
                    }
                  }
                },
                uiSchema: [
                  {
                    type: "Tab",
                    controls: [
                      {
                        id: "name",
                        label: "Office name",
                        widget: "input",
                        scope: "#/properties/name"
                      },
                      {
                        id: "type",
                        label: "Office type",
                        widget: "select",
                        scope: "#/properties/type"
                      }
                    ]
                  }
                ],
                defaultValueById: { // defaultValueById is optional
                  name: "default value",
                  type: 2
                },
                validate: (values, formMetaData) => JMap.Form.validateData(formMetaData, JMap.Form.getPreparedData(formMetaData, values)),
                onSubmit: values => {
                  // Here you process/persist the data. This function can:
                  //  - returns nothing: means onSubmit success
                  //  - returns a string: the string is an error that will be displayed
                  //  - returns a promise: the form will display a loading button until the promise resolved
                  JMap.Application.Message.info(`Submitted values: ${JSON.stringify(values)}`)
                }
              })
            },
            onPanelDestroy: panelContainerId => {
              JMap.Application.Form.destroyByContainerId(panelContainerId)
            }
          }]
        }
      };
    </script>
    <script defer type="text/javascript" src="https://cdn.jsdelivr.net/npm/jmap-app-js@7_Kathmandu_HF3"></script>  
  </body>
</html>
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.jmapcloud.io/en/jmap-ng/jmap-ng-developer-documentation/examples/create-a-custom-form-in-a-div.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
