Get element of a newly opened & loaded window - Javascript - javascript

While being on a twitter account's page (let's say StackOverflow: https://twitter.com/stackoverflow), I'm trying to get the username of the account, then open a new window querying the account's username on google search. Finally I'd like to get the query text of the newly opened tab.
To do so, I did the following:
function getUserName(callback) {
url = window.location.href;
console.log(url);
sn = url.split("/").slice(-1)[0];
console.log(sn);
window.location.href = `https://google.com/search?q=${sn}`;
callback();
};
function getQuery() {
console.log(window.location.href);
}
getUserName(getQuery);
The problem is that it doesn't wait for the new page to be loaded and thus the console.log() form getQuery() is the twitter's one, instead of the google's.
I know this is a matter of callback and await/async, I've been reading a lot about it but those subjects are confusing me.

Just pass https://google.com/search?q=${sn} into a global variable and use that.
Like this:
let windowHref = window.location.href;
function getUserName(callback) {
url = window.location.href;
console.log(url);
sn = url.split("/").slice(-1)[0];
console.log(sn);
windowHref = `https://google.com/search?q=${sn}`;
window.location.href = windowHref;
callback();
};
function getQuery() {
console.log(windowHref);
}
getUserName(getQuery);

As far as getting the query text of the newly opened tab. You need make use of the callback function within your getUserName() function.
function getUserName(callback) {
url = window.location.href;
console.log(url);
sn = url.split("/").slice(-1)[0];
console.log(sn);
windowHref = `https://google.com/search?q=${sn}`;
callback(windowHref); // Sending back the url to the callback as parameter
};
function getQuery(queryText) { // Value returned from the callback.
console.log(queryText);
}
getUserName(getQuery);
I tried your scenario with linkedin: Sharing the snippets below:

Related

Is there a way to call a specific javascript function in a single js file for a specific page URL?

