Electron: Linking pages using buttons click event - javascript

I have created a button(Connect), when I click it should go to the other page(second.html). It works with localhost, but not with Electron App. What am I doing wrong?
<script>
$(document).ready(() => {
$( '#buttonConnect').on('click',() =>{
const inputIp = $('#ip');
if(inputIp.val() !== ""){
window.location.href = "observer.html ?ip="+inputIp.val();
}else{
alert("Check Connection Settings!");
}
});
});
</script>
<button class="btn btn-primary" id="buttonConnect">Connect</button>

You need to communicate with electron from your remote window to tell it which URL to load.
Using IPC is the recommended way of doing that.
(a former solution was using remote which is deprecated now)
In your remote code (your jQuery code from above, in this case):
let { ipcRenderer } = require("electron");
$(document).ready(() => {
$( '#buttonConnect').on('click',() =>{
const inputIp = $('#ip');
if (inputIp.val() !== ""){
ipcRenderer.send("load-page", `second.html?ip=${inputIp.val()}`);
}
else {
alert("Check Connection Settings!");
}
});
});
In your main electron code (probably app.js):
let electron = require("electron");
let { BrowserWindow, ipcMain } = electron;
// ...
ipcMain.on("load-page", (event, uri) => {
let win = new BrowserWindow({ /* ... */ });
// I don't know your directory structure.
// You may have to adapt the following line.
win.loadURL(`file://${__dirname}/${uri}`);
});

Related

cant click the button (electron)

im try to do a project that connect pc to pc like screencast. when following the coding online im having a problem when trying to click the button. i cant click the button to pup up the id code.
This the code for app.js
const { app, BrowserWindow, ipcMain } = require('electron')
const path = require('path')
const { v4: uuid4} = require('uuid');
const screenshot= require('screenshot-desktop');
var socket = require('socket.io-client')('http://172.20.10.3:5000');
var interval;
const createWindow = () => {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 500,
height: 150,
webPreferences: {
preload: path.join(__dirname, 'index.js')
}
})
// and load the index.html of the app.
mainWindow.removeMenu();
mainWindow.loadFile('index.html')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
}
// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(() => {
createWindow()
app.on('activate', () => {
// On macOS 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 (BrowserWindow.getAllWindows().length === 0)
createWindow()
})
})
// Quit when all windows are closed, except on macOS. There, it's common
// for applications and their menu bar to stay active until the user quits
// explicitly with Cmd + Q.
app.on('window-all-closed', () => {
if (process.platform !== 'darwin')
app.quit()
})
ipcMain.on("start-share", function(event , arg){
var uuid = uuid4();
socket.emit("join-message", uuid);
event.reply("uuid", uuid);
})
ipcMain.on("stop-share", function(event, arg){
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
This is the index.js file
const ipcRenderer = require ('electron').ipcRenderer;
window.onload = function(){
ipcRenderer.on("uuid", (event, data)=>{
document.getElementById("code").innerHTML = data;
})
}
function startShare(){
ipcRenderer.send("start-share", {} );
document.getElementById("start").style.display = "none";
document.getElementById("stop").style.display = "block";
}
function stopShare(){
ipcRenderer.send("stop-share", {});
document.getElementById("stop").style.display = "none";
document.getElementById("start").style.display = "block";
}
this is the popup when running the code. i cant click the start button
enter image description here
im following this video from (youtube)
this the documentation that i follow in electronelectron website
if someone having problem to see the codes i will try to edit and insert more code or maybe send a zip file. im really needed some help in developed this project for education purpose
im expecting some guide to develop this project. if can i would like the same in the video but i have follow that video from start to end but stuck in the middle of the video. really needed the help
It seems you didn't add your startShare and stopShare functions to your index.html. The preload script is used only for a bridge between your main process and ui process. It doesn't have window object and doesn't attach itself to the index.html.
webPreferences: {
preload: path.join(__dirname, 'index.js')
}
You have to create a bridge and pass ipcRenderer.on function to your ui process. Or you also can add nodeIntegration: true to your webPreferences object. You can read some disadvantages about it.
Then you need to attach your index.js file to the index.html using <script> tag.

How to use proxys with the electron BrowserWindow function

I have a program that will create a browser window to a specific site, what I need is for each browser window to have a separate proxy. Example proxies entered as so: IP:PORT:USER:PASS,IP:PORT:USER:PASS,IP:PORT:USER:PASS etc... and then it will open as many browser windows as proxys. Here is my current code:
const path = require('path')
const url = require('url')
let defaultWindow, dimWindow, colorWindow, framelessWindow;
let parentWindow, childWindow;
function createWindows () {
parentWindow = new BrowserWindow({title: 'Parent'});
childWindow = new BrowserWindow({parent: parentWindow, modal: true,show: false, title: 'Child'});
childWindow.loadURL('https://github.com');
childWindow.once('ready-to-show', () => {
childWindow.show()
});
}
app.on('ready', createWindows);
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit();
}
});
app.on('activate', () => {
if (win === null) {
createWindow();
}
});
If anyone knows how an answer would be greatly appreciated.
Ive worked this one out myself thankfully.
You simply add this into the script:
var proxyList = '161.202.226.195:8123'
var url = 'supremenewyork.com'
and then replace the old lines of code with this:
childWindow.webContents.session.setProxy({proxyRules:`http=foopy,direct://${proxyList}`}, function () {
childWindow.loadURL(`${url}`);
},
yes that is working proxy as of the date this is posted so you may try it yourself if you dont have access to paid proxies :)

