cody
October 15, 2018, 4:07pm
1
I’m trying to add a modal to ask if you want to save unsaved changes when you try to navigate to another page.
I see there is an “app:guard” event, which is great, but I am wondering if there is a way to set a global flag.
I want to set a property on the JetApp instance from a view and use it in the “app:guard” event handler.
you can use some intermediate module to pass values between views
cody
October 16, 2018, 1:11pm
3
Where do you store values for a single view? Right now I am using a form and adding values to the form.
intermediate.ts
export const storage = {};
someview.ts
import {storage} from "intermediate";
export default class extends JetView {
someMethod: ()=> {
storage.someFlag = value;
}
}
otherview.ts
import {storage} from "intermediate";
export default class extends JetView {
someMethod: ()=> {
if(storage.someFlag == value) {
...
}
}
}
also you can use webix.storage.session to interchange data.
https://docs.webix.com/api__refs__storage.session.html
cody
October 16, 2018, 2:15pm
5
Thanks that works great!
In the app:guard event how do you stop navigation?
AFAIK you can return false or set confirm to reject obj.confirm = Promise.reject();
cody
October 16, 2018, 5:10pm
7
Returning false doesn’t work. The event handler takes function(url, view, nav)
. What is obj
?
cody
October 16, 2018, 5:11pm
8
nav.confirm = Promise.reject();
seems to work.
cody
October 16, 2018, 7:02pm
9
How do you continue after you have stopped navigation? This is what I have now.
app.attachEvent("app:guard", function(url, view, nav){
if (shared.storage.unsavedChanges){
// Cancel navigation
nav.confirm = Promise.reject();
var unsavedModal = webix.ui({
view: "window",
height: 250,
width: 300,
left: 50,
top: 50,
move: true,
head: "You have unsaved changes",
body: {cols: [
{view: "button", value: "Continue", click: function(){
// nav.redirect = "/#!" + url;
// nav.confirm = Promise.resolve();
window.open("/#!" + url, "_self");
}},
{view: "button", value: "Cancel", click: function(){
unsavedModal.hide();
}},
]}
});
unsavedModal.show();
}
});
cody
October 16, 2018, 7:39pm
10
Okay doing all three seems to be working.
nav.redirect = "/#!" + url;
nav.confirm = Promise.resolve();
window.open("/#!" + url, "_self");
@cody
app.attachEvent("app:guard", function (url, view, nav) {
if (shared.storage.unsavedChanges) {
// Cancel navigation
nav.confirm = nav.confirm.then(function () {
return new Promise(function (resolve, reject) {
var unsavedModal = webix.ui({
view: "window",
height: 250,
width: 300,
left: 50,
top: 50,
move: true,
head: "You have unsaved changes",
body: {
cols: [
{
view: "button", value: "Continue", click: function () {
// nav.redirect = "/#!" + url;
// nav.confirm = Promise.resolve();
//window.open("/#!" + url, "_self");
unsavedModal.close();
resolve(true);
}
},
{
view: "button", value: "Cancel", click: function () {
unsavedModal.close();
reject();
}
},
]
}
});
unsavedModal.show();
})
})
}
});
mdissel
October 17, 2018, 6:49am
12
Seems to be generic functionality, how could we integrate this in a modular way in every form?
@mdissel
you can implement some view level service
export function saveGuardService(app, view, config) {
view.on(app, "app:guard", function (url, view, nav) {
if (view.getRoot().isDirty()) {
nav.confirm = nav.confirm.then(function () {
return new Promise(resolve, reject){
//show confirmation
}
})
}
})
}
{
init: function(){
this.use(saveGuardService, {});
}
}
cody
October 19, 2018, 2:23pm
14
Thanks, having storage in a model works. I tried to have a this.storage on the view but I couldn’t figure it out.
mdissel
October 19, 2018, 2:48pm
15
@integral Can you please extend the sample with the optimal way of showing a confirmation window?
@mdissel
return new Promise(resolve, reject){
webix.confirm({
title: "Close",
text: "Data is unsaved!<br/>Do you want to continue?",
type:"confirm-error",
callback:function(result){
if (result) resolve();
else reject();
}
});
}