Button that opens a new panel and Another Button that opens a new tab

Hi, I was wondering if someone could give me some assistance as to how to make a button go to another panel page. Also, how to go about having another button open a new tab that redirects to a website.

Are you using the add-on SDK for this addon?

yes

You’ll want a contentScriptFile on the panel. The script should listen for the clicks. Then the content script should port.emit back to the panel at which point your addon script will in the case of going to another panel simply close the first one (or hide it) and show the second one. For the new tab, same thing, just open the tab.

If you want, my addon has some of the functionality, it opens and closes a panel, it opens a new tab, and in whitelist.js it listens (addEventListener) for a click, and launches a function that both port.emit and port.on some information. If you need more information, please reply back here.

Hi, thanks for the help. Unfortunately, I am very new at this, but we all
gotta start somewhere. I downloaded the zip file from GitHub. It works, but I am having trouble understanding the code and what it is that I need.

If you don’t mind , could you show me the code of an example that has a simple
button that navigates to another panel.

The index.js would contain something akin to

var panels = require("sdk/panel");
var { ToggleButton } = require("sdk/ui/button/toggle");

var button = ToggleButton({
    id: "panelButton",
    label: "panelButton",
    icon: {
        "16": "./button16.png",
        "32": "./button32.png",
        "64": "./button64.png" // data/button##.png in the addon.
    },
    onChange: showOrig
});

var newPanel = panels.Panel({
    width: 300,
    height: 400,
    contentURL: "./secondPanel.html", // data/secondPanel.html in the addon.
});

var origPanel = panels.Panel({
    width: 300,
    height: 400,
    contentURL: "./firstPanel.html", // data/firstPanel.html in the addon.
    contentScriptFile: "./firstPanel.js" // data/firstPanel.js in the addon.
});

function showOrig(state) {
    if(state.checked) {
        origPanel.show({
            position: button
        });
        origPanel.port.on("switchPanel", function() {origPanel.hide(); newPanel.show({position: button});});
        origPanel.port.on("showNewTab", function() {origPanel.hide(); require("sdk/tabs").open("");}); // The page you want to open
    }
}

firstPanel.html would have buttons (HTML buttons, input type=“button”) for showing the new panel and opening the tab. firstPanel.js would contain something like:

document.getElementsByTagName("button")[0].addEventListener("click",newPanel);
document.getElementsByTagName("button")[1].addEventListener("click",openTab);
// Assuming your first button is for the new panel, and second is for opening a new tab
// You can use any getElement such as getElementById if you have it setup.

function newPanel() {
    self.port.emit("switchPanel", "");
}

function openTab() {
    self.port.emit("showNewTab", "");
}

Hopefully that helps some. I may have typo’d, I didn’t test this code.

firstPanel.js

//document.addEventListener('DOMContentLoaded', function() {
document.getElementsByName("button")[0].addEventListener("click",newPanel);


//document.getElementsByName("button")[1].addEventListener("click",openTab);
// Assuming your first button is for the new panel, and second is for opening a new tab
// You can use any getElement such as getElementById if you have it setup.


function newPanel() {
    self.port.emit("switchPanel", "");
}

/*
function openTab() {
    self.port.emit("showNewTab", "");
}*/

/*index.js*/

var panels = require("sdk/panel");
var { ToggleButton } = require("sdk/ui/button/toggle");

var button = ToggleButton({
    id: "panelButton",
    label: "panelButton",
    icon: {
        "16": "./icon-16.png",
        "32": "./icon-32.png",
        "64": "./icon-64.png" // data/button##.png in the addon.
    },
    onChange: showOrig
});

var newPanel = panels.Panel({
    width: 300,
    height: 400,
    contentURL: "./secondPanel.html" // data/secondPanel.html in the addon.
});

var origPanel = panels.Panel({
    width: 300,
    height: 400,
    contentURL: "./firstPanel.html", // data/firstPanel.html in the addon.
    contentScriptFile: "./firstPanel.js" // data/firstPanel.js in the addon.
});

function showOrig(state) {
    if(state.checked) {
        origPanel.show({
            position: button
        });
        origPanel.port.on("switchPanel", function() {origPanel.hide(); newPanel.show({position: button});});
       // origPanel.port.on("showNewTab", function() {origPanel.hide(); require("sdk/tabs").open("https://discrouse.mozilla-community.org");}); // The page you want to open
    }
}

This is what is working thus far; I imagine I need to change the second button name to something else for the newtab function to work

Can you put it into code formatting? There should be a little button that looks like </> just highlight the code and click it.

<!--firstPanel.html-->

<!doctype html>

<head>
    <title>First Panel</title>
    </head>
    <body>
    <p>This is the first panel</p>
    <input type="button" name="button" value="Hello"/>
    
    </body>
    </html>

You need a second button there.

<html>
<body>
<p>First Panel</p>
<input type="button" name="button" value="New Panel"><!-- [0] -->
<input type="button" name="button" value="Open Tab"><!-- [1] -->
</body>
</html>

If the comments help.

Is it supposed to open several new tabs when I click the button again without closing the FF extension page?

I’m not sure why it’d doing that, but destroying the panel seems to fix it.

var panels = require("sdk/panel");
var { ToggleButton } = require("sdk/ui/button/toggle");
var newPanel;
var origPanel;

var button = ToggleButton({
    id: "panelButton",
    label: "panelButton",
    icon: {
        "16": "./icon-16.png",
        "32": "./icon-32.png",
        "64": "./icon-64.png" // data/icon-##.png in the addon.
    },
    onChange: showOrig
});

function createNewPanel() {
    newPanel = panels.Panel({
    width: 300,
    height: 400,
    contentURL: "./secondPanel.html" // data/secondPanel.html in the addon.
    });
}

function createOrigPanel() {
    origPanel = panels.Panel({
    width: 300,
    height: 400,
    contentURL: "./firstPanel.html", // data/firstPanel.html in the addon.
    contentScriptFile: "./firstPanel.js" // data/firstPanel.js in the addon.
    });
}

function showOrig(state) {
    if(state.checked) {
        createOrigPanel();
        origPanel.show({
            position: button
        });
        origPanel.port.on("switchPanel", function() {origPanel.hide();createNewPanel();newPanel.show({position: button});});
        origPanel.port.on("showNewTab", function() {origPanel.hide(); require("sdk/tabs").open("https://discourse.mozilla-community.org/t/button-that-opens-a-new-panel-and-another-button-that-opens-a-new-tab/3442");}); // The page you want to open
    }
    else {
        origPanel.destroy();
        newPanel.destroy();
    }
}

I’ve uploaded an example to github

https://github.com/Arenlor/feckless-fibula

Hey @TheOne you reviewers have any complaints about my solution?

That example looks ok to me.

1 Like

should it still work when I have locally saved data and external saved in terms of keep my saved data

I’m not sure what you’re asking.

something similiar to this

If you give an example of what you’re trying I can probably help.

The only time I see the panel hiding itself is when it opens a new tab. I tried both ways. I’d need to see your full code and everything to be able to help.