gameDesign = {
makeSeats: function( num ) { //num = number of seats
var seats = [];
var seat;
var seatWidth = 20;
var seatHeight = 20;
var total = 100;
for( var i=1; i<= num; i++ ) {
seat = $('<div id="seat_'+i+'" class="seats"><div id="index_'+i+'" style="height:100%; width:100%;"><div style="height:100%; width:100%;">Sit Here</div></div></div>');
seat.children(":first").children(":first").click( function(event, i){
var tim = i;
gameDesign.sitOnIndexNo( tim ); });
},
sitOnIndexNo: function( seatIndex ) {
tableFunc.makePlayerSit( RummyGlobal.myInfo.get_jid(), seatIndex );
}
}
Problem: On clicking "Sit Here" index value is being passed as undefined .. I know this is something related to closures .. but, I need further explanation and solution ..
function(event, i){ ...
expects i as it's second argument and any i inside its body is unrelated to any i outside its body.
jQuery passes only one argument to an event handler it calls - the event. Additionaly, it passes the target element as this. This means that the second argument is always undefined.
If you do this:
for(var i=0; i<num; i++){
var seat = $("...");
seat.find("...").click(function(e){
gameDesign.sitOnIndexNo(i)
)
}
you access the variable i after its value has changed. You can create a self-invoking function to capture the value of i:
for(var i=0; i<num; i++){
var seat = $("...");
var handler = (function(i){
return function(event){
gameDesign.sitOnIndexNo(i)
)
})(i);
seat.find("...").click(handler);
}
... or use seat.data, as suggested by #ClarkPan.
Firstly, you've declared the 'click' eventHandler to accept a parameter of 'i' as the second parameter. However, jquery parameter only passes through a single event object as the first parameter to the eventHandler. This means, when you assign 'tim' to be 'i', it'll come up with undefined.
Secondly, after changing this, if you were to run your code again, you'd get 'tim' to be equal to 'num' + 1, because the 'i' that's being referenced belongs in the 'makeSeats' function scope, and isn't stored as part of the function.
What you want is something like this:
for(var i = 0; i <= num; i++){
$('.foo').click({i:i}, function(e){
gameDesign.sitOnIndexNo(e.data.i);
});
}
More info on the 'data' property thats past to the eventHandler can be found here.
You mention "clicking", so I assume you're plannning to generate all these divs saying "Sit Here". When the user clicked "Sit Here", the function sitOnIndexNo is called. Based on this assumption, here's my suggestion:
gameDesign = {
makeSeats: function( num ) { //num = number of seats
for( var i=1; i<= num; i++ ) {
$("#id_of_element_where_you_want_to_put_the_div").
append('<div id="'+i+'" class="seats" style="height:100%; width:100%;">Sit Here</div></div></div>');
}
},
sitOnIndexNo: function( seatIndex ) {
tableFunc.makePlayerSit( RummyGlobal.myInfo.get_jid(), seatIndex );
}
}
// Event handler:
$(".seats").live("click", (function(e) {
var tim = $(this).attr("id");
gameDesign.sitOnIndexNo(tim);
});
So basically, the makeSeats function generates the "Sit Here" divs and their click events are handled by the new event handler.
Related
I am dynamically creating a checkbox. Now I want to call a function(lets say Hello world) whenever the checkbox is checked. I used setAttribute to call the function, but I am facing problems while passing parameters. I want the values of i and j to be passed to function.
Following is my code -
function addTable(message) {
var paxArray=new Array();
var mealsArray= new Array();
mealsArray=['Vegeterian Food','Non Vegeterian Food', 'Indian Continental','Chinese'];
paxArray=message.data;
for(var i=0;i<paxArray.length;i++){
var x= document.createElement('tr');
x.innerHTML=paxArray[i];
document.getElementById("Content").appendChild(x);
for(var j=0;j<mealsArray.length;j++){
var row=document.createElement('tr');
var meal=document.createElement('td');
var check_box=document.createElement('td');
var check=document.createElement('input');
check.type="checkbox";
check.id="checkbox"+i+j;
check.setAttribute("onchange","Helloworld(i+j);");
meal.innerHTML=mealsArray[j];
check_box.appendChild(check)
row.appendChild(check_box);
row.appendChild(meal);
document.getElementById("Content").appendChild(row);
}
}
}
function Helloworld(index){
document.getElementById("text").innerHTML=index;
}
Here i+j you are passing are simply characters not variable values.
Try:
say var i = 4; var j=3;
if you want to call Helloworld(43)
check.setAttribute("onchange","Helloworld("+i+j+");");
if you want to call Helloworld(7)
var k=i+j;
check.setAttribute("onchange","Helloworld("+k+");");
You could do like this
check.setAttribute("onchange",`"Helloworld(" + (i + j) + ");"`);
If you don't use (i + j) and put just "Helloworld(" + i + j + ");", you will get concatenation and not sum
Use
function assignFunction(i, j) {
return function() {
Helloworld(i+j);
}
}
check.onchange = assignFunction(i+j);
I have two arrays.
var fruits = [];
var tasks = [];
When I enter a value in the text field it fires a function that pushes the value to an array. It then fires a separate function that stringifies the array and saves it in local storage. ("when" is my alias for document.addeventlistener).
when(toDo, "keypress", function(event){
if (event.key == "Enter" || event.keyCode == 13) {
pushArray();
stringifyArray(fruits);
toDo.value = "";
}
});
// function that adds new task to the array
function pushArray(){
var newtask = new Task(toDo.value, "No note yet");
fruits.push(newtask);
}
// function that stringifies given array and stores it in local storage
function stringifyArray(array){
var makeString = JSON.stringify(array);
var setItem = localStorage.setItem("tasks", makeString);
}
When I loop through the first array and try to display object.Name and .Note in a div it works fine:
when(button, "click", function(event){
demolist.innerHTML = "";
for(i=0; i< fruits.length; i++){
demolist.innerHTML += fruits[i].Name + " " + fruits[i].Note + "<br>";
}
});
But when I fire a function that parses that array, populates the second and tries to loop through it in the same manner I get "undefined undefined" even though I can see that the array contains all the objects I submitted when I check the console.
function parseArray(){
var getArray = localStorage.getItem("tasks");
var parseObj = JSON.parse(getArray);
tasks.push(parseObj);
}
when(button2, "click", function(event){
function parseArray()
demolist2.innerHTML = "";
for(i=0; i< tasks.length; i++){
demolist2.innerHTML += tasks[i].Name + " " + tasks[i].Note + "<br>";
}
});
https://jsfiddle.net/bjxs3LdL/
(NO JQUERY SOLUTIONS PLEASE)
I am new to coding and stackoverflow so forgive the long post.
Fix your parseArray() function by changing
tasks.push(parseObj);
to
tasks = parseObj;
EDIT: Sorry for all the edits, it's hard to wrap my around the control flow. To fix the issue of the first note not getting saved, add a stringifyArray(fruits); call to the end of your submitNote() function.
The parseArray call is wrong, try rewiriting button2 listener like this:
when(button2, "click", function(event){
parseArray();
demolist2.innerHTML = "";
for(i=0; i< tasks.length; i++){
demolist2.innerHTML += tasks[i].Name + " " + tasks[i].Note + "<br>";
}
});
Otherwise, your code needs a redesign, but that's for another opportunity.
When I execute the following script, only one value is displayed in the alert:
<script>
window.onload = function () {
var num = 15;
for (var i = 0; i < 10; i++) {
$('<tr style="background-color: aqua" id = ' + i + '></tr>').appendTo("table");
for (var j = 0; j < 10; j++) {
num++;
$('<td id ='+num+'></td>').appendTo("#"+i);
$('<button>S</button>').data("field", i, j).appendTo("#" + num);
}
}
$('td').on('click', 'button', function () {
var d = $(this);
alert(d.data("field")); // here alert shows one variable
});
}
</script>
How can I store two values in the element's data? Maybe I can send an array?
You can set them as object or array .
$('<button>S</button>').data("field", [i,j] ).appendTo("#" + num);
and alert them using
alert( d.data("field").join(',') ); // here alert shows one variable
as per comment "Calling join(",") is not actually necessary, the override of toString() implemented by arrays already performs this operation." . so you can all simply
alert( d.data("field") );
check this on http://jsfiddle.net/xhPjh/
The data you store using the jQuery data method can be an object. So you can store the values this way:
$('<button>S</button>').data("field", { i: i, j: j});
And read them out again like this:
var d = $(this),
field = d.data("field");
alert(field.i);
alert(field.j);
You should also look into using jQuery's ready method instead of window.onload.
Hello I want to extract elements from both arrays with the same url .How can i loop these two arrays and get their content, because it gives me undefined for the news_url and i think it outputs twice the items in the console.
function geo(news_array,user_tweets){
console.log(news_array,user_tweets);
for (var x=0; x<user_tweets.length; x++) {
var user = user_tweets[x].user;
var date = user_tweets[x].date;
var profile_img = user_tweets[x].profile_img;
var text = user_tweets[x].text;
var url=user_tweets[x].url;
second(user,date,profile_img,text,url);
}
function second(user,date,profile_img,text,url){
for (var i = 0; i < news_array.length; i++) {
var news_user = news_array[i].news_user;
var news_date = news_array[i].news_date;
var news_profile_img = news_array[i].news_profile_img;
var news_text = news_array[i].news_text;
var news_url=news_array[i].url;
if (url==news_array[i].news_url) {
geocode(user,date,profile_img,text,url,news_user,news_date,news_profile_img,news_text,news_url);
}
}
}
function geocode(user,date,profile_img,text,url,news_user,news_date,news_profile_img,news_text,news_url) {
console.log(url,news_url);
}
}
The problem is
in news_tweets function, you add news_url to news_array. So you should call
news_array[i].news_url
in second function.
I modify your code as
news_url: (item.entities.urls.length > 0)?item.entities.urls[0].url : '' in news_tweets function
add close brace } for geo function and remove } from last
add new_array parameter to second function like second(user, date, profile_img, text, url,news_array);
Modify code can be tested in http://jsfiddle.net/rhjJb/7/
You have to declare some variables before the first for loop, so that they can be accessed in the scope of the second function. Try to replace your first for loop with the following code:
var user, date, profile_img, text, url;
for (var x=0; x<user_tweets.length; x++){
user = user_tweets[x].user;
date = user_tweets[x].date;
profile_img = user_tweets[x].profile_img;
text = user_tweets[x].text;
url=user_tweets[x].url;
second(user,date,profile_img,text,url);
}
Moreover, in the if of your second function, news_array[i].news_url isn't defined. Use if (url == news_url) instead.
I am trying to create functions with the same name as the buttons' ids
var a = ["ab1","aj6","yt5","gf5","js9"]
for (i = 0; i < a.length; i++) {
var el = a[i];
function el(){
list.find(el);
}
$(function() {
$("#"+el).click(el);
}
}
When I do this, I get an
Uncaught TypeError: Cannot read property 'handler' of undefined on
the anonymous function
. But when I change the function name to say "calculate" rather then the var el, it works fine. Any ideas?
if you are trying to bind a click handler to each element with an "id" in the array, then:
var a = ["ab1","aj6","yt5","gf5","js9"]
$.each(a,function(i,val){ //for each item
$("#"+val).on('click',function(){ //bind a click handler
list.find(val); //that finds that element in "list"
});
//or
$("#"+val).click(function(){
list.find(val);
});
//or
$("#"+val).bind('click',function(){
list.find(val);
});
//or
$('body').delegate('#'+val,'click',function(){
list.find(val);
});
})
I don't know, what you're trying to achieve, but "Yes , it is possible to create functions with array values":
var a = ["ab1","aj6","yt5","gf5","js9"];
for (var i = 0; i < a.length; i++) {
window[a[i]] = function(){
};
}
After this, you have 5 global functions with "ab1","aj6","yt5","gf5","js9" names.
You cannot have two variables with the same name. Both var el and function el are called el. JavaScript considers function names as variable names (sort of) where the function is assigned to.
Also, you should probably use a function statement instead of a function declaration. See http://kangax.github.com/nfe/ for more info.
Do it is like this:
var a = ["ab1","aj6","yt5","gf5","js9"]
for (i = 0; i < a.length; i++) {
var el = a[i];
$("#"+el).click(functon(){
list.find(el);
});
}