Div container to expand with dynamic grid - javascript

this is kind of a two parter. I have a dynamic grid composed of divs (.unit) that I'm trying to contain in one larger div (#pallet). The grid increases based on the integer the user gives in a prompt. My question is how do I get the larger div to expand relative to the size of my grid without using absolute positioning? Also the grid isn't ever reduced to the user given value, it only increases. Any help would be much appreciated!
$(document).ready(function() {
var userChoice = 10;
for(var x = 0; x < userChoice; x++) {
for(var y = 0; y < userChoice; y++) {
var unit = $("<div class='unit'></div>");
unit.appendTo('#pallet'); //puts div "unit" into div "pallet" using appendTo
}
}
$(".unit").hover(function(){ //jquery selects the "unit" div and issues a function on it to change the css
$(this).css("background-color", "black"); //this is in reference to .unit changing the css to black
});
document.getElementById("reset").onclick = gridReset; //reset is the id of our button, so when it's clicked it will call our function gridReset
function gridReset() { //function grid reset first asks a prompt then stores the user's choice value in a variable and puts it through checks to see if its valid
userChoice = prompt("Between 1 and 64 how big would you like your grid?"); //we put our user choice in the function so as to not call a prompt at the start of the page load AND to store the variable in the scope
if (isNaN(userChoice)) {
alert(userChoice + " is not a number");
}
else if (userChoice >= 65 || userChoice <= 0) {
alert("Choose a number between 1 and 64");
}
else {
$(".unit").empty();
$(".unit").css("background-color", "blue");
for(var x = 0; x < userChoice; x++) { //for loop creates iteration of userChoice
for(var y = 0; y < userChoice; y++) { //for loop creates iteration of userChoice
var unit = $("<div class='unit'></div>"); //creates a variable "unit" = to a jquery div element with a class of unit
unit.appendTo('#pallet'); //puts div "unit" into div "pallet" using appendTo
$(".unit").hover(function(){ //jquery selects the "unit" div and issues a function on it to change the css
$(this).css("background-color", "black"); //this is in reference to
.unit changing the css to black
});
}
}
}
}
});
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Odin Div Project</title>
<link rel="stylesheet" type="text/css" href="styles/styles.css" />
</head>
<body>
<button id="reset" type="button">Reset Grid</button>
<div id="pallet">
</div>
<script type="text/javascript" src="scripts/jquery-3.2.0.min.js">
</script>
<script type="text/javascript" src="scripts/script.js"> </script>
</body>
</html>
CSS:
#pallet {
position: relative;
left: 425px;
top: 150px;
background-color: black;
height: 440px;
width: 440px;
}
.unit {
position: relative;
background-color: blue;
height: 20px;
width: 20px;
margin: 1px;
display: inline-block;
float: left;
}

Related

The button only works once

