npm package: @pawsitiwe/sulu-forms-ajax-validation
Description: Frontend counterpart for plug and play communication with Sulu AJAX forms interface
Author: Pawsitiwe
Latest version: 0.4.0

# Sulu Forms AJAX Validation

**Frontend counterpart to the [Sulu Forms Ajax Validation Bundle](https://github.com/pawsitiwe/sulu-forms-ajax-validation-bundle).**

## Installation

```sh
npm i @pawsitiwe/sulu-forms-ajax-validation
```
## Usage

### JavaScript

The JavaScript is required and is used for asynchronous live validation.

```js
import { SuluAjaxForm } from '@pawsitiwe/sulu-forms-ajax-validation';

new SuluAjaxForm();
```

The constructor can accept two parameters:

1. `form` is the form element on which Sulu Ajax Form should be initialized. Default is `document.querySelector('.ajax-form')`.
2. `options` is an object used to configure Sulu Ajax Forms. The default values are documented in the table below:

| Option                       | Typ     | Default                                                                                                                                                                                                                                                                                                                                                                                                                                                  | Beschreibung                                                          |
|------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------|
| classes                      | object  | <pre>{<br>&nbsp;&nbsp;field: 'field',<br>&nbsp;&nbsp;fieldsWrapper: 'fields',<br>&nbsp;&nbsp;groupWrapper: 'check-radio-group',<br>&nbsp;&nbsp;errorContainer: 'error-container',<br>&nbsp;&nbsp;errorElement: 'error',<br>&nbsp;&nbsp;errorState: 'has-error',<br>&nbsp;&nbsp;submitting: 'submitting',<br>&nbsp;&nbsp;submitButton: 'submit',<br>&nbsp;&nbsp;apiErrorNotification: 'api-error',<br>&nbsp;&nbsp;confirmation: 'confirmation'<br>}</pre> | Selectors used by Sulu Ajax Forms and states assigned to elements.    |
| disableOnSubmit              | boolean | <code>true</code>                                                                                                                                                                                                                                                                                                                                                                                                                                        | Disables the submit button during the submit request.                 |
| scrollToFirstErrorOnSubmit   | boolean | <code>true</code>                                                                                                                                                                                                                                                                                                                                                                                                                                        | Smoothly scrolls to the first validation error after a failed submit. |
| focusFirstErrorFieldOnSubmit | boolean | <code>true</code>                                                                                                                                                                                                                                                                                                                                                                                                                                        | Focuses the first validation error field after a failed submit.       |
| animateConfirmation          | boolean | <code>true</code>                                                                                                                                                                                                                                                                                                                                                                                                                                        | Animates the confirmation message after a successful submit.          |
| additionalHeaders            | object  | <code>{}</code>                                                                                                                                                                                                                                                                                                                                                                                                                                          | Additional header, like authorization for fetch request               |
| successRedirectUrl           | string\|null | <code>null</code>                                                                                                                                                                                                                                                                                                                                                                                                                                   | Optional URL to redirect to after successful validation. JS option overrides form data attribute. |
| allowCrossOriginRedirect     | boolean | <code>false</code>                                                                                                                                                                                                                                                                                                                                                                                                                                      | Allows redirects to different origins (e.g., <code>thanks.mysite.com</code>). Keep <code>false</code> for security unless needed. |
### Form Events

#### `successfullySubmitted`

Fires after successful form submission. Validation passes and confirmation is shown (or redirect triggered).

```js
form.addEventListener('successfullySubmitted', (event) => {
    const { valid, fields } = event.detail;
    console.log('Form submitted successfully');
});
```

#### `submitInvalid`

Fires after a failed form submission. Validation errors have been applied to the DOM.

```js
form.addEventListener('submitInvalid', (event) => {
    const { response } = event.detail;
    // Custom handling: show toast, log analytics, etc.
    console.log('Errors:', response.fields);
});
```

**Redirect Usage:**

Via JS option (overrides data attribute):

```js
new SuluAjaxForm(formElement, {
    successRedirectUrl: '/thank-you'
});
```

Via form data attribute (fallback if no JS option):

```html
<form class="ajax-form" data-validation-url="/validate" data-success-redirect-url="/thank-you">
    ...
</form>
```

**Cross-origin redirects:**

For redirecting to a different origin (e.g., `https://thanks.mysite.com`), you must explicitly enable it:

```js
new SuluAjaxForm(formElement, {
    successRedirectUrl: 'https://thanks.mysite.com/success',
    allowCrossOriginRedirect: true
});
```

**Important:** Cross-origin redirects have security implications:
- Session cookies will **not** be sent to the cross-origin thank-you page
- You must pass session data via URL parameters if needed (e.g., `https://thanks.mysite.com/success?token=xyz`)
- Same-origin redirects (default) maintain cookies automatically

When a `successRedirectUrl` is provided, the form redirects immediately after successful validation instead of showing the confirmation message.

### Cross-Origin Requests

#### Session Handling

The library uses `credentials: 'same-origin'` for all AJAX validation and submission requests. This ensures session cookies are sent and received during the validation flow, maintaining your session state throughout the form interaction.

**Same-origin validation endpoint (default):**
```js
// Validation endpoint: https://mysite.com/api/validate
// Session cookies are automatically maintained ✅
new SuluAjaxForm(formElement, {
    successRedirectUrl: '/thank-you'  // Same-origin redirect
});
```

**Cross-origin redirects:**

When redirecting to a different origin after successful validation, session cookies will **not** be transferred to the cross-origin page due to browser security policies.

```js
new SuluAjaxForm(formElement, {
    successRedirectUrl: 'https://thanks.mysite.com/success',
    allowCrossOriginRedirect: true  // Must explicitly enable
});
```

#### Passing Session Data Cross-Origin

If you need to redirect to a cross-origin thank-you page with session context, pass data via URL parameters:

**Backend approach (recommended):**

Your validation endpoint can return session data:

```json
{
    "valid": true,
    "sessionToken": "xyz789",
    "submissionId": "12345"
}
```

Frontend listens for the success event and builds the redirect URL:

```js
const form = document.querySelector('.ajax-form');
new SuluAjaxForm(form, {
    allowCrossOriginRedirect: true
});

form.addEventListener('successfullySubmitted', (event) => {
    const { sessionToken, submissionId } = event.detail;
    const redirectUrl = `https://thanks.mysite.com/success?token=${sessionToken}&id=${submissionId}`;
    window.location.assign(redirectUrl);
});
```


### Scss

```scss
@use "@pawsitiwe/sulu-forms-ajax-validation" as forms;
```

#### Usage

Mixins can either be included all at once (**recommended**) …

```scss
@include forms.all();
```

… or selectively (**not recommended**).

```scss
.example-form-class {
    .example-error-class {
        @include forms.api-error-notification();
    }
    .example-honeypot-field-class {
        @include forms.hide-honeypot-field();
    }
    // ...
}
```

#### Configuration

To configure the mixins, use the `configure` mixin. This must be included before using any other mixins.

```scss
@include forms.configure((...));
```

A full list of configuration options can be found at [/src/styles/_config.scss](src/styles/_config.scss).