Popups and Windows

Creating windows and popups with Webix Jet views

Temporary views like popups and windows can be created with this.ui(). It returns the UI object. this.ui() takes care of the windows it creates and destroys them when their parent views are destroyed.

Windows as Simple Views

Consider a simple popup view that will appear in the center of the screen:

// views/window1.js
const win1 = {
view:"popup",
position:"center",
body:{ template:"Text 1 (center)" }
};
export default win1;

Let's define a view class that will create this popup:

// views/top.js
import {JetView} from "webix-jet";
export default class TopView extends JetView {
config(){
return {
cols:[
{ view:"form", width: 200, rows:[
{ view:"button", value:"Show Window 1" }
]},
{ $subview: true }
]
};
}
}

The popup can be created in init() of TopView. Add a new win1 property to the class (this.win1), initialize the popup with this.ui() and assign it to the win1 property. this.ui() returns a UI object with all Webix methods of the view.

// views/top.js
import win1 from "views/window1";
...
init(){
this.win1 = this.ui(win1);
}

To show the popup, you must get the win1 property of the class and call the show() method of the Webix popup. This is the button click handler that shows the popup:

// views/top.js
...
{ view:"form", width: 200, rows:[
{ view:"button", value:"Show Window 1", click:() =>
this.win1.show() }
]}

this.win1.show() renders the popup at a position, defined in the config of the popup (position:"center"). If you don't set position, win1 will be rendered in the top left corner.

Note

Windows and popups created with this.ui have a peculiar feature. Once a window is created, its config is put in an anonymous Jet view, initialized specifically for this purpose. As a result, the $scope property of a window will refer not to its master Jet view, but to this anonymous view. To get to the master view that created the window, call this.$scope.getParentView() from a simple function and this.getParentView() from an arrow function.

Windows as Jet View Classes

You can define windows and popups as view classes as well. Have a look at a similar popup, defined as a class:

// views/window2.js
import {JetView} from "webix-jet";
export class WindowsView extends JetView {
config(){
return {
view:"popup",
top:200, left:300,
body:{ template:"Text 2 (fixed position)" }
};
}
}

This popup, when shown, will appear at a fixed position on screen (top:200, left:300).

Because this popup view is a class, you have to define the method (or attach an event) that will call the show() method of a Webix popup.

// views/window2.js
import {JetView} from "webix-jet";
export class WindowsView extends JetView {
config(){
return {
view:"popup",
top:200, left:300,
body:{ template:"Text 2 (fixed position)" }
};
}
showWindow(){
this.getRoot().show();
}
}

this.getRoot() refers to the popup UI returned by config().

To show this popup, you must call showWindow.

Here's how you initiate and show this class popup by TopView:

  1. To create a popup, use this.ui() inside init() of TopView.

  2. Add a new win2 property, create the popup with this.ui() and assign the popup to win2.

  3. this.ui() returns a class, so you can call class methods. To show the popup, call showWindow().

// views/top.js
import {JetView} from "webix-jet";
import WindowView from "views/window2";
export default class TopView extends JetView {
config(){
return {
cols:[
{ view:"form", width: 200, rows:[
{ view:"button", value:"Show Window 2", click:() =>
this.win2.showWindow() }
]},
{ $subview: true }
]
};
}
init(){
this.win2 = this.ui(WindowsView);
}
}

Check out the demo on GitHub >>

Jet View Embedded in the Body of a Window/Popup

You can also embed Jet views into the body of a window or a popup. For instance, this is the Jet class view you want to embed:

// views/embeddable.js
export default class Embeddable extends JetView{
config(){
return {
template:"I'm cozily inside a window"
};
}
}

To embed this view in a window, import it and put it into the window body:

// views/window3.js
import Embeddable from "views/embeddable";
export default class Window extends JetView{
config(){
return {
view:"window", position:"center", head:"Window",
body: Embeddable
}
}
showWindow(){
this.getRoot().show();
}
}

Including Windows in the app URL

Jet views inside windows can have complex structures, e.g. with several layers of subviews. In this case it would be useful to keep the UI of the window in the app URL and navigate inside the window in the same way as it is done for the rest of Jet views.

The solution is to include a view with a window as a dynamic subview. The window will still be shown above the UI of the parent, but otherwise will behave as an ordinary subview. Follow these steps:

  1. create a $subview:true element in the parent view and add the popup:true property to it,

  2. show the window-view with this.show().

// views/top.js
import { JetView } from "webix-jet";
export default class TopView extends JetView{
config(){
return {
rows:[
{
view:"button", width: 120, value:"Data",
click:() => this.show("popup")
},
{ $subview:true, popup:true }
]
};
}
}

"popup" is the file with the window, e.g.:

import { JetView } from "webix-jet";
export default class PopupView extends JetView {
config(){
return {
view:"window", head:false, position:"center",
body:{
template:"Window with data"
}
};
}
}

Adding a Context Menu

You can also attach a context menu to widgets with this.ui().

Let's attach a context menu to a simple template. This is a Jet view with the template:

// views/top.js
import {JetView} from "webix-jet";
export default class TopView extends JetView {
config(){
return {
localId:"body", template:"A place for context"
};
}
}

The context menu will be created by this.ui() in init() of the top view. After that, the context menu will be attached to the template. To reference the template, you can use its local ID:

// views/top.js
import {JetView} from "webix-jet";
export default class TopView extends JetView {
config(){
return {
localId:"body", template:"A place for context"
};
}
init(){
var context = this.ui({
view:"contextmenu", localId:"context",
data:["Add","Rename","Delete",{ $template:"Separator" },"Info"]
});
context.attachTo(this.$$("body").getNode());
}
}

You do not need to destroy the context menu when its master view is destroyed.

Check out the example >>