Reputation: 382
I'm using JavaScript/jQuery. I'm having an issue with looping through an array to display the data as well as removing contents via button clicks.
Original Code in Question
HTML
<textarea id="sds">Apple
Banana
Grape
Orange</textarea>
<input type="hidden" id="sdh" />
Problem: Every button returns 5!
<div id="popup" title="Poof">
</div>
Script
var sds = $("#sds").val();
var sda = sds.split("\n");
var sdi = "";
$.each(sda, function(k, s) {
sdi += "<input type='text' id='sd" + k + "' value='" + s + "' /><button id='button" + k + "'>Click Me</button><br />";
$("#sdh").val(k);
});
$("#popup").html(sdi);
var h = $("#sdh").val();
var i = 0;
while (i <= h) {
$("#button" + i).click(function() {
// Here is where I have a problem trying to manipulate the input associated to the button.
alert(i); // Test to see what returns for the value of i.
$("#sd" + i).val("Clicked button " + i);
});
i++;
}
CSS (Thanks for providing the CSS to make the demo look better, Jose!)
#sds {
display: none;
}
Revised Code
HTML
<textarea rows="4" cols="40" id="sds">Apple
Banana
Grape
Orange</textarea>
<input type="text" id="sd" value="Click here to verify" />
<input type="hidden" id="key" />
<div id="popup" title="Verify Multiple Fruits">
</div>
Script
$(document).ready(function() {
var sds = $("#sds").val();
var sda = sds.split("\n");
var sdi = "";
$.each(sda, function(key, sd) {
sdi += "<input type='text' id='sd" + key + "' value='" + sd + "' /><button id='button'" + key + "'>Remove</button><br />";
alert(key); // Test to see what returns for the value of i.
$("#button" + key).click(function() {
// Here is where I have a problem trying to manipulate the input associated to the button.
$("#sd" + key).val("Clicked button " + i);
});
$("#key").val(key);
});
$("#popup").html(sdi);
});
$(function() {
$("#popup").dialog({
autoOpen: false,
buttons: {
"Update": function() {
var key = $("#key").val();
var i = 0;
var sds = "";
while (i <= key) {
sds += $("#sd" + i).val() + "\n";
i++;
}
sds = sds.slice(0, -1);
$("#sds").val(sds);
$(this).dialog("close");
},
"Cancel": function() {
$(this).dialog("close");
}
},
close: function() {
},
height: 320,
hide: {
duration: 1000,
effect: "explode"
},
modal: true,
resizable: false,
show: {
duration: 1000,
effect: "blind"
},
width: 480
});
$("#sd").focus(function() {
$("#popup").dialog("open");
});
});
CSS (Thanks again for the CSS here, Jose!)
#sds {
display: none;
}
#popup input,
#popup button {
float: left;
width: auto;
}
#popup input {
clear: left;
}
Revised Code after Applying One of the Answers
HTML
<textarea rows="4" cols="40" id="sds">Apple
Banana
Grape
Orange
Pear
Strawberry</textarea>
<input type="text" id="sd" value="Click here to verify." />
<input type="hidden" id="key" />
<div id="popup" title="Verify Multiple Fruits"></div>
Script
$(document).ready(function() {
$.each($("#sds").val().split("\n"), function(key, sd) {
$("#popup").append(
$("<input type='text' id='sd" + key + "' value='" + sd + "' />").add(
$("<button id='button" + key + "'>Remove</button><br />").click(function() {
$("#sd" + key).val("");
$("key").val(key);
})));
});
});
$(function() {
$("#popup").dialog({
autoOpen: false,
buttons: {
"Update": function() {
var key = $("#key").val();
var i = 0;
var sds = "";
while (i <= key) {
sds += $("#sd" + i).val() + "\n";
i++;
}
sds = sds.slice(0, -1);
$("#sds").val(sds);
$(this).dialog("close");
},
"Cancel": function() {
$(this).dialog("close");
}
},
close: function() {
},
height: 320,
hide: {
duration: 1000,
effect: "explode"
},
modal: true,
resizable: false,
show: {
duration: 1000,
effect: "blind"
},
width: 480
});
$("#sd").focus(function() {
$("#popup").dialog("open");
});
});
CSS (This is really awesome, Jose!)
#sds {
display: none;
}
#popup input,
#popup button {
float: left;
width: auto;
}
#popup input {
clear: left;
}
Suppose the value of sds is Apple, Banana, Grape and Orange on different lines. Each button created by the .each() loop will have the correct number assigned, but when trying to change the value, the variable i returns 5 on the alert message box while the next line doesn't seem to work at all - due to the index being off.
How can I revise this code to make it work like it's supposed to?
Corrected the error mentioned by the loving and caring commentators. Still not working. Obviously that wasn't the issue as my original code that I copied off of had the parenthesis closed correctly. I was hand-jamming the code here since I have no ability to copy and paste the code here, so a small typo was made. My question is about the logic, not typo. Thanks!
In order to minimize the confusion, I've revised the code section of this question to reflect the original code I had, so it'll show the consistency with the answers Jose provided below.
Obviously, the revised code also had more issues, so I made a new revision yet again. Here is what I've gotten so far. It's still quirky, but works on most part. I'm going to need help with the cancel action on the modal dialog since it won't bring back the previous values from the textarea tag. Also, please, note the version changes on jQuery and addition of jQuery UI to the JSFiddle demo to reflect my development environment.
The Ultimate Solution
HTML
<textarea rows="4" cols="40" id="sds">Apple
Banana
Grape
Orange
Pear
Strawberry</textarea>
<input type="text" id="sd" value="Click here to verify." />
<div id="popup" title="Verify Multiple Fruits"></div>
Script
$(document).ready(function() {
if ($("#sds").val()) {
var i = 0;
$.each($("#sds").val().split("\n"), function(key, sd) {
$("#popup").append(
$("<input type='text' class='blah' id='sd" + key + "' value='" + sd + "' />").add(
$("<button id='button" + key + "'>Remove</button><br />").click(function() {
$("#sd" + key).val("");
})));
i++;
window["i"] = i;
});
}
});
$(function() {
$("#popup").dialog({
autoOpen: false,
buttons: {
"Update": function() {
var i = window["i"];
var sds = "";
$(".blah").each(function(i) {
if ($(this).val()) {
sds += $("#sd" + i).val() + "\n";
}
});
sds = sds.slice(0, -1);
$("#sds").val(sds);
$(this).dialog("close");
},
"Cancel": function() {
$(this).dialog("close");
}
},
close: function() {
$("#popup").html("");
if ($("#sds").val()) {
var i = 0;
$.each($("#sds").val().split("\n"), function(key, sd) {
$("#popup").append(
$("<input type='text' class='blah' id='sd" + key + "' value='" + sd + "' />").add(
$("<button id='button" + key + "'>Remove</button><br />").click(function() {
$("#sd" + key).val("");
})));
i++;
window["i"] = i;
});
}
},
height: 320,
hide: {
duration: 1000,
effect: "explode"
},
modal: true,
resizable: false,
show: {
duration: 1000,
effect: "blind"
},
width: 480
});
$("#sd").focus(function() {
if ($("#sds").val()) {
$("#popup").dialog("open");
}
});
});
CSS
#sds {
display: none;
}
#popup input,
#popup button {
float: left;
width: auto;
}
#popup input {
clear: left;
}
Thoughts after Solving the Issue
I was initially irritated by the people who pointed out the typos rather than trying to see the entire picture to discover the "big" flaw with the program itself because that's what I thought I would have done for people who would ask me for guidance. Then, it hit me when I thought about how I would really react when I see petty mistakes like typos and bad grammars. I admit I hate seeing those petty mistakes, mostly because I have an obsessive-compulsive disorder when it comes to writing anything, including codes. Now that I've learned about JSFiddle, I'll test my code there before trying to post a question here from now on. It has been a terrific learning experience and thanks to all for the assistance.
Upvotes: 3
Views: 1279
Reputation: 15319
There are several ways to solve this problem.
Inside the loop, declare an anonymous function and call it immediately, passing in i
as the parameter local_i
. In other words, i
has a global scope, but the local_i
has a scope limited to the anonymous function. This way, the click event "sees" the local_i
value, not the i
(5) as you had before.
while (i <= h) {
(function (local_i) {
$("#button" + local_i).click(function() {
alert(local_i); // Test to see what returns for the value of i.
$("#sd" + local_i).val("Clicked button " + local_i);
});
})(i); // <-- HERE I am calling the function
i++;
}
There is one pattern here: You want i=0
for #button0
, i=1
for #button1
.
So, just get the index from the id. This solution requires no loops.
// select all buttons inside #popup, that have an id starting by "button"
$("#popup button[id^=button]").click(function() {
var i = parseInt($(this).attr('id').replace('button', ''));
alert(i); // Test to see what returns for the value of i.
$("#sd" + i).val("Clicked button " + i);
});
$.each($("#sds").val().split("\n"), function(k, s) {
$("#popup").append(
// append the text box
$("<input type='text' id='sd" + k + "' value='" + s + "' />").add(
// and the button with the click already defined
$("<button id='button" + k + "'>Click Me</button>").click(function() {
alert(k);
$("#sd" + k).val("Clicked button " + k);
}))
);
});
Brand new code was pasted into the question. To fix the problem in that code, just change
$("#button" + key).click(function() {
// Here is where I have a problem trying to manipulate the input associated to the button.
$("#sd" + key).val("Clicked button " + i);
});
to
$("#button" + key).click(function() {
var i = $(this).attr('id').replace('button', '');
$("#sd" + i).val("Clicked button " + i);
});
You can use the other alternatives I wrote above. Hope this helps.
Upvotes: 3
Reputation: 2557
you have an error here
$("#button" + i.click(function() {
it should be
$("#button" + i).click(function() {
corrent that and it will work.
Upvotes: 1