Accessing Array inside jquery function 'undefined' - javascript

I have a 2 Dimension Array.
I am trying to access it inside my Mousemove jquery function INSIDE my Canvas function. When i try so, i get the following error :
Uncaught TypeError: Cannot read property '0' of undefined
function Canvas(_canvas) {
this.pixels = new Array();
for (var i = 0; i<this.canvas.width; i++) {
var row = new Array();
for (var j=0; j<this.canvas.height; j++) {
row.push(i*j);
}
this.pixels.push(row);
}
$("#" + _canvas).mousemove(function(e){
var offset = $(this).offset();
console.log(this.pixels[parseInt(e.clientX-offset.left)][parseInt(e.pageY-offset.top)]);
});
};
My array is accessible properly from any other function inside my Canvas function, except for the Jquery ones. Any thoughts on that ?
Thanks

alias this into that to avoid ambiguity in the event handler between the instance and the event-raising element:
function Canvas(_canvas) {
var that=this;
this.pixels = new Array();
for (var i = 0; i<this.canvas.width; i++) {
var row = new Array();
for (var j=0; j<this.canvas.height; j++) {
row.push(i*j);
}
this.pixels.push(row);
}
$("#" + _canvas).mousemove(function(e){
var offset = $(this).offset();
console.log(that.pixels[parseInt(e.clientX-offset.left)][parseInt(e.pageY-offset.top)]);
});
};

Related

Splice out data, unknown position

I have a ToDo list, using localStorage... I need to be able to remove the item from the ToDo list... I try to use "dataArray.splice();" But the problem is I don't know how i can remove the object when the position is unknown...
function getTodoItems() {
for (var i = 0; i < dataArray.length; i++) {
if (!dataArray[i].listItem.length) return;
var itemList = document.getElementById("my-todo-list");
var list = document.createElement("li");
itemList.appendChild(list);
list.innerHTML = dataArray[i].listItem;
var spanItem = document.createElement('span');
spanItem.style.float = 'right';
var myCloseSymbol = document.createTextNode('\u00D7');
spanItem.classList.add("closeBtn");
spanItem.appendChild(myCloseSymbol);
listItems[i].appendChild(spanItem);
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
console.log(dataArray);
}
var list = document.getElementsByTagName('li');
list[i].onclick = function() {
this.classList.toggle("checked");
}
}
}
Then probably get its position:
const position = dataArray.indexOf(/*whatever*/);
dataArray.splice(position, 1);
You can get the position of the element using 'indexOf'
let pos = dataArray.indexOf(element);
dataArray.splice(pos,1)
IndexOf() wont work if you are trying to find the index of an entire object or array inside the array.
If you need to find the index of an entire object inside your array, you test each one's value to find out if it is the correct one. I would use findIndex();
Try this in your console:
var array = [];
for (var i = 0; i < 10; i++ ){ array.push({item: i}) }
console.log('Current Array: ', array);
var indexOfResult = array.indexOf({item: 3});
console.log('indexOf result: ',indexOfResult);
var findIndexResult = array.findIndex(object => object.item === 3);
console.log('findIndex result: ',findIndexResult)

How to make a javascript function with elementid like argument?