The following code on the website page creates a button that the user receives a random number at any time by clicking the button:
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>rand100.html</title>
<style type = "text/css">
fieldset {
width: 600px;
margin-right: auto;
margin-left: auto;
}
label {
float: left;
width: 250px;
text-align: right;
margin-right: 1em;
clear: left;
}
span {
float: left;
}
button {
display: block;
clear: both;
margin: auto;
}
</style>
<script type = "text/javascript">
function roll(){
//create variables for form elements
var spnRaw = document.getElementById("spnRaw");
var spn100 = document.getElementById("spn100");
var spnFinal = document.getElementById("spnFinal");
//get random number
var raw = Math.random();
spnRaw.innerHTML = raw;
//multiply by 100
var times100 = raw * 100;
spn100.innerHTML = times100;
//get the ceiling
var final = Math.ceil(times100);
spnFinal.innerHTML = final;
} // end roll
</script>
</head>
<body>
<h1>Make random numbers 1 - 100</h1>
<form>
<fieldset>
<label>raw</label>
<span id = "spnRaw">0</span>
<label>times 100</label>
<span id = "spn100">0</span>
<label>final</label>
<span id = "spnFinal">0</span>
<button type = "button"
onclick = "roll()">
roll the dice
</button>
</fieldset>
</form>
</body>
</html>
Now I want to make every user receive just one random number, that is, if the user clicks on the button and receives a random number, and again clicking on the button, this time a new random number will not be displayed.
That is, each user, if more than once, clicks the button, only receives a random number, no more.
How can I do this now?
That is to change the code so that even if the user after opening the site and clicking the button and then receiving the random number, clicked the button again, a new random number will not be received.
Please check the below code. just use a boolean e.g doRoll variable and set it to true. When you call roll() for the first time set the boolean variable to false after getting the random number.
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>rand100.html</title>
<style type = "text/css">
fieldset {
width: 600px;
margin-right: auto;
margin-left: auto;
}
label {
float: left;
width: 250px;
text-align: right;
margin-right: 1em;
clear: left;
}
span {
float: left;
}
button {
display: block;
clear: both;
margin: auto;
}
</style>
<script type = "text/javascript">
var doRoll = true;
function roll(){
if(doRoll)
{
//create variables for form elements
var spnRaw = document.getElementById("spnRaw");
var spn100 = document.getElementById("spn100");
var spnFinal = document.getElementById("spnFinal");
//get random number
var raw = Math.random();
spnRaw.innerHTML = raw;
//multiply by 100
var times100 = raw * 100;
spn100.innerHTML = times100;
//get the ceiling
var final = Math.ceil(times100);
spnFinal.innerHTML = final;
doRoll = false;
}
} // end roll
</script>
</head>
<body>
<h1>Make random numbers 1 - 100</h1>
<form>
<fieldset>
<label>raw</label>
<span id = "spnRaw">0</span>
<label>times 100</label>
<span id = "spn100">0</span>
<label>final</label>
<span id = "spnFinal">0</span>
<button type = "button"
onclick = "roll()">
roll the dice
</button>
</fieldset>
</form>
</body>
</html>
You can define the value before the function:
var random = Math.random();
function roll() {
...
}
Or set it inside the function only if it is undefined:
var random;
function roll() {
if (typeof random === 'undefined') {
random = Math.random();
}
...
}
Or create some flag:
var rolled = false;
function roll() {
if (rolled) {
return;
}
...
rolled = true;
}
Or remove an event listener from the button:
function roll() {
...
button.onclick = null;
}
The link to the button object you can get from the event object:
function roll(event) {
...
event.target.onclick = null;
}

Two div with same class name overlapping each other

