Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to open new window in place of current window in Electron

I am have been able to open a new window when i click a button, however, its a new pop up window. How can I have the new window open up in place of the main window?

var app = require('app')
var BrowserWindow = require('browser-window')
var ipc = require('ipc')

app.on('ready', function () {
    var mainWindow = new BrowserWindow ({
        width: 800,
        height: 600
    })
    mainWindow.loadURL('file://' + __dirname + '/main.html')
    //mainWindow.openDevTools() //opens inspect console

    var prefsWindow = new BrowserWindow ({
        width: 400,
        height: 400,
        show: false
    })
    prefsWindow.loadURL('file://' + __dirname + '/prefs.html')

With the code above, a new window pops up. Ive attached a screenshot to show what I mean.

popup window

Instead of that popup window, i want 'prefs' to replace the main window (and other options to replace the main window once added).

like image 242
machinebit Avatar asked Mar 17 '16 21:03

machinebit


3 Answers

In case anyone interested, this is what I did.

assuming I have login form and after signing in I wanted to show the main window where things will happen.

setup your index.js

const electron = require('electron');
const url = require('url');
const path = require('path');

const { app, BrowserWindow } = electron;

let loginWindow;
var mainIndex = '../../index.html'; //the login window
var directoryHtml = '../html/'; //directory of where my html file is, the main window is here except the login window
var iconPath = '../../images/logo.png'; //replace with your own logo
let { ipcMain } = electron;
var newWindow = null;

app.on('ready', function () {
    loginWindow = new BrowserWindow({//1. create new Window
        height: 600, width: 450,
        minHeight: 600, minWidth: 450, //set the minimum height and width
        icon: __dirname + iconPath,
        frame: false, //I had my own style of title bar, so I don't want to show the default
        backgroundColor: '#68b7ad', //I had to set back color to window in case the white screen show up
        show: false //to prevent the white screen when loading the window, lets not show it first
    });

    loginWindow.loadURL(url.format({ //2. Load HTML into Window
        pathname: path.join(__dirname, mainIndex),
        protocol: 'file',
        slashes: true
    }));

    loginWindow.once('ready-to-show', () => {
        loginWindow.show() //to prevent the white screen when loading the window, lets show it when it is ready
    })
});

//dynamically resize window when this function is called
ipcMain.on('resize', function (e, x, y) {
    loginWindow.setSize(x, y);
}); 

/** start of showing new window and close the login window **/
ipcMain.on('newWindow', function (e, filenName) {

    if(newWindow){
        newWindow.focus(); //focus to new window
        return;
    }

    newWindow = new BrowserWindow({//1. create new Window
        height: 600, width: 800,
        minHeight: 600, minWidth: 800,
        icon: __dirname + iconPath,
        frame: false,
        backgroundColor: '#68b7ad',
        show: false
    }); 

    newWindow.loadURL(url.format({ //2. Load HTML into new Window
        pathname: path.join(__dirname, directoryHtml + filenName),
        protocol: 'file',
        slashes: true
    }));

    newWindow.once('ready-to-show', () => { //when the new window is ready, show it up
        newWindow.show()
    })

    newWindow.on('closed', function() { //set new window to null when we're done
        newWindow = null
    })

    loginWindow.close(); //close the login window(the first window)
});
/** end of showing new window and closing the old one **/

app.on('closed', function () {
    loginWindow = null;
});

// Quit when all windows are closed.
app.on('window-all-closed', function () {
    // On OS X it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
        app.quit()
    }
})

app.on('activate', function () {
    // On OS X it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (loginWindow === null) {
        createWindow()
    }
})

index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Login Window</title>
</head>

<body>
    <h1>Login</h1>
    <!-- . . . . -->
    <button id="btn-login" onclick="loginNow()"></button>
    <!-- . . . . -->
    <script>
        function loginNow(){
            //.....
            //assuming the authentication is valid, we want to show now the new window which will be our main window
            const { ipcRenderer } = require('electron'); //require electron

            //using ipcRenderer, let's call the function in index.js where the function name is `newWindow`, 
            //the `main.html` is the new html file I want to show, use your own.
            ipcRenderer.send('newWindow','main.html'); 
        }
    </script>
</body>

</html>

I don't if this is the right way to do it, and I don't know the disadvantage of doing it like this but I hope none. hope this help someone.

like image 182
Polar Avatar answered Oct 16 '22 15:10

Polar


You have a few options.

You could just call prefsWindow.focus() to ensure the second window is on top of the first.

You could hide or close the main window with mainWindow.hide() or mainWindow.destroy(), leaving only the second window open. Then reopen it when your done.

Or instead of having two windows, you could just load your prefs page into the first window, and when done back to the main page.

like image 29
Teak Avatar answered Oct 16 '22 13:10

Teak


Instead of creating a new window, just load the prefs.html into the mainWindow. Your old content (main.html) will get replaced without additional windows opening.

When the respective button is placed inside the main.html you will need to apply this loading via the ipc remote module.

Following this SO answer for Electron 0.35.0 and above:

// In main process.
const ipcMain = require('electron').ipcMain;

// in main process, outside of app.on:
ipc.on('load-page', (event, arg) => {
    mainWindow.loadURL(arg);
});

// In renderer process (web page).
const ipc = require('electron').ipcRenderer;

Loading the new page can then be performed as follows:

ipc.send('load-page', 'file://' + __dirname + '/prefs.html');
like image 11
Jens Habegger Avatar answered Oct 16 '22 15:10

Jens Habegger