I have an DevExpress Mvc token extension, where the user will insert several items.
Using javascript I send the items to the controller, which is working fine.
My function look like this:
$(function() {
$("#btnSave").click(function () {
var name = window.ComboBox.GetValue();
var i;
var team = new Array();
var tokens = window.tokenBox.GetTokenCollection();
for (i = 0; i < tokens.length; i++) {
team.push(tokens[i]);
}
var s = new Array();
var ss = window.tokenBox2.GetTokenCollection();
for (i = 0; i < ss.length; i++) {
s.push(ss[i]);
}
var w = new Array();
var ww = window.tokenBox3.GetTokenCollection();
for (i = 0; i < ww.length; i++) {
w.push(ww[i]);
}
var o = new Array();
var oo = window.tokenBox4.GetTokenCollection();
for (i = 0; i < oo.length; i++) {
o.push(oo[i]);
}
var t = new Array();
var tt = window.tokenBox5.GetTokenCollection();
for (i = 0; i < tt.length; i++) {
t.push(tt[i]);
}
$.ajax({
type: "post",
url: '#Url.Action("Action","Controller")',
data: { name:name, team:team, s:s, o:o, w:w, t:t },
beforeSend: function () {
window.loadingPanel.Show();
},
success: function (response) {
$("#mainAjax").html(response);
window.loadingPanel.Hide();
}
});
});
});
I want to use a function, to get the items from token and put them in an array (not repetitive code like above), something like this:
function GetTokenItems(token) {
var list = new Array();
var el = document.getElementsById(token);
var tokens = el.GetTokenCollection();
for (var i = 0; i < tokens.length; i++) {
list.push(tokens[i]);
}
return list;
};
This function is not working, error says:
Uncaught TypeError: document.getElementsById is not a function
How can I pass the Id of the tokenBok like argument in a function, or/and what is wrong with my function?
**Edit:**
I made the correction document.getElementById and now I get the error:
Uncaught TypeError: el.GetTokenCollection is not a function
Should be document.getElementById(id):
Returns a reference to the element by its ID; the ID is a string which can be used to identify the element; it can be established using the id attribute in HTML, or from script.
document.getElementById(...)
// ^ without s
I found the answer of my issue, maybe will be helpfull for others!
For Devexpress mvc extensions is enough to use the name of the extension like argument, no need to look for him with document.getElementById, so my function is working like this:
function GetTokenItems(token) {
var list = new Array();
var tokens = token.GetTokenCollection();
for (var i = 0; i < tokens.length; i++) {
list.push(tokens[i]);
}
return list;
};
now I can call this function like this:
var team=GetTokenItems(tokenBox); and is working!!!

For loop in Adobe ExtendScript

my for-loop in the "setEase" function won't increase "i"
function storeKeyframes(){
var properties = app.project.activeItem.selectedProperties;
var activeProperty = null;
var keySelection = null;
var curKey = null;
var curKeyTime = null;
var curKeyIndex = null;
var theEase = new KeyframeEase(0 , slider_1_slider.value);
for (var i = 0; i < properties.length; i++){
activeProperty = properties[i];
setEase();
}
function setEase(){
for (var i = 0; i < activeProperty.selectedKeys.length ; i++){
keySelection = activeProperty.selectedKeys;
curKey = keySelection[i];
curKeyTime = activeProperty.keyTime(curKey);
curKeyIndex = activeProperty.nearestKeyIndex(curKeyTime);
activeProperty.setInterpolationTypeAtKey(curKeyIndex, KeyframeInterpolationType.BEZIER, KeyframeInterpolationType.BEZIER);
activeProperty.setTemporalEaseAtKey(curKeyIndex,theEase, theEase);
}
}
}
I just can't figure out why. Am I missing something?
I tried your code and indeed "i" is not increasing, but for me the reason was that there was an error.
The main reason for error is that the 2nd and 3rd arguments to setTemporalEaseAtKey() should be arrays of KeyframeEase, not just KeyframeEase (see the scripting guide).
Another reason is that activeProperty needs not be an actual Property, hence querying activeProperty.selectedKeys.length will throw an error.
On a side note, what you call curKeyIndex is actually the same as curKey, so you dont need the nearestKeyIndex stuff. The following code works for me:
function storeKeyframes(){
var comp = app.project.activeItem;
if (!comp || comp.typeName !== "Composition") return;
var properties = comp.selectedProperties;
var i, I=properties.length;
var ease1 = new KeyframeEase(0,100);
for (i=0; i<I; i++){
if (properties[i] instanceof Property) setEase(properties[i], ease1);
};
};
function setEase(property, ease1){
var ease = property.propertyValueType===PropertyValueType.Two_D ? [ease1, ease1] : (property.propertyValueType===PropertyValueType.Three_D ? [ease1, ease1, ease1] : [ease1]);
var keySelection = property.selectedKeys;
var i, I=keySelection.length;
for (i=0; i<I; i++){
property.setInterpolationTypeAtKey(keySelection[i], KeyframeInterpolationType.BEZIER, KeyframeInterpolationType.BEZIER);
property.setTemporalEaseAtKey(keySelection[i], ease, ease);
};
};
storeKeyframes();
This works for me. Take a look into the console of the ESTK. I would suggest passing your activeProperty to your setEase function. So you keep your scopes clean.
Also it is better to not use the same iterator.
function main() {
storeKeyframes();
}
function storeKeyframes() {
var properties = app.project.activeItem.selectedProperties;
for (var i = 0; i < properties.length; i++) {
activeProperty = properties[i];
$.writeln(i + " in storeKeyframes");
setEase(activeProperty);
}
function setEase(ap) {
for (var j = 0; j < ap.selectedKeys.length; j++) {
$.writeln(j + " in setEase");
}
}
}
main();