I have a question, i wanted to know if there is a way to call a specific function if a specific page URL is opened?
#shop_modal is in http://myurl/liste-boutique.php
#dep_modal is in http://myurl/index.php
Right now, i have Error when i try to open the #dep_modal because JS cant find #shop_modal on that page same page, so it does not execute below that.
I think AJAX can help figuring this out, otherwise i will have to split the code in 2 JS files, which i don't want to
const new_shop = $("#new_shop")[0];
const save_shop = $("#shop_form")[0];
const close_shop_modal = $("#close_shop_modal")[0];
const new_departement = $("#new_dep")[0];
const save_departement = $("#dep_form")[0];
const close_dep_modal = $("#close_dep_modal")[0];
// I want this to be called if the URL is http://my-URL/liste-boutique.php
new_shop.addEventListener('click', function(){
$("#shop_modal")[0].style.visibility = "visible";
})
// I want this to be called if the URL is http://my-URL/index.php
new_departement.addEventListener('click', function(){
$("#dep_modal")[0].style.visibility = "visible";
})
i need to ask question, but i don't know what to change here
Thanks again !!
You can check window.location.href. E.g.
if (window.location.href === 'http://my-URL/liste-boutique.php') {
new_shop.addEventListener('click', function(){
$("#shop_modal")[0].style.visibility = "visible";
});
}
Instead of checking the url, check if the element you want to find is on the page:
var $new_shop = $("#new_shop");
if ($new_shop.length > 0) {
var new_shop = $new_shop[0];
new_shop.addEventListener('click', function(){
$("#shop_modal")[0].style.visibility = "visible";
})
}
(I've used $ prefix on $new_shop to show it's a jquery object just for clarity)
Or, using your code as-is:
var new_shop = $("#new_shop")[0];
if (new_shop != undefined) {
new_shop.addEventListener...
Alternatively, if you use jquery, you don't need to worry about it as it will automatically not apply if the element doesn't exist:
$("#new_shop").click(() => { $("#shop_modal)").fadeIn(); });

Functions are not being executed as intended. I expect the page to switch to 'setup' but that doesn't happen

I'm creating a very basic log-in function on GAS HTML. In my HTML, I have a form that collects and stores user input with assigned variables (fn, ln, em, pw). It then sends the info to the sheet (which has formulas that verify the credentials) then a certain cell ('E2') will display "Found" or "Not Found". Then it will print the name in cell ('E1') if the if statement is false. This part does execute correctly, but the 2 functions, render('setup') and notFound() will not execute (regardless of when the if statement is true or false, neither one works.
I know the render('setup') function works perfectly fine in the doGet and when it is called in other functions.
function signIn(fn,ln,em,pw) {
var url = 'www.somelink.com'
var ss = SpreadsheetApp.openByUrl(url);
var login = ss.getSheetByName('login');
var fname = login.getRange('F1');
var lname = login.getRange('G1');
var email = login.getRange('H1');
var pword = login.getRange('I1');
fname.setValue(fn);
lname.setValue(ln);
email.setValue(em);
pword.setValue(pw);
var check = login.getRange('E2').getDisplayValue();
var name = login.getRange('F2').getDisplayValue();
if (check === "Not Found"){
return notFound(); // THIS DOESN'T EXECUTE
} else {
login.getRange('E1').setValue(name);
return render('setup'); // AND THIS DOESN'T EXECUTE
}
}
EDIT: HTML for the call signIn function.
<div class="button" align="center">
<button id="submit" class="btn waves-effect waves-light" onclick="var fn = document.getElementById('first_name').value;
var ln = document.getElementById('last_name').value;
var em = document.getElementById('email').value;
var pw = document.getElementById('password').value;
google.script.run.signIn(fn,ln,em,pw)">Submit
<i class="material-icons right">send</i>
</button>
If I understand you correctly, you want your web app to redirect the user to another HTML page after submitting the values, if some conditions are met.
You cannot do this by just calling a server-side function from the client-side: google.script.run is used to retrieve data that is not available on the client, but not to render a different HTML file.
What you could do instead is the following:
Instead of returning a function (like render or notFound), return a parameter that can be used on the client-side. For example, you could do:
function signIn(fn,ln,em,pw) {
// Rest of your code
if (check === "Not Found") {
return "notFound";
} else {
return "setup";
}
}
Your client-side function (which I've called callSignIn) can then pass this returned parameter to another function called redirect, thanks to withSuccessHandler(function) (this handler is necessary since google.script.run.signIn(fn,ln,em,pw) by itself will always return void):
function callSignIn() {
var fn = document.getElementById('first_name').value;
// Rest of your code
google.script.run.withSuccessHandler(refresh).signIn(fn,ln,em,pw);
}
Next, the value returned by signIn is passed as an argument of the function refresh, which refreshes the web app with window.open if the argument is setup, all the while passing setup as a query parameter (pageRedirect), which can later be used by the event parameter (you can retrieve the web app URL dynamically from the server-side instead of writing it manually — see this answer):
function refresh(redirectPage) {
if (redirectPage === "setup") {
window.open("https://script.google.com/macros/s/{your-web-app-id}/exec?pageRedirect=" + redirectPage, "_top");
} else {
// Whatever you want to do if "notFound"
}
}
Finally, back to the server-side, the function doGet gets called by the GET request from window.open. This function can check if there is a query parameter in the request via e.parameter, thanks to the event object, and render a different page depending on this parameter:
function doGet(e) {
if (!e.parameter.pageRedirect) {
return HtmlService.createHtmlOutputFromFile("index");
} else {
return HtmlService.createHtmlOutputFromFile(e.parameter.pageRedirect)
}
}
Reference:
Class google.script.run (Client-side API)
Window.open()
Web Apps: Request parameters

Empty response from XHR

I have a table which gets populated by results after the user has filtered them. Each result gets the user to a detail page. I want the user to go back to the search results without resetting the table. The 'back to results' button on the detail page has this JavaScript:
document.getElementById('back').onclick = function(e){
const newpage = window.open("index.html?fromDetail=yes", "_self");
newpage.onload = advancedSearchFromDetail()
}
And this is the JavaScript function which is executed once the destination page is reached:
function advancedSearchFromDetail () {
event.preventDefault()
var table = $('#mainTable').DataTable()
table.clear()
// Get the parameters in the sessionStorage
const pe1id = sessionStorage.getItem('pe1id');
const pe2id = sessionStorage.getItem('pe2id');
const plid = sessionStorage.getItem('plid');
const dateFrom = sessionStorage.getItem('dateFrom');
const dateTo = sessionStorage.getItem('dateTo');
const includeUndated = sessionStorage.getItem('includeUndated');
const data = new FormData()
data.append('pe1id', pe1id)
data.append('pe2id', pe2id)
data.append('plid', plid)
data.append('dateFrom', dateFrom)
data.append('dateTo', dateTo)
data.append('includeUndated',includeUndated)
const oReq = new XMLHttpRequest();
oReq.open("post", 'modules/advanced_search.xq', true);
oReq.send(data);
oReq.onreadystatechange = function () {
if (oReq.readyState === XMLHttpRequest.DONE && oReq.status === 200) {
const result = JSON.parse(oReq.responseText);
[populate the table]
}
}
The curious thing is that this code works when it is launched from the main page. All the parameters are there and get correctly sent. The response nevertheless is empty, blank. If I double click on the XHR details in my browser's console in order to open the .xq file with the parameters I even get the JSON results in a new page! What am I overlooking? I can't understand why it's not working if the parameters are there, the XHR call is there, I get 200 status and all that.
Edit
If I launch the function in the browser's console it works. Does this have to do something with the fact that I call the function with newpage.onload = advancedSearchFromDetail() then? If yes, how can I work around it?
OK, as I suspected, the issue appears to be how I call the function, i.e. via the .onload instruction. Therefore I appended a parameter to the URL if the user is coming from a 'detail' page, and added this JavaScript in the main page:
var urlParams = new URLSearchParams(window.location.search);
if (urlParams.has('fromDetail')) {
advancedSearchFromDetail()}
And I've delete the .onload instruction in the previous JavaScript. I'm not sure this is the best solution, if anyone has a better one please do comment here.

addPreSearch filter not applying

I am trying to use the addPreSearch function to add a custom filter to a lookup field, but the function does not seem to execute fully before the results of the lookup are displayed. The code for this looks something like this:
function onFieldChange(executionContext) {
var formContext = executionContext.getFormContext();
formContext.getControl("test_code").removePreSearch(testFunctionFilter);
formContext.getControl("test_code").addPreSearch(testFunctionFilter);
}
function testFunctionFilter(executionContext) {
var formContext = executionContext.getFormContext();
var record1 = formContext.getAttribute("test_record1_link").getValue(); //get linked record
var record1FullId, record1Id, stringRecordId, idLength, record1Guid = "0";
if (record1 != null) {
record1Id = record1[0].id;
record1Id = record1FullId.slice(1, -1);
stringRecordId = record1FullId.toString();
idLength = stringRecordId.length;
//Guid when retrieved from tablet does not have parenthesis on each end
if (idLength == 36) {
record1Guid = record1FullId;
} else {
record1Guid = recordId;
}
}
var fieldValue;
Xrm.WebApi.retrieveRecord("test_record1", record1Guid, "?$select=test_field1")
.then(function(result1) {
fieldValue = result1.test_field;
var options = generateOptions(executionContext, fieldValue); //creates option string using retrieved fieldValue
Xrm.WebApi.retrieveMultipleRecords("test_record2", options)
.then(function(result) {
var codes = getCodes(result2, fieldValue);
filter = generateFilter(codes, record1Guid); //creates custom filter using provided parameters
console.log(filter); //displays filter correctly
formContext.getControl("test_codelookup").addCustomFilter(filter, "test_coderecord"); //not working?
});
});
}
The filter is generated correctly using the functions used above whose definitions aren't shown. That isn't the issue. I've tried creating a separate test function where I hard coded one of the filters that the function above generated, and the lookup displayed the correct results. The testFunctionFilter should run to completion before the results of the lookup are displayed, correct? Because the filter is logged to the console after the results of the lookup appear. Are the nested asynchronous Xrm.WebApi calls somehow causing the issue? I'm not quite sure what is wrong. Please advise.
You are right. Xrm.WebApi calls are always Asynchronous, which is unusable in this case of adding dynamic filter using addCustomFilter.
You have to use XMLHttpRequest and make that call as Synchronous by setting third parameter as false like below:
var req = new XMLHttpRequest();
req.open("GET", Xrm.Utility.getGlobalContext().getClientUrl() +
"/api/data/v9.0/test_record1?$select=test_field1", false);
In order to work around the async delay, I think you're going to have to reorganise your code:
Add a form OnLoad event and execute the query to retrieve test_field1 and cache the results in a parameter
In the OnChange event, remove the presearch filter, re-execute the query to retrieve test_field1 and update the same parameter (from onload)
In testFunctionFilter use the cached results rather than building the presearch filter from scratch

Fast way to redirect tab when new page is loading

I'm trying to redirect a tab to a new page when the URL matches my pattern before it's done loading. The method I came up with does the redirection after a good part of the page is done loading yet.
var tabs = require("sdk/tabs");
var tab_utils = require("sdk/tabs/utils");
function logShow(tab) {
console.log(tab.url + " is loaded; " + pattern.test(tab.url));
if (pattern.test(tab.url)) {
var lowLevelTab = viewFor(tab);
console.log(tab_utils.setTabURL (lowLevelTab, newURL(tab.url)));
// also simply replacing this bit with
// tab.url = "foo" doesn't speed things up
}
}
tabs.on('load', logShow);
Is there a good way of calling setTabURL (...) earlier?
I finally found the best way to do it:
function listener(event) {
var channel = event.subject.QueryInterface(Ci.nsIHttpChannel);
var url = event.subject.URI.spec;
// Here you should evaluate the url and decide if make a redirect or not.
if (pattern.test(url)) {
// If you want to redirect to another url,
// you have to abort current request, see: [1] (links below)
channel.cancel(Cr.NS_BINDING_ABORTED);
// Set the current gbrowser object (since
// the user may have several windows/tabs)
var goodies = loadContextGoodies(channel);
var domWin = goodies.aDOMWindow; // method suggested by
var gBrowser = goodies.gBrowser; // Noitidart [2] (links below)
var browser = goodies.browser; // for reference see comment below
var htmlWindow = goodies.contentWindow;
// and load the fixed URI
browser.loadURI(newUrl(url));
} else {
// do nothing, let Firefox keep going on the normal flow
}
}
exports.main = function() {
events.on("http-on-modify-request", listener);
}
credit where credit is due: answer by matagus (on question asked by Andrew)
[1]: Link: Intercepting Page Loads
[2]: Noitidart: 'from topics: How can I change the User Agent in just one tab of Firefox? and Is it possible to know the target DOMWindow for an HTTPRequest?'
Never used sdk/tabs before, but you could load your content hidden.
Once your page has loaded your logShow function will run.
Then build into this function some "reveal body" functionality.

Categories