On clicking a button my program will create a dynamic div with a class name dynamictextbox . There is a label with the class name mytxt and textbox with class name mytext inside this div which is also dynamically created.
When i create a new dynamic div it is overlapping with previously created div.
Below is the CSS i've used
.dynamictextbox{
width:50%;
position:relative;
padding:10;
}
.dynamictextbox .mytxt{
position:absolute;
left:0px;
right:50%;
}
.dynamictextbox .mytext{
position:absolute;
left:51%;
right:100%;
}
Below is the HTML code
<div id="Enter your name" class="dynamictextbox">
<label class="mytxt">Enter your name</label>
<input type="text" name="Enter your name_name" id="Enter your name_id" class="mytext">
</div>
<br />
<div id="bigData" class="dynamictextbox">
<label class="mytxt">Now this is a long text which will overlap the next div.Need solution for this. Please give me a solution for this</label>
<input type="text" name="bigData_name" id="bigDate_id" class="mytext">
</div>
<br />
<div id="div_temp" class="dynamictextbox">
<label id="txtlb" class="mytxt">Dynamic Label</label>
<input type="text" name="tb" id="tb" class="mytext">
</div>
<br />
What you need here, is to expand the element according to the content height. Unfortunately you cannot do this using CSS. So we'll have to move along with javascript.
Here goes the script
<script>
var max = 0;
function setHeight() {
var elements = document.getElementsByClassName('mytxt');
var height = 0;
for (var i = 0; i < elements.length; i++) {
height = elements[i].scrollHeight;
if (height > max) {
max = height;
}
}
elements = document.getElementsByClassName('dynamictextbox');
for (var i = 0; i < elements.length; i++) {
elements[i].style = "min-height: " + max + "px";
}
}
</script>
At the end of all the divs call the funtion setHeight().
<script>setHeight()</script>
So the output will look like this
P.S. I've added borders to the class dynamictextbox for testing purposes.
This may be helpful - JSFIDDLE
Just remove the .mytxt class from your CSS and increase the left attribute of .mytext class
.dynamictextbox .mytext{
position:absolute;
left:60%;
right:100%;
}
Update the code below. Is this what you where going after?
$("#add").on("click", function(){
// just a helper function for some random content
function dynamicText(){
var min = 1;
var max = 50;
var random = Math.floor(Math.random() * max) + min;
var text = "";
for(var i = 0; i < random; i++){
text += "text ";
}
return text;
}
// add to the container
var addMe = "\
<div class='dynamictextbox'>\
<label class='mytxt'>"+dynamicText()+"</label>\
<textarea class='mytext'>"+dynamicText()+"</textarea>\
</div>\
";
var container = $("#container");
container.append(addMe);
});
.dynamictextbox{
width:50%;
padding:10;
margin-top: 10px;
background: #CCC;
overflow: auto;
}
.dynamictextbox .mytxt{
position: relative;
float: left;
width: calc(50% - 10px);
}
.dynamictextbox .mytext{
float: right;
width: calc(50% - 10px);
height: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
On clicking a button my program will create a dynamic div with a class name dynamictextbox . There is a label with the class name mytxt and textbox with class name mytext inside this div which is also dynamically created.
<br><hr><br>
<button id="add">ADD</button><br><br>
<div id="container"></div>

How do I add a button to my code that changes something on a timed basis?

I have a working traffic light in JavaScript that changes every time I press the button, how do I make it so if I press another button it will change color automatically on a timed basis?
My current code is the following:
<!DOCTYPE html>
<html>
<head>
<style>
#black {
background: black;
padding: 20px;
width: 150px;
height: 450px;
}
#red {
border-radius: 100px;
background: red;
width: 130px;
height: 130px;
position: relative;
top: 10px;
left: 10px;
}
#amber {
border-radius: 100px;
background: orange;
width: 130px;
height: 130px;
position: relative;
top: 20px;
left: 10px;
}
#green {
border-radius: 100px;
background: green;
width: 130px;
height: 130px;
position: relative;
top: 30px;
left: 10px;
}
</style>
</head>
<body>
<script>
var seq = [["red","grey","grey"],["red","orange","grey"],["grey","grey","green"],["grey","orange","grey"]];
var y = 0;
function lights() {
if (y < 4){
var current = seq[y];
var r = current[0];
var a = current[1];
var g = current[2];
document.getElementById("red").style.background= r;
document.getElementById("amber").style.background= a;
document.getElementById("green").style.background = g;
y++
} else {
y = 1
document.getElementById("red").style.background= "red";
document.getElementById("green").style.background= "grey";
document.getElementById("amber").style.background = "grey";
}
}
</script>
<div id="black">
<button onclick=lights()>Next cycle</button>
<div id="red"></div>
<div id="amber"></div>
<div id="green"></div>
</div>
</body>
</html>
If you want to schedule some code to run once after a certain amount of time has passed, use setTimeout. For example if you have a function doColorChange that takes a color argument, then in your click handler you could say something like:
doColorChange('green'); // set the color now
setTimeout(function () {doColorChange('yellow');}, 2000);
setTimeout(function () {doColorChange('red');}, 4000);
Note that the functions you pass to setTimeout are not guaranteed to run after exactly the amount of time you specify. They are queued up and become eligible to run after that amount of time.
If you want to have the same code run over and over again, you can use setInterval instead. For example if you have a toggleColor function you could do
setInterval(toggleColor, 2000);
to call it (roughly) every 2 seconds.
Hello please revised the following code, hope this works for you. It's not using any jQuery only raw JS and HTML.
traffic-light.js
// Initialize variables at runtime
var currentSignalState = null,
previousSignalState = null,
trafficLight,
signalChangeLoop;
// Fire the constructor when DOM is available
window.onload = function () {
trafficLight = document.getElementById("traffic-light");
construct();
};
// Constructor function definition
function construct(){
// Assign initial values for your signal states
currentSignalState = "green";
// Between Green and Red states is alwasy yellow so let's initialize it
previousSignalState = "yellow";
// When DOM is ready the paragraph can be found and we can then assign the initial value of the state
trafficLight.innerHTML = currentSignalState;
}
// Manually change the traffic light's value
function changeTrafficSignal(){
// Local variable representing the next state
var newSignalState = "";
// Between Green and Red is always Yellow
if(currentSignalState == "green" || currentSignalState == "red"){
newSignalState = "yellow";
// If state is Yellow and is coming from a Red state
} else if(currentSignalState == "yellow" && previousSignalState == "red" ){
newSignalState = "green";
// Will catch state Yellow coming from Green
} else{
newSignalState = "red";
}
// Update our global values to be used on next iteration
previousSignalState = currentSignalState;
currentSignalState = newSignalState;
trafficLight.innerHTML = newSignalState;
}
// Initiate an interval loop to change the traffic signal state
function startTrafficSignalAuto(){
// *Suggested: alter to pass a parameter and make the interval value dynamic
signalChangeLoop = setInterval(changeTrafficSignal, 2000);
}
// Stop the interval loop
function stopTrafficSignalAuto(){
clearInterval(signalChangeLoop);
}
index.html
<!-- Loads the Javascript and fires the constructor -->
<script src="traffic-light.js" type="text/javascript"></script>
<!-- Paragraph where the value of the current traffic light state is displayed-->
<p id="traffic-light"></p>
<!-- Will change the signal state based on current and previous signal states -->
<button onclick="changeTrafficSignal()">Manual Change</button>
<!-- Will initiate the interval to auto change || Sugested: supply a dynamic time by passing it as a parameter -->
<button onclick="startTrafficSignalAuto()">Automatic Start</button>
<!-- Will stop the interval loop -->
<button onclick="stopTrafficSignalAuto()">Automatic Stop</button>

