Changing location of html element dynamically using javascript - javascript

I am trying to change the pixel location of an html element using JavaScript. My function should take in a user input for the location and change the pixel coordinates according to an array.
This function should create a button at the user inputted location, but nothing happens. I think the issue is with setting a style attribute that requires both a text string and the variable that stores the location string. Any help would be appreciated.
var arr = [
["A1", "left:81px;"],
["A2", "left:145px;"]
]
function moveObject(arr) {
var location = prompt("Enter location", "A1");
var i;
for (let i = 0; i < arr.length; i++) {
if (arr[i][0] === location) {
destination = arr[i][1] + ";";
}
}
var box = document.createElement("button");
box.setAttribute("style", "position: absolute;");
box.setAttribute("style", destination)
box.innerText = location;
document.body.appendChild(box);
}
moveObject(arr)

Combine the css value strings and only call setAtrribute('style') once.
The second call wipes out the first
You are also adding an extra ; when it already exists in the value in your array.
Note I have not added any validation that the user entered value exists in the array. You will need to do that yourself before adding undefined values in the style
var arr = [
["A1", "left:81px;"],
["A2", "left:145px;"]
]
function moveObject(arr) {
var location = prompt("Enter location", "A1");
var i;
for (let i = 0; i < arr.length; i++) {
if (arr[i][0] === location) {
destination = arr[i][1] ;
}
}
var box = document.createElement("button");
// combine style values
box.setAttribute("style", "position: absolute;" + destination);
box.innerText = location;
document.body.appendChild(box);
}
moveObject(arr)

Several issues
I removed a stray " and added some text. Then I moved the left from the string and used the location as a lookup table instead
var arr = {
"A1": {"left":"81px"},
"A2": {"left":"145px"}
}
function moveObject(arr) {
var location = prompt("Enter location", "A1");
if (arr[location]) {
var box = document.createElement("button");
box.setAttribute("style", "position: absolute;");
var key = Object.keys(arr[location])
box.style[key] = arr[location][key]
box.innerText = location;
document.body.appendChild(box);
}
else alert("Location '"+location+"' not available")
}
moveObject(arr)

Related

Replace window when script ends JavaScript/HTML [duplicate]

