How to make nested divs resize based on user input - javascript

I am doing a project from The Odin Project. Basically this.
Here is the code:
HTML
<!DOCTYPE html>
<html>
<head>
<script src="js/jQuery.js"></script>
<link type="text/css" rel="stylesheet" href="css/sketch.css">
<script src="js/sketch.js"></script>
</head>
<body>
<div class="grid_controls">
<button class="clear">Clear</button>
</div>
<div class="container">
</div>
</body>
</html>
CSS
/*=================
General
=================*/
body {
background: aqua;
}
/*=================
Sketchpad Holder
=================*/
.container {
width: 500px;
height: 400px;
background-color: orange;
overflow: hidden;
margin: auto;
position: relative;
top: 20px;
}
.box {
width: 16px;
height: 16px;
background: yellow;
display: inline-block;
margin: 1px 1px 1px 1px;
left: 0.5%;
right: auto;
position: relative;
}
.clear {
position: relative;
margin: auto;
text-align: center;
}
Javascript/Jquery
var default_grid_num = 435;
var div_limit = prompt("How large would you like your grid to be?");
var button_prompt = "Would you like to redraw the grids?";
/*var div_limit = prompt("number")*/
$(document).ready(function() {
for(var i = 1; i <= div_limit; i++)
$(".container").append("<div class='box'></div>");
$(".container > div").hover(function() {
$(this).css("background-color", "red");
});
$("button").click(function() {
$(".box").fadeOut();
if(confirm("Would you like to redraw the grid?"));
{
boxes_per_row = prompt("Define width of grid.");
}
});
});
What I want to do is get user input(.div_limit) and resize the divs(.box) based on the users input(.div_limit) So if the user only typed in the number one, the one div would take up the whole container box.
Here is what I have so far: http://codepen.io/zappdapper/full/epdPKb/
I know I can do this, but how?

I've made a jsfiddle that uses the mod operator % and some math to determine a percentage for the boxes.
I've included max_per_row as well to determine how many should show in a row.

