Getting divs next to each other when clicking on a button / JQuery - javascript

i am making a kind of storyboard where you can add and remove frames but i need to set divs next to each other, the code i now have it places the div's beneath each other. I want to make it with a loop
Here is my code:
HTML
<div id="storyboard">
<div id="container">
<div class="frame">
<div class="frame__outer">
<div class="frame__inner"></div>
<div class="frame__content"></div>
<div type="button" value="fade_in" class="add__button"> + </div>
</div>
</div>
</div>
</div>
JS
_this.addClickFunction = function() {
var i = 0;
$('.add__button').click(function() {
$('.frame').after('<div id="container'+(i++)+'"></div> <div class="frame__outer"> <div class="frame__inner"></div><div class="frame__content"></div></div>');
});
};

Use append() instead of after() function. This should work:
_this.addClickFunction = function() {
var i = 0;
$('.add__button').click(function() {
$('.frame').append('<div id="container'+(i++)+'"></div> <div class="frame__outer"> <div class="frame__inner"></div><div class="frame__content"></div></div>');
});
};
This works for keeping one .frame element and adding multiple divs to it of the structure:
<div class="container[i]">
<div class="frame__outer">
<div class="frame__inner"></div>
<div class="frame__content"></div>
</div>
</div>

If you want to arrange elements side by side which normaly are block elements and thus are positioned underneath eachother by default use either css floats or css flexbox.
https://css-tricks.com/all-about-floats/
https://css-tricks.com/snippets/css/a-guide-to-flexbox/

i need to set divs next to each other
Try this example to add new story container to all current .container
var i = 1;
$('.add__button').click(function() {
i++;
$(".container").each(function(x) {
$(this).after('<div id="container' + x + '_' + i + '" class="container"><div class="frame"><div class="frame__outer"> <div class="frame__inner"></div><div class="frame__content">story ' + i + '</div></div></div></div>');
});
});
.frame__outer {
padding: 20px;
background: #222;
color: white;
border-bottom: solid 3px green;
margin: 5px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="storyboard">
<input type='button' value='add story' class="add__button" />
<div id="container" class='container'>
<div class="frame">
<div class="frame__outer">
<div class="frame__inner"></div>
<div class="frame__content">story 1</div>
</div>
</div>
</div>
</div>

Related

How to correctly target by class name?

I am trying to practice some things on JS, I want to toggle a number of divs on click to change their color but I can't seem to target correctly the first one. It was fine when I did it by tag name but by class it doesnt seem to work. What am I doing wrong? Thanks!
EDIT. This is what my code looks like after your corrections.
<body>
<div class="container">
<div class="one">
</div>
<div class="two">
</div>
<div class="three">
</div>
<div class="four">
</div>
</div>
<script src="script.js"></script>
</body>
let boxOne = document.getElementsByClassName("one")[0]
boxOne.onclick = function() {
alert("Clicked!")
}
I'm going to add that its better to assign an id and use getElementById if the selector is only used by one element.
let boxOne = document.getElementById("one");
let allBoxes = document.getElementsByClassName("square");
boxOne.onclick = function() {
alert("Clicked via ID");
}
const arr = [1, 2, 3];
arr.forEach(i => {
allBoxes[i].onclick = function() {
alert("Clicked via Class");
}
})
.square {
width: 100px;
height: 100px;
background: blue;
margin: 20px;
font-size: 50px;
color: white;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
cursor: pointer;
}
<body>
<div class="container">
<div class="square" id="one">
1
</div>
<div class="square" id="two">
2
</div>
<div class="square" id="three">
3
</div>
<div class="square" id="four">
4
</div>
</div>
</body>
With this line:document.getElementsByClassName(".one")[0]
you are already targeting the div, so change out this:
boxOne[0].onclick =
to this:
boxOne.onclick =
document.
getElementsByClassName returns array of elements with that className (without dot)
querySelector is used for css selectors (eg. ".one", "div.one")
querySelectorAll like 2. but returns array
let boxOne = document.getElementsByClassName("one")[0]
boxOne.onclick = function() {
alert("Clicked!")
}
div {
width: 100px;
height: 100px;
margin: 30px;
background: blue
}
<body>
<div class="container">
<div class="one">
</div>
<div class="two">
</div>
<div class="three">
</div>
<div class="four">
</div>
</div>
<script src="script.js"></script>
</body>

Add or Remove class on click - Javascript

I am trying to add a class when you click on a box then remove the class when you click the button. But no class os added or removed.
var leftBox = document.getElementsByClassName("left");
var rightBox = document.getElementsByClassName("right");
function expandLeft() {
leftBox.className = leftBox.className + "zero-width";
rightBox.className = rightBox.className + "full-width";
}
function expandRight() {
leftBox.className = leftBox.className + "full-width";
rightBox.className = rightBox.className + "zero-width";
}
function originalLeft(){
leftBox.removeClass(leftBox, "zero-width");
rightBox.removeClass(rightBox, "full-width");
}
function originalRight(){
leftBox.removeClass(rightBox, "full-width");
rightBox.removeClass(leftBox, "zero-width");
}
<div class="row">
<div class="wrapper flex full-width">
<div class="form_wrapper flex full-width">
<div class="left">
<div class="form_wrapper--left" onclick="expandRight()">
<div><button id="shrink" onclick="originalLeft()">click here</button> .
</div>
</div>
</div>
<!-- END OR RIGHT BOX --
<!-- START OR RIGHT BOX -->
<div class="right">
<div class="form_wrapper--right" onclick="expandLeft()">
<div>
<button id="shrink" onclick="originalLeft()">click here</button>
</div>
</div>
</div>
<!--- END of Right Box --->
</div>
</div>
</div>
The effect should be that when you click one box it expands left and you can click a button and it returns. Vice versa for the other side.
You can use .toggleClass() in jQuery.
maybe this link helps:
https://api.jquery.com/toggleclass/
try this:
document.getElementById("test").addEventListener("click", enlarge);
document.getElementById("btn").addEventListener("click", resume);
function enlarge() {
document.getElementById("test").classList.add("enlarge");
}
function resume() {
document.getElementById("test").classList.remove("enlarge");
}
#test {
width: 100px;
height: 100px;
background-color: green;
margin-bottom: 20px;
}
.enlarge {
transform: scaleX(2);
}
<div id="test"></div>
<button id="btn">
Resume
</button>

