Skip to content

Allt om WordPress, webbutveckling — och mer därtill

🐛 Contact Form 7 i Elementor-popup: varför formuläret laddar om sidan och hur du fixar det

🐛 Contact Form 7 i Elementor-popup: varför formuläret laddar om sidan och hur du fixar det

Du lägger till ett kontaktformulär via Contact Form 7 inuti en Elementor Pro-popup. Användaren fyller i fälten, klickar på "Skicka" och hela sidan laddas om.

Inga felmeddelanden. Ingen bekräftelse på att formuläret skickats. Bara en omladdning och en förlorad lead.

Det här är en känd konflikt: CF7 förlitar sig på AJAX för att skicka, men inuti en dynamiskt laddad popup hinner dess JavaScript inte binda sig till formuläret. Resultatet blir att webbläsaren utför en vanlig HTML-submit, just den som orsakar omladdningen.

Problemet har funnits i åratal, men det fixas med bara två rader kod. Nedan följer två fungerande lösningar: en modern (renare och mer tillförlitlig) och ett alternativ från GitHub, plus valfria förbättringar och en checklista för felsökning.

💡 Snabb översikt:

  • Grundorsak: CF7 initieras vid sidladdning, men popupen med formuläret dyker upp senare, så skriptet vet ingenting om dess innehåll
  • Lösning 1: ominitiera CF7 när händelsen elementor/popup/show aktiveras; JavaScript väntar på att popupen öppnas och plockar upp formuläret
  • Lösning 2: spåra klick på knappen som öppnar popupen med en fördröjning för animationen; denna metod kommer från en GitHub-diskussion om Elementor
  • Valfritt: återställ formuläret vid nyöppning och stäng popupen automatiskt efter en lyckad inskickning
  • Checklista för felsökning: webbläsarkonsol, jQuery-konflikter, caching-plugins

Varför CF7 specifikt går sönder i en popup

Programmerare som fixar en bugg i Contact Form 7 i WordPress

Contact Form 7 är byggt på AJAX: formuläret skickas utan omladdning, fältvalidering sker i realtid och fel- eller bekräftelsemeddelanden visas direkt. Hela denna mekanism binder sig dock till DOM:en vid sidladdning via ett anrop till wpcf7.init().

Elementor Pro laddar popup-innehåll dynamiskt, efter händelsen DOMContentLoaded. När en användare klickar på en knapp och popupen öppnas, infogas dess HTML i dokumentet, men CF7 vet ingenting om det. Formuläret inuti popupen förblir oinitierat.

Vad som händer sedan: utan en aktiv AJAX-hanterare utför webbläsaren en vanlig HTML-formulärinskickning. Attributet action aktiveras och sidan laddas om. Popupen stängs naturligt (dess tillstånd återställs vid navigering). Användaren ser en omladdning och lämnar sidan.

Många utvecklare försöker behandla symptomen: de blockerar popupen från att stängas via event.stopPropagation(), skriver över Elementors interna funktioner eller förhindrar formulärinskickning med e.preventDefault(). Ingen av dessa metoder adresserar grundorsaken (den saknade CF7-initieringen). Vissa kan till och med förstöra popup-animationer eller Elementor på hela webbplatsen.

Det finns bara en tillförlitlig lösning: vänta på att popupen öppnas och anropa uttryckligen wpcf7.init() för varje formulär inuti.

Lösning 1: ominitiering vid popup-öppning (modern metod)

Denna metod använder Elementors inbyggda händelse elementor/popup/show. Placera koden i ditt aktiva temas functions.php eller lägg till den via ett snippets-plugin som Code Snippets.

Skapa en säkerhetskopia av functions.php innan du redigerar.