JavaScript cannot find method a second time?

I'm attempting to build a poker game. The method in question is very simple, and it works when it runs the first time.
This part isn't perfect convention because I'm just using it to test my methods:
var $ = function (id) { return document.getElementById(id); };
var test = function() {
var deck = new POKER.Deck();
var hand = new POKER.Hand();
for (var i = 0; i < 7; i++){
hand.addCard(deck.dealCard());
}
hand.sortByRank();
for (var j = 0; j < 7; j++){
var img = document.createElement("img");
var card = hand.getCardAtIndex(j); //** <------- WORKS HERE**
img.src = card.getImage();
$("images").appendChild(img);
}
var testHand = new POKER.Hand();
testHand = hand.removePairs();
for (var k = 0; k < testHand.length; k++) {
var img2 = document.createElement("img");
var card2 = testHand.getCardAtIndex(k); // **<------FAILS HERE**
img2.src = card2.getImage();
$("handImg").appendChild(img2);
}
};
window.onload = function() {
test();
};
The first and second loop work, and the hand is displayed and everything. When it gets to the last loop, the debugger tells me "TypeError: testHand.getCardAtIndex is not a function"
I was attempting to test the removePairs method (to test for straights more easily), and when watching the variables in the debugger, testHand clearly gets populated correctly. The method seems to work just fine.
getCardAtIndex:
POKER.Hand.prototype.getCardAtIndex = function(index) {
return this.cards[index];
};
removePairs:
POKER.Hand.prototype.removePairs = function(){
var allCards = this.cards;
var tempCards = [];
var uniqueRanks = [];
var unique;
for(var i = 0; i < allCards.length; i++){
unique = true;
for(var j = 0; j < uniqueRanks.length; j++){
if(allCards[i].getRank() == uniqueRanks[j]){
unique = false;
break;
}
}
if(unique){
uniqueRanks.push(allCards[i].getRank());
tempCards.push(allCards[i]);
}
}
return tempCards;
};
I'm completely perplexed.
var testHand = new POKER.Hand();
testHand = hand.removePairs();
hand.removePairs() returns an Array, not a Hand object.
That's why you don't have access to the getCardAtIndex method.
If cards is a public property you could do:
testHand.cards = hand.removePairs();
Or you can have a setter method:
testHand.setCards(hand.removePairs);

Callback is undefined and other stories

