I want to store the current tab url in the following <input> field:
<input type="text" id="pdurl" value=>
The code I wrote in popup.js is the following:
chrome.tabs.query({active : true, currentWindow: true}, function (tabs) {
var tab = (tabs.length === 0 ? tabs : tabs[0]);
var activeTabUrl = tab.url;
});
document.getElementById("pdurl").innerHTML = var activeTabUrl;
I already have the tabs permission set in manifest file.
Your code is totally wrong. There are some serious problems, which would have been easy to avoid checking the popup console for errors. Here they are:
First of all chrome.tabs.query is an asynchronous method. This means that the code is evaluated and queued to be executed; when it executes, the callback function (which you're specifying as second argument) is called and executed. This means that the last line you wrote will always fail because the variable you want to use still doesn't exist (the query function hasn't still finished working).
You are creating a useless (and wrong (because you're assigning an array to it)) variable inside the callback: there's no need of your tab variable, because querying an active tab in the current window always returns a single tab, so you just need to use tabs[0].
Your activeTabUrl variable is defined with the var keyword, which will make it private, and you won't be able to use it outside the function (which is what you're trying to do in the last line, althought it's still wrong).
In the last line you are trying to assign the variable you created in the callback function to the innerHTML of your input: this statement is so wrong on so many levels I don't even know where to start: first of all if you want to actually see something in the text input you have to modify its value; secondly: the variable is not defined; plus, the var statement in your assignment makes it syntactically wrong; fourth: even doing all of the three previous conditions right you still are out of the callback.
Stated the above, this is the correct code for what you're trying to do:
chrome.tabs.query({active : true, currentWindow: true}, function (tabs) {
document.getElementById("pdurl").value = tabs[0].url;
});
I strongly recommend you to take a look at some JavaScript tutorial, and to check the console for errors* before asking questions like this one.
* Errors in the popup of an extension are shown in the popup console, which you can open right clicking on the extension's icon and choosing "Inspect popup".
Related
I have setup a Custom JavaScript variable that works intermittently. The function is simply designed to return true or false if a text is contained on the page.
The below code works fine when the page is loaded directly from the URL bar and when executed in the developer tools console. When running the function in the console, the function indeed turns true. When the code is executed within debug mode in GTM, the value returns false when a history change event occurs.
function() {
var content = document.body.innerText;
var query = "text to search";
if (content.search(query) > -1 ) {
return true;
} else {
return false;
}
}
Any assistance/insight is very much appreciated!
To me this seems like expected behavior. Since you are talking about history changes, you are probably working with a single page application, or some other page where the DOM is changed after the initial page load.
Custom Javscript variables evaluate a function and return the result each time you reference it. How I imagine the flow of operations goes is this.
Page Loads (target text is in the page body) -> Custom JS evaluates on page view and returns true -> User presses some button -> DOM is modified to display new content (target text is removed and no longer present -> History change occurs -> Custom JS evaluates again, the text is no longer present so returns false.
If the target text is still present after the history change, then I can understand why we have some unexpected behavior. The history change trigger is based off of the push state api so what could be happening is that the pushState() function is called before the DOM is finished being modified. In this case, the text isn't present at time of the history change event even though it is shortly afterwards.
You could change the page so pushState() is only called after the DOM is done being modified, use a custom event as a trigger instead (again, pushing it after the DOM is done being modified), or use a different trigger like the element visibility trigger that will only fire after the new DOM elements you want to target appear on-screen.
On Page A, I have a s.tl() call on click of "Link A" where I am filling evar1 and triggering off an event1. This link A leads to Page B
Code on link click in page A
$(document).on('click','.nav.navbar-nav.subnav-breadcrumb a',function(){
if($(this).text().toLowerCase().indexOf('create group')!=-1){
s.events = "event1";
s.linkTrackEvents = "event1";
s.eVar1 = "Step 1";
s.linkTrackVars = "eVar1,events";
s.tl(true,'o','Step 1');
}
});
On pageload of Page B, in the do Plugins sections, I try to get the value of eVar set in the prev s.tl() call by the following code
function s_doPlugins(s) {
console.log(s.getPreviousValue(s.eVar1,'cookie_name','event1')
}
However, I get the value as 'undefined'. Does getPreviousValue() plugin not work on previous s.tl() calls? What am I doing wrong here?
As mentioned in the documentation, since you are using the 3rd argument of s.getPreviousValue(), it will only store and trigger if the specified event is set (in both your case and doc example, that is event1).
Since you are setting event in the link click, s.getPreviousValue() triggers because s_doPlugins gets called on all s.t() and s.tl() calls, so at that point you should see the value in your cookie_name cookie (look in s_pers cookie if you are using combined cookie plugin).
However, on the next page (Page B) event1 isn't set, so when s_doPlugins gets called for the on-page s.t() call, s.getPreviousValue() will not update/return previous value.
In other words, when you specify an event in the 3rd argument, the plugin only triggers when the specified event is present in s.events. Basically first thing it does is check if 3rd arg exists then go through s.events and see if it's in there. If it's not, that's it, function ends with no return value (and that's why you get undefined returned).
I'm not sure what you're actually trying to accomplish but in my experience there aren't many use cases for specifying an event in the 3rd argument.
I came across a peculiar issue when trying to make an ajax call and isolate the actions of the function to itself. Here is the code snippet
$(document).on('click', 'input.action', function(event) {
var self = this;
$.ajax({
url:'http://date.jsontest.com/',
method:'GET',
cache:false,
dataType:'json',
success:self.process,
error:function(){self.process(false);}
});
self.process = function(data) {
if (data) {
alert(data.time);
}
else {
alert("Operation Failed!");
}
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="container">
<input type="button" value="Get Time" class="action"/>
</div>
Let me briefly explain what I am trying to do, on click of the button, I wish to receive some data from the server and display the data. I am using a process function to process the received data. In case of an error I reuse the process function in a different way to display the error message. I simply use the self variable to contain all the elements within the parent function. I fully understand the following:
What I know
I do not have to use the self to contain the process function because another method will not have access to it
Because the process method in the snippet above is declared after the ajax call for the program as far as it is concerned the process function is undefined.
I clearly know how to fix it.
Experiment:
Click on the Get Time button
Wait for as long as you want but see no result, which is expected because of the process function is declared after the ajax call
Click on the Get Time button again
It works now! Some time (which is probably not your time :P) is displayed now!!
What I wish to know:
What just happened? why does it work the second time and everytime after? Remember this only works for ajax calls, if it were the case that the assignment is retained in the function after calling it once, then this should work in every situation but it does not. Here is an experiment to show that it does not work the same way when ajax calls are not used: Fiddle - Experiment
The Solution:
I am adding a sample solution based on #Felix Kling's answer below. In the Sample Solution, there are two buttons Get Time and Get Date. I've attached the parameter to retrieve time in case of Get Time and date in the case of Get Date to the object self and it is interesting that once I click on Get Time nothing happens just like before but if I click on either Get Time or Get Date the second time only time is displayed.
What just happened?
In a simplified way, this:
var process;
// First click
ajaxCall(process); // process is still undefined
process = function() { ... };
// second click
ajaxCall(process); // process is defined
process = function() { ... };
The assignment to self.process "persists" between events because self refers to the same element.
Here is an experiment to show that it does not work the same way when ajax calls are not used: ...
It doesn't work in your fiddle because of one big difference: you are trying to execute process immediately. But it doesn't exist, so an error is thrown. At this point the script terminates and won't execute the rest of the function, where the function definition takes place.
In your example here, the execution of process is delayed. The script "doesn't know" that there is no function to call until the response was received.
There is nothing "special" going on here. Yes, accepted that the first time it returns undefined as it is yet to be defined.
But, you're attaching the function to the same element input.action. So, the next time, when you click the button, this already has the process method attached to it, so gets called when clicked again.
Try adding one more button with same class and click each once. Now though you've clicked the first button, clicking the second button will still not create an alert as it has not yet had the process function attached to it.
I've got a column with a URL set to execute a function on click, but when I click it, it goes adds a # to the end of the url instead of executing the function. The URL is registering as:
<a onclick='OpenLandLRegistration(1)' href='#'>Register</a>
Here's the javascript code:
function OpenLandLRegistration(event_id){
var eventurl ="/Lists/Events/DispForm.aspx?ID="+meeting_id;
var options = {
url:"/Lists/Attendees/Item/newifs.aspx?List=%7B9E2217C5%2DE878%2D406D%2DB25A%2D2FA7EAADFC17%7D&meeting_id="+meeting_id,
width: 750,
height: 600,
dialogReturnValueCallback: DialogCallback
};
//SP.SOD.execute('sp.ui.dialog.js', 'SP.UI.ModalDialog.showModalDialog', options);
window.open(eventurl);
}
function DialogCallback(dialogResult, returnValue){ }
EDIT:: Here is a working example of what I'm trying to do:
link
The javascript converts the link to html and the executes the function on click.
To prevent a link from firing, just add a return false; at the end of your OpenLandLRegistration() function.
Also the problem could be coming from the fact that in this example, at least, the meeting_id variable you're attempting concatenate with "/Lists/Events/DispForm.aspx?ID=" is undefined, so it'll throw a reference error and exit immediately.
Also worth noting that nothing is happening with options either, beyond it getting defined.
Have you heard of Firebug for Firefox? It's an excellent debugger for javascript that can really help you step through bugs as you work through things like this.
I have the following code in the popup.js of a chrome extension.
var tt;
chrome.tabs.query({ active: true, currentWindow: true, windowType: 'normal' },
function (tabs) {
tt = 5;
});
document.getElementById('elm').textContent = tt;
But the weird thing is value of tt is undefined when accessed out side of the function, but it shows "5" if the document.getElementById('elm').textContent = tt; is put inside the function. So why is the variable value is not retained when the control exit the function ?
What am I doing wrong here ?
This code runs when the popup is shown. I.e. when the browser action's button is clicked and I simplified the code be readable. Actually I'm trying to get the current tab's id in to a variable. But nothing works.
Just found the answer, if anyone ran into this again, this is what happened.
The chrome.tabs.query is an async operation so the callback function was called a little bit later. But the document.getElementById('elm').textContent = tt; line was executed before the callback was called and it caused the issue. When debugging this did not happen as the stepping through the code delays the execution of that line.