Run function after each() jQuery - javascript

I know that the each() in jQuery is synchronous, but it doesn't seem to behaving that way. When I do this:
$('#findRankBtn').click(function () {
var websiteURL = $('#websiteURL').val();
var searchTerms = $('#searchTerm').val();
var pageNumber = $('#currentPage').val();
//INSERTS A + FOR EVERY SPACE
var searchTerms = searchTerms.replace(" ", "+");
searchGoogle(searchTerms, pageNumber, websiteURL);
});
function searchGoogle(searchTerms, pageNumber, websiteURL) {
$.getJSON("https://www.googleapis.com/customsearch/v1?key=AIzaSyDPuIrijE0IQ6330vMLN2p-L_4J6y_G60c&cx=013036536707430787589:_pqjad5hr1a&q=" + searchTerms + "&alt=json&start=" + pageNumber,
function (recievedData) {
//console.log(recievedData);
$.each(recievedData.items, function (i, item) {
$('#resultsDiv').append('<p class="resultLink">' + item.link + '</p>');
var linkAddress = $('.resultLink:last').text();
if (linkAddress.indexOf(websiteURL) !== -1) {
alert('found');
$('.resultLink:last').attr('class', 'yourLink');
$('#ifFound').attr('value', 'true');
}
});
var ifFound = $('#ifFound').val();
var currentPage = $('#currentPage').val();
var nextPage = CurrentPage + 1;
if (ifFound == 'false') {
//INCREMENT PAGE
$('#currentPage').attr('value', nextPage);
//GRAB DATA AGAIN
var websiteURL = $('#websiteURL').val();
var searchTerms = $('#searchTerm').val();
//INSERTS A + FOR EVERY SPACE
var searchTerms = searchTerms.replace(" ", "+");
//SEARCH GOOGLE
searchGoogle(searchTerms, nextPage);
}
});
}
Basically if it doesn't find the desired link on the first page of results, it should go on to the next page. I have a working fiddle for just the first page here: http://jsfiddle.net/p8DY3/1/
so how can I get searchGoogle() to run until it finds what it's looking for?
Maybe there's a better way of going about it that's in the Google API that I don't know about?
Sorry if my question is amateur, I've only begun to learn JavaScript on my own a month ago.

