Leave without saving

Hi all,

This has been asked before but quite a long time ago: https://www.wix.com/velo/forum/coding-with-velo/warning-user-visitor-that-changes-not-saved-when-leaving-site

I’m very keen to add a feature where if a user tries to close their tab or window without saving their data, the browser pauses and asks them if they’re sure they want to leave without saving.

Is there any way - easy or complicated - to implement this? Would be a big help :slight_smile:

Many thanks,

Luke

If you have the site under your own domain, you can create a custom element that prompt an alert on beforeunload.
Of curse, you’ll have to pass the mode (‘saved’ / ‘edit’) to the element by element.setAttribute.
Whether or not it is complicated depends on your knowledge.
It’ll take a few minutes for someone who knows what to do. If you never worked with custom elements it might take you more.

You should read these articles:
Google Search

https://support.wix.com/en/article/wix-editor-adding-a-custom-element-to-your-site

https://www.wix.com/velo/reference/$w/customelement/introduction

https://www.wix.com/velo/reference/$w/customelement/setattribute

Thanks so much for the advice! This worked perfectly.

Implementation below for anyone interested…

I have added a custom element called #leaveWithoutSaving in the footer of my site. Any time I want it to trigger the prompt I run the following snippet:

$w('#leaveWithoutSaving').setAttribute('unsaved', true);

And my code for the custom element itself is:

// parameter which tetermines whether leave without saving prompt is triggered
let unsaved = false

class leaveWithoutSaving extends HTMLElement {
    constructor() {
        super();
    }

    // call back runs when an attribute is changed 
    attributeChangedCallback(name, oldValue, newValue) {

        if (name === 'unsaved') {
            unsaved = true;
        } else if (name === 'saved') {
            unsaved = false;
        }
    }
    static get observedAttributes() {
        return ['unsaved', 'saved'];
    }
}

customElements.define('leave-without-saving', leaveWithoutSaving);

// function which triggers the leave without saving prompt
window.onbeforeunload = function () {
    if (unsaved === true) {
        return 'Are you sure you want to leave without saving?';
    }
};

Thanks again!

Luke

You’re welcome. I’m glad to hear it worked for you.
2 minor comments:

  1. You don’t need the constructor at all in this case.
  2. You can do everything with the ‘unsaved’ attribute. No need to observe the ‘saved’ attribute.

Something like:

//...
static get observedAttributes() {
        return ['unsaved'];
    }
 attributeChangedCallback(name, oldValue, newValue) {
        if (name === 'unsaved') {
            unsaved = newValue === 'true';
        }
    }
//...

And on the page:

allInputs.onChange(() => $w('customEl').setAttributes('unsaved','true'));
//after saving:
 $w('customEl').setAttributes('unsaved','false')

P.S. You should go for the single-attribute approach, because your code doesn’t cover all scenarios.
For example, if the user made some changes, saved them, and then made some other changes and tried to leave without saving the new changes.
Your code will not catch it (because the ‘unsaved’ attribute value hasn’t changed since the previous iteration - unless you set its value to be a random big number or the current time converted to string).
My code will catch it.

It that code possible to for when the visitor close his dynamic site it setfieldvalue from a field to true and save it?

Are you talking about saving it before the user clicked “Yes” to leave the page? or after?

Before leave the page save boolech field to true. With the popup window or without is not important, here the post: https://www.wix.com/velo/forum/coding-with-velo/save-field-true-befor-leave-page

You can try using pagehide event.
I’m not sure it will work fine on any browser (you should send an order to the Velo page to save the form).
https://www.wix.com/velo/reference/$w/customelement/on

And what i can make with that?

addEventListener('pagehide', (event) => { });onpagehide = (event) => { };