Easy steps to prevent window.onbeforeunload from triggering when submitting a form using Vue

Presently, I am utilizing a component named countdowntimer.vue, specifically designed as a countdown timer for an online examination platform. My goal is to implement an onbeforeunload event on the window object while ensuring that the timer automatically submits upon completion without being disrupted by the window event itself. Despite my attempts to integrate this code within the vuejs component, it fails to respond as desired; either hindering the submission process with interruptions or failing to function altogether, allowing any event to navigate away from the page without constraint.

Below is the code snippet depicting the countdown timer:

<template>
    <div>
        <div v-if="finished" v-text="expiredText"></div>

        <div v-else>
            <span>{{ remaining.minutes }} Minutes, </span>
            <span>{{ remaining.seconds }} Seconds</span>
            left...
        </div>
    </div>
</template>

....

Despite various trials of setting the method as a computed property and employing different if statements as watchers, the method does not yield the expected outcomes as previously mentioned.

The blade template in which the code is implemented is presented below:

@extends('layouts.app')

@section('content')
   ...
    </div>
@endsection

.....

Upon observation, there appears to be a script tag located outside of the @endsection block. It has been discerned that this placement fails to establish a connection with elements from the blade template. Attempts were made to access the form object similarly done in the vue component. However, this resulted in a null or undefined response - rendering it impossible to attach an event listener. Interestingly, executing the same logic within the browser console produced the anticipated results. The assigned onsubmit="" event intended for the form failed to reach the underlying script tags, leading to an unaltered value in the submitForm variable. Moreover, manually clicking the submit button succeeded in triggering the function clicked(). Under these circumstances, confusion ensues regarding the feasibility of achieving the desired outcome solely through vue. Additionally, the nonfunctional nature of the onsubmit="" event raises uncertainties. Moving the script tags inside the @section could potentially prompt errors from vue. Hence, any recommendations or insights on resolving these issues would be greatly appreciated.

Answer №1

To begin with, ensure that you pass a method reference to beforeunload, not the result of calling that method. Remove the ():

created () {
    this.refreshEverySecond();
    document.addEventListener('beforeunload', this.redirect); // not this.redirect()
},

A simple solution to toggle the handler on and off is to use a flag:

data () {
    return {
        limiter: this.until * 10000
        preventSubmit: true
    };
},

In your methods, update or utilize that flag accordingly:

methods: {
    // ...
    timeUp() {
        this.preventSubmit = false; // ALLOW redirect now

        const form = document.querySelector('[data-form-submit]');
        const radios = document.querySelectorAll('input[type=radio]');
        radios.forEach(radio => radio.style.display = 'none');
        form.submit(function(e) {
            console.log(e);
        });
    },
    redirect () {
        if (this.preventSubmit) {
           // implement steps to prevent submit
        }
    }
},

Another Approach

Alternatively, you can remove the listener:

created () {
    this.refreshEverySecond();
    document.addEventListener('beforeunload', this.redirect); // not this.redirect()
},

And in your methods:

methods: {
    // ...
    timeUp() {
        document.removeEventListener('beforeunload', this.redirect);
        // ...

I believe using the flag alternative is more reliable.


Proper Handling of beforeunload

As per feedback, here's a demo showcasing how it could function.

You can view the JSFiddle DEMO here or see the demonstration below.

new Vue({
  el: '#app',
  data: {
    preventSubmit : true
  },
  mounted () {
    window.addEventListener("beforeunload", this.redirect);
},
  methods: {
  redirect(event) {
    if (this.preventSubmit) {
      var confirmationMessage = "\o/";
      event.returnValue = confirmationMessage;  
      return confirmationMessage;
      }
    }
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <p>preventSubmit ? {{ preventSubmit  }}</p>
  <button @click="preventSubmit = !preventSubmit ">Toggle preventSubmit </button>
</div>
<br>
<a href="/somewhere-else">click to try to navigate away</a>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The isAuthenticated status of the consumer remains unchanged even after being modified by a function within the AuthContext

I am working on updating the signout button in my navigation bar based on the user's authentication status. I am utilizing React Context to manage the isAuthenticated value. The AuthProvider component is wrapped in both layout.tsx and page.tsx (root f ...

How to send a JavaScript variable to Flask and trigger an AJAX reload action

Introduction: I have explored similar inquiries and attempted to apply relevant code/concepts but without success. -https://stackoverflow.com/questions/43645790/passing-javascript-variable-to-python-flask -https://stackoverflow.com/questions/10313001/is- ...

Add a fresh item into an array in Json between existing elements

After looping through a JSON object using foreach, the output is as follows: {"Comment": {"id":"1","post_id":"31","created":"14263241"} , "User": {"fname":"Test","lname":"Test2"} } {"Comment": {"id":"2","post_id":"32","created":"14263257"} , "User": {"f ...

Is there a way to eliminate unnecessary chunks from MUI in NextJS?

I recently created a single page and noticed that there is a significant amount of unused JavaScript in my codebase. Specifically, I am using MUI and React icons. Any suggestions on how to efficiently manage this issue? To address the problem, I attempte ...

Tips for making an appended element match the height of an image

After embedding the div .soonOverlay into specific .smallCatalogBlock's, I am facing difficulty in adjusting the height of soonOverlay to match only the height of the img within smallCatalogBlock. Currently, its height extends throughout the entire co ...

Able to retrieve individual elements from an array, but not able to loop through them

I am facing an issue with my code where I have two arrays - one containing URLs and the other external data. These two arrays are perfectly aligned, but when I try to access them in a loop using AJAX requests, only the first element of the URL array prints ...

The "useState" React Hook is restricted from being used in a class component. To utilize React Hooks, they can only be invoked within a React function component or a custom React Hook function

I am relatively new to React frontend development and I am currently working on adding a temporary drawer to my Material-UI NavBar. Here is the code snippet where I added the drawer: class Navbar extends Component { render() { const { authentic ...

Automatically closing the AppDateTimePicker modal in Vuexy theme after selecting a date

I am currently developing a Vue.js application using the Vuexy theme. One issue I have encountered is with a datetimepicker within a modal. The problem arises when I try to select a date on the datetimepicker component - it closes the modal instead of stay ...

What is the best way to manage asynchronous data within AngularJS directives?

Having encountered similar challenges to this specific scenario, I am currently facing issues with handling asynchronous data within my directives. The main issue arises when trying to pass asynchronously fetched data into these directives. Initially, I at ...

Pass the most recent properties to the mousemove event handler

I am currently developing a click-and-drag feature, which involves: setting up a moveListener on the onMouseDown event having the moveListener trigger an action that updates certain props of the component (props.whichChange) cleaning up the mouseUp event ...

Issue with specific route causing server to throw 500 error

Recently, I have been working on a small school project that involves creating our own API and connecting it to an Angular front end. While following some tutorials, I encountered an issue where my application started throwing internal server error 500 af ...

Do Material-UI pickers only validate on blur, not on change events?

When you type inside the DatePicker component, validation is triggered immediately. Is there a way to trigger validation on blur instead of onChange when using @material-ui/pickers with material-ui v4 Passing the value to the blur function should work a ...

Once logged out in Vue Router, the main app template will briefly display along with the login component

After clicking the logout button, I am experiencing an issue where my main UI remains visible for a few seconds before transitioning to a blank page and displaying the login form component. This behavior is occurring within the setup of my App.vue file: & ...

Any number of elements in a single JSX code snippet

In my React code, I've created a function called optionTemplate to be used as a prop in a React component. const optionTemplate = (option) => { return ( <div className="flex align-items-center gap-2" style={ ...

Can the client side version of expressjs routes be utilized?

Can you create client-side routes in the style of expressjs to trigger a callback function for specific routes? For example: app.get('/dogs', function(req, res, next) { // do stuff }); Is there a way to achieve this functionality on the cli ...

Having trouble accurately obtaining the height of a DIV element using jQuery

After trying to troubleshoot on my own, I ran into a roadblock due to my specific requirements not being met by existing solutions. The issue at hand is as follows: I have a sticky DIV element positioned to the left, nested within another DIV Element wit ...

What is the process for uploading an image with express-fileupload?

Looking to upload an image to Cloudinary via Postman using the express-fileupload library for handling multipart forms. Here is a snippet from my index.ts file: import fileUpload from "express-fileupload"; app.use(fileUpload()); In my controller ...

What could be the reason for the malfunctioning dropdown menu in my navigation bar upon clicking it?

After spending hours practicing creating a navbar using Bootstrap 3.3.7, I've hit a roadblock - the dropdown is not working when clicked on. It's frustrating because I have double-checked all my scripts and ensured that I have the latest version ...

Creating an alarm clock with customizable time and date formats using ReactJS with Material-UI integration

Here is the code I have written: const date = new Date(); const currentTime = `${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`; const getDay = `${date.getDay()} ${date.getMonth()} ${date.getDate()}`; return ( <Box> < ...

What is the best way to extract a single item from an array in Javascript and assign it to a different variable

I am currently dealing with an array of objects structured like this: contacts: [ { id: 1, name: "John Doe", email: "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="066c696e6846616b676f6a2865696b">[emai ...