javascript api simplified - javascript

Was using fourquare api to get venue, had previously had a clickable list written out from api but cut it down to just one venue name written to screen. Then decided it'd be best to just send it over to php. So when I did what I thought was logical cutting of the code, it stopped working completely.
My program has this, working:
$(document).ready(function doEverything(element) {
$.getJSON("https://api.foursquare.com/v2/venues/search?ll=" + lat + "," + lng + "&client_id=L2VWBKPOW45D5X3FJ3P4MJB5TGVJ4ST2J005RIVAFIWG44ND%20&client_secret=ZKDAOLHASCA31VUOGMBTAS3RFYUOMXL4IFFYPRURIDQA3QMA%20&v=20111107", function(data) {
one = data.response.venues[0].name;
var list = [];
list[0] = [one];
function Make() {
for (var i = 0; i < 1; i++) {
var div = document.createElement("div");
div.style.margin = "-435px 100px 0px 110px";
div.innerHTML = list[i];
!
function() {
var index = 0;
div.onclick = function() {
doSomething(this);
};
}();
document.body.appendChild(div);
}
}
function doSomething(element) {
var value = element.innerHTML;
switch (value) {
case one:
break;
}
}
Make();
});
});
Then I decided I wanted to pass a variable over to php using this:
theVar = 10; //just to make things simple.
urlString = "cookiestesttwo.php?var=" +theVar;
window.location = urlString;
So I tried to simplify my api code to this, and it stopped working:
$(document).ready() {
$.getJSON("https://api.foursquare.com/v2/venues/search?ll=" + lat + "," + lng + "&client_id=L2VWBKPOW45D5X3FJ3P4MJB5TGVJ4ST2J005RIVAFIWG44ND%20&client_secret=ZKDAOLHASCA31VUOGMBTAS3RFYUOMXL4IFFYPRURIDQA3QMA%20&v=20111107", function(data) {
one = data.response.venues[0].name;
document.write(one)
theVar = one
urlString = "cookiestesttwo.php?var=" + theVar;
window.location = urlString;)
};
};​

$(document).ready() { is not proper syntax and does throw errors.
Furthermore there was another syntax error at the end of the function. you reversed } and )
$(document).ready(function() {
$.getJSON("https://api.foursquare.com/v2/venues/search?ll=" + lat + "," + lng + "&client_id=L2VWBKPOW45D5X3FJ3P4MJB5TGVJ4ST2J005RIVAFIWG44ND%20&client_secret=ZKDAOLHASCA31VUOGMBTAS3RFYUOMXL4IFFYPRURIDQA3QMA%20&v=20111107", function(data) {
one = data.response.venues[0].name; // if one is local to this function then use VAR otherwise you'll leak it globally.
document.write(one);
theVar = one; // same here for the VAR keyword.
urlString = "cookiestesttwo.php?var=" + theVar; // and here as well. NO GLOBAL LEAKS!
window.location = urlString;
});
});
I threw a few more hints in the comments.

Your problem might be that you use document.write() when the DOM is already complete. You are not supposed to do that. Create an element document.createElement( "div" ) and set the innerText() and then append it to the dom. Much like you did before the refactor.
EDIT
I understand that it wasn't the document.write() but just do clarify what I was talking about I wrote a little refactor. I also threw out the theVar = one since that is redundant. Also make sure to declare your variables in the right scope. Therefore I added a var in front of the one.
$(document).ready(function() {
$.getJSON("https://api.foursquare.com/v2/venues/search?ll="+lat+","+lng+"&client_id=L2VWBKPOW45D5X3FJ3P4MJB5TGVJ4ST2J005RIVAFIWG44ND%20&client_secret=ZKDAOLHASCA31VUOGMBTAS3RFYUOMXL4IFFYPRURIDQA3QMA%20&v=20111107",
function(data){
var one = data.response.venues[0].name;
var div = document.createElement( "div" );
div.innerText( one );
document.appendChild( div );
window.location = "cookiestesttwo.php?var=" + one;
});
});
But if you change the location of the window. There is no point to document.write() or appending a new div since you leave the site anyways.

Related

Alert or Console.log not working from dynamically loaded JavaScript

