Open URL in certain Tab with Dojo - javascript

I have the following function where I attempt to load a specified url into a new or existing tab (contentPane), I have it working for the most part, however when an existing tab is specified the original url still gets reloaded instead of adding the new html, how can I accomplish the part where an existing tab is passed without having to remove the attribute refreshOnShow upon creating a new tab??
openTab = function(url,title, id){
var tab = dijit.byId(id);
var centerPane = dijit.byId('centerPane');
if (tab){
//if target container exists then let's load the url and add it to the container
centerPane.selectChild(tab);
$.get(url, function(data) {
$('#'+id).html(data);
});
centerPane.selectChild(tab);
} else {
var newTab = new dijit.layout.ContentPane(
{
'title': title,
href:url,
closable:true,
selected:true,
parseOnLoad:true,
preventCache:true,
refreshOnShow:true
}, id);
centerPane.addChild(newTab);
centerPane.selectChild(newTab);
}
};

So what you are doing is basically saying, when this tab is re-opened, let me append my content, and dojo is saying, 'I just opened this tab, and refreshOnShow is true, so let me go get my content from the server again'.
I think the cleanest way to get around that is to do as you say and set refreshOnShow to false. Why do you have it set to true, does the tab have content that needs to be refreshed consistently from the server?
If what you want is something like this (for an existing tab):
User clicks
Dojo goes and refreshes existing tab content
Your manual (jquery based) handler goes and gets some other content
and appends it to (or otherwise uses it with) the content dojo
automatically refreshed
Then you should be able to do something like this:
newTab.connect(newTab, 'onLoad', function(){
// do my stuff after the dojo content has loaded
})
Which just adds an event handler to the contentpane for your tab that fires after the tab has gone to the server for its content.

This is how my updated function looks, it works for me:
openTab = function(url,title, id){
var tab = dijit.byId(id);
var centerPane = dijit.byId('centerPane');
if (tab){
//if target container exists then let's load the url and add it to the container
tab.href = url;
tab.set('title',title);
centerPane.selectChild(tab);
} else {
var newTab = new dijit.layout.ContentPane(
{
'title': title,
href:url,
closable:true,
selected:true,
parseOnLoad:true,
preventCache:true,
refreshOnShow:true
}, id);
centerPane.addChild(newTab);
centerPane.selectChild(newTab);
}
};

Related

window.open remove reference from parent

I have one page with list of reports and after clicking on report it redirects me to internal report page in new tab with:
window.open(reportIdUrl,reportId);
So when i am back on report list and i want to open same report i will use
window.open("",reportId);
if(redirect.location.href === "about:blank" || redirect.location.href !== '<internalreportpage>') {
redirect = window.open(reportUrl,reportId);
redirect.focus();
} else {
redirect.focus();
}
But when someone from new tab with internal report page navigates somehow to report list page (within this tab) and then tries to open internal report page it will open it in same tab as it is tab reference not content reference.
Does anybody know some way to drop reference when i access if condition?
Something like:
window.open("",reportId);
if(redirect.location.href === "about:blank" || redirect.location.href !== '<internalreportpage>') {
window.dropReference(reportId) //change_me
redirect = window.open(reportUrl,reportId);
redirect.focus();
} else {
redirect.focus();
}
So it will create new tab with new reportId reference?
Thanks
EXAMPLE
--reportlistpage
linkToReport1 (window.open(report1Url,1))
linkToReport2 (window.open(report2Url,2))
.
.
.
You click on linkToReport1 - 2 tabs are opened. One with reportlistpage and one with internal-report/report1.
You go back to parent tab and click to linkToReport1. Tab is opened with reference to "1" and will focus to it and no new tab is opened (this is ok).
You are on linkToReport1 and you redirect with some menu hyperlink to reportlistpage (within linkToReport1 tab). Url changed to /report-list
You click to linkToReport1. Nothing happen (this is not ok) because you are on the tab with reference to 1 (content and url changed), now you want to open a new tab with /internal-report/report1 url and store it as 1 with window references.
I figured it out. It is bit simple when you realize you can set or reset window.name. So there is nothing like references from parent.
Based on content you can do something following. In the page you want to keep track in tab,
at the beginning (in my case internalReport id):
var currentWindow = window.self;
currentWindow.name = reportId; //this is in case someone manually opened it without window.open(internalReportUrl, reportId)
then bind resetting of window.name on beforeunload event (e.g.):
var resetWindowName = function() {
var currentWindow = window.self;
currentWindow.name = ""
}
window.addEventListener('beforeunload', resetWindowName);
So when you redirect from internalreportpage somewhere, name is cleared and you can repeadetly call
window.open(internalReportUrl,reportId)
which will open new tab for you.

How to detect url change in a new browser tab and get back the url?