This question already has answers here:
Window location replace - timeout help? Javascript question
(2 answers)
Closed 1 year ago.
Is there a way I can insert:
location.replace("https://www.google.com");
After all the functions in my javascript have run, aka when my script ends? I've tried putting it in different parts of my script but it just replaces it straight away.
This is my script currently (sorry it's so long its a text adventure game):
var currentFrame = 0;
var images = document.getElementById("images");
var text = document.getElementById("text");
var buttonBox = document.getElementById('buttonBox');
var input = document.getElementById('input');
//this is the variable for the name of the character
var yerdog;
//this is how after we type in the character name and hit enter
//we will add the name to the variable, remove the input box and start our first scenario
input.onkeypress = function(event) {
console.log(input.value);
if (event.key == "Enter" || event.keyCode == 13) {
yerdog = input.value;
input.parentNode.removeChild(input)
advanceTo(scenario.two)
}
};
//this changes the text and puts in your characters name
var changeText = function(words) {
text.innerHTML = words.replace("Your dog", yerdog);
};
//this takes the image link and puts it in the proper format, sending it to the html
var changeImage = function(img) {
images.style.backgroundImage = "url(" + img + ")";
};
//this looks at the number of options we have set and creates enough buttons
var changeButtons = function(buttonList) {
buttonBox.innerHTML = "";
for (var i = 0; i < buttonList.length; i++) {
buttonBox.innerHTML += "<button onClick="+buttonList[i][1]+">" + buttonList[i][0] + "</button>";
};
};
//this is what moves the game along
var advanceTo = function() {
if (currentFrame >= scenario.length) {
//finish the game code here:
location.replace("https://www.google.com");
}
var s = scenario[currentFrame];
changeImage(s.image)
changeText(s.text)
changeButtons(s.buttons)
};
var scenario = [
one: {
image: "https://s9.postimg.org/eceo9mp73/5860028206_d66810105f_b.jpg", //dog
text: "You have finally decided to take your dog out for a walk. You smile and pat your trusty companion's head. What the dog's name?\n",
},
];
input.onkeypress = function(event) {
console.log(input.value);
if (event.key == "Enter" || event.keyCode == 13) {
yerdog = input.value;
input.parentNode.removeChild(input)
currentFrame = currentFrame + 1; // <--- here
advanceTo() // <-- and here
}
};
//this is the code that starts the game
advanceTo(scenario.one);
You can use ifelse statement as well as timeout for it
setTimeout ( "location()", 5000 );
function location( )
{
location.replace("https://www.google.com");
}
var currentFrame = 0;
var images = document.getElementById("images");
var text = document.getElementById("text");
var buttonBox = document.getElementById('buttonBox');
var input = document.getElementById('input');
//this is the variable for the name of the character
var yerdog;
var scenario = [
{
image: "https://s9.postimg.org/eceo9mp73/5860028206_d66810105f_b.jpg", //dog
text: "You have finally decided to take your dog out for a walk. You smile and pat your trusty companion's head. What the dog's name?\n",
buttons: [],
},
]
//this changes the text and puts in your characters name
var changeText = function(words) {
text.innerHTML = words.replace("Your dog", yerdog);
};
//this takes the image link and puts it in the proper format, sending it to the html
var changeImage = function(img) {
images.style.backgroundImage = "url(" + img + ")";
};
//this looks at the number of options we have set and creates enough buttons
var changeButtons = function(buttonList) {
buttonBox.innerHTML = "";
for (var i = 0; i < buttonList.length; i++) {
buttonBox.innerHTML += "<button onClick="+buttonList[i][1]+">" + buttonList[i][0] + "</button>";
}
};
//this is what moves the game along
var advanceTo = function() {
if (currentFrame >= scenario.length) {
//finish the game code here:
console.log("end of the game");
//location.replace("https://www.google.com"); // uncomment on your page
return;
}
var s = scenario[currentFrame];
changeImage(s.image)
changeText(s.text)
changeButtons(s.buttons)
};
input.onkeypress = function(event) {
console.log(input.value);
if (event.key == "Enter" || event.keyCode == 13) {
yerdog = input.value;
input.parentNode.removeChild(input)
currentFrame = currentFrame + 1; // <--- here
advanceTo() // <-- and here
}
};
//this is the code that starts the game
advanceTo();
<div id="images"></div>
<div id="text"></div>
<div id="buttonBox"></div>
<input type="text" id="input"/>
Based on the code your posted you have 3 important parts:
the advanceTo function
the input.onkeypress event
the scenario list
for that I can suggest one of two changes:
change the scenario to an array (end and call the replace when there is no more elements)
add a end scenario (that calls the replace when it comes to it)
Array approach:
you can change the scenario to an array instead an object:
var scenario = [
{
image: "https://s9.postimg.org/eceo9mp73/5860028206_d66810105f_b.jpg", //dog
text: "You have finally decided to take your dog out for a walk. You smile and pat your trusty companion's head. What the dog's name?\n",
},
{
image: "https://s9.postimg.org/eceo9mp73/5860028206_d66810105f_b.jpg", //dog
text: "You have finally decided to take your dog out for a walk. You smile and pat your trusty companion's head. What the dog's name?\n",
},
]
Also store the current frame in a variable (I suggest at the top of your code):
var currentFrame = 0;
So you can call advanceTo and starting the game (we are not passing the index anymore because is stored in the currentFrame variable:
advanceTo()
and change the logic of the advanced to a little bit:
var advanceTo = function() {
if (currentFrame >= scenario.length) {
//finish the game code here:
location.replace("https://www.google.com");
return;
}
var s = scenario[currentFrame];
changeImage(s.image)
changeText(s.text)
changeButtons(s.buttons)
};
At the end, you need to change your input.onkeypress event:
input.onkeypress = function(event) {
console.log(input.value);
if (event.key == "Enter" || event.keyCode == 13) {
yerdog = input.value;
input.parentNode.removeChild(input)
currentFrame = currentFrame + 1; // <--- here
advanceTo() // <-- and here
}
};

Saving a couple of strings in the local storage

I'm trying to save some strings in the local storage, I'm trying to do this but I get undefined in the local storage.
I'm asking the user for the players names, and then I want to store them in the local storage in order to use them again.
Here's what I'm trying :
const x = localStorage.getItem('playersNum');
const parentDiv = document.getElementById('player-list');
for (let i = 0; i < x; i++) {
const newInput = document.createElement("INPUT");
newInput.setAttribute("type", "text");
newInput.setAttribute("class", "form-control");
newInput.setAttribute("id", `player${i}`);
newInput.setAttribute("placeholder", "Player's Name");
parentDiv.appendChild(newInput);
}
//get all input elements of type text and starting id with player
const input = document.querySelectorAll("[type='text'][id^='player']");
const btn = document.getElementById('startGame');
btn.addEventListener('click', function() {
//reset border style of all input elements
[...input].forEach(el => el.style.border = '');
//get all empty input elements
let empty = [...input].filter(el => el.value.trim() == "");
//check length
if (empty.length) {
//show alert
// alert('Please fill in the players names');
//set border style to empty input elements
empty.forEach(el => el.style.border = '1px solid red');
}
else {
window.location.assign('game.html');
localStorage.setItem('playersNames', String(input.value));
}
});
You're declaring input with querySelectorAll, so you need to read input as an array.
localStorage.setItem('playersNames', String(input[0].value));
Then, if you want all player's names you will need to iterate through the array. Also, you need to get the previous value of localStorage and append to it, since it gets overwritten every time you set it.
const input = document.querySelectorAll("[type='text'][id^='player']");
for (i=0; i < input.length; i++) {
var checkForStorage = localStorage.getItem('playersNames');
if (checkForStorage !== null) {
localStorage.setItem('playersNames', checkForStorage + ',' + String(input[i].value))
} else {
localStorage.setItem('playersNames', String(input[i].value));
}
};

How can I display my var array name in HTML textblock?

I want to display my var array names in a textblock. These need to change depending on what box is ticked in my form.
Now I can show the values in the array, but I need to display the actual name too. I am VERY new to coding, and I have trouble finding the right words to describe my problem, thus not finding any solution. I hope you can help me out.
var color_prices = new Array();
color_prices["Orange"]=1;
color_prices["Blue"]=2;
color_prices["Green"]=3;
function getColorPrice()
{
var ColorPrice=0;
var theForm = document.forms["order-form"];
var selectedColor = theForm.elements["COLOR"];
for(var i = 0; i < selectedColor.length; i++)
{
if(selectedColor[i].checked)
{
ColorPrice = color_prices[selectedColor[i].value];
break;
}
}
return ColorPrice;
}
var colorPrice = getColorPrice();
document.getElementById('colorPrice').innerHTML = colorPrice.toFixed(2);
Right now I 'stole' some code online to display the value of "orange" in my html (so "1") and this works but I have no idea how to display the value "orange" in my html.
I hope I explained it correctly.
A solution could be to change your ColorPrice variable to be an object to be able to store the color price and the color name, in my example I'm also changing the name of the variable to colorDetails to be more descriptive about what is containing
var color_prices = new Array();
color_prices["Orange"]=1;
color_prices["Blue"]=2;
color_prices["Green"]=3;
function getColorDetails()
{
//here we rename the variable and convert from integer to object
var colorDetails = {
price: 0,
name: undefined
};
var theForm = document.forms["order-form"];
var selectedColor = theForm.elements["COLOR"];
for(var i = 0; i < selectedColor.length; i++)
{
if(selectedColor[i].checked)
{
//here we store the color price inside colorDetails
colorDetails.price = color_prices[selectedColor[i].value];
//and we add this new line where we save the name of the color
colorDetails.name = selectedColor[i].value;
break;
}
}
return colorDetails;
}
var colorDetails = getColorDetails();
document.getElementById('colorPrice').innerHTML = colorDetails.name + ": " + colorDetails.price.toFixed(2);

Unable to parse json using javascript

I have a json which i'm trying to parse it using javascript. Iteration count and the pages getting appended to it are going to be dynamic.
Expected Result
Just like the above image i'm able to take dynamic iteration keys from the below mentioned json.
Iteration.json
{
"count":[
{
"iteration1":[
{
"PageName":"T01_Launch"
},
{
"PageName":"T02_Login"
}
]
},
{
"iteration2":[
{
"PageName":"T01_Launch"
},
{
"PageName":"T02_Login"
}
]
}
]
}
When i click on iteration it has to populate the corresponding pagenames for that particular iteration as shown in expected result image. But what i get actually is (refer the image below):
Please find the code that i tried:
var pagenamearray = [];
$.getJSON("iteration.json", function(json) {
var hits = json.count;
var iterations, tnname, iteration;
for (var k in hits) {
var value;
if (hits.hasOwnProperty(k)) {
value = hits[k];
var iteratearray = [];
for (var j in value) {
if (value.hasOwnProperty(j)) {
j;
var check = value[j];
for (var i in check) {
if (check.hasOwnProperty(i)) {
var test = check[i];
for (var t in test) {
if (test.hasOwnProperty(t)) {
var pagename = JSON.stringify(t)
var arr = []
if (pagename.includes("PageName")) {
//alert("Key is " +pagename + ", value is" + JSON.stringify(test[t]));
for (var it = 0; it < hits.length; it++) {
if ((Object.keys(hits[it])).includes(j)) {
var pagenamevalue = test[t];
arr[it] = [];
arr.push(pagenamevalue);
}
}
}
//alert(arr)
}
pagenamearray.push(arr);
}
}
}
}
var row = document.createElement('div');
row.setAttribute("class", "row");
row.setAttribute("id", j)
var gridWidth = document.createElement('div');
gridWidth.setAttribute("class", "col-lg-12");
var panelRoot = document.createElement('div');
panelRoot.setAttribute("class", "panel panel-default");
var panelHeading = document.createElement('div');
panelHeading.setAttribute("class", "panel-heading");
var heading3 = document.createElement('a');
heading3.setAttribute("class", "panel-title");
var icon = document.createElement('i');
icon.setAttribute("class", "fa fa-long-arrow-right fa-fw");
heading3.appendChild(icon);
heading3.innerHTML = j;
heading3.setAttribute("onclick", "doit('" + j + "');");
panelHeading.appendChild(heading3);
/* var panelBody=document.createElement('div');
panelBody.setAttribute("class","panel-body");
panelBody.setAttribute("id","panellinks");*/
panelRoot.appendChild(panelHeading);
// panelRoot.appendChild(panelBody)
gridWidth.appendChild(panelRoot);
row.appendChild(gridWidth);
document.getElementById("analysis").appendChild(row);
}
}
}
});
function doit(value) {
var ul = document.getElementById(value);
if (ul != undefined) {
$("#" + "expandlinks").remove();
$("#" + value + value).remove();
}
var accordion = document.getElementById(value);
var panelBody = document.createElement('div');
panelBody.setAttribute("class", "panel-body");
panelBody.setAttribute("id", "expandlinks")
var tablediv = document.createElement('div')
var tablelink = document.createElement('a');
tablediv.appendChild(tablelink);
var graphdiv = document.createElement('div')
var graphlink = document.createElement('a');
graphdiv.appendChild(graphlink);
var recommndiv = document.createElement('div');
var recommendlink = document.createElement('a');
recommndiv.appendChild(recommendlink)
//alert(pagenamearray.length)
tablelink.innerHTML = pagenamearray;
/*graphlink.innerHTML="Timeline View";
recommendlink.innerHTML="Recommendations";*/
panelBody.appendChild(tablediv);
panelBody.appendChild(recommndiv);
panelBody.appendChild(graphdiv);
accordion.appendChild(panelBody);
}
Any advise on how to achieve this would be of great help. Thanks in advance.
I think the problem is how you assign the pagenamearray to tablelink.innerHTML. This converts the array to a string, converting all elements in the array to a string too and separating them by a comma each. However, your pagenamearray contains some empty arrays too; these will convert to an empty string in the process, but will still have a comma before and after them.
In your example code above, the pagenamearray will end up with a value of [[[],"T01_Launch"],[[],"T02_Login"],[null,[],"T01_Launch"],[null,[],"T02_Login"]] - when converted to a String, this will result in ",T01_Launch,,T02_Login,,,T01_Launch,,,T02_Login". So instead of assigning it to the innerHTML value directly, you'll first have to filter out the empty arrays and null values.

How to prevent Javascript updating entire control, and refreshing content?

I have this code:
function addFormControls() {
var e = document.getElementById("ProductsList");
var prodid = e.options[e.selectedIndex].value;
var prodvalue = e.options[e.selectedIndex].text;
if (num == 0) {
document.getElementById("ProductsPanel").innerHTML = '<h3>Products added to Variant</h3>';
}
if (num < 10) {
var boolCheck = checkArrayData(prodid);
if (boolCheck == false) {
document.getElementById("ProductsPanel").innerHTML = document.getElementById("ProductsPanel").innerHTML + prodvalue + '<input type="text" id="' + prodid + 'product" value="0" width="50px" maxlenght="2" /><input type="button" onclick="updateArrayData(\'' + prodid + '\', document.getElementById(\'' + prodid + 'product\').value);" value="Update Number" /><br />';
num++;
prodIdArray.push({
'key': prodid,
'value': prodvalue,
'num': 0
});
document.getElementById("productsArray").value = prodIdArray;
} else {
alert("Sorry product has already been added!");
}
}
}
which happily updates a div tag with new info, however if you look at the section where it prints a text box to the screen, line 13, these textbox's will be updated by the user.
So in short, textboxs are added, and value update.
however if there is a textbox with value 5, then this function called again to add another textbox, the previous textbox' values will be wiped clean!
So, how do i prevent this, will i have to do some, for loop over div controls taking the values, then put them back after this function is called?!?
I create some javascript to save all the values in a particular input's value field before adding the control, then return all the saved values back to their respected inputs.
function saveValuesOfProducts()
{
// initialise the array
numOfProds = new Array();
// get all the elements which are inputs
var x=document.getElementsByTagName("input");
// remove all un necessary inputs
x = leaveTextInputs(x);
// loop through the entire list of inputs left saving their value
for (i=0; i<x.length; i++)
{
numOfProds.push(x[i].value);
}
}
function returnValuesOfProducts()
{
// get all the elements which are inputs
var x=document.getElementsByTagName("input");
// remove all un necessary inputs
x = leaveTextInputs(x);
// loop through the entire list of saved values and return them to the input
for (i=0; i<numOfProds.length; i++)
{
x[i].value = numOfProds[i];
}
}
function leaveTextInputs(value)
{
// create a new blank array
var newArr = new Array();
// loop through all the elements in passed array
for (i=0; i<value.length; i++)
{
// cache the element
var thevalue = value[i];
// check if the element is a text input
if (thevalue.type == "text")
{
// check the id consists of product in it!
var regexteststring = thevalue.id;
// create the pattern to match
var patt1 = /product/i;
if (regexteststring.match(patt1) == "product")
{
// as additional check, if it has a size quantity of 2 then its defo out stuff
if (thevalue.size == 2)
{
newArr.push(thevalue);
}
}
}
}
// now return the new array
return newArr;
}

Categories

Resources