How can I change the x position of a div via javascript when I click on another div this way?

<body>
<div id = "SiteContainer">
<div id = "NavigationButtons"></div>
<div id = "ShowReelContainer">
<div id= "NavigationBackward" name = "back" onclick="setPosition();">x</div>
<div id= "NavigationForward" name = "forward" onclick="setPosition();">y</div>
<div id = "VideoWrapper">
<div id = "SlideShowItem">
<img src="Images/A.png" alt="A"></img>
</div>
<div id = "SlideShowItem">
<img src="Images/B.png" alt="B"></img>
</div>
<div id = "SlideShowItem">
<img src="Images/C.png" alt="C" ></img>
</div>
</div>
</div>
</div>
<script>
var wrapper = document.querySelector("#VideoWrapper");
function setPosition(e)
{
if(e.target.name = "forward")
{
if!(wrapper.style.left = "-200%")
{
wrapper.style.left = wrapper.style.left - 100%;
}
}
else
{
if(e.target.name = "back")
{
if!(wrapper.style.left = "0%")
{
wrapper.style.left = wrapper.style.left + 100%;
}
}
}
}
</script>
</body>
Hi, I am very new to javascript. What I am trying to do, is change the x-position of a div when another div (NavigationForward or NavigationBackward) is clicked. However it does not appear to do anything at all. Basically if the div with name forward is clicked, I want to translate the VideoWrapper -100% from it's current position and +100% when "back". The css div itself VideoWrapper has a width of 300%. Inside this div as you can see is a SlideShowItem which is what will change. Perhaps I am adding and subtracting 100% the wrong way?
EDIT:
Thanks everyone for helping me out with this...I had just one more query, I am trying to hide the arrows based on whether the wrapper is at the first slide or the last slide. If its on the first slide, then I'd hide the left arrow div and if it's on the last, I'd hide the right arrow, otherwise display both of em. Ive tried several ways to achieve this, but none of em work, so Ive resorted to using copies of variables from the function that works. Even then it does not work. It appears that my if and else if statements always evaluate to false, so perhaps I am not retrieving the position properly?
function HideArrows()
{
var wrapper2 = document.getElementById("VideoWrapper");
var offset_x2 = wrapper2.style.left;
if(parseInt(offset_x2,10) == max_x)
{
document.getElementById("NavigationForward").display = 'none';
}
else if(parseInt(offset_x2,10) == min_x)
{
document.getElementById("NavigationBackward").display = 'none';
}
else
{
document.getElementById("NavigationForward").display = 'inline-block';
document.getElementById("NavigationBackward").display = 'inline-block';
}
}
//html is the same except that I added a mouseover = "HideArrows();"
<div id = "ShowReelContainer" onmouseover="HideArrows();">
To achieve this type o slider functionality your div VideoWrapper must have overflow:hidden style, and your SlideShowItemdivs must have a position:relative style.
Then to move the slides forward or backward you can use the style left which allows you to move the divs SlideShowItem relative to it's parent VideoWrapper.
I've tested this here on JSFiddle.
It seems to work as you described in your question, although you may need to do some adjustments, like defining the width of your slides, how many they are and so on.
For the sake of simplicity, I defined them as "constants" on the top of the code, but I think you can work from that point on.
CSS
#VideoWrapper{
position:relative; height:100px; white-space:nowrap;width:500px;
margin-left:0px; border:1px solid #000; overflow:hidden; }
.SlideShowItem{
width:500px; height:100px;display:inline-block;position:relative; }
#NavigationForward, #NavigationBackward{
cursor:pointer;float:left; background-color:silver;margin-right:5px;
margin-bottom:10px; text-align:center; padding:10px; }
HTML
<div id = "SiteContainer">
<div id = "NavigationButtons">
</div>
<div id = "ShowReelContainer">
<div id= "NavigationBackward" name = "back" onclick="setPosition('back');">prev</div>
<div id= "NavigationForward" name = "forward" onclick="setPosition('forward');">next</div>
<div style="clear:both;"></div>
<div id = "VideoWrapper">
<div class= "SlideShowItem" style="background-color:blue;">
Slide 1
</div>
<div class = "SlideShowItem" style="background-color:yellow;">
Slide 2
</div>
<div class = "SlideShowItem" style="background-color:pink;">
Slide 3
</div>
</div>
</div>
</div>
JavaScript
var unit = 'px'; var margin = 4; var itemSize = 500 + margin; var itemCount = 3; var min_x = 0; var max_x = -(itemCount-1) * itemSize;
function setPosition(e) {
var wrapper = document.getElementById("VideoWrapper");
var slides = wrapper.getElementsByTagName('div');
var offset_x = slides[0].style.left.replace(unit, '');
var curr_x = parseInt(offset_x.length == 0 ? 0 : offset_x);
if(e == "forward")
{
if(curr_x <= max_x)
return;
for(var i=0; i<slides.length; i++)
slides[i].style.left= (curr_x + -itemSize) + unit;
}
else if(e == "back")
{
if(curr_x >= min_x)
return;
for(var i=0; i<slides.length; i++)
slides[i].style.left= (curr_x + itemSize) + unit;
} }
After you analyze and test the code, I don't really know what's your purpose with this, I mean, you maybe just playing around or trying to develop something for a personal project, but if you are looking for something more professional avoid to create things like sliders on your own, as there are tons of plugins like this available and well tested out there on the web.
Consider using jQuery with NivoSlider, it works like a charm and is cross browser.
I would recommend using jQuery, this will reduce your coding by quite a bit. Can read more here: http://api.jquery.com/animate/
I've created a simple fiddle for you to take a look at. This example uses the .animate() method to reposition two div elements based on the CSS 'left' property.
CSS:
#container {
position: absolute;
left: 1em;
top: 1em;
right: 1em;
bottom: 1em;
overflow: hidden;
}
#one, #two {
position: absolute;
color: white;
}
#one {
background: pink;
width: 100%;
top:0;
bottom:0;
}
#two {
background: blue;
width: 100%;
left: 100%;
top:0;
bottom:0;
}
HTML:
<div id="container">
<div id="one">Div One</div>
<div id="two">Div Two</div>
</div>
JavaScript/jQuery:
var one, two, container;
function animateSlides(){
one.animate({
left : '-100%'
}, 1000, function(){
one.animate({
left : 0
}, 1000);
});
two.animate({
left : 0
}, 1000, function(){
two.animate({
left:'100%'
}, 1000);
});
};
$(function(){
one = $('#one');
two = $('#two');
container = $('#container');
setInterval(animateSlides, 2000);
});
JSFiddle Example: http://jsfiddle.net/adamfullen/vSSK8/3/