I use the following function to dynamically load JavaScript:
function loadJS(file, c)
{
var jsEl = document.createElement("script");
jsEl.type = "application/javascript";
jsEl.src = file;
jsEl.async = false;
document.body.appendChild(jsEl);
if (c) { jsEl.addEventListener('load', function (e) { c(null, e); }, false); }
document.getElementsByTagName("head")[0].appendChild(jsEl);
}
Below is one of the functions contained within a dynamically added file:
function formelements_SELECT_add(x)
{
console.log("add");
alert("add");
var id = x[1];
var value = x[2];
var index = x[3];
var select = document.getElementById(id);
var option;
option = document.createElement("option");
option.text = value;
select.add(option, index);
}
I know the JavaScript file gets added correctly and the function gets executed because an option is added to the select element. Why does the alert and console.log not execute? If I click inspect, then there are no error messages.
EDIT
This is the code I use to call the function:
var typeAndElement = x[0][0] + "_" + x[0][1];
start = i + 1;
if (!window[typeAndElement])
{
loadJS("https://websemantica.org/scripts/" + x[0][0] + "/" + x[0][1] + ".js", continueManipulatingElements(typeAndElement, actions, x, start, total));
return;
}
else
{
fn = window[typeAndElement + "_" + x[0][2]];
if (typeof fn === 'function')
fn(x);
}
I didn't want to include it initially, because I already knew it was working and it will be unclear how it works considering it is using dynamic data.
Also, I have edited the loadJS function:
function loadJS(file, c)
{
var jsEl = document.createElement("script");
jsEl.type = "text/javascript";
jsEl.src = file;
jsEl.async = false;
if (c) { jsEl.addEventListener('load', function (e) { c(null, e); }, false); }
document.getElementsByTagName("head")[0].appendChild(jsEl);
}
The problem appears to be solved now.
Three things jump out:
You're appending the script to the page twice, once to document.body, and the other to document.getElementsByTagName("head")[0]. The second one will move the script from the first place to the second. You really only need to do one of those.
You're looking the load event after appending the element. If the script is in cache, you can miss the event. Hook it before appending the script to the DOM.
You're not doing anything in the quoted code to call the function that's defined by the script you're adding.
Other side notes:
No need to set type, the default is JavaScript.
No need to set async, all dynamically-inserted script elements are async (now, it wasn't always true).
As Jarosław Wlazło points out document.alert isn't a function; just alert is all you need. :-)
In addition: document has no alert method. It belongs to window, so you can call it like this alert('add');

How do I update an element's class on the mouse events for another element?

So I've been reading Mozilla's js docs all day, trying to figure this out. I'm still a newb with JavaScript, and I plan on learning this stuff, but I'm getting really frustrated that I can't figure it out and move on to the rest of my project.
This codepen is what I have so far. I'm trying to change the class for #bear to reflect the mouseOver and MouseOut events for every .thing class. The class should be: past event, then a dash, then current event.
Hopefully the comments illustrate what I'm trying to accomplish. I'm sure that I'm doing just about everything wrong here, but don't really know how to proceed with fixing it.
Could anyone help me?
JAVASCRIPT BELOW FOR REFERENCE
var thing = "nothing";
document.getElementsByClassName("thing").onMouseOver = function() {
document.getElementById("bear").className = thing + "-thing" + this.attr("data-thing");
thing = "thing" + this.attr("data-thing");
}
document.getElementsByClassName("thing").onMouseOut = function() {
document.getElementById("bear").className = thing + "-nothing";
thing = "nothing";
}
getElementsByClassName returns a collection - so you have to iterate over the collection and create your bindings:
var elems = document.getElementsByClassName("thing");
for (var i = 0; i < elems.length; i++) {
elems[i].onmouseover = function() {
//replace #bear's class to reflect mouse history
document.getElementById("bear").className = thing + "-thing" + this.getAttribute("data-thing");
//update var thing
thing = "thing" + this.getAttribute("data-thing");
}
elems[i].onmouseout = function() {
//replace #bear's class to reflect mouseOut
document.getElementById("bear").className = thing + "-nothing";
//update var thing to reflect mouseOut
thing = "nothing";
}
}
Example: http://codepen.io/anon/pen/yNrVEy'
Also, .attr is a jQuery method - you need to use getAttribute for vanilla JS
first things first: document.getElementsByClaassName(class) returns an ARRAY. so you can't just do a dot-attribute assignment with it.
Instead:
var thing = "nothing";
var thingies = document.getElementsByClassName("thing");
for (i=0;i<thingies.length;i++){
thingies[i].onMouseOver = function() {
document.getElementById("bear").className = thing + "-thing" + this.attr("data-thing");
thing = "thing" + this.attr("data-thing");
};
thingies[i].onMouseOut = function() {
document.getElementById("bear").className = thing + "-nothing";
thing = "nothing";
};
}
If you are open to use jQuery, here is another approach:
var thing = "nothing";
$(".thing").hover(function(){
var newclass=thing + "-thing" + $(this).attr("data-thing");
$("#bear").addClass(newclass);
thing = "thing" + $(this).attr("data-thing");
}, function(){
$("#bear").addClass(thing + "-nothing");
thing = "nothing";
})

Pass jQuery variable to Javascript Function

I have a table in a separate HTML file that I am loading with jQuery. I am then defining the variable "aa". I am attempting to use this variable in my JavaScript Function "report(period)". I tried creating a global variable but that didn't help. I am not entire sure I was doing it correctly. I am fairly new to JavaScript and know even less of jQuery. I've gone through other similar posts but it’s very difficult to understand exactly what's happening. Any help would greatly be appreciated.
jQuery
jQuery(function($) {
aa = document.getElementById('part1Table').rows[0].cells[2].innerHTML;
});
Javascript
function report(period) {
x = document.getElementById("tblabiNew").rows[2].cells[1].innerHTML; /*----- for testing use a number instead (example: x = "205-000040-634") ------*/
/*---------------------------------------------------------------------------------------------- Start - Object Removal Control ------------------------------------------------------------------------------------*/
if (x==aa) {
var i = 1; do {
+ i; i++;
var e = document.getElementById (i);
e.style.display = 'none'
} while (i < 15)
/*polebrea21*/
var polebrea = 21;
do {
+ polebrea;
polebrea++;
var e = document.getElementById (polebrea);
e.style.display = 'none'
} while (polebrea < 28)
/*polebrea31*/
var polebrea = 31;
do {
+ polebrea;
polebrea++;
var e = document.getElementById (polebrea);
e.style.display = 'none'
} while (polebrea < 38)
/*regulatory51*/
var regulatory = 51;
do {
+ regulatory;
regulatory++;
var e = document.getElementById (regulatory);
e.style.display = 'none'
} while (regulatory < 64)
/*regulatory51*/
/*regulatory81*/
var regulatory = 81;
do {
+ regulatory;
regulatory++;
var e = document.getElementById (regulatory);
e.style.display = 'none'
} while (regulatory < 94)
};
};
If you want "global" variable you should declare it outside of all functions body. So this should be.
var aa;
jQuery(function($) {
aa = //do something with aa
});
but anything you use without declaring is by default global (mind it work that way only in browsers).
If you want create local variable, add var keyword before it name, like this:
function report(period) {
var x = //...
}
I believe your aa variable is not declared because report function is called before page is ready.
Everything in function given to jQuery() run after DOM is ready, so if I write:
jQuery(function($) { console.log(1); });
console.log(2);
I get "2, 1" and not "1, 2".
You should really learn JavaScript and jQuery if you want to use it. Your report code seems like it can be replaced with one line with jQuery.
If I understand your scenario correctly you are not able to obtain the relevant node because the HTML fetched via ajax has not been injected into the DOM and hence can't be fetched using document.getElementById.
Could you provide the code which fetches the remove HTML and then what is done with it ? That may be helpful to understand the situation.
Anyway, this is something you may want to try:
$.ajax({
method: "GET",
url: "some/remote/url",
success: function(htmlContent) {
aa = $(htmlContent).find('#part1Table')[0].rows[0].cells[2].innerHTML;
// Do some processing
}
})

Only the last data in my for loop assigns

Hey I have a simple loop like this:
for(var i in nodes) {
var d = document.createElement('div');
d.className = 'box';
d.id = 'node' + i;
document.getElementById('node').appendChild(d);
document.getElementById('node'+ i).innerHTML = nodes[i].name;
document.getElementById('node'+ i).addEventListener('mousedown', function() {
var info = nodes[i]; display_parent(info);
}, false);
}
function display_parent(data){
console.log(data);
}
The problem is all the divs hold the same information aka the last one in the loop, i tried to assign the data to a local variable to info but it still does not work.
Any ideas how I can fix that?
It is due to closure in 'mousedown' event handler. You have to use something like this:
document.getElementById('node'+i).addEventListener('mousedown',
(function(node) {
return (function() {
display_parent(node);
});
}(nodes[i])), false);

Unique html item ID in Javascript

I am building a drag'n'drop gui builder in Javascript. So far so good.
As I add items to the GUI and configure them; I have two mechanisms for addressing them:
the 'class' - which I use for doing things to all instances of an item (eg CSS, generic functionality and so on and so forth) and which I can bind javascript libraries to... and I can make full use of polymorphic class names (ie class="name1 name2 name3 name4" with different things bound to each class name...)
the 'id' - which refers to this particular instance of a text box or a paragraph and which I can bind javascript libraries to
My problem is this: the 'id' must be unique across all html items on the page (by definition) so how do I ensure this? I need to get all the id's of all the items and then maintain some sort of state table.
Starting from a blank bit of html this is pretty reasonable - but I need to start from a partly created bit of html with a mixture of existing 'id's - some of which will be in my unique scheme and some of which wont be...
The way to do this best ought to be a solved problem.
Suggestions, tips, examples?
The best way to do this will depend entirely upon the structure and organization of your javascript. Assuming that you are using objects to represent each of your GUI elements you could use a static counter to increment your ids:
// Your element constructor
function GuiElement() {
this.id = GuiElement.getID();
}
GuiElement.counter = 0;
GuiElement.getID = function() { return 'element_' + GuiElement.counter++; };
Of course you probably have more than one type of element, so you could either set each of them up so that they have their own counter (e.g. form_1, form_2, label_1, label_2) or so that they all share a counter (e.g. element_1, element_2, element_3), but either way you will probably want them to inherit from some base object:
// Your base element constructor
function GuiElement(tagName, className) {
this.tagName = tagName;
this.className = className;
}
GuiElement.counter = 0;
GuiElement.getID = function() { return 'element_' + GuiElement.counter++; };
GuiElement.prototype.init = function() {
this.node = document.createElement(this.tagName);
this.node.id = this.id = GuiElement.getID();
this.node.className = this.className;
}
// An element constructor
function Form() {
this.init();
}
Form.prototype = new GuiElement('form', 'form gui-element');
// Another element constructor
function Paragraph() {
this.init();
}
Paragraph.prototype = new GuiElement('p', 'paragraph gui-element');
You could also go this route if you would rather keep some variables "private":
// Your element constructor constructor
var GuiElement = (function() {
var counter = 0;
function getID() {
return 'element_' + counter++;
}
return function GuiElement(tagName, className) {
return function() {
this.node = document.createElement(tagName);
this.node.id = this.id = getID();
this.node.className = className + ' gui-element';
this.className = className;
};
}
})();
// Create your element constructors
var Form = GuiElement('form', 'form'),
Paragraph = GuiElement('p', 'paragraph');
// Instantiate elements
var f1 = new Form(),
f2 = new Form(),
p1 = new Paragraph();
Update: If you need to verify that an id is not already in use then you could add the check you and of the getID methods:
var counter = 0;
function getID() {
var id = 'element_' + counter++;
while(document.getElementById(id)) id = 'element_' + counter++;
return id;
}
function uniqueId() {
return 'id_' + new Date().getTime();
}
If you happen to be using the Prototype library (or want to check it out), you can use the Element.identify() method.
Otherwise, Darin's response is a good idea as well.
function generateId() {
var chars = "0123456789abcdefghiklmnopqrstuvwxyz",
string_length = 8,
id = '';
for (var i = 0; i < string_length; i++) {
var rnum = Math.floor(Math.random() * chars.length);
id += chars.substring(rnum, rnum + 1);
}
return id;
}
Close enough to unique is good enough. Don't use the Date() solution unless you're only generating a single ID at any given time...

Categories