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

Viewed 22342

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).

5 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.

I had faced a similar issue when creating an application that foremost required authentication before accessing the actual content. So the first and main page of the application was a login form. After the login was successful, a new page should load instead where the actual content was suppossed to be. To do so, i have done the following:

In main.js or index.js how you'd name it, instead of loading the second window at the start and then show it, i load it inside an IPC event listener. So it loads the page when the IPC listener receives a certain event.

const {ipcMain} = require('electron');

ipcMain.on('login', (event, arg) => {
loginPage.loadURL(url.format({
pathname: path.join(__dirname, 'mainpage.html'),
protocol: 'file',
slashes: true
}));
});

Note, that loginPage is my main window that gets created on app.on() and mainpage is the second page that gets created after a successful login.

Then in my loginPage.html, after i verify the login, if it's successful i send that IPC renderer message back to the main process. Which is fairly simple to do:

var ipc = require('electron').ipcRenderer;

ipc.send('login', 'an-argument');

Above method should work. I am just a beginner so i cannot say if it's the best way to do this or if it has any unwanted implication that are not immediately seen, but it's worked out for me so you might as well give it a try.

I was fighting the same issue as you did until I found a simple solution. Here's the JS code:

const electron = require('electron');
let rootPath = "src/Page/index.html" //Path to the html file

LoadNewWindowInCurrent(rootPath); //Opens new html file in current window

//Here's the ready function for you to use
function LoadNewWindowInCurrent (PathToHtml){
   let localWindow = electron.remote.getCurrentWindow(); 
   localWindow.LoadFile(PathToHtml);
}
Related