Skip to content

Instantly share code, notes, and snippets.

@mishterk
Last active June 18, 2026 10:52
Show Gist options
  • Select an option

  • Save mishterk/966f2aa4442cb157834d41d9f06c4449 to your computer and use it in GitHub Desktop.

Select an option

Save mishterk/966f2aa4442cb157834d41d9f06c4449 to your computer and use it in GitHub Desktop.
Advanced Forms — workaround for WYSIWYG fields failing to initialise on paginated form pages 2+ (Hookturn ticket #9201). Proper fix queued for AF v1.9.3.9.
/**
* Advanced Forms — WYSIWYG fix for paginated forms
* ----------------------------------------------------------------
* Workaround for a known issue in Advanced Forms ≤ 1.9.3.8: when a
* WYSIWYG (TinyMCE) field is placed on page 2 (or later) of a
* paginated form, two things go wrong:
*
* 1. The editor fails to initialise — the toolbar renders but you
* cannot click into the editor or type.
* 2. (once #1 is fixed) navigating to that page scrolls the browser
* down to the editor instead of the top of the form, because
* TinyMCE grabs focus as it rebuilds its iframe.
*
* This snippet hooks Advanced Forms' page-change action and:
* - re-initialises any visible WYSIWYG editor on the new page
* (content typed on a previous visit is preserved), and
* - pins the viewport back to the top of the form afterwards.
*
* A proper plugin fix is planned for v1.9.3.9. Once that ships this
* snippet can be removed.
*
* --- How to install ---
*
* Option 1 — Theme functions.php (recommended):
*
* add_action( 'wp_footer', function () {
* if ( ! wp_script_is( 'af-forms-script', 'enqueued' ) ) {
* return;
* }
* ?>
* <script>
* // paste the IIFE below
* </script>
* <?php
* }, 99 );
*
* Option 2 — A "Code Snippets"-style plugin: paste the IIFE below as
* a frontend snippet (no wrapping <script> tags).
*
* Option 3 — Custom HTML block on the form page itself: paste the
* IIFE wrapped in <script>…</script>.
*/
(function () {
if (typeof window.acf === 'undefined' || !window.acf.addAction) return;
var $ = window.jQuery;
// How far above the form to land (px). Increase if you have a sticky header.
var SCROLL_OFFSET = 40;
window.acf.addAction('af/form/page_changed', function (page, previousPage, form) {
var pinToFormTop = function () {
var top = form.$el.offset().top - SCROLL_OFFSET;
window.scrollTo(0, Math.max(top, 0));
};
// Land at the top of the form straight away.
pinToFormTop();
// Re-initialise any WYSIWYG editors revealed on the new page.
form.$el.find('.acf-field-wysiwyg').each(function () {
var $field = $(this);
if (!$field.is(':visible')) return;
var fieldInstance = window.acf.getField($field);
if (!fieldInstance) return;
if (typeof fieldInstance.disableEditor === 'function') {
fieldInstance.disableEditor();
}
// Defer one tick so the layout settles before TinyMCE re-inits.
setTimeout(function () {
fieldInstance.initializeEditor();
}, 50);
});
// TinyMCE grabs focus/scroll as it rebuilds its iframe — that's what
// dragged the page down to the editor. Re-assert the form top a couple
// more times while the editor settles.
setTimeout(pinToFormTop, 120);
setTimeout(pinToFormTop, 400);
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment