onlystcm / dash-unload-component Goto Github PK
View Code? Open in Web Editor NEWDASH component which listens to unload event
License: Other
DASH component which listens to unload event
License: Other
Callback is not triggered when a different URL is entered, callback only works when tab/window is closed
Using this brilliant component leads to a JavaScript error in Chrome, because dash_unload_component.min.js.map
is included in the webpage. This can be resolved by replacing the code block starting on line 32 with:
_js_dist = [
{
'relative_package_path': 'dash_unload_component.min.js',
'namespace': package_name
},
{
'relative_package_path': 'dash_unload_component.min.js.map',
'namespace': package_name,
'dynamic': True
}
]
After this modification the JavaScript error is resolved.
Hi, thanks for create this listener.
However sometimes the listener is not working when I am closing the tab again in the same window (first i close the tab, the listener is work, and when i opened it again in another tab and then close it, the listener is not work). I have to open it in a new window, just the listener will work.
And when I add this listener into my complete app, sometimes it will not work when close it (first time).
Hi threre,
directly when I load the page I am getting:
dash_unload_component.v1_2_2m1673883418.min.js.map:1 Uncaught SyntaxError: Unexpected token ':' (at dash_unload_component.v1_2_2m1673883418.min.js.map:1:11)
I added duc.Unload dash-unload-component
to the page like this:
duc.Unload(id='page_unload_listener')
html.Div(id='unload_dummy_output')
...
@app.callback(Output('unload_dummy_output', 'children'), Input('page_unload_listener', 'close'))
def on_site_closed(close):
print(close)
if close is True:
stop_server() # shuts down the server
return None
Content of dash_unload_component.v1_2_2m1673883418.min.js.map
:
{"version":3,"sources":["webpack://dash_unload_component/webpack/bootstrap","webpack://dash_unload_component/external \"PropTypes\"","webpack://dash_unload_component/external \"React\"","webpack://dash_unload_component/./src/lib/components/Unload.react.js","webpack://dash_unload_component/./src/lib/index.js"],"names":["installedModules","__webpack_require__","moduleId","exports","module","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","window","Unload","props","setProps","close","event","returnValue","handleClose","keepOpen","Component","addEventListener","this","removeEventListener","defaultProps","propTypes","id","PropTypes","string","isRequired","bool","func"],"mappings":"yCACE,IAAIA,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUC,QAGnC,IAAIC,EAASJ,EAAiBE,GAAY,CACzCG,EAAGH,EACHI,GAAG,EACHH,QAAS,IAUV,OANAI,EAAQL,GAAUM,KAAKJ,EAAOD,QAASC,EAAQA,EAAOD,QAASF,GAG/DG,EAAOE,GAAI,EAGJF,EAAOD,QA0Df,OArDAF,EAAoBQ,EAAIF,EAGxBN,EAAoBS,EAAIV,EAGxBC,EAAoBU,EAAI,SAASR,EAASS,EAAMC,GAC3CZ,EAAoBa,EAAEX,EAASS,IAClCG,OAAOC,eAAeb,EAASS,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEZ,EAAoBkB,EAAI,SAAShB,GACX,oBAAXiB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAeb,EAASiB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAeb,EAAS,aAAc,CAAEmB,OAAO,KAQvDrB,EAAoBsB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQrB,EAAoBqB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFA1B,EAAoBkB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOrB,EAAoBU,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRzB,EAAoB6B,EAAI,SAAS1B,GAChC,IAAIS,EAAST,GAAUA,EAAOqB,WAC7B,WAAwB,OAAOrB,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAH,EAAoBU,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRZ,EAAoBa,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG/B,EAAoBkC,EAAI,GAIjBlC,EAAoBA,EAAoBmC,EAAI,G,gBClFvChC,EAAOD,QAAUkC,OAAkB,W,cCAnCjC,EAAOD,QAAUkC,OAAc,O,85BCGxBC,E,YACjB,WAAYC,GAAO,M,IAAA,O,4FAAA,S,EACf,K,EAAA,eAAMA,GAAN,G,gDADe,qBAgBL,WACV,EAAKA,MAAMC,SAAS,CAAEC,OAAO,MAjBd,kBAoBR,SAACC,GAER,OADAA,EAAMC,YAAc,8EACbD,EAAMC,cApBb,EAAKC,YAAc,EAAKA,YAAYf,KAAjB,MACnB,EAAKgB,SAAW,EAAKA,SAAShB,KAAd,MAHD,E,sPADaiB,gB,kDAQ5BT,OAAOU,iBAAiB,SAAUC,KAAKJ,aACvCP,OAAOU,iBAAiB,eAAgBC,KAAKH,Y,6CAI7CR,OAAOY,oBAAoB,SAAUD,KAAKJ,aAC1CP,OAAOY,oBAAoB,eAAgBD,KAAKH,Y,+BAchD,OAAQ,U,gCAIhBP,EAAOY,aAAe,CAClBT,OAAO,GAIXH,EAAOa,UAAY,CAEfC,GAAIC,IAAUC,OAAOC,WAGrBd,MAAOY,IAAUG,KAMjBhB,SAAUa,IAAUI,MCnDxB","file":"dash_unload_component.min.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 2);\n","(function() { module.exports = window[\"PropTypes\"]; }());","(function() { module.exports = window[\"React\"]; }());","import React, {Component} from 'react';\nimport PropTypes from 'prop-types';\n\nexport default class Unload extends Component {\n constructor(props) {\n super(props); \n this.handleClose = this.handleClose.bind(this);\n this.keepOpen = this.keepOpen.bind(this);\n }\n \n componentDidMount() {\n window.addEventListener('unload', this.handleClose);\n window.addEventListener('beforeunload', this.keepOpen);\n }\n \n componentWillUnmount() {\n window.removeEventListener('unload', this.handleClose);\n window.removeEventListener('beforeunload', this.keepOpen);\n }\n \n handleClose = () => {\n this.props.setProps({ close: true });\n }\n \n keepOpen = (event) => {\n event.returnValue = 'Warning!\\n\\nYou will lose unsaved data if you navigate away from this page.';\n return event.returnValue\n }\n \n \n render() {\n return (null);\n }\n}\n\nUnload.defaultProps = {\n close: false,\n //text: 'Warning!\\n\\nYou will lose unsaved data if you navigate away from this page.'\n};\n\nUnload.propTypes = {\n //The ID used to identify this component in Dash callbacks\n id: PropTypes.string.isRequired,\n\n // The state of a window, to check if it is closed or still open\n close: PropTypes.bool,\n \n // Text that to be shown went browser is closed (does not work on all browsers)\n //text: PropTypes.string,\n\n // Dash-assigned callback that should be called whenever any of the properties change\n setProps: PropTypes.func\n};\n","/* eslint-disable import/prefer-default-export */\nimport Unload from './components/Unload.react';\n\nexport {\n Unload\n};\n"],"sourceRoot":""}
pip versions:
dash==2.7.1
dash-core-components==2.0.0
dash-extensions==0.1.10
dash-html-components==2.0.0
dash-table==5.0.0
dash-unload-component==1.2.2
Library does not currently work with the Firefox browser.
Has been tested on Chromium and Opera
Your function is perfect in my use of Dash, thank you! However, let's imagine that several dash sessions are open simultaneously (example: session1, session2 and session3). When closing session1, the callback is called, "close" parameter has been modified. On the other hand, when closing session2, the callback is not called, which is problematic.
And I can't explain that when closing session3, the callback is called. In fact, it works one in two for several open sessions.
When I speak of sessions, it is because I differentiated each session by an identifier (see -> https://dash.plotly.com/sharing-data-between-callbacks, uuid4 function of the uuid package).
Being new to python, I can't help you rectify your code to make it work !
Hi @ONLYstcm ,
Thanks for implementing this component. I have a use case for this. However, When I go to a different URL, it asks me a confirmation pop up for leaving the page & Ideally in my application, it's not required. Is there a way to avoid the pop-up?
Hi there, I am having issues using this component, it is only firing when a closed tab is reopened. I saw you mentioned it in another issue here, but perhaps if you still have the source react js files it would be good if you could upload react JS to the repo that is not minified, its difficult to fix the issue myself without that.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.