Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@ public function run(array $properties = [])
];

$currentStep = $this->getCurrentStep();
$nextStep = (int) $currentStep + 1;
$prevStep = (int) $currentStep - 1;
$totalSteps = $form->getStepsTotal();

if ($totalSteps >= 1) {
if ($currentStep >= $totalSteps) {
$currentStep = $totalSteps;
Expand Down Expand Up @@ -150,7 +153,7 @@ public function run(array $properties = [])
$hooks[] = 'FormaliciousHookHandleForm';
}

if ($currentStep >= $totalSteps) {
if ($currentStep >= $totalSteps && isset($_POST[$parameters['submitVar']])) {
if (!in_array('FormaliciousHookRemoveForm', $hooks, true)) {
$hooks[] = 'FormaliciousHookRemoveForm';
}
Expand Down Expand Up @@ -200,13 +203,34 @@ public function run(array $properties = [])
}
} else {
$hooks[] = 'redirect';


/**
* Setting up redirect in a way that allows variable/dynamic destination, based on value stored in the submit input/button.
* This way, form data on the step that is being navigated away from will always be posted/saved.
* Navigation and pagination should then be done via submit inputs/buttons instead of <a> tags.
*
* A related change to FormIt's Request class is necessary for this additional functionality.
*/

/* Default redirect destination */
$destination = $nextStep;

/* Check for alternate destination request */
if ($_POST) {
foreach ($_POST as $key => $value) {
if (strpos($key, $parameters['submitVar']) !== false) {
$destination = is_numeric($value) ? $value : $destination ;
break;
}
}
}

if (!empty($form->get('form_action'))) {
$parameters['formAction'] = $form->get('form_action');
}

$parameters['redirectTo'] = $this->getStepUrl([
$this->getProperty('stepParam') => $currentStep + 1
$this->getProperty('stepParam') => (int) $destination
], 'full');

if (empty($placeholders['submitTitle'])) {
Expand Down Expand Up @@ -237,17 +261,20 @@ public function run(array $properties = [])
$placeholders['prevUrl'] = $this->getStepUrl();
} else {
$placeholders['prevUrl'] = $this->getStepUrl([
$this->getProperty('stepParam') => $currentStep - 1
$this->getProperty('stepParam') => $prevStep
]);
$placeholders['submitValPrev'] = $prevStep;
}

if ($totalSteps === 1) {
$placeholders['currentUrl'] = $this->getStepUrl();
} else {
$placeholders['currentUrl'] = $this->getStepUrl([
$this->getProperty('stepParam') => $currentStep
]);
}
/* Renaming the placeholder currentUrl to formAction, as it makes its purpose more immediately clear */
$placeholders['formAction'] = $totalSteps === 1
? $this->getStepUrl()
: $this->getStepUrl([$this->getProperty('stepParam') => $currentStep]);

$placeholders['submitValLast'] = $totalSteps;

/* Set orignal for backward compatibility */
$placeholders['currentUrl'] = $placeholders['formAction'];

return $this->getChunk($this->getProperty('tplForm'), array_merge($placeholders, $parameters, [
'FormItParameters' => $this->parseParameters($parameters),
Expand Down Expand Up @@ -363,6 +390,7 @@ public function parseEmailFields(array $emailFields = [])
*/
public function getStepUrl(array $parameters = [], $scheme = null)
{
$stepParam = $this->getProperty('stepParam');
$stepRedirect = $this->getProperty('stepRedirect');
$requestUrl = '';
$requestParam = $this->modx->getOption('request_param_alias', null, 'q');
Expand All @@ -375,8 +403,8 @@ public function getStepUrl(array $parameters = [], $scheme = null)
unset($requestParams[$requestParam]);
}

if ($requestParams[$this->getProperty('stepParam')]) {
unset($requestParams[$this->getProperty('stepParam')]);
if (isset($requestParams[$stepParam])) {
unset($requestParams[$stepParam]);
}

if (!empty($stepRedirect)) {
Expand Down
58 changes: 57 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Formalicious is a tool for MODX content managers, which enables them to manage c

## Snippets

**Voorbeeld snippet call:**
**Example snippet call:**

```
{'!FormaliciousRenderForm' | snippet : [
Expand Down Expand Up @@ -49,3 +49,59 @@ To show the form on a page:
System settings:

* formalicious.source: the media source id Formalicious will use

## Multi-Step Paged Forms

New in version 3.1.2, logic has been added to persist data across multiple step forms when moving forward, backward, or jumping between steps. To function, FormIt 5.1.2+ is required.

### Basic Markup

Note that, in the example below, the value of the placeholder `formaliciousSteps` is the total number of steps in your form. Also important is that for the special use buttons (previous and skip to last) to work, their names must be the `submitVar` appended with a unique string. In this case, “_prev” and "_last" are used to distiguish those buttons from the default submit one.

```html
<form action="[[!+formAction]]" id="form-[[!+id]]" method="post" enctype="multipart/form-data">
[[!+formalicious.form]]
<div class="form-pagination">
[[!+step
:neq=`1`
:then=`
<button type="submit" name="[[!+submitVar]]_prev" value="[[!+submitValPrev]]">
[[%formalicious.prev? &namespace=`formalicious` &topic=`default`]]
</button>
`
:else=``
]]
<!-- Note that `submitTitle` will output either “Next” or “Submit” depending on which page the user is on -->
<button type="submit" name="[[!+submitVar]]">
[[!+submitTitle]]
</button>
</div>
</form>
```
### Customizing the Next/Submit Button

If you want to override the standard next/submit labels provided by `submitTitle`, use a conditional that applies your own label text, for example:
```html
<button type="submit" name="[[!+submitVar]]">
[[!+step
:is=`[[+formaliciousSteps]]`
:then=`My Next Label`
:else=`My Final Submit Label`
]]
</button>
```

### Skipping to the Last Step

For forms where intermediate steps may not require their fields to be filled in, a voting ballot for example, the ability to skip to the last step might be useful. To do so, add another button for this purpose:
```html
[[!+step
:lt=`[[+formaliciousSteps]]`
:then=`
<button type="submit" name="[[!+submitVar]]_last" value="[[!+submitValLast]]">
Skip to Last Step
</button>
`
:else=``
]]
```