I have a link that will open a url in a new tab like this:
<span data-bind="text: connectorLoginLink, visible: shouldShowConnectorLoginLink, click: openTeamViewerUrl"></span>
As I want to detect the URL change in the new tab, I thought I had to use window.open(url) to open this link. Then, keep track of the new window.
In viewmodel:
public openTeamViewerUrl() {
var newWindow = window.open('http://www.google.com', '_blank', 'location=yes');
}
I want to set the opened tab to a newWindow object, then monitor it by using something like this:
var currentPage = newWindow.location.href;
setInterval(function () {
console.log(currentPage);
if (currentPage !== newWindow.location.href) {
// page has changed, set new page as 'current'
currentPage = newWindow.location.href;
console.log(currentPage);
// do other thing...
}
}, 1000);
I got the error back when trying window.open: Blocked opening 'http://www.google.com/' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.
Really got stuck on this. How to by pass the allow-popups? Can this feature be achieved using other methods?
To detect a change of URL you can use javascript unload event on the window, see https://developer.mozilla.org/en-US/docs/Web/Events/unload
window.addEventListener('unload', function(event) {
console.log('Navigation occuring');
});

How to set the title for the new browser tab?

I have a question about the new tab for the link.
Is there anyway I can set the browser tab title before user clicks a link? It seems like there is no way to debate the title for the new tab if the html contained in the new tab doesn't have title attribute. Am I right? How do I set the title?
//the href is dynamic so I can't set them one by one because I have 100+ html file here
<a href="test.html" target="_blank">open me<a>
As you have it, this is not possible because your links are just normal HTML links. When the new page opens in a new tab, the current page will not have any reference to it and so cannot change it in any way. You will need to open the page using javascript and set the title that way.
You can dynamically set this up in window onload to find all a tags and add a click event whihc opens the window and sets the title.
If you want different titles for each page, you can store this in a data- attribute in the a tag.
Note tho that this will only work with pages in the same domain (for security), and that it does not handle people right clicking and pressing "Open in New Window". Middle click in Windows does seem to work however.
HTML
open me
JavaScript
window.addEventListener("load", function() {
// does the actual opening
function openWindow(event) {
event = event || window.event;
// find the url and title to set
var href = this.getAttribute("href");
var newTitle = this.getAttribute("data-title");
// or if you work the title out some other way...
// var newTitle = "Some constant string";
// open the window
var newWin = window.open(href, "_blank");
// add a load listener to the window so that the title gets changed on page load
newWin.addEventListener("load", function() {
newWin.document.title = newTitle;
});
// stop the default `a` link or you will get 2 new windows!
event.returnValue = false;
}
// find all a tags opening in a new window
var links = document.querySelectorAll("a[target=_blank][data-title]");
// or this if you don't want to store custom titles with each link
//var links = document.querySelectorAll("a[target=_blank]");
// add a click event for each so we can do our own thing
for(var i = 0; i < links.length; i++) {
links[i].addEventListener("click", openWindow.bind(links[i]));
}
});
Sample JsFiddle
You can pass the title with hash and get it on another page, if this another page is yours and you can modify its code.
1st page:
...
<a href="test.html#the_title_you_want" target="_blank">open me<a>
...
2nd page - modify the body opening tag like this:
<body onload="document.title=window.location.hash.replace('#','');">
If the page you are linking to isn't yours, you can use window.open method:
open me
I have not seen addEventListener work reliably, especially when opening a new page using javascript. The best way to change the tab title and have it work reliably is to set a timeout until the page loads. You may have to play with the timeout value, but it works.
var newWindow = window.open(url, '_blank');
setTimeout(function () {
newWindow.document.title = "My Tab Name";
}, 100);
You have two options. Using pure HTML, you can let the user open up links, then later on change the title. Or you can change the title with inline JavaScript. Here's how you do both:
Method 1
Change your links by assigning a target attribute, and then later on use that window name to control the document. For instance in your links it would be: <a href="whatever" target="theNewWindow">. Whenever you want to change the title for this page, you'd use JavaScript as such: window.open("", "theNewWindow").document.title = "New Page Title!"; The problem with this method however is that all links with that target/window name will open in that same window. In addition, after the first time the link is clicked, your browser won't automatically switch to the new tab/window.
Method 2
Change your links by assigning an onclick attribute, which would open the link manually and change the title of the page immediately. Basically it would come down to look like: <a href="whatever" onclick="var w=window.open(this.href, '_blank'); (w.onload=function(){w.document.title='New Page Title!';})(); return false;">. This opens the window based on the href attribute, immediately changes the title, and sets the window to change the title to that when it finishes loading (just in case there really was a title tag).
The problem with both of these methods (as mentioned by others) is your html files have to be on the same domain.
The simplest way is a follows:
var winTab = window.open("", "_blank")
//Open URL by writing iframe with given URL
winTab.document.write("write iframe with your url in src here")
//Set Title for the new tab
winTab.document.title = "Form Title"
You could make your own Page 2 that opens up the other pages (the ones you can't edit), in a frameset. You can then either change the title dynamically when loading your page 2, or as others have suggested if you use window.open you can control the title from the parent page.
If you are in page 1, and opening page 2 in a new tab, you can't set title for page 2 from page 1.
If you have access to page 2 then it's possible, otherwise not.

Get title of child window after it loads fully

I need to detect changes in the title of a window for OAuth.
I have a link that opens the authentication page in a new window, and I'm just trying to pull the title data. However, for some reason the page doesn't load until all my code executes so the title it finds is just an empty string.
$("#signon").on("click", function () {
var url = $(this).data('authurl');
var handle = window.open(url);
var title = window.document.title;
var title2 = handle.document.title;
});
title is fine, but title2 is null and the handle window hasn't loaded.
I've tried .ready, .onload, .load, and an eventListener, but none of them made a difference.
Why isn't the child window loading any data until this code completes?

how to resume script when new window loads

I am writing an page action extension for Google Chrome. The extension injects the following script into a search page after it loads. After the script finds all the occurrences of class "f_foto" (typically 10 items), it finds the first link in each of them, puts these hrefs in an array and then iterates thru the array opening a new window for each link and examining the result. That's what it is supposed to do.
Everything works ok in this code except the last part. The new window opens in a new tab (I have tabs permission) but it only finishes loading after the script finishes. Each new window overwrites the previous one in the same tab which would be ok if I had a chance to examine the contents first. So if I run it without using the debugger when the script finishes the new tab contains the last item in the array and focus is on the new tab. As far as I can see, handleResponse is never called.
If I run it in the DOM inspector and stop it at window.open, I can see that the new tab opens with "About Blank" in the title and the tab shows a spinning thingy showing that it is loading. Stepping thru the code, detailWin remains undefined even after detailWin=window.open(profileLinks[i], "Detail Window"); is executed. I've tried replacing window.onload = handleResponse; with detailWin.onload =handleResponse; but in this case detailWin is undefined.
It seems to me I need to add an event listener that fires when the new window is loaded and executes handleResponse. Yes? No?
//PEEK.JS//
var req;
var detailWin;
var profileLinks = new Array();
function handleResponse()
{
// var contentDetail = document.getElementsByClassName("content");
alert("Examine Detail Page Here");
};
//drag off the f_foto class
var searchResult = document.getElementsByClassName("f_foto");
alert("Found Class f_foto "+searchResult.length+" times.");
//collect profile links
for (var i = 0; i<searchResult.length; ++i)
{
var profileLink=searchResult[i].getElementsByTagName("a");
profileLinks[i]=profileLink[0].href;
// alert(i+1+" of "+searchResult.length+" "+profileLinks[i]+" length of "+profileLinks[i].length);
}
for (var i = 0; i<searchResult.length; ++i)
{
//DYSFUNCTIONAL CODE: New window finishes loading only after script completes, how to execute handleResponse?
detailWin=window.open(profileLinks[i], "Detail Window");
window.onload = handleResponse;
}
Option #1: make two separated content scripts - one for the search page only, one for the profile page only. Search script would only open profile link, profile script would only process it (contains code inside your handleResponse())
Option #2 If for some reasons you don't want to inject profile script to all profile pages, only to those you opened yourself from the search page, then instead of opening windows from a content script you should send a message to a background page asking it to open a profile link in a new tab and inject your profile script.
You still will have two content scripts.
search.js (injected to search pages only):
//PEEK.JS//
var req;
var detailWin;
//drag off the f_foto class
var searchResult = document.getElementsByClassName("f_foto");
alert("Found Class f_foto "+searchResult.length+" times.");
//collect profile links
for (var i = 0; i<searchResult.length; ++i)
{
var profileLink=searchResult[i].getElementsByTagName("a");
profileLinks[i]=profileLink[0].href;
// alert(i+1+" of "+searchResult.length+" "+profileLinks[i]+" length of "+profileLinks[i].length);
}
for (var i = 0; i<searchResult.length; ++i)
{
//tell bkgd page to open link
chrome.extension.sendRequest({cmd: "openProfile", url: profileLinks[i]});
}
profile.js (will be injected to profile pages you opened)
var contentDetail = document.getElementsByClassName("content");
alert("Examine Detail Page Here");
background.html:
chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
if(request.cmd == "openProfile") {
chrome.tabs.create({url: request.url}, function(tab){
//profile tab is created, inject profile script
chrome.tabs.executeScript(tab.id, {file: "profile.js"});
});
}
});
Option #3: Maybe you don't need to create profile window at all? If all you need is to find something in the page source, then you can just load that page through ajax and parse it (you would need to do it in a background page).

Categories