website breaks when running this function - javascript

I have the following function:
function Test() {
var x = document.getElementById("input").value;
var res = "";
var c = 1;
var stoc = "";
while (x > 0) {
var help = c.toString();
var h = help.length;
while (h > 0) {
res += help[h - 1];
h--;
}
if (res === help) {
stoc += res + ";" + " ";
x--;
}
c++;
}
document.getElementById("stoc").innerHTML = stoc;
}
Whenever i trigger the function the button stays pushed and the site stops responding. The algorithm is supposed to return the first x polindrom (that are written the same way from right to left ex 121) numbers.

Your browser is crashing because x is never getting decremented causing the loop to never exit. Check the value of help in the debugger.

Related

JS: creating user input amount of rows

I'm new to JavaScript and I'm trying to create user input amount of rows. I know how to do this with document.write but I can't get this to work with innerHTML.
This is what I've got so far:
function myFunction() {
var x = document.getElementById("myText").value;
if ( (x >> 0) > 0 ) {
for ( --- I've tried everything I can think of here but nothing works -- ) {
document.getElementById("secondblock").innerHTML = x + "<br />"
}
This bit:
if ( (x >> 0) > 0 ) {
is for making sure the input is a number -- I'm using the same input field for other (string) functions too. I'm sure there's some better way to check whether my var x is a number or not, but I've just been using this method.
This is what I'm trying to create (if user inputs number 5):
1.
2.
3.
4.
5.
Try this
document.getElementById("secondblock").innerHTML += x + "<br />"
Full example
function myFunction() {
var x = document.getElementById("myText").value;
for(let i = 0; i <= x; i++) {
x.innerHTML += i + "<br />"
}
}
With innerHTML you are resetting the innerHTML every time. So to get the desired output you just need to concat the previous innerHTML as well. Try the code below and you will see the innerHTML resetting to the last insert.
function myFunction() {
var x = document.getElementById("myText").value;
for(let i = 0; i <= x; i++) {
x.innerHTML += i + "<br />"
}
x.innerHTML = 'Tadaaaa'
}
the issue was that you were over-writing the innerHtml instead of appending.
here's an example of how you can change innerHTML whenever the input changes:
<input value="5" id="myText" onchange="myFunction()">
<div id="secondblock"></div>
<script>
function myFunction() {
var x = document.getElementById("myText").value;
document.getElementById("secondblock").innerHTML = "";
if ( (x >> 0) > 0 ) {
for (let i = 0; i < x; i++) {
document.getElementById("secondblock").innerHTML += (i + 1) + "<br />"
}
}
}
</script>
The problem is you are replacing inputs in for loop everytime. Instead you need to concat every input and then replace with innerHTML. Check below:
function myFunction() {
let value = document.getElementById("myText").value;
let x = parseInt(value)
if (!isNaN(x) && parseInt(x) > 0 ) {
let finalStr = '';
for(let i=1;i<=x;i++){
finalStr += i +'<br />'
}
document.getElementById("secondblock").innerHTML = finalStr;}
}
Does the function get called?
put console.log in first line to check
if it doesn't get called check your html do you have an event attached with the function?
for the function:
function myFunction() {
console.log('do i get called?');
var x = document.getElementById("myText").value;
if ( (x >> 0) > 0 ) {
//get the element
var el = document.getElementById("secondblock");
//clean html for next call
el.innerHTML = '';
for (let i = 1; i <= x; i++) {
// you were overriding second block instead of adding to it
el.innerHTML += i + "<br />"
}
}
}
You can use this below:
function myFunction() {
var x = document.getElementById("myText").value;
if ( isNaN(x) ) {
for ( --- I've tried everything I can think of here but nothing works -- )
{
document.getElementById("secondblock").innerHTML = x + "<br />"
}
}
}
OR
function myFunction() {
var x = document.getElementById("myText").value;
if ( typeof(x) == 'number' ) {
for ( --- I've tried everything I can think of here but nothing works -- )
{
document.getElementById("secondblock").innerHTML = x + "<br />"
}
}
}

Unexpected behavior in simple jquery selector script

EDIT: If anyone, ever need this script for some reason, i made a cleaner fully working version: https://jsfiddle.net/qmgob1d5/3/
I have a jquery script that is supposed to highlight elements in a from-to manner. It should work backwards as well.
Here is working fiddle: https://jsfiddle.net/qmgob1d5/
It works fine, until I select zero (first box) as second element. Then the var Start = Math.min(ClickOne, ClickTwo || 16); doesn't seems to work as expected. What went wrong?
Here is the script:
var FirstClick;
var ClickOne;
var ClickTwo;
$('.ColorPreview').on('click',function() {
var ColorId = $(this).attr('id');
ColorId = Number(ColorId.split('_')[1]);
if (!FirstClick) {
//reset function
for (var i = 0; i < 16; i++) {
$('#Color_' + i).removeClass('SelectColor'); }
var ClickTwo;
ClickOne = ColorId;
FirstClick = true;
}
else {
ClickTwo = ColorId;
FirstClick = false; }
console.log('ClickOne ' + ClickOne)
console.log('Clicktwo ' + ClickTwo)
var Start = Math.min(ClickOne, ClickTwo || 16);
var End = Math.max(ClickOne, ClickTwo || 0);
console.log('start ' + Start)
console.log('end ' + End)
for (var i = Start; i <= End; i++) {
$('#Color_' + i).addClass('SelectColor'); }
});
When ClickTwo is 0, the expression ClickTwo || 16 will evaluate to 16.
Try
var Start = Math.min(ClickOne, ClickTwo == null ? 16 : ClickTwo);
Or else initialize ClickTwo to 16 at the beginning of the function.

Show modal and wait for action for each element while looping

I'm looking for simple solution for a loop where I have to confirm each element. I was looking at pausing and resuming, but it's quite a hassle. Is there any other way to make it easy? I'm sure that this problem is not so rare and many people have stuck upon it.
What I want to achieve is this - I'm looping through the list and if I don't find item by its EAN code then it opens search function to find this and after the item is found (or not) user clicks Next and resume with looping until same situation occurs.
Some code that I have for now:
for(var f = 0; f < biLen; f++){
var ean_parsed = parsedList[i][1];
if(beerList[f].get("ean") === ean_parsed){
console.log("Beer found: " + beerList[f].get("beer_name"));
break;
} else {
if(f === biLen - 1){
//open modal, search for item and then continue looping
console.log("B'r not found: " + parsedList[i][0]);
}
}
}
edit (whole function code instead of piece of it):
function parserCompareList(){
var parsedList = parseResult;
var piLen = parsedList.length;
var beerList = listaPiwArr;
var biLen = beerList.length;
var new_offer = [];
var counter = document.getElementById('imHeader');
for(var i = 0; i < piLen; i++){
counter.innerHTML = i + "/" + piLen; //plain text that's keeping where we actually are with this
for(var f = 0; f < biLen; f++){
var ean_parsed = parsedList[i][1];
if(beerList[f].get("ean") === ean_parsed){
console.log("Beer found: " + beerList[f].get("beer_name"));
break;
} else {
if(f === biLen - 1){
console.log("B'r not found: " + parsedList[i][0]);
}
}
}
}
}
ANSWER:
var indexCache;
function loop() {
var index = indexCache || 0;
for (var f = index; f < biLen; f++) {
var ean_parsed = parsedList[i][1];
if (beerList[f].get("ean") === ean_parsed) {
console.log("Beer found: " + beerList[f].get("beer_name"));
break;
} else {
if (f === biLen - 1) {
// Assuming $modal is the bootstrap modal
indexCache = f;
//$modal.modal().one('hide.bs.modal', loop);
$('#importModal').modal('show').one('hidden.bs.modal', loop) // <-- this one works like a charm
return;
}
}
}
}
loop();
var indexCache;
function loop() {
var index = indexCache || 0;
for (var f = index; f < biLen; f++) {
var ean_parsed = parsedList[i][1];
if (beerList[f].get("ean") === ean_parsed) {
console.log("Beer found: " + beerList[f].get("beer_name"));
break;
} else {
if (f === biLen - 1) {
// Assuming $modal is the bootstrap modal
indexCache = f;
$modal.modal().one('hide.bs.modal', loop);
return;
}
}
}
}
loop();
We have an indexCache variable that holds the index of the beer that is being handled.
If EAN is found, great! we handle it and move on to the next beer.
If not, we store the current beer index in the cache and show the modal and quit the loop immediately. When the modal is hidden, the loop resumes from the cached index.
PS. I am assuming you are using Twitter Bootstrap modal. And therefore, adding a handler to the event 'hide.bs.modal'. But similar thing could be done with your own modal implementation if that is the case.

Multidimensional Array problems

I've been trying to fix this for about 3 days now, and I can't seem to find why it doesn't work.
I've got this function, which loads an image, and loads through all the pixels to create a grid of walls for A* pathfinding. I'm using CraftyJS to create this game, maybe it is that?
However, it seems to load perfectly fine, but when I try to use it in my game, it gives me loads of undefined values on most of the tiles. In fact, I feel like it only fills one row, instead of all 45.
This is the function that fills the GRID:
var babyStart = 0, babyNodes = [], grid = new Array(new Array());
function getGridFromImage(img, worldWidth, worldHeight) {
var image = new Image(); //maak een image object
var c = document.getElementById("mapLoader");
var context = c.getContext("2d");
image.src = img; //pak het plaatje erbij
image.onload = function () {
context.drawImage(image, 0, 0);
var data = context.getImageData(0, 0, worldWidth, worldHeight); //Verkrijg de Pixeldata
console.log(data);
var count = 0, tmr = null, length = data.data.length, x = 0, y = 0;
babyNodes = [];
while(count <= length) {
grid[y] = new Array();
//Verkrijg de kleuren DATA
var r = data.data[count]; //Rood channel
var g = data.data[count + 1]; //Groen channel
var b = data.data[count + 2]; //Blauw channel
//console.log(data[0]);
//console.log("Count/length: " + count + "/" + length + ";r: " + r + ";g: " + g + ";b: " + b);
if (r == 0 && g == 0 && b == 0) {
grid[y][x] = 1;
} else {
grid[y][x] = 0;
}
if (b > 0) {
babyNodes[b - 255] = count;
}
if (g == 255) {
babyStart = count;
}
count += 4;
x++;
if (x >= worldWidth) {
y += 1;
x = 0;
}
}
loading = false;
};
};
Sorry the comments are dutch, but I think most of you don't even need these comments anyways :P.
I try to collect the data in another function in another JS file, it looks a little like this:
Crafty.scene("lvlWoonkamer", function () {
Crafty.sprite("images/levels/Woonkamer.png", {
achtergrond: [0,0,1280,720]
});
Crafty.e("2D, DOM, achtergrond").attr({x: 0, y: 0});
console.log("Starting grid count");
for (var i = 0; i < 45; i++) {
var str = "";
for(var ii = 0; ii <= 80; ii++) {
str += grid[i][ii] + ",";
console.log("[" + i + "][" + ii + "]");
}
str += ";";
}
console.log(str);
});
This is the output I receive:
undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,0,undefined,;
Sorry for the bad code blocks and stuff, I have no idea how it works XD (Just pressed ctrl + K and copy paste).
I have no idea why it's doing this, I tried all kinds of things with the multi-dimensional arrays, looked up a lot, copy pasted a lot but it just doesn't seem to work...
(I'm already glad it loads the image tbh XD).
I'm kinda new to JavaScript and HTML5 and all that, so please be easy on me.
Sem Wong.
Edit: So I found out that I was clearing the Array everytime I did grid[y] = new Array();, so I changed it to if (grid[y] == null) grid[y] = new Array();. Now it works partly better, still getting some undefines but I'll get to the bottom of it :).
Edit 2: I fixed it completely and pathfinding is working also (A* OP). Thanks everyone for helping! It was the getGridFromImage function that was failing me, because it constantly cleared my grid[y]. I got a fixed version below for those who had the same problem as I did (Don't think there's anyone as stupid as me , but I guess new developers might have the same issue)
var babyStartX = 0, babyStartY = 0, babyNodes = [], grid = new Array(new Array());
function getGridFromImage(img, worldWidth, worldHeight) {
var image = new Image(); //maak een image object
var context = document.getElementById("mapLoader").getContext("2d");
image.src = img; //pak het plaatje erbij
image.onload = function() {
context.drawImage(image, 0, 0);
var data = context.getImageData(0, 0, worldWidth, worldHeight); //Verkrijg de Pixeldata
console.log(data);
var count = 0, length = data.data.length, x = 0, y = 0;
while(count <= length) {
if (grid[x] == null) grid[x] = new Array();
//Verkrijg de kleuren DATA
var r = data.data[count]; //Rood channel
var g = data.data[count + 1]; //Groen channel
var b = data.data[count + 2]; //Blauw channel
//console.log(data[0]);
//console.log("Count/length: " + count + "/" + length + ";r: " + r + ";g: " + g + ";b: " + b);
if (r == 0 && g == 0 && b == 0) {
grid[x][y] = 1;
} else {
grid[x][y] = 0;
}
if (b > 0 && g == 0 && r == 0) {
babyNodes[b - 254] = [x,y];
}
if (g == 255 && b == 0 && r == 0) {
babyStartX = x;
babyStartY = y;
babyNodes[0] = [x,y];
}
count += 4;
x++;
if (x >= worldWidth) {
y += 1;
x = 0;
}
}
loading = false;
}; };
I am not familiar with Crafty, so sorry if I am wrong, but I suppose Scott Sauyet is right. JavaScript is by default asynchronous, so perhaps you are calling the second function before the first one finished?
There is some background information on callbacks here: http://recurial.com/programming/understanding-callback-functions-in-javascript/
The concept behind callbacks is that you can call a module inside another so they are always ran sequentially.
function build(argument1, argument2) {
// Do things
check;
}
function check() {
// Do things
}
Your case would probably be something like this, but I can't really tell from your code.
function getGridFromImage(img, worldWidth, worldHeight) {
// Rest of your function
check;
}
function check() {
Crafty.scene("lvlWoonkamer", function () {
Crafty.sprite("images/levels/Woonkamer.png", {
achtergrond: [0,0,1280,720]
});
Crafty.e("2D, DOM, achtergrond").attr({x: 0, y: 0});
console.log("Starting grid count");
for (var i = 0; i < 45; i++) {
var str = "";
for(var ii = 0; ii <= 80; ii++) {
str += grid[i][ii] + ",";
console.log("[" + i + "][" + ii + "]");
}
str += ";";
}
console.log(str);
});
}
// Actually start the first function here;
getGridFromImage(img, worldWidth, worldHeight);

I don't understand this substring error

I noticed FireFox reports an error in my code, but can't understand what is wrong.
[13:36:02.868] TypeError: arr[i][0].substring is not a function # file:///home/asdf/Desktop/app/dic.js:10
Which seems to point to the ss variable line. AFAIK, I'm using it correctly (ie on the end of a string). Here the code snippet...
// quick array example...
var arr = [
["tammikuuta", "January"],
["helmikuuta", "February"],
["maaliskuuta", "March"]
];
function userInput(val){
var result = document.getElementById('result');
result.innerHTML = '';
if(val && val.length > 2){
for(var i = 0; i < arr.length; i++){
var ss = arr[i][0].substring(0,val.length); // ss (SubString) checks the number of characters currently typed
if(ss.toLowerCase() !== val.toLowerCase()){ // check substring against the user input
continue;
}
else { // display the output...
var res = arr[i][1];
var reg = eval('/'+val+'/i');
var found = arr[i][0].replace(reg, '<span class="r">$&<\/span>');
if(result.innerHTML.length > 0){
result.innerHTML += ',<br />';
}
result.innerHTML += found + '<b>' + ' > ' + '</b>' + '<span class="g">' + res + '<\/span>';
}
}
}
else {return;}
}
Please advice?
Edited: More code requested.
try this
var ss = arr[i][0].toString()
ss = ss.substring(0,val.length);

Categories