How to force the closing of an Electron app?

I have an electron app that loads the URL of the web version of the app.
However I cannot close the application by clicking in the X button and I dont have access to the webapp.
I have tried this:
let count = BrowserWindow.getAllWindows().length;
///returns 1, so there is only 1 window)
window.onbeforeunload=function(e){
e.returnValue=undefined;
return undefined;
}
window.close();
app.quit();
Nothing happens.
app.exit(0) works, but I dont want to use it. Is there a way I can close the app with window.close and app.quit?
EDIT:
The problem are those global beforeunload events. If i click remove in the devtools I am able to close the app.
Also this let names= window.eventNames();returns an array that does not have any beforeunload events
In the file where you created the BrowserWindow, you can attach an event to the 'close' handler for the window. For Electron, this is usually main.js.
const {app, BrowserWindow} = require('electron');
let mainWindow = null;
app.on('ready', () => {
mainWindow = new BrowserWindow({
//options here
});
mainWindow.loadURL([url here]);
//attach event handler here
mainWindow.on("close", () => {
mainWindow = null;
app.quit();
});
});
For good measure, in the case that you may have more than one window, place this in your main.js file.
app.on('window-all-closed', () => {
if(process.platform !== "darwin")
app.quit();
});
You need to save the BrowserWindow object reference. Then listen for a 'closed' event and dereference it:
const { app, BrowserWindow } = require('electron');
let win; // = new BrowserWindow();
win.on('closed', () => {
win = null
})
After dereference, it's all simple, just listen for 'window-all-closed' event on app:
app.on('window-all-closed', () => {
app.quit()
})

Windows 10 universal app not resuming from previous session