JavaScript for loop not changing link text

I have a nested for loop inside a for loop that is supposed to change the link text to a random number between 1 and 5. The ID of the links are "aX_Y", X and Y being numbers. The links are arranged in a 4x3 square. The problem is that the random numbers for the link text is only displayed for the last row:
<!DOCTYPE html>
<html>
<head>
<title>RISK</title>
<style type="text/css" media="screen">
a:link, a:visited {color: #eee;border:3px solid #ccc;text-decoration:none;padding:20px;}
.one {background: #7B3B3B;}
.two {background: #547980;}
#status {color: #eee;padding:1px;text-align:center}
.current {border:3px solid #000;}
</style>
<script type="text/javascript" charset="utf-8">
var xTurn = true;
var gameOver = false;
var numMoves = 0;
function newgame()
{
var status = document.getElementById('status');
numMoves = 0;
gameOver = false;
xTurn = true;
status.innerHTML = 'Player One\'s turn';
for(var x = 0; x < 4; x++)
{
for(var y = 0; y < 3; y++)
{
document.getElementById('a' + x + '_' + y).innerHTML = Math.floor(Math.random()*5 + 1);
console.log('a' + x + '_' + y);
}
}
}
function current(selected)
{
var status = document.getElementById('status');
var value = selected.value;
}
//document.getElementById("status").setAttribute("class", "two");
</script>
<meta name="viewport" content="user-scalable=no, width=device-width" />
</head>
<body onload='newgame();'>
<p id="status" class="one">Player One's turn</p>
<br />
<br />
<br />
<br /><br />
<p><input type="button" id="newgame" value="New Game" onclick="newgame();" /></p>
</body>
</html>
Here is a direct link to it:
https://dl.dropbox.com/u/750932/iPhone/risk.html
This change to your CSS fixes the issue:
a:link, a:visited
{
color: #eee;
border:3px solid #ccc;
text-decoration:none;
display:inline-block;
padding:20px;
}
(Tested in Firefox)
Your Javascript code is fine; all of the grid squares are getting populated with random numbers. What I am seeing instead is that each row of links is overlapping the previous row, so the numbers in the previous row are being hidden.
Is the overlapping intentional?
All the random numbers are being generated correctly. The top 2 rows are just hidden due to your CSS rules. You can prove this by making the following CSS change:
Change the line that looks like this:
a:link, a:visited {color: #eee;border:3px solid #ccc;text-decoration:none;padding:20px;}
to this:
a:link, a:visited {color: #eee;border:3px solid #ccc;text-decoration:none;}
And voila, it's all working beautifully.
Heh, I'm pretty sure it is working...the other boxes are just overlapped by the ones in front and you can't see them. Firebug shows values inside all the boxes.
a {
display:block;
float:left;
}
br {
clear:both;
}
...though actually those top-level elements shouldn't be restyled like that necessarily, I'd put it all in a <div id="game"></div> and make them .game a and .game br.

Categories

Resources