Modify DOM based on amount of divs after specific class

Is there any way to modify DOM based on amount div after specific class?
For example, if I have a div with a class called row and after that I have 4 div elements. Is there a way to change these 4 div element class depending on how many div elements there are?
Code:
<div class="row">
<div class="col-1-of-4">
some content
</div>
<div class="col-1-of-4">
some content
</div>
<div class="col-1-of-4">
some content
</div>
<div class="col-1-of-4">
some content
</div>
</div>
Another example I have a div class row again, but this time I want 3 div elements after that, then I would want these div elements to have a class called col-1-of-3, not col-1-of-4. If I would have just 2 div elements after that then class col-1-of-2 and if just one div element then no class at all.:
Code:
<div class="row">
<div class="col-1-of-3">
some content
</div>
<div class="col-1-of-3">
some content
</div>
<div class="col-1-of-3">
some content
</div>
</div>
Also these div elements with classes called col-1-of-4, col-1-of-3 and col-1-of-2 have their own div elements inside them, but they should stay like they were.
Is it possible to achieve with JavaScript or PHP?
You would need to write conditional blocks to handle this if I'm understanding you correctly (wanting a JS or PHP solution).
Note: It goes without saying that a similar solution can be completed with a CSS-only approach, as outlined here: Can CSS detect the number of children an element has?
Here's an example (using jQuery) with 3 sets of row's, with varying children (2, 3, 4):
$(function() {
var $rows = $(".row");
$rows.each(function() {
$row = $(this);
var $children = $(">div", $row),
total = $children.size();
$children.addClass("col-1-of-" + total);
});
});
.row {
border: 1px solid #000;
margin: 10px;
}
.row > div {
margin: 10px;
}
.row .col-1-of-2 {
border: 1px solid #f00;
}
.row .col-1-of-3 {
border: 1px solid #0f0;
}
.row .col-1-of-4 {
border: 1px solid #00f;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div>
some content
</div>
<div>
some content
</div>
</div>
<div class="row">
<div>
some content
</div>
<div>
some content
</div>
<div>
some content
</div>
</div>
<div class="row">
<div>
some content
</div>
<div>
some content
</div>
<div>
some content
</div>
<div>
some content
</div>
</div>
When you run the snippet, you must inspect the elements. I've added borders so you can see the difference.
Theres a number of ways to achieve this. I'd maybe add another class name so you can easily identify groups of divs, and differentiate between parent and child divs. Does this help you get where you're going? Basically find the number of children in a row and then concatenate that number into the class name.
var x = document.getElementsByClassName('row')[0].childElementCount
var element = document.getElementsByClassName('row')[0];
element.classList.add(`col-1-of-${x}`);
.row {
width: 100%;
display:flex;
flex-grow: 1;
margin-bottom: 2px;
}
.col {
float:left;
background: rgba(255,0,0,.2);
text-align: center;
margin-right: 2px;
}
.col:first-child:nth-last-child(1),
.col:first-child:nth-last-child(1) ~ .col{
width: calc(100% / 1);
}
.col:first-child:nth-last-child(2),
.col:first-child:nth-last-child(2) ~ .col{
width: calc(100% / 2);
}
.col:first-child:nth-last-child(3),
.col:first-child:nth-last-child(3) ~ .col{
width: calc(100% / 3);
}
.col:first-child:nth-last-child(4),
.col:first-child:nth-last-child(4) ~ .col{
width: calc(100% / 4);
}
.col:first-child:nth-last-child(5),
.col:first-child:nth-last-child(5) ~ .col{
width: calc(100% / 5);
}
<div class="row">
<div class="col">1</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="col">4</div>
</div>
<div class="row">
<div class="col">1</div>
<div class="col">2</div>
<div class="col">3</div>
<div class="col">4</div>
<div class="col">5</div>
</div>
so this is with float, can be used in a sass/scss mixin to create code automagically. there should be also a flex solution but i dont have it at hand at the moment

change nextAll() individually jQuery

function func(x) {
var y = $("#" + (x.id));
//nextAll get the number at the end of their id -=1
//y.nextAll().attr('id', )
//
y.remove()
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="maindiv">
<div id="div1" onclick="func(this)">Lorem</div>
<div id="div2" onclick="func(this)">Ipsum</div>
<div id="div3" onclick="func(this)">Dolor</div>
<div id="div4" onclick="func(this)">Sit</div>
<div id="div5" onclick="func(this)">Amet</div>
</div>
How would I loop through every div after the selected div?
For example, if the user clicks on div2, div3 will have a function, along with div4 and div5.
You can use each to iterate the elements in the selection
function func(x) {
var y = $(x);
y.nextAll().each(function(index, element){
// do something
})
y.remove()
}
To catch only the divs after the clicked element:
function func(x) {
$(x).nextAll().remove();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="maindiv">
<div id="div1" onclick="func(this)">Lorem</div>
<div id="div2" onclick="func(this)">Ipsum</div>
<div id="div3" onclick="func(this)">Dolor</div>
<div id="div4" onclick="func(this)">Sit</div>
<div id="div5" onclick="func(this)">Amet</div>
</div>
An alternative is using Next Siblings Selector (“target selector ~ next siblings selector”)
$('[id^=div]').on('click', function() {
$(`#${$(this).attr('id')} ~ div`).fadeOut(function() {
$(this).remove()
});
});
[id^=div] {
border: 1px dashed lightgreen;
padding: 5px;
margin: 5px;
cursor: pointer
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="maindiv">
<div id="div1">Lorem</div>
<div id="div2">Ipsum</div>
<div id="div3">Dolor</div>
<div id="div4">Sit</div>
<div id="div5">Amet</div>
</div>

Swap div in DOM and visually on click using jquery

I've a few divs which need to be swapped on click of the corresponding buttons.
<html>
<head>
<style>
.box {
height: 25%;
width: 45%;
padding: 1%;
margin-left: 1%;
margin-top: 1%;
border: 1px solid black;
float: left;
}
</style>
<script src="css/jquery-3.2.0.js"></script>
</head>
<body>
<div class="container">
<div class="box" id="one">
<p>one</p>
<button onclick="moveMe_right()">Swap with right!</button>
<button onclick="moveMe_down()">Swap with down!</button>
</div>
<div class="box" id="two">
<p>two</p>
<button onclick="moveMe_left()">Swap with left!</button>
<button onclick="moveMe_down()">Swap with down!</button>
</div>
<div class="box" id="three">
<p>three</p>
<button onclick="moveMe_right()">Swap with right!</button>
<button onclick="moveMe_top()">Swap with top!</button>
</div>
<div class="box" id="four">
<p>four</p>
<button onclick="moveMe_left()">Swap with left!</button>
<button onclick="moveMe_down()">Swap with down!</button>
</div>
</div>
</body>
</html>
For e.g., when I click on Swap with right in div one, it should swap div one and div 2 visually as well as in the DOM it should change to -
<div class="container">
<div class="box" id="two">
<p>two</p>
<button onclick="moveMe_right()">Swap with right!</button>
<button onclick="moveMe_down()">Swap with down!</button>
</div>
<div class="box" id="one">
<p>one</p>
<button onclick="moveMe_left()">Swap with left!</button>
<button onclick="moveMe_down()">Swap with down!</button>
</div>
<div class="box" id="three">
<p>three</p>
<button onclick="moveMe_right()">Swap with right!</button>
<button onclick="moveMe_top()">Swap with top!</button>
</div>
<div class="box" id="four">
<p>four</p>
<button onclick="moveMe_left()">Swap with left!</button>
<button onclick="moveMe_down()">Swap with down!</button>
</div>
</div>
Likewise, how would I also achieve the same for swapping with any of the left, top, down divs?
Basically, using insertBefore/After will not swap the divs, but move them along, this can be demonstrated by using your current method
$(toMove1).insertAfter($(toMove1).next());
To get the top left div to swap with the one below you could expand on this and use
$(toMove1).insertAfter($(toMove1).next().next());
But this would only move div 'one' to the place of div 'three'. Then div 'two' would fall into div 'one's slot, and 'three' into 'two's.
However, once a div has been moved what happens next?
For example, if you keep clicking 'Swap with right' should it swap with the div below and to the left, should it re-label the button to 'Swap with left'?
I have added four positional divs (with a 'parent' class), so you can move the divs you want in the DOM, and also use rules for labels etc. within each area. I've demonstrated using 'topLeft', 'bottomRight' etc. but you could have an array of many different positions and use indexes if you want.
The code below can be refactored to selectively update event handlers, label changing, and code reduction, but to make it easy to see what is happening I have left it pretty verbose.
<html>
<head>
<style>
.box {
height: 25%;
width: 45%;
padding: 1%;
margin-left: 1%;
margin-top: 1%;
border: 1px solid black;
float: left;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<div id="topLeft" class="parent">
<div class="box" id="one">
<p>one</p>
<button class="right">Swap with right!</button>
<button class="down">Swap with down!</button>
</div>
</div>
<div id="topRight" class="parent">
<div class="box" id="two">
<p>two</p>
<button class="left">Swap with left!</button>
<button class="down">Swap with down!</button>
</div>
</div>
<div id="bottomLeft" class="parent">
<div class="box" id="three">
<p>three</p>
<button class="right">Swap with right!</button>
<button class="top">Swap with top!</button>
</div>
</div>
<div id="bottomRight" class="parent">
<div class="box" id="four">
<p>four</p>
<button class="left">Swap with left!</button>
<button class="top">Swap with top!</button>
</div>
</div>
</div>
<script>
$(document).ready(function () {
// Set the event handlers on load...
resetEvents();
});
function UpdateDivs(parent1, parent2, class1, class2) {
var parent1Content = $('#' + parent1).children();
var parent2Content = $('#' + parent2).children();
$(parent1Content).find('.' + class1).each(function () {
swapButtonClass(this);
});
$(parent2Content).find('.' + class2).each(function () {
swapButtonClass(this);
});
$('#' + parent1).append(parent2Content);
$('#' + parent2).append(parent1Content);
resetEvents();
}
function resetEvents() {
// Clear the current handlers - because the buttons will change their class.
// The handlers are still attached to the buttons that were seen with that class initially.
// This could be done selectively, but for demo purposes, just resets all of them when the DOM is changed.
$('.right').unbind('click');
$('.left').unbind('click');
$('.top').unbind('click');
$('.down').unbind('click');
$('.right').click(function () {
var parent1 = $(this).parents('.parent').attr('id');
var parent2 = parent1.replace('Left', 'Right');
UpdateDivs(parent1, parent2, 'right', 'left');
});
$('.left').click(function () {
var parent1 = $(this).parents('.parent').attr('id');
var parent2 = parent1.replace('Right', 'Left');
UpdateDivs(parent1, parent2, 'left', 'right');
});
$('.down').click(function () {
var parent1 = $(this).parents('.parent').attr('id');
var parent2 = parent1.replace('top', 'bottom');
UpdateDivs(parent1, parent2, 'down', 'top');
});
$('.top').click(function () {
var parent1 = $(this).parents('.parent').attr('id');
var parent2 = parent1.replace('bottom', 'top');
UpdateDivs(parent1, parent2, 'top', 'down');
});
$('.container').eq(0);
}
function swapButtonClass(button) {
// Swap class and labels when moving the divs around.
switch (button.className) {
case "right":
$(button).removeClass('right').addClass('left').text($(button).text().replace('right', 'left'));
break;
case "left":
$(button).removeClass('left').addClass('right').text($(button).text().replace('left', 'right'));
break;
case "top":
$(button).removeClass('top').addClass('down').text($(button).text().replace('top', 'down'));
break;
case "down":
$(button).removeClass('down').addClass('top').text($(button).text().replace('down', 'top'));
break;
}
}
</script>
</body>
</html>
It seems you have created multiple questions for this issue :).
I answered your previous question here.
jsfiddle here
Code
function resetButtons() {
// enable and show all buttons
$("button").prop("disabled", false).show();
// First box (top left), disable and hide top and left
var firstBox = $(".box").eq(0);
firstBox.find(".top").prop("disabled", true).hide();
firstBox.find(".left").prop("disabled", true).hide();
// Second box (top right), disable and hide top and right
var secondBox = $(".box").eq(1);
secondBox.find(".top").prop("disabled", true).hide();
secondBox.find(".right").prop("disabled", true).hide();
// Third box (bottom left), disable and hide down and left
var thirdBox = $(".box").eq(2);
thirdBox.find(".down").prop("disabled", true).hide();
thirdBox.find(".left").prop("disabled", true).hide();
// Fourth box (bottom right), disable and hide down and right
var fourthBox = $(".box").eq(3);
fourthBox.find(".down").prop("disabled", true).hide();
fourthBox.find(".right").prop("disabled", true).hide();
}
For swapping, we will play with array-index of the boxes and swap the html content of each box.
function swapContent(divA, divB) {
var tempDiv = divA.html();
divA.html(divB.html());
divB.html(tempDiv);
}
For example, right button will swap current box and the one next to it (on its right).
$(".container").on("click", ".right", function(e) {
var currentBox = $(this).parents('.box');
var currentIndex = $(".box").index(currentBox);
console.log(currentIndex, "right", currentBox);
swapContent(
currentBox,
$(".box").eq(currentIndex+1)
);
resetButtons();
});
Ok, I've got this to work for swapping with left & right divs.
Now, stuck with top and down!
Here's my updated code.
<html>
<head>
<style>
.box {
height: 25%;
width: 45%;
padding: 1%;
margin-left: 1%;
margin-top: 1%;
border: 1px solid black;
float: left;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
</head>
<body>
<div class="container">
<div class="box" id="one">
<p>one</p>
<button class="right">Swap with right!</button>
<button class="down">Swap with down!</button>
</div>
<div class="box" id="two">
<p>two</p>
<button class="left">Swap with left!</button>
<button class="down">Swap with down!</button>
</div>
<div class="box" id="three">
<p>three</p>
<button class="right">Swap with right!</button>
<button class="top">Swap with top!</button>
</div>
<div class="box" id="four">
<p>four</p>
<button class="left">Swap with left!</button>
<button class="down">Swap with down!</button>
</div>
</div>
<script>
$(document).ready(function() {
$('.right').click(function(){
//alert('ok');
var toMove1 = $(this).parents('.box');
//toMove2 = toMove1.next();
$(toMove1).insertAfter($(toMove1).next());
});
$('.left').click(function(){
//alert('ok');
var toMove1 = $(this).parents('.box');
//toMove2 = toMove1.prev();
$(toMove1).insertBefore($(toMove1).prev());
});
$('.container').eq(0);
/*
$('.down').click(function(){
//alert('ok');
toMove1 = $(this).parents('.box');
//toMove2 = toMove1.prev();
var toMove2 = $(toMove1).insertAfter($(toMove1).next());
$(toMove2).insertAfter($(toMove2).next());
});
$('.top').click(function(){
//alert('ok');
toMove1 = $(this).parents('.box');
//toMove2 = toMove1.prev();
$(toMove1).insertAfter($(toMove1).prev());
});
$(".box").first().css({"background-color":"yellow"});
$('.box:first-child').eq(3).removeClass('.left');
$('.box:first-child').eq(3).addClass('.right');
*/
});
</script>
</body>
</html>
Also, how do I ensure that the button swap with right changes to swap with left if it's a right element and similarily, changes accordingly for each button, when a div is swapped?

Categories