I have a multidimensional array like this:
var squares = new Array();
for(var i = 0; i <= 8; i++)
{
squares[i] = new Array();
for(var j = (i * 20) + 1; j <= 20 * i + 20; j++)
{
if (squares[i] == null)
{
squares[i] = ''+j;
}
else
{
squares[i].push('' + j);
}
}
}
I want to get the the index from the multidimensional array when I click on a square:
angular.element('.click').click(function() {
var squareId = angular.element(this).attr('id'); //Rutans id
for(var k = 0; k <= 8; k++)
{
var squareIndex = squares[k].indexOf(squareId);
}
console.log(squareIndex);
But this only results in -1 by console.log. Anyone who can help me?
Using indexOf() you are only checking that the ID exists within that array. So if it occurs in the first array, it will continue to loop over them return -1 overwriting the previous value.
What you need to do is stop the loop when you find it and return k, the index of the array you are currently iterating through.
Here is a fiddle, hope this helps
Fiddle
var squares = new Array();
for(var i = 0; i <= 8; i++)
{
squares[i] = new Array();
for(var j = (i * 20) + 1; j <= 20 * i + 20; j++)
{
if (squares[i] == null)
{
squares[i] = ''+j;
}
else
{
squares[i].push('' + j);
}
}
}
console.log(squares);
$('a').on('click', function(){
var squareId = $(this).attr('id');
var squareIndex = 0,
numberIndex = 0;
for(var k = 0; k < squares.length; k++)
{
squareIndex = squares[k].indexOf(squareId);
if (squareIndex > -1) {
numberIndex = squareIndex;
squareIndex = k;
break
}
}
alert('NumberIndex: '+ numberIndex+' ParentSquareIndex: '+ squareIndex);
});
please see here http://plnkr.co/edit/aldjCQRchgESR7IWn367?p=preview i hope that will help.
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.2.x" src="https://code.angularjs.org/1.2.22/angular.js" data-semver="1.2.22"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello !</p>
<table>
<tr ng-repeat="lines in squares track by $index ">
<td ng-repeat="nr in lines track by $index" ng-click="getMyId(nr)">{{nr}}</td>
</tr>
</table>
</body>
</html>
JS:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
var squares = [];
for(var i = 0; i <= 8; i++)
{
squares[i] = [];
for(var j = (i * 20) + 1; j <= 20 * i + 20; j++)
{
if (squares[i] === null)
{
squares[i] = ''+j;
}
else
{
squares[i].push('' + j);
}
}
}
$scope.squares = squares;
$scope.getMyId = function(id){
alert(id);
}
console.log(squares);
});
Related
Alright, in my results for my program the results are displayed in a horizontal list (for e.x, HI,HELLO,HI,HELLO). I am trying to get these results to be in a numbered list from top to bottom.
function button() {
var inputArray = [];
var size = 4;
for (var i = 0; i < size; i++) {
inputArray[i] = prompt('Enter Element ' + (i + 1));
inputArray.sort();
document.getElementById("demo").innerHTML =
inputArray.map(function(x) {
return x.toUpperCase()
});
}
var str = String(inputArray).toUpperCase().split(",");
}
<button onclick="button();">Array</button>
<p id="demo"></p>
https://repl.it/repls/DangerousCloudyNumber
Just use an ordered list (<ol>) instead of a paragraph (<p>) and add list items (<li>) to the values while mapping them:
function button(){
var inputArray = [];
var size = 4;
for(var i=0; i<size; i++) {
inputArray[i] = prompt('Enter Element ' + (i+1));
inputArray.sort();
document.getElementById("demo").innerHTML = inputArray.map(function(x){ return "<li>"+x.toUpperCase()+"</li>"}).join("");
}
var str = String(inputArray).toUpperCase().split(",");
}
<!DOCTYPE html>
<html>
<head>
<script src="script.js"></script>
<meta charset="utf-8">
<title>Program</title>
</head>
<body>
<button onclick="button();">Array</button>
<ol id="demo"></ol>
</body>
</html>
function button(){
var inputArray = [];
var size = 4;
var final_html = "<ol>"
for(var i=0; i<size; i++) {
input = prompt('Enter Element ' + (i+1));
if (input === null) {
document.getElementById("demo").innerHTML = inputArray.map(function(x){
if (x != null) {
final_html = final_html +"<li>"+x.toUpperCase()+"</li>";
}
});
document.getElementById("demo").innerHTML = final_html;
return; //break out of the function early
}else{
inputArray[i] = input;
}
inputArray.sort();
}
}
I'm trying to make a script that gives whatever you're pointing at (that has the class foxrainbowhover) an asynchronous rainbow effect.
I've got it working for the most part but unfortunately it, for some reason, only affects the last element inside of the array. I've ran it all through mentally several times but cannot find a single thing wrong with it. I'm hoping you'll be able to help. Here's what the effect should look like: https://jsfiddle.net/Laoderv6/
(function(){let rainbowhover = document.getElementsByClassName('foxrainbowhover');
let rainbowelements = [];
let hoverinterval = [];
let hovercounters = [];
for(let i = 0; i < rainbowhover.length; i++) {
rainbowelements[i] = spanElementContents(rainbowhover[i]);
}
//Set up the wavey effect with counters.
for(let id = 0; id < rainbowelements.length; id++) {
for(let i = 0; i < rainbowelements[id].length; i++) {
hovercounters[id] = [];
hovercounters[id][i] = 0 + i;
}
}
// Add event listeners for every item classed foxrainbowhover.
for(let id = 0; id < rainbowhover.length; id++) {
rainbowhover[id].addEventListener("mouseenter", function startanimation() {
console.log('hit');
hoverinterval[id] = setInterval(() => {
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = 'hsl(' + (hovercounters[id][i] + Math.floor(i * 1)) + ', 100%, 70%';
console.log(rainbowelements[id]);
hovercounters[id][i]++;
}
}, 8);
}, false);
rainbowhover[id].addEventListener("mouseleave", function stopanimation() {
console.log('agh');
clearInterval(hoverinterval[id]);
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = 'black';
}
}, false);
}
})()
function spanElementContents(element) {
let spans = [];
let chars = [];
chars.push(element.innerText.split(""));
for(let i = 0; i < chars.length; i++){
element.innerHTML = chars[i].map(function(char) {
return '<span>' + char + "</span>";
}).join('');
}
let temphtmlcollection = [].slice.call(element.children)
for(let j = 0; j < temphtmlcollection.length; j++) {
spans.push(temphtmlcollection[j]);
}
return spans;
}
body {
background-color: black;
}
h1 {
color: white;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Page Title</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
<h1 class="foxrainbowhover">test1</h1>
<h1 class="foxrainbowhover">test111</h1>
<h1 class="foxrainbowhover">test111111</h1>
</body>
</html>
You are constantly resetting your array. You need to initialize it in the outer loop.
Change this:
for(let id = 0; id < rainbowelements.length; id++) {
for(let i = 0; i < rainbowelements[id].length; i++) {
hovercounters[id] = [];
hovercounters[id][i] = 0 + i;
}
}
to this:
for(let id = 0; id < rainbowelements.length; id++) {
hovercounters[id] = [];
for(let i = 0; i < rainbowelements[id].length; i++) {
hovercounters[id].push(i);
}
}
or more simply:
or (let id = 0; id < rainbowelements.length; id++) {
hovercounters[id] = rainbowelements[id].map((_, i) => i);
}
let rainbowhover = document.getElementsByClassName('foxrainbowhover');
let rainbowelements = [];
let hoverinterval = [];
let hovercounters = [];
for (let i = 0; i < rainbowhover.length; i++) {
rainbowelements[i] = spanElementContents(rainbowhover[i]);
}
//Set up the wavy effect with counters.
for (let id = 0; id < rainbowelements.length; id++) {
hovercounters[id] = rainbowelements[id].map((_, i) => i);
}
// Add event listeners for every item classed foxrainbowhover.
for(let id = 0; id < rainbowhover.length; id++) {
rainbowhover[id].addEventListener("mouseenter", function startanimation() {
hoverinterval[id] = setInterval(() => {
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = 'hsl(' + (hovercounters[id][i] + Math.floor(i * 1)) + ', 100%, 70%';
hovercounters[id][i]++;
}
}, 8);
}, false);
rainbowhover[id].addEventListener("mouseleave", function stopanimation() {
clearInterval(hoverinterval[id]);
for(let i = 0; i < rainbowelements[id].length; i++) {
rainbowelements[id][i].style.color = 'black';
}
}, false);
}
function spanElementContents(element) {
let spans = [];
let chars = [];
chars.push(element.innerText.split(""));
for(let i = 0; i < chars.length; i++){
element.innerHTML = chars[i].map(function(char) {
return '<span>' + char + "</span>";
}).join('');
}
let temphtmlcollection = [].slice.call(element.children)
for(let j = 0; j < temphtmlcollection.length; j++) {
spans.push(temphtmlcollection[j]);
}
return spans;
}
h1 {
color: black;
}
<h1 class="foxrainbowhover">test1</h1>
<h1 class="foxrainbowhover">test111</h1>
<h1 class="foxrainbowhover">test111111</h1>
This is what happens when you use asynchronous functions inside a for loop. Here are a couple of ways to fix the problem:
Use let instead of var
Create a function that uses closure and returns a new function
Use a try catch or IIFE block to create a new scope
Let
for (let index = 0; index < 5; index++) {
setTimeout(() => {
console.log(index)
}, 250);
}
Function Wrapper
for (let index = 0; index < 5; index++) {
setTimeout(getFunction(index), 250);
}
function getFunction(index) {
return function() {
console.log(index);
};
}
Try Catch Block
for (let index = 0; index < 5; index++) {
try {
throw index;
} catch (index) {
setTimeout(() => {
console.log(index);
}, 250);
}
}
IIFE Block
for (let index = 0; index < 5; index++) {
(function(index) {
setTimeout(() => {
console.log(index);
}, 250);
})(index);
}
How can I sort array.length numerically? In this image my numbers generator should be ordered in descending order.
I tried creating a new array with the push function. My code is as follows:
var newArray = [];
newArray.push(myArray.length);
Unfortunately this doesn't work. I'm a beginner in javascript and I haven't been able to find another solution.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="hack.js" defer></script>
</head>
<body>
<div id="demo" style="width: 500px;border: 1px solid black;"></div>
<script>
var myNumbers = '';
for (var i = 10; i <= 40; i++) {
var myArray = [];
for (var j = 2; j < i; j++) {
if (i % j == 0) {
myArray.push(j);
}
}
myNumbers += "<p>" + i + " number of generators = " + myArray.length + '</p>';
}
document.getElementById("demo").innerHTML = myNumbers;
</script>
</body>
</html>
var myNumbers = [];
for (var i = 10; i <= 40; i++) {
var myArray = [];
for (var j = 2; j < i; j++) {
if (i % j == 0) {
myArray.push(j);
}
}
var value = { int: i, length: myArray.length, html:"<p>" + i + " number of generators = " + myArray.length + '</p>' }
myNumbers.push(value);
}
myNumbers.sort(function(a, b){
return b.length - a.length;
});
document.getElementById("demo").innerHTML = myNumbers.map(function(d) { return d['html']; }).join('')
first you can store mappings of numbers and their generator count in an array of objects. Then you can sort this array using a comparator function. The iterate over this array add elements based on this sorted array.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="hack.js" defer></script>
</head>
<body>
<div id="demo" style="width: 500px;border: 1px solid black;"></div>
<script>
var myNumbers = '', myArray = [];
for (var i = 10; i <= 40; i++) {
var count = 0;
for (var j = 2; j < i; j++) {
if (i % j == 0) {
count++;
}
}
myArray.push({number: i, generators: count});
}
myArray.sort(function(a,b){
return b.generators - a.generators;
});
for(var i=0; i<myArray.length; i++)
myNumbers += "<p>" + myArray[i].number + " number of generators = " + myArray[i].generators + '</p>';
document.getElementById("demo").innerHTML = myNumbers;
</script>
</body>
</html>
This is the table created dynamically using javascript, I want to show this textbox value in alert message using GetCellValues() function.
function makeTable()
{
row=new Array();
cell=new Array();
row_num=20;
cell_num=4;
tab=document.createElement('table');
tab.setAttribute('id','newtable');
tbo=document.createElement('tbody');
tbo.setAttribute('id','tabody');
for(c = 0;c < row_num; c++)
{
row[c]=document.createElement('tr');
for(k = 0; k < cell_num; k++)
{
cell[k] = document.createElement('td');
if (k > 0)
{
cont=document.createElement("input");
cont.setAttribute('type','text');
cell[k].appendChild(cont);
row[c].appendChild(cell[k]);
}
else
{
cont=document.createTextNode("0" + (c+1));
cell[k].appendChild(cont);
row[c].appendChild(cell[k]);
}
}
tbo.appendChild(row[c]);
}
tab.appendChild(tbo);
document.getElementById('mytable').appendChild(tab);
mytable.setAttribute("align", "top-left");
}
Please check the GetCellValues() function, this function is not showing the textbox value in alert message.
function GetCellValues()
{
row=new Array();
cell=new Array();
row_num=20;
cell_num=4;
tab = document.getElementsByTagName('table');
tbo = tab.getElementsByTagName('tbody');
for(c = 0;c < row_num; c++)
{
row = tbo.getElementsByTagName('tr');
for(k = 0; k < cell_num; k++)
{
cell = row.getElementsByTagName('td');
{
cont=cell.getElementsByTagName('input');
{
alert(cont.value);
}
}
}
}
}
I think you need some modification in GetCellvalues function as tab.getElementsByTagName('tbody'); will not get elements having tag name tbody for thi you should use document.getElementsByTagName.
you can check working demo of you code here
If you are getting an alert box with [object HTMLCollection] message in it, then you need to use
alert(cont[0].value) in place of alert(cont.value) at the end of your GetCellValues function.
getElementsByTagName returns collection, you need to iterate through it or assume the first element - apply to row, cell, e.g.
var rows = tbo.getElementsByTagName('tr');
for (var c = 0; c < row_num; c++) {
row = rows[c];
var cells = row.getElementsByTagName('td');
for (var k = 0; k < cell_num; k++) {
cell = cells[k];
// and so on
}
}
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<table id="mytable"></table>
<input type="button" onclick="GetCellValues(20, 4);" value="click me" />
<script type="text/javascript">
function makeTable() {
row = new Array();
cell = new Array();
row_num = 20;
cell_num = 4;
tab = document.createElement('table');
tab.setAttribute('id', 'newtable');
tbo = document.createElement('tbody');
tbo.setAttribute('id', 'tabody');
for (c = 0; c < row_num; c++) {
row[c] = document.createElement('tr');
for (k = 0; k < cell_num; k++) {
cell[k] = document.createElement('td');
if (k > 0) {
cont = document.createElement("input");
cont.setAttribute('type', 'text');
cont.setAttribute('value', '');
cell[k].appendChild(cont);
row[c].appendChild(cell[k]);
}
else {
cont = document.createTextNode("0" + (c + 1));
cell[k].appendChild(cont);
row[c].appendChild(cell[k]);
}
}
tbo.appendChild(row[c]);
}
tab.appendChild(tbo);
document.getElementById('mytable').appendChild(tab);
mytable.setAttribute("align", "top-left");
}
makeTable();
function GetCellValues(row_num, cell_num) {
var arrInput = document.getElementsByTagName('input');
var index = (row_num - 1) * (cell_num - 1);
alert(arrInput[index].value);
}
</script>
</body>
</html>
A shortcut approach would be to use ID attribute of tag.
Sample TD tag with ID:
<td id="1_1">1st row 1st column</td><td id="1_2">1st row 2nd column</td>
Javascript to get TD with ID:
var row_len=1,col_len=2;
for (r = 0; r< row_len; r++) {
for (c = 0; c < coll_len; c++) {
alert(document.getElementById(r+'_'+c));
}
}
The below code is my html code
Star.html
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="CssText.css">
</head>
<body>
<form>
Enter number of rows: <input type="text" name="t1" /> <input
type="button" value="Display Diomond"
onclick="return myFunction(this.form)" />
</form>
<p id="p"></p>
<script src="StarPrint.js"></script>
</body>
</html>
The below code is my javascript code
StarPrint.js
function myFunction(form) {
var no;
no = form.t1.value;
no = no / 2;
var no2 = no;
var no3 = no;
var no4 = no;
var no5 = no;
var no6 = no;
for ( var i = 0; i < no; i++) {
for ( var index = 0; index < no2; index++) {
document.getElementById("p").innerHTML ="  ";
}
no2 = no2 - 1;
for ( var index2 = 0; index2 < (i * 2) + 1; index2++) {
document.getElementById("p").innerHTML = "*";
}
document.getElementById("p").innerHTML="</br>";
}
document.getElementById("p").innerHTML="  ";
for ( var i = 0; i < no3 + 1; i++) {
for ( var index = 0; index <= i; index++) {
document.getElementById("p").innerHTML = "  ";
}
for ( var index2 = 0; index2 < (no4 * 2) - 3; index2++) {
document.getElementById("p").innerHTML = "*";
}
no4 = no4 - 1;
document.getElementById("p").innerHTML = "</br> ";
}
}
I want to print pattern of diamond structure.The above program was working when I used document.write instead of document.getElementById("p").innerHTML with some modification.Where is that error I am not getting it.
You are replacing the content of p every time you call document.getElementById("p").innerHTML =.
Instead, save the text into a variable and only assign it to p at the end:
function myFunction(form) {
var no;
no = form.t1.value;
no = no / 2;
var no2 = no;
var no3 = no;
var no4 = no;
var no5 = no;
var no6 = no;
var diamond = "";
for ( var i = 0; i < no; i++) {
for ( var index = 0; index < no2; index++) {
diamond +="  ";
}
no2 = no2 - 1;
for ( var index2 = 0; index2 < (i * 2) + 1; index2++) {
diamond += "*";
}
diamond+="</br>";
}
diamond+="  ";
for ( var i = 0; i < no3 + 1; i++) {
for ( var index = 0; index <= i; index++) {
diamond += "  ";
}
for ( var index2 = 0; index2 < (no4 * 2) - 3; index2++) {
diamond += "*";
}
no4 = no4 - 1;
diamond += "</br> ";
}
document.getElementById("p").innerHTML = diamond;
}
Working Example - http://jsfiddle.net/fdadE/
You are not appending the stuff you want, but just assigning. Replace all = with += like below:
document.getElementById("p").innerHTML = "  ";
to
document.getElementById("p").innerHTML += "  ";