I have developed a windows 10 universal app using Html,css and JS. For allowing inline scripts i am using ms-appx-web context and has set ms-appx-web:///login.html as start page in manifest.
Whenever I open my app in windows 10 mobile it works fine but if I switch to another app and then go to app again by selecting it from windows app list. Then it instead of resuming app from saved state it restarts it.
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState === activation.ApplicationExecutionState.terminated) {
}
if (WinJS.Application.sessionState.url) {
localStorage.setItem("UserName", WinJS.Application.sessionState.name);
window.location = WinJS.Application.sessionState.url;
}
args.setPromise(WinJS.UI.processAll().then(function () {
}));
}
};
app.oncheckpoint = function (args) {
var location = window.location.href;
var name = localStorage.getItem("UserName");
WinJS.Application.sessionState.name = name;
WinJS.Application.sessionState.url = location;
};
Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", function (args) {
if (WinJS.Application.sessionState) {
window.location = WinJS.Application.sessionState.url;
localStorage.setItem("UserName", WinJS.Application.sessionState.name);
}
}, false);
Windows.UI.WebUI.WebUIApplication.addEventListener("suspending", function (args) {
var location = window.location.href;
var name = localStorage.getItem("UserName");
WinJS.Application.sessionState.name = name;
WinJS.Application.sessionState.url = location;
}, false);
app.start();
})();
Can anyone suggest me what am I doing wrong?
I changed my app.onactivated event in main.js
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.launch) {
if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) {
} else {
}
args.setPromise(WinJS.UI.processAll());
var name = Windows.Storage.ApplicationData.current.roamingSettings.values["name"];
var url = Windows.Storage.ApplicationData.current.roamingSettings.values["url"];
if (name) {
localStorage.setItem("UserName", name);
}
if (url) {
window.location.href = url;
}
}
};
But it stops running on window.location.href = url; line.
What i am trying to do is store username and current url on suspending event and want to restore it on resume event (when user opens app from app list which is already running.)
but if I switch to another app and then go to app again by selecting it from windows app list. Then it instead of resuming app from saved state it restarts it.
I think you are not using Single-Page Navigation for your app.
Please refer to Single-page navigation: the recommended model:
The script context is destroyed and must be initialized again. The app might receive system events but not handle them because the script context is being destroyed and reinitialized.
So the script context is already destroyed after you navigated to other page.
To fix the problem, the best solution is to make your app a single paged application. And navigate pages using PageControl. You can refer to Quickstart: Using single-page navigation to get started.
Update:
but when I use window.location.href for redirecting in main.js it closes app.
It's because you are using it in WinJS script. When you are leaving the page WinJS script context will be destroyed and thus executing the codes inside crash the app. To fix this you can use windows lifecycle API instead:
var roaming=Windows.Storage.ApplicationData.current.roamingSettings;
Windows.UI.WebUI.WebUIApplication.addEventListener("activated", function (args) {
if (args.detail[0].kind === activation.ActivationKind.launch) {
if (roaming.values["currentUri"]) {
window.location.href = roaming.values["currentUri"];
}
}
});
Windows.UI.WebUI.WebUIApplication.addEventListener("suspending", function (args) {
roaming.values["currentUri"] = window.location.href;
roaming.values["UserName"] = evt.srcElement.value;
//save the other information of the page here
});
Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", function (args) {
var roam = Windows.Storage.ApplicationData.current.roamingSettings;
if (roam) {
if (roam["currentUri"])
{
window.location.href = roam["currentUri"];
}
}
}, false);
You can also refer to my demo.
Notes: If you don't use WinJS at all, just remove the reference. Loading WinJS library on every page is not efficient.
I have changed my main.js as :
(function () {
"use strict";
//No need of WinJS
var activation = Windows.ApplicationModel.Activation;
var roaming = Windows.Storage.ApplicationData.current.roamingSettings;
// For App Start Up
Windows.UI.WebUI.WebUIApplication.addEventListener("activated", function (args) {
if (args.detail[0].kind === activation.ActivationKind.launch) {
if (roaming.values["currentUri"]) {
if (roaming.values["UserName"])
{
localStorage.setItem("UserName", roaming.values["UserName"]);
window.location.href = roaming.values["currentUri"];
}
}
}
});
// For App Suspension
Windows.UI.WebUI.WebUIApplication.addEventListener("suspending", function (args) {
roaming.values["currentUri"] = window.location.href;
roaming.values["UserName"] = localStorage.getItem("UserName");
});
// For Resuming App
Windows.UI.WebUI.WebUIApplication.addEventListener("resuming", function (args) {
var roam = Windows.Storage.ApplicationData.current.roamingSettings;
if (roam) {
if (roam.values["currentUri"]) {
localStorage.setItem("UserName", roam.values["UserName"]);
window.location.href = roam.values["currentUri"];
}
}
}, false);
// not working backpressed event
Windows.UI.WebUI.WebUIApplication.addEventListener("backpressed", function (args) {
// to do
}, false);})();
Everything is working fine. But I dont know how to add back key press event without using winjs.
Can anyone suggest me?
How to add back key press event without winjs?

Make a link from Electron open in browser