1/**
2 * Reinitialize Contact Form 7 when opening an Elementor popup.
3 * Fixes page reload after form submission.
4 */
5function sdstudio_cf7_reinit_in_popup() {
6 ?>
7 <script>
8 jQuery( document ).on( 'elementor/popup/show', function() {
9 document.querySelectorAll( '.wpcf7 form' ).forEach( function( form ) {
10 if ( typeof wpcf7 !== 'undefined' ) {
11 wpcf7.init( form );
12 }
13 });
14 });
15 </script>
16 <?php
17}
18add_action( 'wp_footer', 'sdstudio_cf7_reinit_in_popup' );

Efter att du sparat, öppna popupen med formuläret och testa den: fyll i de obligatoriska fälten felaktigt och klicka på "Skicka". Valideringsmeddelanden ska visas direkt utan omladdning. Skicka sedan formuläret korrekt och bekräfta att bekräftelsemeddelandet också visas inuti popupen.

Koden väntar på händelsen elementor/popup/show, som garanterat aktiveras efter att popup-innehållet har renderats. Sedan hittar querySelectorAll alla CF7-formulär i den aktuella DOM:en, och wpcf7.init() kopplar påtvingat AJAX-validering och inskickning till var och en. Kontrollen typeof wpcf7 !== 'undefined' skyddar mot fel om CF7 av någon anledning inte har laddats.

Lösning 2: spåra klick på popup-knappen (alternativ metod)

Denna metod publicerades i Elementors GitHub-diskussion #7798 av användaren @drinkmaker. Istället för att spåra popup-öppning övervakar den klick på en knapp eller länk med href='#elementor-action', vilket är exakt hur Elementor utlöser popups.

Fördröjningen setTimeout(..., 800) ger tid för popupens visningsanimation innan koden hittar och initierar formuläret. Markören .elementor förhindrar att samma formulär initieras två gånger.

1/**
2 * Alternative initialization of CF7 in Elementor popups.
3 * Source: https://github.com/elementor/elementor/issues/7798 (drinkmaker)
4 */
5function sdstudio_elementor_cf7_alt_init() {
6 ?>
7 <script type='text/javascript'>
8 jQuery( document ).ready( function() {
9
10 jQuery( document ).on( 'click', "a[href='#elementor-action']", function() {
11
12 setTimeout( function() {
13
14 jQuery( '.elementor-popup-modal form.wpcf7-form:not(.elementor)' ).each( function( index ) {
15 wpcf7.initForm( jQuery( this ) );
16 jQuery( this ).addClass( 'elementor' );
17 });
18
19 }, 800 );
20
21 });
22
23 });
24 </script>
25 <?php
26}
27add_action( 'wp_footer', 'sdstudio_elementor_cf7_alt_init' );

Vilken metod du ska välja: den första (som använder händelsen elementor/popup/show) är att föredra eftersom den förlitar sig på Elementors dokumenterade API, är renare och inte är beroende av timeouts. Den andra har testats i produktion i åratal och fungerar som en pålitlig Plan B om den första av någon anledning inte fungerar.

Valfritt: återställ formulär vid nyöppning

När en användare stänger popupen och öppnar den igen förblir formulärfälten ifyllda. Detta är förvirrande: det är oklart om formuläret skickades eller inte. Ett litet tillägg till den första lösningen fixar detta:

1/**
2 * Reset CF7 form each time an Elementor popup opens.
3 */
4function sdstudio_cf7_reset_on_popup_open() {
5 ?>
6 <script>
7 jQuery( document ).on( 'elementor/popup/show', function() {
8 jQuery( '.wpcf7 form' ).each( function() {
9 this.reset();
10 jQuery( this ).find( '.wpcf7-not-valid' ).removeClass( 'wpcf7-not-valid' );
11 jQuery( this ).find( '.wpcf7-response-output' ).hide();
12 jQuery( this ).find( '.wpcf7-not-valid-tip' ).remove();
13 });
14 });
15 </script>
16 <?php
17}
18add_action( 'wp_footer', 'sdstudio_cf7_reset_on_popup_open' );