UPDATE
I've taken another look at your example and your comment and come up with this:
http://jsfiddle.net/xw4cbo5n/
I edited the example slightly so that instead of asking two questions, only one is asked: "How many boxes per row of grid" (this is similar to your example).
It then goes on to draw out a grid where each row contains that number and sets each bow width and height accordingly. I also edited your CSS styles slightly.
Is that closer to what you're looking for?
I've created a JSFiddle which displays two prompts when run:
1) How many boxes would you like?
2) How many boxes should take up one row?
http://jsfiddle.net/5vg6n232/
After the responses are given, the grid is drawn.
I've edited your CSS slightly but the main functionality is driven by a couple of functions:
function drawBoxes(){
takes care of adding the correct number on divs to the page. After this is done it calls:
function restyle(numberofBoxesPerRow){
which simply reset's the CSS width of each box based on how may boxes per row the user specified.
Does this answer your question?

Related

creating multiple vertical lines in HTML using loops

I'm new to JS and would like to create 10 vertical lines in my webpage. I have written my HTML code as
<div id="verticle-line"></div>
and in my CSS I have
#verticle-line {
width: 1px;
min-height: 400px;
background: red;
margin:15px;
float:left
}
How Can I create 10 such lines in my webpage using JavaScript?
There are many ways to do this but the easiest would probably be this:
for(var i=0; i<10; i++) {
document.write('<div class="verticle-line"></div>');
}
Use a for loop to write 10 divs on your page. I also changed id to class, because you should not have more than one element with the same id on your page. Make sure you change your CSS to match a class.
See this -
for(x=0; x<9;x++) {
var vertical = document.createElement('div');
vertical.className = "verticle-line";
document.getElementById('wrapper').appendChild(vertical);
}
.verticle-line {
width: 1px;
min-height: 400px;
background: red;
margin: 15px;
float: left
}
<div id="wrapper">
<div class="verticle-line"></div>
</div>

How to trigger a show or hide operation based on div size when the browser is resized

I am designing a summary container for the author page in a book publishing website. Some authors have more summary content while others have less content. I want to enable/ disable show more/less button dynamically when the height of the div container crosses a cutoff height(180px). So, it turns out to control the height of the div container dynamically (180px and original height). I need a piece of code which works perfectly in all browsers.
I have got a code implemented here:
http://jsfiddle.net/rraagghhu/9dgs6432/3/
HTML :
<div class = "container">
<div class="info-wrapper">
<div class="info">
Chetan Bhagat is the author of six blockbuster books.These include five novels—Five Point Someone (2004), One Night # the Call Center (2005), The 3 Mistakes of My Life (2008), 2 States (2009),
Revolution 2020 (2011), the non-fiction title What Young India Wants (2012) and Half Girlfriend (2014). Chetan’s books have remained bestsellers since their release.
Four out his five novels have been already adapted into successful Bollywood films and the others are in process of being adapted as well. The New York Times called him the ‘the biggest selling English language novelist in India’s history’. Time magazine named him amongst the ‘100 most influential people in the world’ and Fast Company, USA, listed him as one of the world’s ‘100 most creative people in business’. Chetan writes columns for leading English and Hindi newspapers, focusing on youth and national development issues. He is also a motivational speaker and screenplay writer. Chetan quit his international investment banking career in 2009 to devote his entire time to writing and make change happen in the country. He lives in Mumbai with his wife, Anusha, an ex-classmate from IIM-A, and his twin boys, Shyam and Ishaan. You can email him at info#chetanbhagat.com or fill in the Guestbook with your feedback. You can also follow him on twitter (#chetan_bhagat) or like his Facebook fanpage (https://www.facebook.com/chetanbhagat.fanpage).
</div>
(more)
(less)
</div>
<div class = "footer"> THIS IS FOOTER </div>
</div>
CSS:
.container{
background-color: yellow;
}
.footer{
background-color: yellow;
}
.info-wrapper {
height: auto;
position: relative;
width: auto;
padding: 0 0 2.5em 0;
background-color: red;
}
.info {
max-height: 180px;
height: auto;
width: auto;
overflow: hidden;
position: relative;
text-align: justify;
}
.info:after, .aftershadow {
bottom: 0;
width: auto;
height: auto;
}
.info-wrapper a {
left: 50%;
position: relative;
font: 700 .67em/1.25em Arial;
text-align: center;
text-decoration: underline;
cursor: pointer;
}
.less { height: auto; display: none; }
.more { display: none; }
Jquery:
if($(".info")[0].scrollHeight > $(".info").height()) {
$("a.more").show();
}
$("a.more").click(function(e){
e.preventDefault();
$(".info").css({"overflow": "visible"});
$("a.less").show();
$("a.more").hide();
return false;
});
$("a.less").click(function(e){
e.preventDefault();
$(".info").css({"overflow": "hidden"});
$("a.more").show();
$("a.less").hide();
return false;
});
As you can see, the footer stays at the absolute position. If the more button is clicked, the (less) should come down, below that should come the footer. Is it possible to enable/disable the show more/less button dynamically when the browser is shrunk/expanded?
Set the max-height to 100% for show more and set the max-height to 180px when show less.
Updated JSFiddle
You don't need the overflow to ever be shown, instead just increase the max-height to 100%.
$("a.more").click(function(e){
e.preventDefault();
$(".info").css({"max-height": "100%"});
$("a.less").show();
$("a.more").hide();
return false;
});
I also added in some padding so you can see the text a bit easier.
Updated fiddle
This is really another question, but using innerHeight instead of height you can detect if the text is overflowing with the padding on window resize:
$(window).resize(function(){
if($(".info")[0].scrollHeight > $(".info").innerHeight()) {
$("a.more").show();
}
});
I also positioned the less/more button absolutely at the bottom of the info box to overlay any text that might extend into the padding:
.info-wrapper a {
left: 0; bottom: 0;
width: 100%;
background: red;
position: absolute;
font: 700 .67em/1.25em Arial;
text-align: center;
text-decoration: underline;
cursor: pointer;
line-height: 20px;
}
Full code is in this fiddle
You are not removing the max-height from the CSS and that is what is causing the issue. You can do two things here:
Either you can set the max-height to 100%
or, you can set the max-height in another css class and add and remove that class to the info div dynamically
Create a css style:
.restrict{
max-height: 180px;
}
On click of more:
$(".info").removeClass('restrict');
On click of less:
$(".info").addClass('restrict');
See my forked fiddle with the changes:
https://jsfiddle.net/jdnf5vka/4/
Yes you can enable and disable the buttons as the browser is resized.
You'll need to build your javascript like this:
// make your function re-usable
var buttonChecker = function() {
// show / hide buttons logic here
}
// bind the function to the resize event (note, no parenthesis for calling the function here, it's just a reference passed in that is then called when the resize event is triggered)
$(window).on('resize', buttonChecker);
// call your function on page load so the buttons are correctly shown then (note, parenthesis are used, function is called
buttonChecker();
This way when the browser is resized the show / hide button functionality will be re-called.
PS - here is the OPs example fixed: http://jsfiddle.net/9dgs6432/20/ - note the contents of the buttonChecker() function and the logic to hide as well as show.

Javascript, HTML5 (canvas) progressbar with update

I'm looking for the best way to do a progress bar (in my case it's a life bar for a game) in an html5 canvas.
I don't know if it's better to use javascript and dom element, or draw this bar directly in the canvas.
I need an update function, for example myBar.updateValue(40), and I need to show the new bar without refresh all the page or all the canvas, of course.
Do you know something like that? An existing script? Thanks!
It’s very easy in HTML/CSS:
<style>
#progress-holder{width:400px;height:20px;background:grey}
#progress{width:0;height:100%;background:black}
</style>
<div id="progress-holder">
<div id="progress"></div>
</div>
<script>
var progress = document.getElementById('progress');
function updateValue(perc) {
progress.style.width = perc+'%';
}
updateValue(40);
</script>
DEMO: http://jsbin.com/EGAzAZEK/1/edit
And animating with CSS: http://jsbin.com/EGAzAZEK/3/edit
HTML:
<div class='progress'>
<div class='progress-bar' data-width='//Enter a percent value here'>
<div class='progress-bar-text'>
Progress: <span class='data-percent'>//This is auto-generated by the script</span>
</div>
</div>
</div>
CSS:
html, body {
margin: 0;
padding: 15px;
width: 100%;
height: 100%;
position: relative;
color: #fff;
}
.progress {
position: relative;
width: 100%;
height: 30px;
}
.progress-bar {
margin-bottom: 5px;
width: 0%;
height: 30px;
position: relative;
background-color: rgb(66, 139, 202);
}
.progress-bar-text {
position: absolute;
top: 0px;
width: 100%;
text-align: center;
/*
Do not change the values below,
unless you want your text to display away from the bar itself. */
line-height: 30px;
vertical-align: middle;
}
jQuery:
$('.progress-bar').each(function (){
var datawidth = $(this).attr('data-width');
$(this).find("span.data-percent").html(datawidth + "%");
$(this).animate({
width: datawidth + "%"
}, 800);
});
Link to JSFiddle
The HTML data-width attribute is used to track the percent the bar should be set to. Change it to your liking.
The jQuery script works with ALL progress bars on your page (See the JSFiddle, so you don't have to copy and paste the same jQuery for every new progress bar.
(Just be sure to keep the structure of the HTML, or change it to your liking).
The div "progress" is just an expander, it can be named whatever your want - without you having to change the jQuery.
EDIT:
If you can use Javascript & HTML, don't use a canvas. Canvas (imho) are good for only 1 thing: Seat bookings for concerts, theaters and alike.

Unwanted vertical spacing between divs [duplicate]

This question already has answers here:
Why does my image have space underneath?
(3 answers)
Closed 7 years ago.
I want to lay out a grid by appending divs to body and letting them wrap around the screen. Why am I getting spacing between the rows? It remains regardless of margin & padding; see below image.
Here is the markup:
<!DOCTYPE html>
<html>
<head>
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js' type='text/javascript'></script>
</head>
<body>
<style>
.square {
display: inline-block;
width: 80px;
height: 80px;
border: black thin solid;
}
</style>
<script>
$(function() {
for( var i=0; i<60; i++ ) {
$('body').append( $('<div class="square"></div>') );
}
});
</script>
</body>
</html>
Here is what it looks like:
http://dl.dropbox.com/u/257081/squares.png
Because it's inline-block, it's treated like a line of text, so it gets some space between each line. You can alter the line-height or font-size of the container to fix it (or both, to be on the safe side):
body {
font-size: 1px;
line-height: 0;
}
This should fix it nice and good
body { line-height: 0;}
Solution: Add float: left to your .square class.
Refer this fiddle: http://jsfiddle.net/techfoobar/VdJhp/1/
It's your display that's doing it. You have it set to inline-block. Try doing float: left; instead. That took care of it for me.

How do I achieve equal height divs (positioned side by side) with HTML / CSS ?

I have two divs inside of a container. One on the left, one on the right, side by side. How am I able to make each one be of equal height, even though they have different content.
For example, the right div has a lot of content, and is double the height of the left div, how do I make the left div stretch to the same height of the right div?
Is there some JavaScript (jQuery) code to accomplish this?
You could use jQuery, but there are better ways to do this.
This sort of question comes up a lot and there are generally 3 answers...
1. Use CSS
This is the 'best' way to do it, as it is the most semantically pure approach (without resorting to JS, which has its own problems). The best way is to use the display: table-cell and related values. You could also try using the faux background technique (which you can do with CSS3 gradients).
2. Use Tables
This seems to work great, but at the expense of having an unsemantic layout. You'll also cause a stir with purists. I have all but avoided using tables, and you should too.
3. Use jQuery / JavaScript
This benefits in having the most semantic markup, except with JS disabled, you will not get the effect you desire.
Here's a way to do it with pure CSS, however, as you'll notice in the example (which works in IE 7 and Firefox), borders can be difficult - but they aren't impossible, so it all depends what you want to do. This example assumes a rather common CSS structure of body > wrapper > content container > column 1 and column 2.
The key is the bottom margin and its canceling padding.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Equal Height Columns</title>
<style type="text/css">
<!--
* { padding: 0; margin: 0; }
#wrapper { margin: 10px auto; width: 600px; }
#wrapper #main_container { width: 590px; padding: 10px 0px 10px 10px; background: #CCC; overflow: hidden; border-bottom: 10px solid #CCC; }
#wrapper #main_container div { float: left; width: 263px; background: #999; padding: 10px; margin-right: 10px; border: 1px solid #000; margin-bottom: -1000px; padding-bottom: 1000px; }
#wrapper #main_container #right_column { background: #FFF; }
-->
</style>
</head>
<body>
<div id="wrapper">
<div id="main_container">
<div id="left_column">
<p>I have two divs inside of a container. One on the left, one on the right, side by side. How am I able to make each one be of equal height, even though they have different content.</p>
</div><!-- LEFT COLUMN -->
<div id="right_column">
<p>I have two divs inside of a container. One on the left, one on the right, side by side. How am I able to make each one be of equal height, even though they have different content.</p>
<p> </p>
<p>For example, the right div has a lot of content, and is double the height of the left div, how do I make the left div stretch to the same height of the right div?</p>
<p> </p>
<p>Is there some JavaScript (jQuery) code to accomplish this?</p>
</div><!-- RIGHT COLUMN -->
</div><!-- MAIN CONTAINER -->
</div><!-- WRAPPER -->
</body>
</html>
This is what it looks like:
you can get it working with js:
<script>
$(document).ready(function() {
var height = Math.max($("#left").height(), $("#right").height());
$("#left").height(height);
$("#right").height(height);
});
</script>
I've seen many attempts to do this, though none met my OCD needs. You might need to dedicate a second to get your head around this, though it is better than using JavaScript.
Known downsides:
Does not support multiple element rows in case of a container with dynamic width.
Does not work in IE6.
The base:
red is (auxiliary) container that you would use to set margin to the content.
green is position: relative; overflow: hidden and (optionally, if you want columns to be centered) text-align: center; font-size: 0; line-height: 0;
blue display: block; float: left; or (optionally, if you want columns to be centered) display: inline-block; vertical-align: top;
So far nothing out of ordinary. Whatever content that blue element has, you need to add an absolutely positioned element (yellow; note that the z-index of this element must be lower than the actual content of the blue box) with this element and set top: 0; bottom: 0; (don't set left or right position).
All your elements now have equal height. For most of the layouts, this is already sufficient. My scenario required to have dynamic content followed by a static content, where static content must be on the same line.
To achieve this, you need to add padding-bottom (dark green) eq to the fixed height content to the blue elements.
Then within the yellow elements create another absolutely positioned (left: 0; bottom: 0;) element (dark blue).
Supposedly, if these boxes (yellow) had to be active hyperlinks and you had any style that you wanted to apply to the original blue boxes, you'd use adjacent sibling selector:
yellow:hover + blue {}
Here is a the code and demo:
HTML:
<div id="products">
<ul>
<li class="product a">
<a href="">
<p class="name">Ordinary product description.</p>
<div class="icon-product"></div>
</a>
<p class="name">Ordinary product description.</p>
</li>
<li class="product b">
<a href="">
<p class="name">That lenghty product description or whatever else that does not allow you have fixed height for these elements.</p>
<div class="icon-product"></div>
</a>
<p class="name">That lenghty product description or whatever else that does not allow you have fixed height for these elements.</p>
</li>
<li class="product c">
<a href="">
<p class="name">Another ordinary product description.</p>
<div class="icon-product"></div>
</a>
<p class="name">Another ordinary product description.</p>
</li>
</ul>
</div>
SCSS/LESS:
#products {
ul { position: relative; overflow: hidden; text-align: center; font-size: 0; line-height: 0; padding: 0; margin: 0;
li { display: inline-block; vertical-align: top; width: 130px; padding: 0 0 130px 0; margin: 0; }
}
li {
a { display: block; position: absolute; width: 130px; background: rgba(255,0,0,.5); z-index: 3; top: 0; bottom: 0;
.icon-product { background: #ccc; width: 90px; height: 90px; position: absolute; left: 20px; bottom: 20px; }
.name { opacity: 1; }
}
.name { position: relative; margin: 20px 10px 0; font-size: 14px; line-height: 18px; opacity: 0; }
a:hover {
background: #ddd; text-decoration: none;
.icon-product { background: #333; }
}
}
}
Note, that the demo is using a workaround that involves data-duplication to fix z-index. Alternatively, you could use pointer-events: none and whatever solution for IE.
here is very simple solution with a short css display:table
<div id="main" class="_dt-no-rows">
<div id="aside" contenteditable="true">
Aside
<br>
Here's the aside content
</div>
<div id="content" contenteditable="true">
Content
<br>
geht's pellentesque wurscht elementum semper tellus s'guelt Pfourtz !. gal hopla
<br>
TIP : Just clic on this block to add/remove some text
</div>
</div>
here is css
#main {
display: table;
width: 100%;
}
#aside, #content {
display: table-cell;
padding: 5px;
}
#aside {
background: none repeat scroll 0 0 #333333;
width: 250px;
}
#content {
background: none repeat scroll 0 0 #E69B00;
}
its look like this
Well, I don't do a ton of jQuery, but in the CSS/Javascript world I would just use the object model and write a statement as follows:
if(leftDiv.style.height > rightDive.style.height)
rightDiv.style.height = leftDiv.style.height;
else
leftDiv.style.height = rightDiv.style.height)
There's also a jQuery plugin called equalHeights that I've used with some success.
I'm not sure if the one I'm using is the one from the filament group mentioned above, or if it's this one that was the first google result... Either way a jquery plugin is probably the easiest, most flexible way to go.
Use this in jquery document ready function. Considering there are two divs having ids "left" and "right."
var heightR = $("#right").height();
var heightL = $("#left").height();
if(heightL > heightR){
$("#right").css({ height: heightL});
} else {
$("#left").css({ height: heightR});
}
Although many disagree with using javascript for this type of thing, here is a method that I used to acheive this using javascript alone:
var rightHeight = document.getElementById('right').clientHeight;
var leftHeight = document.getElementById('left').clientHeight;
if (leftHeight > rightHeight) {
document.getElementById('right').style.height=leftHeight+'px';
} else {
document.getElementById('left').style.height=rightHeight+'px';
}
With "left" and "right" being the id's of the two div tags.
This is what I use in plain javascript:
Seems long, but is very uncomplicated!
function equalizeHeights(elements){
//elements as array of elements (obtain like this: [document.getElementById("domElementId"),document.getElementById("anotherDomElementId")]
var heights = [];
for (var i=0;i<elements.length;i++){
heights.push(getElementHeight(elements[i],true));
}
var maxHeight = heights[biggestElementIndex(heights)];
for (var i=0;i<elements.length;i++){
setElementHeight(elements[i],maxHeight,true);
}
}
function getElementHeight(element, isTotalHeight){
// isTotalHeight triggers offsetHeight
//The offsetHeight property is similar to the clientHeight property, but it returns the height including the padding, scrollBar and the border.
//http://stackoverflow.com/questions/15615552/get-div-height-with-plain-javascript
{
isTotalHeight = typeof isTotalHeight !== 'undefined' ? isTotalHeight : true;
}
if (isTotalHeight){
return element.offsetHeight;
}else{
return element.clientHeight;
}
}
function setElementHeight(element,pixelHeight, setAsMinimumHeight){
//setAsMinimumHeight: is set, we define the minimum height, so it can still become higher if things change...
{
setAsMinimumHeight = typeof setAsMinimumHeight !== 'undefined' ? setAsMinimumHeight : false;
}
var heightStr = "" + pixelHeight + "px";
if (setAsMinimumHeight){
element.style.minHeight = heightStr; // pixels
}else{
element.style.height = heightStr; // pixels
}
}
function biggestElementIndex(arr){
//http://stackoverflow.com/questions/11301438/return-index-of-greatest-value-in-an-array
var max = arr[0];
var maxIndex = 0;
for (var i = 1; i < arr.length; i++) {
if (arr[i] > max) {
maxIndex = i;
max = arr[i];
}
}
return maxIndex;
}
I agree with initial answer but the JS solution with equal_heights() method does not work in some situations, imagine you have products next to each other. If you were to apply it only to the parent container yes they will be same height but the product name sections might differ if one does not fit to two line, this is where i would suggest using below
https://jsfiddle.net/0hdtLfy5/3/
function make_children_same_height(element_parent, child_elements) {
for (i = 0; i < child_elements.length; i++) {
var tallest = 0;
var an_element = child_elements[i];
$(element_parent).children(an_element).each(function() {
// using outer height since that includes the border and padding
if(tallest < $(this).outerHeight() ){
tallest = $(this).outerHeight();
}
});
tallest = tallest+1; // some weird shit going on with half a pixel or something in FF and IE9, no time to figure out now, sowwy, hence adding 1 px
$(element_parent).children(an_element).each(function() {
$(this).css('min-height',tallest+'px');
});
}
}

Categories

Resources