Is there any (simple/built-in way) to open a new browser (I mean default OS browser) window for a link from Electron instead of visiting that link inside your Electron app ?
You can simply use :
require("shell").openExternal("http://www.google.com")
EDIT: #Arjun Kava's answer is much better these days.
This answer is quite old and assumes you have jQuery.
const shell = require('electron').shell;
// assuming $ is jQuery
$(document).on('click', 'a[href^="http"]', function(event) {
event.preventDefault();
shell.openExternal(this.href);
});
mainWindow.webContents.on('new-window', function(e, url) {
e.preventDefault();
require('electron').shell.openExternal(url);
});
Requires that you use target="_blank" on your anchor tags.
My code snippet clue accordingly to the depreciations in Electron version ^12.0.0
const win = new BrowserWindow();
win.webContents.setWindowOpenHandler(({ url }) => {
// config.fileProtocol is my custom file protocol
if (url.startsWith(config.fileProtocol)) {
return { action: 'allow' };
}
// open url in a browser and prevent default
shell.openExternal(url);
return { action: 'deny' };
});
To make all Electron links to open externally in the default OS browser you will have to add an onclick property to them and change the href property so it doesn't load anything in the Electron app.
You could use something like this:
aTags = document.getElementsByTagName("a");
for (var i = 0; i < aTags.length; i++) {
aTags[i].setAttribute("onclick","require('shell').openExternal('" + aTags[i].href + "')");
aTags[i].href = "#";
}
But make sure the entire document has loaded before doing this otherwise it is not going to work.
A more robust implementation would look like this:
if (document.readyState != "complete") {
document.addEventListener('DOMContentLoaded', function() {
prepareTags()
}, false);
} else {
prepareTags();
}
function prepareTags(){
aTags = document.getElementsByTagName("a");
for (var i = 0; i < aTags.length; i++) {
aTags[i].setAttribute("onclick","require('shell').openExternal('" + aTags[i].href + "')");
aTags[i].href = "#";
}
return false;
}
Remember that if you load external files you will have to make them go through this process as well after they are fully loaded.
Some handy solutions can be found in this gist.
By listening on the body, the following solutions will work on <a> tags that may not yet exist when the JavaScript runs, but only appear in the DOM at a later time.
This one by luizcarraro requires jQuery:
$('body').on('click', 'a', (event) => {
event.preventDefault();
require("electron").shell.openExternal(event.target.href);
});
You can change the selector to target only certain links, e.g. '#messages-view a' or 'a.open-external'.
Here is an alternative without any library (derived from zrbecker's):
document.body.addEventListener('click', event => {
if (event.target.tagName.toLowerCase() === 'a') {
event.preventDefault();
require("electron").shell.openExternal(event.target.href);
}
});
Consult the gist for more examples.
I use this method with Electron v.13.
We intercept the user's navigation (window.location) and open the URL in the default browser.
See the doc : https://www.electronjs.org/docs/latest/api/web-contents#event-will-navigate
const { shell } = require('electron');
window.webContents.on('will-navigate', function (e, url) {
e.preventDefault();
shell.openExternal(url);
});
On tsx syntax (Electron):
import { shell } from "electron";
shell.openExternal("http://www.google.com")
In the view component use simple a link:
<a href="https://google.com" target="_blank" rel="noreferrer">
<button type="button">
button title
</button>
</a>
And in file public/electron.js add default behavior for all a link navigations:
function createWindow() {
...
// Open urls in the user's browser
win.webContents.setWindowOpenHandler((edata) => {
shell.openExternal(edata.url);
return { action: "deny" };
});
}
To open an external link in an Electron's Project you will need the module Shell (https://www.electronjs.org/docs/api/shell#shell) and the method openExternal.
But if you are looking for an abstract way to implement that logic is by creating a handler for a custom target to your target attribute.
const {shell} = require('electron');
if (document.readyState != "complete") {
document.addEventListener('DOMContentLoaded', function() {
init()
}, false);
} else {
init();
}
function init(){
handleExternalLinks();
//other inits
}
function handleExternalLinks(){
let links = document.getElementsByTagName('a')
let a,i = 0;
while (links[i]){
a = links[i]
//If <a target="_external">, so open using shell.
if(a.getAttribute('target') == '_external'){
a.addEventListener('click',(ev => {
ev.preventDefault();
let url = a.href;
shell.openExternal(url);
a.setAttribute('href', '#');
return false;
}))
}
console.log(a,a.getAttribute('external'))
i++;
}
}
To run an Electron project in your actual browser (Chrome, Mozilla, etc), add this to your script are external script:
aTags = document.getElementsByTagName("a");
for (var i = 0; i < aTags.length; i++) {
aTags[i].setAttribute("onclick","require('shell').openExternal('" + aTags[i].href + "')");
aTags[i].href = "#";
}

Categories