Skip to content
Merged
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
7 changes: 4 additions & 3 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

- [PDF Generator Add-on](https://renstillmann.github.io/super-forms/#/pdf-generator-add-on)

## Unreleased
## Oct 20, 2026 - Version 6.3.323

- **Fix:** Clicking the submit button after pressing Tab to leave the form submits again, instead of jumping to the first field and losing the click; keyboard Tab and Shift+Tab navigation is unchanged.
- **Fix:** Switching the form builder to a translation no longer logs a PHP warning about a missing setting type.
Expand All @@ -17,13 +17,14 @@
- **Fix:** WordPress no longer reports that the `super-forms` translations were loaded too early.
- **Improved:** Button and Divider elements can now be shown, hidden or made read-only with conditional logic. In multi-part forms the automatic Prev/Next buttons don't take over the conditions of the submit button.
- **Fix:** A required or validated field inside a column set to Invisible no longer blocks the form with an error the visitor cannot see; the field's value is still submitted, and the server no longer requires it either.
- **Fix:** Pressing Enter in a field no longer submits the form when the submit button is hidden by conditional logic. If another submit button is visible, that one is used.
- **Fix:** In a multi-part form, pressing Enter in a field of any step except the last now does the same as clicking that step's Next button (including the step's validation) instead of submitting the whole form and skipping the remaining steps. If that Next button is hidden by conditional logic, or the step has none, Enter does nothing. On the last step Enter submits the form as before.
- **Fix:** Pressing Enter in a field uses the first submit button that is not hidden by conditional logic and is not read-only. If no such button is available, Enter does nothing.
- **Fix:** In a multi-part form, pressing Enter in a field before the last step activates that step's visible, non-read-only Next button with the usual step validation, instead of submitting the whole form and skipping the remaining steps. If Next is absent, hidden by conditional logic or read-only, Enter does nothing. On the last step Enter uses the first visible, non-read-only submit button.
- **Security fix:** The form builder's preview, language switch, undo/redo, element settings and element HTML requests now require an administrator and a valid security token, so other logged-in users can no longer load form markup or settings.
- **Fix:** When the builder's save or preview request is rejected (for example after the session expired or a security plugin blocked it), the button is restored and a message asks you to reload the page instead of staying on "Saving..." forever.
- **Fix:** PDF Generator font data (Cyrillic and Arabic) is now attached to the Super Forms common script, so it still loads when a JavaScript optimization plugin reorders or delays scripts.
- **Fix:** PDF Generator "Enable debug mode" now only downloads the PDF and no longer submits the form, so no entry is saved and no e-mails are sent.
- **Fix:** When the PDF cannot be created, a message is shown and the visitor can close it and try again, instead of the form staying on "Generating PDF file..." forever. Nothing is submitted in that case.
- **Improved:** Compatibility with WordPress 7.1.3.

## Oct 09, 2026 - Version 6.3.322

Expand Down
4 changes: 2 additions & 2 deletions super-forms.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* @wordpress-plugin
* Plugin Name: Super Forms - Drag & Drop Form Builder
* Description: The most advanced, flexible and easy to use form builder for WordPress!
* Version: 6.3.322
* Version: 6.3.323
* Plugin URI: https://f4d.nl/super-forms
* Author URI: https://f4d.nl/super-forms
* Author: feeling4design
Expand Down Expand Up @@ -44,7 +44,7 @@ final class SUPER_Forms {
*
* @since 1.0.0
*/
public $version = '6.3.322';
public $version = '6.3.323';
public $slug = 'super-forms';
public $apiUrl = 'https://api.super-forms.com/';
public $apiVersion = 'v1';
Expand Down
15 changes: 0 additions & 15 deletions tests/test-button-conditional-client.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,3 @@ for (const action of ['show', 'hide', 'readonly']) {
assert.equal(wrap.removed, false, action + ': button markup kept');
console.log('PASS copy of a button with "' + action + '" conditions loses its conditional logic');
}

// The automatic Prev/Next copies are made from a stripped clone; the button kept in the last step keeps its conditions.
const branchStart = source.indexOf('if(!hasPrevNextBtns){');
assert(branchStart >= 0);
const branch = source.slice(branchStart, source.indexOf('// Now lets loop through all the multi-parts', branchStart));
const lastStep = branch.indexOf(".appendTo($form.find('.super-multipart:last'))");
const strip = branch.indexOf('SUPER.remove_button_conditional_logic(');
const html = branch.indexOf('$button_clone = ');
const nextCopy = branch.indexOf('.addClass(\'super-next-multipart\')');
const prevCopy = branch.indexOf('.addClass(\'super-prev-multipart\')');
assert(lastStep >= 0 && strip > lastStep, 'the submit button kept in the last step is appended before stripping');
assert(strip >= 0 && nextCopy > strip && prevCopy > strip, 'Prev/Next copies are made after stripping');
assert(/\$button_clone = SUPER\.remove_button_conditional_logic\(\$submit_button\.clone\(\)\[0\]\)\.outerHTML;/.test(branch), 'copies are built from a stripped clone of the button');
assert(html >= 0);
console.log('PASS automatic Prev/Next buttons are built from the stripped copy only');
29 changes: 0 additions & 29 deletions tests/test-invisible-column-client.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -116,32 +116,3 @@ test('has_hidden_parent: invisible column counts as hidden only when asked (defa
col.dataset.conditionalAction = 'show';
assert.equal(S.has_hidden_parent(hidden.input, false, false), true);
});

// Every caller except validate_form must keep today's behaviour (invisible-column fields are
// still submitted, counted by conditional logic/math, tabbed to, auto-stepped, calculated).
test('only validate_form relies on the invisible-column default', () => {
const files = ['assets/js/common.js', 'assets/js/frontend/elements.js', 'add-ons/super-forms-calculator/assets/js/frontend/calculator.js'].map(pick);
const relying = [];
for (const file of files) {
const src = fs.readFileSync(file, 'utf8');
const vStart = src.indexOf('SUPER.validate_form = function'), vEnd = src.indexOf('SUPER.scrollToError = function');
const re = /SUPER\.has_hidden_parent\(/g;
let m;
while ((m = re.exec(src)) !== null) {
if (src.slice(m.index, m.index + 40).startsWith('SUPER.has_hidden_parent = ')) continue;
let depth = 1, i = re.lastIndex, args = [''];
for (; depth > 0; i++) {
const ch = src[i];
if (ch === '(') depth++;
if (ch === ')' && --depth === 0) break;
if (ch === ',' && depth === 1) args.push(''); else args[args.length - 1] += ch;
}
const line = src.slice(0, m.index).split('\n').length;
if (args.length < 3 || args[2].trim() !== 'false') {
relying.push(path.relative(root, file) + ':' + line + (file === clientSource && m.index > vStart && m.index < vEnd ? ' (validate_form)' : ''));
}
}
}
assert.equal(relying.length, 1, relying.join('\n'));
assert.match(relying[0], /\(validate_form\)$/);
});
Loading