Funktionen återställer fältvärden med reset(), tar bort CSS-klasser från ogiltiga fält, döljer inskickningsmeddelanden och tar bort valideringstips. Användaren ser alltid ett tomt formulär.

Valfritt: stäng popup efter lyckad inskickning

Efter en lyckad inskickning är det logiskt att automatiskt stänga popupen efter 1,5 sekunder så att användaren hinner läsa bekräftelsen utan att behöva leta efter stängningsknappen:

1/**
2 * Auto-close Elementor popup after successful CF7 submission.
3 */
4function sdstudio_close_popup_on_cf7_success() {
5 ?>
6 <script>
7 document.addEventListener( 'wpcf7mailsent', function() {
8 setTimeout( function() {
9 jQuery( '.dialog-close-button' ).trigger( 'click' );
10 }, 1500 );
11 }, false );
12 </script>
13 <?php
14}
15add_action( 'wp_footer', 'sdstudio_close_popup_on_cf7_success' );

Händelsen wpcf7mailsent aktiveras när servern bekräftar att e-postmeddelandet har skickats. Fördröjningen på 1500 ms ger användaren tid att läsa bekräftelsemeddelandet. Klick på .dialog-close-button använder Elementors standardstängningsknapp. Till skillnad från försök att anropa popup-API:et direkt är denna metod stabil över alla versioner.

Checklista för felsökning

Om formuläret fortfarande laddar om sidan efter att du lagt till koden, gå igenom dessa steg:

  • Webbläsarkonsol. Öppna DevTools (F12 → Console) och leta efter röda JavaScript-fel. En vanlig orsak är att jQuery inte laddas eller krockar med ett annat plugin.

  • Caching. Plugins som WP Rocket, Autoptimize eller cache på servernivå kan minifiera och kombinera skript. Inaktivera tillfälligt aggressiv JS-optimering och testa igen.

  • jQuery i noConflict-läge. Om ett tema eller plugin omsluter jQuery i noConflict, ersätt jQuery med $ med hjälp av en lämplig wrapper, eller använd den fullständiga jQuery-formen.

  • Popup-ID. Se till att formuläret finns inuti den exakta popup som utlöses av en knapp med href='#elementor-action'. För popups som öppnas via andra utlösartyper (till exempel på en timer) är den första metoden med elementor/popup/show mer tillförlitlig.

  • Plugin-konflikt. Inaktivera andra plugins ett i taget och testa, särskilt de som lägger till egna valideringsskript eller modifierar formulärbeteende.

  • CF7-version. Dessa lösningar har testats på Contact Form 7 version 5.7+ och Elementor Pro 3.5+. Om din CF7-version är under 5.7 kan funktionen wpcf7.init() ha ett annat namn; uppdatera pluginet.

⁉️🤔 Vanliga frågor

Varför fungerar CF7 på en vanlig sida men går sönder i en popup?

När en vanlig sida laddas är DOM:en redan uppbyggd och CF7 hinner initiera alla formulär. Elementors popup laddar innehåll asynkront, efter att CF7 har avslutat sitt arbete. Formuläret hamnar i DOM:en men utan en bunden JavaScript-hanterare. Det är därför en kontroll av att "det fungerar på en separat sida" inte hjälper: laddningsförhållandena är fundamentalt olika. Lösningen är alltid tvingad ominitiering när popupen öppnas, oavsett om formuläret fungerar någon annanstans.

Kan jag klara mig utan kod, med ett plugin eller en inställning?

Det finns inget färdigt plugin som låter dig "kryssa i en ruta så fungerar det" för denna bugg. Problemet ligger i skärningspunkten mellan två oberoende produkter (Elementor och CF7), och var och en fungerar korrekt för sig. Tredjepartstillägg som WPB Popup for Contact Form 7 löser problemet annorlunda: de skapar sina egna popups snarare än att fixa Elementor. Koden ovan är det minimala nödvändiga ingreppet. Du lägger till den en gång i functions.php och den kräver inga uppdateringar när nya versioner av CF7 eller Elementor kommer ut.

