> ## Documentation Index
> Fetch the complete documentation index at: https://docs.talview.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Form

> Dynamic form loading and submission with the Proview SDK

## What is Form module

The Form module is part of the Proview SDK, exposed as `Proview.form`. It provides a complete solution for loading, rendering, and managing dynamic forms with integrated authentication.

Once initialized, it lets your application:

* **Load forms** — render forms dynamically by form ID.
* **Submit forms** — handle form submission and validation automatically.
* **Mount UI** — display forms in `sidepanel`, `popup`, or `inline` layout modes.
* **React to events** — subscribe to ready, submitted, and error events.

***

## Quickstart

### 1. Load the SDK and initialize

Declare `Proview.form()` in the `modules` array when calling `Proview.init()`. The `dsn` and `credential` are inherited — no per-module init call needed.

```javascript theme={null}
window.proviewOnLoad = async function () {
  await Proview.init({
    dsn: 'YOUR_PROJECT_DSN',
    credential: Proview.auth.FirebaseAuthStrategy({ token: 'your-firebase-auth-token' }),
    modules: [Proview.form()],
  });
};
```

### 2. Access user object

Once initialized, the user object becomes available globally at `Proview.user` and is Firebase-compatible with `getIdToken()` method.

```javascript theme={null}
const user = Proview.user;
console.log(user.uid, user.email, user.displayName);

// Get ID token when needed
const idToken = await user.getIdToken();
```

### 3. Mount UI

Mount the form UI into a container element.

```javascript theme={null}
const mounted = Proview.form.mount({
  formId: 'form-123',
  containerId: 'form-container',
  mountMode: {
    mode: 'sidepanel', // or 'popup' or 'inline'
  },
});
```

### 4. Open form

Open the form to load data and display the UI.

```javascript theme={null}
const formInstance = await Proview.form.open();
```

### 5. Subscribe to events

Listen to form lifecycle events.

```javascript theme={null}
formInstance
  .on('ready', () => {
    console.log('Form is ready for user input');
  })
  .on('submitted', () => {
    console.log('Form submitted successfully');
  })
  .on('error', ({ message }) => {
    console.error('Form error:', message);
  });
```

### 6. Teardown

When done, unmount the UI.

```javascript theme={null}
mounted.unmount();
```

***

## API Reference

### `Proview.form`

The form module is automatically initialized when `Proview.form()` is included in the `modules` array passed to `Proview.init()`. The `dsn` and `credential` are inherited from the global init — no separate per-module call is needed.

```javascript theme={null}
await Proview.init({
  dsn: 'project-dsn',
  credential: Proview.auth.FirebaseAuthStrategy({ token: 'your-token' }),
  modules: [Proview.form()],
});

// Proview.form is now ready
```

`Proview.form` exposes:

```javascript theme={null}
type FormModule = {
  mount(options: MountOptions): MountedFormUi;
  open(): Promise<FormInstance>;
};
```

The authenticated user is available globally at `Proview.user` after initialization.

***

### `form.mount(options)`

Mounts the form UI into a container element.

| | |
| - | - |
| **Input** | `MountOptions` |
| **Returns** | `MountedFormUi` |

**MountOptions**

```javascript theme={null}
type MountOptions = {
  formId: string;                // Required: Form ID to load
  containerId: string;           // Required: DOM element ID
  mountMode: {
    mode: 'sidepanel' | 'popup' | 'inline';  // Required: Layout mode
  };
};
```

**MountedFormUi**

```javascript theme={null}
type MountedFormUi = {
  unmount(): void;  // Removes UI from DOM
};
```

**Example:**

```javascript theme={null}
const mounted = Proview.form.mount({
  formId: 'form-123',
  containerId: 'form-container',
  mountMode: {
    mode: 'popup',
  },
});

// Later, when done
mounted.unmount();
```

***

### `Proview.form.open()`

Loads form data and displays the form UI. Uses the formId specified in mount().

| | |
| - | - |
| **Input** | None |
| **Promise** | `Promise<FormInstance>` |
| **Async** | Yes, requires await |

**FormInstance**

```javascript theme={null}
type FormInstance = {
  on(event: FormEventName, handler: (payload?: any) => void): FormInstance;
  submit(): Promise<void>;
};
```

**Example:**

```javascript theme={null}
Proview.form.mount({
  formId: 'form-123',
  containerId: 'form-container',
  mountMode: { mode: 'sidepanel' },
});

const formInstance = await Proview.form.open();

formInstance
  .on('ready', () => console.log('Form ready'))
  .on('submitted', () => {
    console.log('Form submitted');
    // Handle success
  })
  .on('error', ({ message }) => {
    console.error('Form error:', message);
  });
```

***

## User Object

After initializing the form module, `Proview.user` provides a Firebase-compatible user object accessible globally.

**User Interface**

```javascript theme={null}
type User = {
  uid: string;                      // User's unique ID
  email: string | null;             // User's email address
  displayName: string | null;       // User's display name
  emailVerified: boolean;           // Email verification status
  isAnonymous?: boolean;            // Is anonymous user
  metadata?: UserMetadata;          // Creation and last sign-in time
  providerData?: ProviderData[];    // Provider-specific info

  // Methods
  getIdToken(forceRefresh?: boolean): Promise<string>;
  getIdTokenResult(forceRefresh?: boolean): Promise<IdTokenResult>;
};
```

**Example:**

```javascript theme={null}
// Access user properties globally after Proview.init()
const user = Proview.user;
console.log(user.uid);
console.log(user.email);
console.log(user.displayName);
console.log(user.emailVerified);

// Get ID token
const idToken = await user.getIdToken();

// Force refresh token
const freshToken = await user.getIdToken(true);
```

***

## Firebase Authentication

### `Proview.auth.FirebaseAuthStrategy(config)`

Creates a Firebase authentication credential for use with the Proview SDK modules.

**Input**

```javascript theme={null}
type FirebaseAuthStrategyConfig = {
  token: string;  // Required: Firebase authentication token
};
```

**Returns** — `FirebaseAuthStrategy`

A credential object passed to `Proview.init()`. All modules declared in the `modules` array inherit it automatically.

**Example:**

```javascript theme={null}
await Proview.init({
  dsn: 'project-dsn',
  credential: Proview.auth.FirebaseAuthStrategy({
    token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
  }),
  modules: [Proview.form()],
});
```

***

## Form Events

The `FormInstance` emits events that you can subscribe to using the `on()` method.

**Event names and payloads**

| Event | Payload | Description |
| - | - | - |
| `ready` | `void` | Form loaded and ready |
| `submitted` | `void` | Form submitted successfully |
| `error` | `{ message: string }` | Error occurred |

**Example:**

```javascript theme={null}
form
  .on('ready', () => {
    // Form is ready for input
  })
  .on('submitted', () => {
    // Form was submitted successfully
  })
  .on('error', ({ message }) => {
    // Handle form error
    alert(`Error: ${message}`);
  });
```

***

## Mount Modes

The form module supports three layout modes for the form UI.

| Mode | Value | Behavior |
| - | - | - |
| **Sidepanel** | `'sidepanel'` | Slides in from side of viewport |
| **Popup** | `'popup'` | Centered modal overlay |
| **Inline** | `'inline'` | Embedded in the page flow |

**Example:**

```javascript theme={null}
// Sidepanel mode
const mounted1 = form.mount({
  formId: 'form-123',
  containerId: 'form-container',
  mountMode: {
    mode: 'sidepanel',
  },
});

// Popup mode
const mounted2 = form.mount({
  formId: 'form-123',
  containerId: 'form-container',
  mountMode: {
    mode: 'popup',
  },
});

// Inline mode
const mounted3 = form.mount({
  formId: 'form-123',
  containerId: 'form-container',
  mountMode: {
    mode: 'inline',
  },
});
```

***

## Error Handling

Form errors follow a consistent structure.

**Error Structure**

```javascript theme={null}
type FormError = {
  code: string;    // Error code for programmatic handling
  message: string; // Human-readable error message
};
```

**Common Error Codes**

| Code | Description |
| - | - |
| `FORM_LOAD_ERROR` | Failed to load form |
| `PANEL_ERROR` | Panel rendering error |
| `TOKEN_INVALID` | Authentication token is invalid |
| `TOKEN_EXPIRED` | Session token expired |
| `AUTH_FAILED` | Authentication failed |
| `FETCH_FAILED` | Network or API request failed |

**Example:**

```javascript theme={null}
try {
  const mounted = Proview.form.mount({
    formId: 'form-123',
    containerId: 'form-container',
    mountMode: {
      mode: 'popup',
    },
  });

  const formInstance = await Proview.form.open();

  formInstance.on('error', ({ message }) => {
    console.error('Form error:', message);
    // Handle error in UI
  });

} catch (error) {
  switch (error.code) {
    case 'AUTH_FAILED':
      alert('Authentication failed. Please log in again.');
      break;

    case 'TOKEN_INVALID':
      alert('Invalid authentication token.');
      break;

    case 'TOKEN_EXPIRED':
      alert('Session expired. Please log in again.');
      break;

    case 'FORM_LOAD_ERROR':
      alert('Failed to load form. Please try again.');
      break;

    case 'PANEL_ERROR':
      alert('Failed to render form panel. Check your page setup.');
      break;

    case 'FETCH_FAILED':
      alert('Network error. Please check your connection.');
      break;

    default:
      alert(`Error: ${error.message}`);
      break;
  }
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.