First you should make sure you are not hitting some sort of rate limit from Google. Look at your Network tab to see if the requests are coming back correctly.
First issue I see is bad math.
var currentPage = $('#currentPage').val(); is a string
Here var nextPage = CurrentPage + 1; you are treating it as a number.
You got to convert the string to a number before you add to it. You are doing string concatenation!.
var nextPage = parseInt(CurrentPage,10) + 1;
NITPICKS
Do not store things in inputs. Use variables, it will make things go so much faster. DOM lookup/manipulation is slow.
Why are you reinventing addClass and val()
$('.resultLink:last').attr('class', 'yourLink');
$('#currentPage').attr('value', nextPage);
should be
$('.resultLink:last').addClass('yourLink');
$('#currentPage').val(nextPage);
Why are you grabbing the search terms and website url again? You already have them passed into the function?
Finally your problem
searchGoogle(searchTerms, nextPage); <-- What are you missing here?
function searchGoogle(searchTerms, pageNumber, websiteURL) { <--what it is expecting
You are passing in 2 things when it wants 3.

Related

Javascript ID Extracted From String Not Working

Here's the situation:
function STP() { var LOC = window.location.href;
var CSV = LOC.substring(LOC.indexOf(',')+1);
var ARR = CSV.split(',');
var STR = ARR[ARR.length -1 ];
var POS = window.document.getElementById(STR).offsetTop;
alert( STR ); };
Explained:
When the page loads, the onload calls the script.
The script gets the location.href and Extracts the element ID by
creating an array and referencing the last one.
So far so good.
I then use that to reference an element ID to get its position.
But it doesn't work.
The STR alert indicates the proper value when it's placed above POS, not below. The script doesn't work at all below that point when the STR var reference is used.
However if I do a direct reference to the ID ('A01') no problem.
Why does one work and not the other when both values are identical? I've tried other ways like using a hash instead of a comma and can extract the value that with .location.hash, but it doesn't work either.
The problem is that when you do
LOC.substring(LOC.indexOf(',') + 1);
you're putting everything after the , into the CSV variable. But there is a space between the comma and the 'A01'. So, the interpreter reduces it to:
var POS = window.document.getElementById(' A01').offsetTop;
But your ID is 'A01', not ' A01', so the selector fails.
function STP() {
var LOC = 'file:///M:/Transfers/Main%20Desktop/Export/USI/2018/Catalog/CAT-Compilations-01a.htm?1525149288810, A01';
var CSV = LOC.substring(LOC.indexOf(',') + 1);
var ARR = CSV.split(',');
var STR = ARR[ARR.length - 1];
console.log(`'${STR}'`);
}
STP();
To solve this, you can increase the index by one:
LOC.substring(LOC.indexOf(',') + 2);
But it would probably be better not to put spaces in URLs when not necessary - if possible, send the user to 'file:///M:/Transfers/Main%20Desktop/Export/USI/2018/Catalog/CAT-Compilations-01a.htm?1525149288810,A01' instead.

Removing parameter values of a url in the next page using javascript only

I need to remove the values from the url after the ? in the next page the moment i click from my first page. I tried a lot of coding but could not get to a rite path. Need help.
The strings ex- Name, JobTitle and Date are dynamically generated values for ref.
Below are the links associated with the code:
Required url
file:///C:/Users/varun.singh/Desktop/www%20updated%2027.8.2015%20Old/www/Candidates/newOne.html?
Resultant url:
file:///C:/Users/varun.singh/Desktop/www%20updated%2027.8.2015%20Old/www/Candidates/newOne.html?Name=Name%201&JobTitle=Title%201&Date=Entered%20Date%201
listItem.onclick = function(){
var elementData=listData[this.id];
var stringParameter= "Name=" + elementData.name +"&JobTitle="+elementData.job_title+"&Date="+ elementData.entered_date;
//window.location.href = window.location.href.replace("ListCandidateNew", "newOne") + "?" + stringParameter;
window.location.href="file:///C:/Users/varun.singh/Desktop/www%20updated%2027.8.2015%20Old/www/Candidates/newOne.html?"
+ stringParameter;
}
This should work:
var url = file:///C:/Users/varun.singh/Desktop/www%20updated%2027.8.2015%20Old/www/Candidates/newOne.html?Name=Name%201&JobTitle=Title%201&Date=Entered%20Date%201
var index = url.lastIndexOf("?");
url = url.slice(0, index+1); // index+1 so that "?" is included
Thanks everond for trying and attempting to answer my problem. Well, i have found the solution using window.sessionStorage as i wanted by keeping the string parameter alive to pass the values. Here is the full code:
I have two pages for passing the value from one to another: ListCandidateNew.html and newOne.html
ListCandidateNew.html
listItem.onclick = function()
{
var elementData=listData[this.id];
var stringParameter= "Name=" + elementData.name +"&JobTitle="+elementData.job_title+"&Date="+ elementData.entered_date;
window.sessionStorage['Name'] = elementData.name;
window.sessionStorage['JobTitle'] = elementData.job_title;
window.sessionStorage['Date'] = elementData.entered_date;
**newOne.html**
function LoadCandidateDetail()
{
document.getElementById('Name').innerHTML = window.sessionStorage['Name'];
document.getElementById('JobTitle').innerHTML = window.sessionStorage["JobTitle"];
document.getElementById('Date').innerHTML = window.sessionStorage["Date"];
}

Updating a ScriptProperty to avoid retrieving duplicate Twitter statuses

I was interested in writing a twitter bot to help out some friends at a local ski resort. I found this tutorial from Amit Agarwal which gave me enough to get started (it did take me more than 5 minutes since I did a lot of modifying). I host the script on google docs.
FIRST I think this is javascript (my understanding is that google apps script uses javascript...) and when I have had problems with the code so far, google searches for javascript-such-and-such have been helpful, but if this is not actually javascript, please let me know so I can update the tag accordingly!
I have no prior experience with javascript, so I am pretty happy that it's actually working. But I want to see if I'm doing this right.
The start function initiates the trigger, which kicks off the fetchTweets() function every interval (30 minutes). In order to avoid duplicates (the first errors I encountered) & potentially being flagged as spam, I needed a way to ensure that I was not posting the same tweets over and over again. Within the start() function, the initial since_id value is assigned:
ScriptProperties.setProperty("SINCE_TWITTER_ID", "404251049889759234");
Within the fetchTweet() function, I think I am updating this property with the statement:
ScriptProperties.setProperty("SINCE_TWITTER_ID", lastID + '\n');
Is this a good way to do this? Or is there a better/more reliable way? And if so, how can I be sure it's updating the property? (I can check the log file and it seems to be doing it, so I probably just need to create a permanent text file for the logger).
Any help is greatly appreciated!!
/** A S I M P L E T W I T T E R B O T **/
/** ======================================= **/
/** Written by Amit Agarwal #labnol on 03/08/2013 **/
/** Modified by David Zemens #agnarchy on 11/21/2013 **/
/** Tutorial link: http://www.labnol.org/?p=27902 **/
/** Live demo at http://twitter.com/DearAssistant **/
/** Last updated on 09/07/2013 - Twitter API Fix **/
function start() {
Logger.log("start!" + '\n')
// REPLACE THESE DUMMY VALUES
// https://script.google.com/macros/d/18DGYaa-jbaAK9rEv0HZ2cMcWjFGgkvVcvr6TfksMNbbu2Brk3gZeZ46R/edit
var TWITTER_CONSUMER_KEY = "___REDACTED___";
var TWITTER_CONSUMER_SECRET = "___REDACTED___";
var TWITTER_HANDLE = "___REDACTED___";
var SEARCH_QUERY = "___REDACTED___" + TWITTER_HANDLE;
// Store variables
ScriptProperties.setProperty("TWITTER_CONSUMER_KEY", TWITTER_CONSUMER_KEY);
ScriptProperties.setProperty("TWITTER_CONSUMER_SECRET", TWITTER_CONSUMER_SECRET);
ScriptProperties.setProperty("TWITTER_HANDLE", TWITTER_HANDLE);
ScriptProperties.setProperty("SEARCH_QUERY", SEARCH_QUERY);
ScriptProperties.setProperty("SINCE_TWITTER_ID", "404251049889759234");
// Delete exiting triggers, if any
var triggers = ScriptApp.getScriptTriggers();
for(var i=0; i < triggers.length; i++) {
ScriptApp.deleteTrigger(triggers[i]);
}
// Setup trigger to read Tweets every 2 hours
ScriptApp.newTrigger("fetchTweets")
.timeBased()
.everyMinutes(30)
//.everyHours(2)
.create();
}
function oAuth() {
//Authentication
var oauthConfig = UrlFetchApp.addOAuthService("twitter");
oauthConfig.setAccessTokenUrl("https://api.twitter.com/oauth/access_token");
oauthConfig.setRequestTokenUrl("https://api.twitter.com/oauth/request_token");
oauthConfig.setAuthorizationUrl("https://api.twitter.com/oauth/authorize");
oauthConfig.setConsumerKey(ScriptProperties.getProperty("TWITTER_CONSUMER_KEY"));
oauthConfig.setConsumerSecret(ScriptProperties.getProperty("TWITTER_CONSUMER_SECRET"));
}
function fetchTweets() {
oAuth();
// I put this line in to monitor whether the property is getting "stored" so as to avoid
// reading in duplicate tweets.
Logger.log("Getting tweets since " + ScriptProperties.getProperty("SINCE_TWITTER_ID"))
var twitter_handle = ScriptProperties.getProperty("TWITTER_HANDLE");
var search_query = ScriptProperties.getProperty("SEARCH_QUERY")
Logger.log("searching tweets to " + search_query + '\n');
// form the base URL
// restrict to a certain radius ---:
//var search = "https://api.twitter.com/1.1/search/tweets.json?count=5&geocode=42.827934,-83.564306,75mi&include_entities=false&result_type=recent&q=";
// unrestricted radius:
var search = "https://api.twitter.com/1.1/search/tweets.json?count=5&include_entities=false&result_type=recent&q=";
search = search + encodeString(search_query) + "&since_id=" + ScriptProperties.getProperty("SINCE_TWITTER_ID");
var options =
{
"method": "get",
"oAuthServiceName":"twitter",
"oAuthUseToken":"always"
};
try {
var result = UrlFetchApp.fetch(search, options);
var lastID = ScriptProperties.getProperty("SINCE_TWITTER_ID");
if (result.getResponseCode() === 200) {
var data = Utilities.jsonParse(result.getContentText());
if (data) {
var tweets = data.statuses;
//Logger.log(data.statuses);
for (var i=tweets.length-1; i>=0; i--) {
// Make sure this is a NEW tweet
if (tweets[i].id > ScriptProperties.getProperty("SINCE_TWITTER_ID")) {
lastID = (tweets[i].id_str);
var answer = tweets[i].text.replace(new RegExp("\#" + twitter_handle, "ig"), "").replace(twitter_handle, "");
// I find this TRY block may be necessary since a failure to send one of the tweets
// may abort the rest of the loop.
try {
Logger.log("found >> " + tweets[i].text)
Logger.log("converted >> " + answer + '\n');
sendTweet(tweets[i].user.screen_name, tweets[i].id_str, answer.substring(0,140));
// Update the script property to avoid duplicates.
ScriptProperties.setProperty("SINCE_TWITTER_ID", lastID);
Logger.log("sent to #" + tweets[i].user.screen_name + '\n');
} catch (e) {
Logger.log(e.toString() + '\n');
}
}
}
}
}
} catch (e) {
Logger.log(e.toString() + '\n');
}
Logger.log("Last used tweet.id: " + lastID + + "\n")
}
function sendTweet(user, reply_id, tweet) {
var options =
{
"method": "POST",
"oAuthServiceName":"twitter",
"oAuthUseToken":"always"
};
var status = "https://api.twitter.com/1.1/statuses/update.json";
status = status + "?status=" + encodeString("RT #" + user + " " + tweet + " - Thanks\!");
status = status + "&in_reply_to_status_id=" + reply_id;
try {
var result = UrlFetchApp.fetch(status, options);
Logger.log("JSON result = " + result.getContentText() + '\n');
}
catch (e) {
Logger.log(e.toString() + '\n');
}
}
// Thank you +Martin Hawksey - you are awesome
function encodeString (q) {
// Update: 09/06/2013
// Google Apps Script is having issues storing oAuth tokens with the Twitter API 1.1 due to some encoding issues.
// Henc this workaround to remove all the problematic characters from the status message.
var str = q.replace(/\(/g,'{').replace(/\)/g,'}').replace(/\[/g,'{').replace(/\]/g,'}').replace(/\!/g, '|').replace(/\*/g, 'x').replace(/\'/g, '');
return encodeURIComponent(str);
// var str = encodeURIComponent(q);
// str = str.replace(/!/g,'%21');
// str = str.replace(/\*/g,'%2A');
// str = str.replace(/\(/g,'%28');
// str = str.replace(/\)/g,'%29');
// str = str.replace(/'/g,'%27');
// return str;
}
When you use ScriptProperties.setProperty("KEY", "VALUE");, internally Script Properties will overwrite a duplicate key (i.e., if an old Property has the same key, your new one will replace it). So in your case, since you are using the same identifier for the key (SINCE_TWITTER_ID), it will replace any previous Script Property that is that key.
Furthermore, you can view Script Properties via File -> Project properties -> Project properties (tab). Imo Google didn't name that very well. User properties as specific to Google users. Script properties as specific to the Script Project you are working under.
Also, it probably isn't a good idea to include \n in your value when you set the property. That will lead to all sorts of bugs down the road, because you'll have to compare with something like the following:
var valToCompare = "My value\n";
instead of:
var valToCompare = "My value";
because the value in SINCE_TWITTER_ID will actually be "some value\n" after you call your fetchTweet() function.
Of course, one seems more logical I think, unless you really need the line breaks (in which case you should be using them somewhere else, for this application).
Its ok like that thou I dont know why you are adding \n at fhe end. Might confuse other code. You can see script properties in the script's file menu+ properties

Improve this search engine detecter with javascript

I have the following code which detects which search engine and what search term has been used:
if (document.referrer.search(/google\.*/i) != -1) {
var start = document.referrer.search(/q=/);
var searchTerms = document.referrer.substring(start + 2);
var end = searchTerms.search(/&/);
end = (end == -1) ? searchTerms.length : end;
searchTerms = searchTerms.substring(0, end);
if (searchTerms.length != 0) {
searchTerms = searchTerms.replace(/\+/g, " ");
searchTerms = unescape(searchTerms);
alert('You have searched: '+searchTerms+' on google');
}
}
That actually works, but unfortunately it doesn't work as expected sometimes.
Sometimes if the referrer was even not google i get an alert with the search term as : ttp://www.domain.com ( without H at the start ) i think that may lead to the bug.
Appreciate any help!
Have you tried leveraging existing JS URL parsing schemes? It might save you a bunch of time. For example:
http://blog.stevenlevithan.com/archives/parseuri
It's cutting the "h" off because q= was not in the referrer string. So your start variable is -1. Then you add 2 to that to get your searchTerms var with a substring. You need to check for start to be equal to -1 and return.
I also think your "google" string detection is not bulletproof, I would rather do something like this...
var ref = document.referrer;
var pcol = ref.indexOf("://") + 3;
if(ref.indexOf("google.com") == pcol || ref.indexOf("www.google.com") == pcol) {
// It is google
}
One last thing, you should use decodeURIComponent instead of unescape.

Is this JavaScript encoding properly written?

I have tried some tips I was given on regards URL encoding but I have no success so far. First, I was given this format,
var url = "http://www.polyvore.com/cgi/add?title="
+ encodeURIComponent(%%GLOBAL_ProductName%%)
+ "&url=" + encodeURIComponent("http://lilaboutique.co.uk/products/"
+ encodeURIComponent(%%GLOBAL_ProductName%%)
+ "&imgurl=" + encodeURIComponent(%%GLOBAL_ThumbImageURL%%)
+ "&desc=" + encodeURIComponent(%%GLOBAL_ProductDesc%%)
+ "&price=" + encodeURIComponent(%%GLOBAL_ProductPrice%%));
which never got to be passed to the href dunno for what reason. Then I played with it some more,
var url = "http://www.polyvore.com/cgi/add?title=encodeURIComponent(%%GLOBAL_ProductName%%)&url=http://lilaboutique.co.uk/products/encodeURIComponent(%%GLOBAL_ProductName%%)&imgurl=encodeURIComponent(%%GLOBAL_ThumbImageURL%%)&desc=encodeURIComponent(%%GLOBAL_ProductDesc%%)&price=encodeURIComponent(%%GLOBAL_ProductPrice%%)";
this time the URL was passed but the values were mixed between the appropriate and other fields displaying the encoding function itself.
Any help clarifying my mistakes is greatly appreciated. I would like to encode just price and description, seems to be the fields giving problems.
A regular link does render without problems
var url = "www.google.com";
var myAnchor = document.getElementById('myAnchor');
myAnchor.href = url;
Thanks for any help
Nicer, cleaner way of doing this:
var toEncode = {
title: '%%GLOBAL_ProductName%%',
url: 'http://lilaboutique.co.uk/products/%%GLOBAL_ProductName%%',
imgurl: '%%GLOBAL_ThumbImageURL%%',
desc: '%%GLOBAL_ProductDesc%%',
price: '%%GLOBAL_ProductPrice%%'
};
var index, queryString = '';
for (index in toEncode)
{
queryString += index + '=' + encodeURIComponent(toEncode[index]) + '&';
}
var url = "http://www.polyvore.com/cgi/add?" + queryString;
jQuery's $.param(obj) is very nice.
In general though I would take a similar approach if you wanted to roll your own. Make a function that accepts an Object, and returns a query string. Then in your server template, you have:
var urlData = {
url: "http://lilaboutique.co.uk/products/",
imgurl: "%%GLOBAL_ThumbImageURL%%",
desc: "%%GLOBAL_ProductDesc%%"
// etc...
}
var url = "http://www.polyvore.com/cgi/add?" + $.param(urlData);
Or whatever conversion function you want to use.

Categories