-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #696 from wmde/improve-form-action
Improve form action domain model
- Loading branch information
Showing
29 changed files
with
332 additions
and
100 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,62 @@ | ||
# Form Actions | ||
|
||
A `form action` is the action an HTML form will perform when the form gets submitted. | ||
In our case the action can be different **URLs** that the user will then get redirected to (spenden.wikimedia.de). | ||
## Background information | ||
A `form action` is URL in an HTML that the browser will send the form data to, when the user submits the form. | ||
In our case, the actions are two different **end points** (URL with protocol, host name and path ) of the fundraising application: | ||
|
||
The URL can have different paths and parameters. | ||
It depends on different A/B tests we want to perform on the fundraising application. | ||
- One for showing the donation form, with pre-filled payment data (path `/donation/new`) | ||
- One for immediately creating an anonymous donation (path `/donation/add`) | ||
|
||
The banners currently use different Vue `composables` that help encapsulating the URL creation process: | ||
The Fundraising Application also needs different **URL parameters** from the banner: | ||
|
||
- The Matomo campaign parameters for associating a donation with a banner | ||
- Impression counts, to check the effectiveness of showing banners repeatedly. | ||
- (optional) Additional parameters that trigger A/B test or feature toggle behavior | ||
|
||
### Important classes | ||
- The `FormAction` class encapsulates URL generation with the different parameters, with the tracking parameters being mandatory. Do not add parameters to the URL via string concatenation, always use its `setParameter` functions! | ||
- The `FormActionCollection` holds the two actions. | ||
|
||
These two classes are part of the entry point initialization (`banner_ctrl.ts` and `banner_var.ts`), are not reactive. We inject the initialized `FormActionCollection` with the `formActions` key, so all components have access to it. | ||
To choose one action (and potentially changing parameters) means our form action must be _reactive_. We achieve this though using Vue composables, by default `useFormAction`. | ||
|
||
## Default form action | ||
- **file name(s):** | ||
- `useFormActions.ts` | ||
- `FormActions.ts` | ||
- `createFormActions.ts` | ||
- `MultiStepDonation.vue` (can override default form action from `useFormAction`) | ||
- **description:** | ||
- If the user can explicitly choose anonymous donations in the form (setting `formModel.addressType.value` to `AddressTypes.ANONYMOUS.value`) _and_ the payment type is not direct debit, then it will return the URL for the direct, anonymous donation | ||
- In all other cases, it will return the URL for the donation | ||
- **used in (banner name):** | ||
- All banners not listed elsewhere in this document. | ||
|
||
## useFormAction.ts | ||
- basic URL that redirects to an anonymous donation process or a donation page where they can choose address options | ||
|
||
## useFormActionWithReceipt.ts | ||
- used when the donation form asks the user about whether they need a receipt | ||
- **file name(s):** | ||
- `useFormActionWithReceipt.ts` | ||
- `FormActions.ts` | ||
- `createFormActions.ts` | ||
- `BannerCtrl.vue` / `BannerVar.vue` (sets result of custom form action composable to `form-action-override` of `MultiStepDonation` component ) | ||
- **description:** | ||
- See [Show Donation Receipt checkbox only below a certain amount threshold with different submit button labels](DonationForms.md) | ||
- **used in (banner name):** | ||
- `C25_WMDE_Desktop_DE_00 VAR` | ||
- `C25_WMDE_Desktop_EN_00 VAR` | ||
|
||
## Creating a new banner test with same banner, but different A/B test behavior in the Fundraising application | ||
|
||
Edit the `banner_var.ts` entry point and add additional parameters to the call `createFormActions`: | ||
|
||
```typescript | ||
// example CTRL | ||
app.provide( 'formActions', createFormActions( page.getTracking(), impressionCount ) ); | ||
// example VAR | ||
app.provide( 'formActions', createFormActions( page.getTracking(), impressionCount, { ap: '1' } ) ); | ||
|
||
``` | ||
|
||
## Creating a new behavior, based on form state | ||
Create a new `useFormActionZZZ` composable (see default `useFormAction.ts` for reference), use it in `BannerVar.vue`. Set `formAction.value` of custom form action composable to `form-action-override` of `MultiStepDonation` component | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,53 @@ | ||
export interface FormActions { | ||
donateWithAddressAction: string; | ||
donateAnonymouslyAction: string; | ||
import { TrackingParameters } from '@src/domain/TrackingParameters'; | ||
|
||
/** | ||
* This class encapsulates URL generation to an end point to the fundraising application and all parameters needed for | ||
* the fundraising application. | ||
* | ||
* The constructor takes the static, non-reactive values available in the entry point. The form components will use | ||
* the injected FormAction classes to dynamically generate a form action from the available, injected form actions | ||
* ( see `useFormAction` and other composables starting with `useFormAction`). | ||
* | ||
* If you need to add parameters inside a reactive property (`useFormAction`), | ||
* use the `setParameter` method of this class instead of using string concatenation! | ||
*/ | ||
export class FormAction { | ||
private readonly url: string; | ||
private readonly params: Record<string, string>; | ||
public constructor( url: string, tracking: TrackingParameters, extraUrlParameters: Record<string, string> = {} ) { | ||
this.url = url; | ||
this.params = { | ||
/* eslint-disable camelcase */ | ||
piwik_kwd: tracking.keyword, | ||
piwik_campaign: tracking.campaign, | ||
banner_submission: '1', | ||
/* eslint-enable camelcase */ | ||
...extraUrlParameters | ||
}; | ||
} | ||
|
||
public setParameter( name: string, value: string ): FormAction { | ||
this.params[ name ] = value; | ||
return this; | ||
} | ||
|
||
public get actionUrl(): string { | ||
const urlParams = new URLSearchParams( this.params ); | ||
return `${this.url}?${urlParams}`; | ||
} | ||
|
||
public toString(): string { | ||
return this.actionUrl; | ||
} | ||
} | ||
|
||
/** | ||
* This class represents the available end points of the fundraising application. | ||
*/ | ||
export class FormActionCollection { | ||
public constructor( | ||
public readonly donateWithAddressAction: FormAction, | ||
public readonly donateAnonymouslyAction: FormAction | ||
) { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.