I got the following script, which is not working propperly. I know about getJSON's async nature, so I tried to build a callback function (jsonConsoleLog), which is supposed to be executed before getJSON get asigned to var (myJson = json;). After running debug in Chrome, I got two things out: A) debug is highlighting jsonConsoleLogcalls inside getJSON function as undefined.
B) Console is throwing TypeError: Cannot read property '0' of null for var friends = myJSON[0].friends;, which means the whole function doesn't work.
I'm in battle with it since saturday and I really don't know what to do. There's clearly something up with my callback function, but shoot me if I know what. Help?
var myJSON = null;
var main = document.getElementsByClassName('main');
var sec = document.getElementsByClassName('sec');
function getJSON(jsonConsoleLog){
$.getJSON('http://www.json-generator.com/api/json/get/cpldILZRfm? indent=2', function(json){
if (json != null){
console.log('Load Successfull!');
};
if (jsonConsoleLog){
jsonConsoleLog(json[0].friends);
}
myJSON = json;
});
};
function jsonConsoleLog(json) {
for (var i = 0; i < json.length; i++) {
console.log('friend: ' + friends[i]);
};
};
getJSON();
var friends = myJSON[0].friends;
function myFn1(){
for(var i = 0; i < friends.length; i++) {
main[i].innerHTML = friends[i].id;
};
};
function myFn2(){
for(var i = 0; i < friends.length; i++) {
main_div[i].innerHTML = friends[i].name;
};
};
main.innerHTML = myFn1();
sec.innerHTML = myFn2();
The first problem is because your function getJSON is expecting one formal argument, which you've called jsonConsoleLog. But you are not passing any arguments to getJSON. This means that inside getJSON the formal parameter, jsonConsoleLog, will indeed be undefined. Note that because you've named the formal parameter jsonConsoleLog, which is the same name as the function you're hoping to call, inside getJSON you won't have access to the function. What you need to do is pass the function as the parameter:
getJSON(jsonConsoleLog);
The second problem is I think to do with the json variable - it doesn't have a property 0 (i.e. the error is occurring when you try to treat it as an array and access element 0), which suggets that json is coming back empty, or is not an array.
you're calling getJSON without the callback parameter - therefore, the local variable jsonConsoleLog is undefined in getJSON
snip ...
function blah(json) { // changed name to avoid confusion in the answer - you can keep the name you had
for (var i = 0; i < json.length; i++) {
console.log('friend: ' + friends[i]);
};
};
getJSON(blah); // change made here (used the function name blah as changed above
var friends = myJSON[0].friends;
function myFn1(){
for(var i = 0; i < friends.length; i++) {
main[i].innerHTML = friends[i].id;
};
};
snip...
The issue with
var friends = myJSON[0].friends;
is duplicated here many many times ... $.getJSON is asynchronous and you are trying to use it synchronously
i.e. when you assign var friends = myJSON[0].friends; myJson hasn't been assigned in $.getjson ... in fact, $.getjson hasn't even BEGUN to run
here's all your code reorganised and rewritten to hopefully work
var main = document.getElementsByClassName('main');
var sec = document.getElementsByClassName('sec');
function getJSON(callback) {
$.getJSON('http://www.json-generator.com/api/json/get/cpldILZRfm? indent=2', function(json) {
if (json != null) {
console.log('Load Successfull!');
};
if (callback) {
callback(json);
}
});
};
function doThings(json) {
var friends = json[0].friends;
for (var i = 0; i < friends.length; i++) {
console.log('friend: ' + friends[i]);
};
function myFn1() {
for (var i = 0; i < friends.length; i++) {
main[i].innerHTML = friends[i].id;
};
};
function myFn2() {
for (var i = 0; i < friends.length; i++) {
main_div[i].innerHTML = friends[i].name;
};
};
main.innerHTML = myFn1();
sec.innerHTML = myFn2();
}
getJSON(doThings);
Correct, fully working code (basically the same as accepted, correct answer but stylistycally bit different)
var main = document.getElementsByClassName('main');
var sec = document.getElementsByClassName('sec');
var friends = null;
function getJSON(jsonConsoleLog){
$.getJSON('http://www.json-generator.com/api/json/get/cpldILZRfm?indent=2', function(json){
if (json != null){
console.log('Load Successfull!');
};
if (jsonConsoleLog){
jsonConsoleLog(json[0].friends);
}
});
};
function jsonConsoleLog(json) {
for (var i = 0; i < json.length; i++) {
console.log('friend: ' + json[i]);
};
friends = json;
myFn1();
myFn2();
};
function myFn1(){
for(var i = 0; i < friends.length; i++) {
main[i].innerHTML = friends[i].id;
};
};
function myFn2(){
for(var i = 0; i < friends.length; i++) {
main[i].innerHTML += friends[i].name;
};
};
getJSON(jsonConsoleLog);

Categories