I need to maintain text box values into an array in javascript onchange event. The text box control is created dynammically in javascript function. I have used below code. But at the end the array contains current element only. Previous values are not maintaining. How can I maintain textbox value each time entered.
<script type="text/javascript" language="javascript">
function DrawTextBox(j) {
var imgElement = document.getElementById('myimage');
var imgCoord = imgElement.getBoundingClientRect();
var cl = imgCoord.left + 20;
var x = x - cl;
var y = y - imgCoord.top;
var rect = document.getElementById(j);
if (rect == null) {
rect = document.createElement("div");
rect.id = j;
var pElement = document.getElementById("imgDiv");
pElement.appendChild(rect);
}
if (w < 0) {
w = 10;
}
if (h < 0) {
h = 10;
}
var l = parseInt(document.getElementById("hright").value) + 150 + 'px';
var style = rect.style;
// style.width = w + "px";
//style.height = h + "px";
style.left = l;
style.top = document.getElementById("htop").value;
style.backgroundColor = "Transparent";
//style.borderColor = "Blue";
style.position = "absolute";
style.borderStyle = "solid";
style.borderWidth = 2 + "px";
style.zIndex = 6000;
document.getElementById(j).innerHTML = "<textarea name=\"comments\" style=\" border:0\" Title=\"Enter Comment\" id=\"T1\" value=\"EnterComment:\" onchange=\"GetText()\" ></textarea>";
//document.getElementById(i).innerHTML = "<input type=\"Textarea\"...blah blah...></input>";
return rect;
}
function GetText() {
array1.push(document.getElementById('T1').value);
alert(array1.join(', '));
}
</script>
Your question doesn´t say if/when/where array1 is declared and when DrawTextBox() is called but you can´t insert multiple elements using the same ID "T1" as it violates basic HTML rules.
Try passing a referens to the current element like this onchange="GetText(this)" and use it in your GetText() function as;
function GetText(el) {
array1.push(el.value);
alert(array1.join(', '));
}
Related
I am new to javascript and trying to learn from the beginning.
I have a script where I can do two different calculations using radio buttons, area and circumference.
I want to display how many times people have counted out different calculations.
If I use to show clicks on button then it counts everything together, but how can I separate them?
document.getElementById("calculate").addEventListener("click", function() {
var button = document.getElementById("calculate");
var x, text;
x = document.getElementById("radius").value;
if (document.getElementById("area").checked) {
if (isNaN(x) || x < 1 || x > 100) {
text = "Fel radie";
document.getElementById('radius').value = '';
} else {
let radius = document.getElementById("radius").value;
area = Math.PI * radius * radius;
}
if (document.getElementById("areaoutput").innerHTML = text);
else(document.getElementById("areaoutput").innerHTML = "Area = " + area);
}
if (document.getElementById("circumference").checked) {
let radius = document.getElementById("radius").value;
if (isNaN(x) || x < 1 || x > 100) {
text = "Fel radie";
document.getElementById('radius').value = '';
} else {
let radius = document.getElementById("radius").value;
circumference = Math.PI * 2 * radius;
}
if (document.getElementById("circoutput").innerHTML = text);
else(document.getElementById("circoutput").innerHTML = "Circumference = " + circumference);
}
if (document.getElementById("area").checked) {
var count = localStorage.on_load_counter || 0;
var button = document.getElementById("calculate");
var display = document.getElementById("areacount");
button.onclick = function() {
localStorage.on_load_counter = display.innerHTML = ++count;
}
}
if (document.getElementById("circumference").checked) {
var count = localStorage.on_load_counter || 0;
var button = document.getElementById("calculate");
var display = document.getElementById("circcount");
}
button.onclick = function() {
localStorage.on_load_counter = display.innerHTML = ++count;
}
}, false);
Try doing something like this
var combinationsDone = [];
Then every time the user does a calculation, you would add an object to combinationsDone.
For example, if they have a radius of 5, and circumference isn't checked, this is what you should do.
var combination = {
radius: 5,
circumference: false
}
if(!combinationsDone.includes(combination)){
combinationsDone.push(combination);
}
What this does is it makes sure that the combination wasn't recorded previously before adding the combination. Then, when you want to get the number of different combinations they have done, just user combinationsDone.length.
You can use a global variable. which is increased every time you call the function.
var myFuncCalls = 0;
function myFunction()
{
myFuncCalls++;
alert( "I have been called " + myFuncCalls + " times" );
}
I'm doing a gallery to use this in my own page, I've placed controller divs correctly, I've made a script but it won't work. That's it:
function changePhoto(id) {
var y = document.getElementById("baza_big_photo_img");
var x = document.getElementById("br_hidden");
y.style.border = "2px solid grey";
x.style.display = "block";
var z = "./zdjecia/" + id + ".jpg";
y.src = z;
var ui = document.getElementById("overlay");
ui.style.display = "block";
var next = document.getElementById("next");
var prev = document.getElementById("prev");
var identity = id;
next.onclick = function(identity) {
var id = identity/1 + 1;
var z = "./zdjecia/" + id + ".jpg";
y.src = z;
}
prev.onclick = function(identity) {
var id = identity;
if(id == 1) {
var z = "./zdjecia/" + id + ".jpg";
} else {
id = id/1 + 1;
var z = "./zdjecia/" + id + ".jpg";
}
y.src = z;
}
}
I mean last two functions, I attached onclick event but it returns NaN in console. This is html code:
<div id="overlay">
<div id="prev"><--</div>
<div id="next">--></div>
<img src="" id="baza_big_photo_img">
</div>
<div class="br4 hidden" id="br_hidden"></div>
<div class="baza_zdjecia" onclick="changePhoto(1);"><img src="./zdjecia/1.jpg" class="fitimg"></div>
<div class="baza_zdjecia" onclick="changePhoto(2);"><img src="./zdjecia/2.jpg" class="fitimg"></div>
<div class="baza_zdjecia" onclick="changePhoto(3);"><img src="./zdjecia/3.jpg" class="fitimg"></div>
<div class="baza_zdjecia" onclick="changePhoto(4);"><img src="./zdjecia/4.jpg" class="fitimg"></div>
<div class="baza_zdjecia" onclick="changePhoto(5);"><img src="./zdjecia/5.jpg" class="fitimg"></div>
<div class="baza_zdjecia" onclick="changePhoto(6);"><img src="./zdjecia/6.jpg" class="fitimg"></div>
<div class="baza_zdjecia" onclick="changePhoto(7);"><img src="./zdjecia/7.jpg" class="fitimg"></div>
<div class="baza_zdjecia" onclick="changePhoto(8);"><img src="./zdjecia/8.jpg" class="fitimg"></div>
I think there is a bug with sending id twice through second functions but I don't know how to fix it, help me please:)
Based on comments it sounds like the identity variable in the onclick events isn't what you expect. Take a look at how that variable is being set:
var identity = id;
next.onclick = function(identity) {
var id = identity/1 + 1;
var z = "./zdjecia/" + id + ".jpg";
y.src = z;
}
You do set a value to that variable, but in the onclick function you declare a new local variable called identity, which has nothing to do with the one you set outside that function. Whatever the browser may be sending as the first (if any) parameter to that event isn't going to be your identity variable, and probably isn't going to be numeric at all.
You don't need the function parameter, just remove it entirely:
var identity = id;
next.onclick = function() {
var id = identity/1 + 1;
var z = "./zdjecia/" + id + ".jpg";
y.src = z;
}
I believe you are illegally transforming you id variable....
next.onclick = function(identity) {
var id = identity/1 + 1;
var z = "./zdjecia/" + id + ".jpg";
y.src = z;
}
...this is why you are returning NAN in your console
try..
var id = identity += 1;
In High Performance Javascript book, I read about for minimizing repaints and reflows, batch DOM changes could lead a better performance, like using:
var el = document.getElementById('mydiv');
el.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;';
instead of
var el = document.getElementById('mydiv');
el.style.borderLeft = '1px';
el.style.borderRight = '2px';
el.style.padding = '5px';
I did a test in Chrome, but the result is opposite, here is my test code:
var ie = (function(){
var undef, v = 3, div = document.createElement('div');
while (
div.innerHTML = '<!--[if gt IE '+(++v)+']><i></i><![endif]-->',
div.getElementsByTagName('i')[0]
);
return v> 4 ? v : undef;
}());
// First insert 100*100 element
var total = 100 * 100;
var round = 100 * 100;
var body = document.querySelector("body");
if (ie) {
total = round = 100 * 10;
}
var createElement = function (id) {
var div = document.createElement("div");
div.setAttribute("id", "id-" + id);
return div;
}
for (var i = 0; i <= total; i++) {
body.appendChild(createElement(i));
}
// Then change style in random
function randomFromInterval(from, to) {
return Math.floor(Math.random() * (to-from+1)+from);
}
function randomWidth() {
return randomFromInterval(0, 200) + "px";
}
function randomHeight() {
return randomFromInterval(0, 200) + "px";
}
function randomColor() {
var r = randomFromInterval(0, 255),
g = randomFromInterval(0, 255),
b = randomFromInterval(0, 255);
return "rgb(" + r + ", " + g + ", " + b + ")";
}
var time = +new Date();
for (var i = 0; i <= round; i++) {
var id = randomFromInterval(0, total);
var div = document.querySelector("#id-" + id);
// The `slower` way...but it is faster, use less time
div.style.width = randomHeight();
div.style.height = randomWidth();
div.style.backgroundColor = randomColor();
// var text = "width: " + randomWidth() + "; height: " + randomHeight() + "; background: " + randomColor() + ";"
// div.style.cssText = text;
}
console.log(+new Date() - time);
Here is my demo:
http://jsfiddle.net/9BV5E/
http://jsfiddle.net/9BV5E/1/
the first one I using .style. way, and the second one is using cssTest way;
And I also test them in IE8, the two way's time are almost the same.
So is the book wrong? Or there are other reasons?
May I ask how you are testing this?
Have you entered the test cases into, say jsperf.com a la these?
The information available roundly indicates cssText is better when setting multiple styles vs individual ones, when performing tests I cant seem to replicate the results you've noted.
I'm having trouble figuring out how to pass values from one function to another. I've created a program where I create boxes using values from a form that show up in the webpage. The values I'm talking about are property values of the boxes themselves.
Here is the function where the values are assigned to the boxes:
function addBox(newbox) {
for (var i = 0; i < newbox.number; i++) {
counter++;
var id = counter;
var scene = document.getElementById("scene");
var div = document.createElement("div");
div.value = id;
console.log(div.value);
div.className += " " + "box";
div.innerHTML += newbox.name;
div.style.backgroundColor = newbox.color;
var x = Math.floor(Math.random() * (scene.offsetWidth-101));
var y = Math.floor(Math.random() * (scene.offsetHeight-101));
div.style.left = x + "px";
div.style.top = y + "px";
scene.appendChild(div);
div.onclick = display;
}
}
Here is the function that I'm having trouble passing the values to. I need to pass them so that I can display them in an alert box when I click on each box:
function display(e) {
alert(e.target.toSource());
}
So far when I click it, I just get an empty pair of brackets in the alert box.
I tried your example in JS Fiddle: http://jsfiddle.net/jCC6n/
I'm seeing at least two problems.
"counter" is undefined, which causes the code to fail when it first attempt to increment it. I added a variable declaration at the top of the function.
toSource is undefined. I replaced that with "outerHTML", which works in Chrome, IE and presumably other browsers.
With the above changes, this worked.
function display(e) {
alert(e.target.outerHTML);
}
function addBox(newbox) {
var counter = 0;
for (var i = 0; i < newbox.number; i++) {
counter++;
var id = counter;
var scene = document.getElementById("scene");
var div = document.createElement("div");
div.value = id;
div.className += " " + "box";
div.innerHTML += newbox.name;
div.style.backgroundColor = newbox.color;
var x = Math.floor(Math.random() * (scene.offsetWidth-101));
var y = Math.floor(Math.random() * (scene.offsetHeight-101));
//div.style.left = x + "px";
//div.style.top = y + "px";
scene.appendChild(div);
div.onclick = display;
}
}
addBox({ number: 3, name: "Hello", color: '#C00' });
Be advised that event handling using onclick event handlers varies from browser to browser. It will be best to use a JavaScript framework that knows all the differences and gives you a unified way to handle events. jQuery is arguably the most used such framework.
I need help with this app. I want the user to choose a name, color and number. When the form is submitted, boxes of the chosen color and number are generated. More boxes can be added and the originals are not erased. Each box has random positioning and a unique id.
Here is my effort: http://jsfiddle.net/christopherpl/gnVj6/
//Invoke functions only after page has fully loaded
window.onload = init;
//Create an array that will be populated by the user generated boxes
var boxes = [];
//Create a global counter variable that keeps track of the number of
//boxes generated
var counter = 0;
//Create a Box constructor function with parameters, to create box objects
//for each box that's generated
function Box(id, name, color, x, y) {
this.id = id;
this.name = name;
this.color = color;
this.x = x;
this.y = y;
}
//Set up the onclick event handler for the generate button input
function init() {
var generateButton = document.getElementById("generateButton");
generateButton.onclick = generate;
var clearButton = document.getElementById("clearButton");
clearButton.onclick = clear;
}
//Get boxes' name from user
function generate() {
var data = document.forms.data;
var textInput = document.getElementById("name");
var name = textInput.value;
if (name == null || name == "") {
alert("Please give your Amazing Box a name");
return;
}
//Get color option from user
var colorSelect = document.getElementById("color");
var colorOption = colorSelect.options[colorSelect.selectedIndex];
var color = colorOption.value;
if (!color) {
alert("Pick a color");
return;
}
//Get number of boxes to be generated from user
var amountArray = data.elements.amount;
for (i = 0; i < amountArray.length; i++) {
if (amountArray[i].checked) {
//Create and append the new <div> element
var div = document.createElement("div");
//Randomly position each <div> element
var x = Math.floor(Math.random() * (scene.offsetWidth-101));
var y = Math.floor(Math.random() * (scene.offsetHeight-101));
//Give each <div> element a unique id
var newId = div;
newId = counter++;
id = newId;
//Add the style, including the background color selected
//by the user.
div.style.left = x + "px";
div.style.top = y + "px";
div.style.backgroundColor = color;
div.setAttribute("class", "box");
scene.appendChild(div);
div.innerHTML = "Box of " + name + "<br />(click me)";
//Create an onclick event displaying the
//details of each box generated
div.onclick = function() {
alert("You clicked on a box with id " + id +
", named Box of " + name + ", whose color is " + color +
" at position " + div.style.top + ", " + div.style.left)
}
//Form reset
data = document.getElementById("data");
data.reset();
}
}
}
//Clear the boxes from scene div
function clear() {
var sceneDivs = document.querySelectorAll("div#scene div");
for (var i = 0; i < sceneDivs.length; i++) {
var scene = document.getElementById("scene");
var cutList = document.getElementsByTagName("div")[1];
scene.removeChild(cutList);
}
}
In your code, when you do this loop:
for (i = 0; i < amountArray.length; i++) {
if (amountArray[i].checked) {
/* make the div */
}
}
You are always just making one box. What you need to do is a second loop, using the value of the radio button as the length of the loop. Something like:
var totalBoxes = 0;
for (i = 0; i < amountArray.length; i++) {
if (amountArray[i].checked) {
totalBoxes = amountArray[i].value;
}
}
for (i = 0; i < totalBoxes; i++) {
/* make the div */
}
That way you will get 5 boxes if the user checked the 5 box, and so on.