Den första metoden fungerade inte. Vad ska jag kontrollera innan jag byter till den andra?

Kontrollera tre saker. För det första: händelsen elementor/popup/show är tillgänglig från och med Elementor Pro 2.7; om din version är lägre, använd den andra metoden direkt. För det andra: öppna konsolen och skriv typeof wpcf7; om det är undefined har CF7-pluginet inte laddat sin JavaScript (leta efter fel eller konflikter). För det tredje: se till att formuläret inuti popupen har klassen .wpcf7; utan den kommer selektorn querySelectorAll('.wpcf7 form') inte att hitta något. I de allra flesta fall fungerar den första metoden direkt. Om inte, använd den andra: den har bevisats på hundratals webbplatser genom åren.

Behöver jag lägga till alla tre snippets eller räcker det med en?

Den första snippet (ominitiering) är det nödvändiga minimumet. Den andra är ett alternativ; lägg bara till den om den första inte löste problemet. Formuläråterställning och automatisk popup-stängning är valfria förbättringar du kan lägga till efter behov: återställning är användbart om popupen öppnas flera gånger under ett och samma besök; automatisk stängning är bra om popupen används för förfrågningar och inte innehåller lång bekräftelsetext. Alla tre snippets är oberoende och kan fungera samtidigt. Det finns inga konflikter mellan dem.

Efter fixen skickas formuläret, men e-postmeddelanden kommer inte fram. Är detta relaterat?

Nej, problem med e-postleverans är en separat fråga som inte är relaterad till att CF7 fungerar i en popup. Om formuläret efter tillämpning av fixen visar ett bekräftelsemeddelande (grön ram) fungerar AJAX-inskickningen korrekt. E-post kommer inte fram: kontrollera SMTP-inställningar, spamfilter hos webbhotellet och mottagaradressen i CF7-formulärets inställningar. För tillförlitlig leverans, använd ett SMTP-plugin som Post SMTP eller FluentSMTP istället för standardfunktionen wp_mail(), eftersom webbhotell ofta blockerar utgående PHP-e-post.

Påverkar denna lösning andra CF7-formulär på webbplatsen?

Nej. Båda metoderna är isolerade: den första väntar på att en Elementor-popup öppnas, den andra spårar endast länkar med href='#elementor-action'. Vanliga CF7-formulär placerade på sidor och i widgets fortsätter att fungera normalt; de initieras vid sidladdning och förblir opåverkade. Den enda brasklappen: om din webbplats använder aggressiv caching med skriptsammanslagning, lägg till popup-koden i dina undantag för minifiering för att undvika dubbel exekvering.

Är det värt att bry sig om anpassad kod år 2026

Båda plugin, Contact Form 7 och Elementor Pro, utvecklas och uppdateras aktivt. CF7 håller sin position som det mest populära WordPress-pluginet för formulär med över 5 miljoner aktiva installationer. Elementor Pro används på var fjärde WordPress-webbplats.

Ändå har buggen som beskrivs här inte åtgärdats på kärnnivå i något av pluginen och kommer sannolikt aldrig att bli det. Orsaken är arkitektonisk: CF7 ansvarar för formulär, Elementor ansvarar för dynamiskt innehåll, och att initiera skript i dynamiskt laddad DOM förblir utvecklarens ansvar.

De goda nyheterna: fixen är trivial, koden läggs till en gång och den kräver inget underhåll. Välj den första metoden (händelsen elementor/popup/show): den är renast och du kan glömma problemet. Om formuläret i popupen används för kritiska leadgenereringsscenarier, lägg till fältåterställning och automatisk stängning också: användarupplevelsen kommer att förbättras märkbart.

Se videon ovan: den visar hela processen för att sätta upp en popup med Contact Form 7 i Elementor. Denna visuella steg-för-steg-guide kompletterar de snippets som tillhandahålls här och hjälper dig att undvika misstag under hopsättningen.