I've added three pictures. Look at them please.
What is the best solution to create something like this? I would create after each row a big container and this container is collapsed. After clicking on one of the 3 overlying containers I would fill the container with the text and show it. But what happens when the display can't show 3 divs in a row, because I will use flex boxes? Is there a better solution with much less jquery?
Maybe something like this is a good place to start:
https://jsfiddle.net/547ec3bx/
HTML
<div class="wrapper">
<div class="row">
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
<div class="row">
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
<div class="row">
<div class="element">
</div>
<div class="element">
</div>
<div class="element">
</div>
</div>
</div>
Javascript
document.querySelectorAll('.row').forEach((element, index) => {
element.style.order = index * 2;
});
document.querySelectorAll('.element').forEach(element => {
element.addEventListener('click', event => {
var newRow = document.createElement('div');
newRow.classList.add('row');
newRow.style.order = +event.currentTarget.parentNode.style.order + 1;
var newElement = document.createElement('div');
newElement.classList.add('element');
newRow.appendChild(newElement);
event.currentTarget.parentNode.parentNode.appendChild(newRow);
});
});
CSS
.element {
min-width: 100px;
height: 50px;
flex: 1;
border: 1px solid black;
flex-wrap: nowrap;
}
.row {
width: 350px;
display: flex;
flex-direction: row;
}
.wrapper {
display: flex;
flex-direction: column;
}
you can use javascript to solve this problem , like this ....
html code:
<div id="a">
<h3>wellcome</h3>
</div>
<div id="b">
<h3>hello...</h3>
</div>
javascript code in external file
function goB()
{
document.getElementById("a").style.display="none";
document.getElementById("b").style.display="block";
}
function
{
document.getElementById("b").style.display="none";
document.getElementById("a").style.display="block";
}
Add a div and set its display to Hidden.
Get onclick event for a particular div and set the display property to block
window.addEventListener("load", function(){
document.getElementById("click").onclick = function(){
document.getElementById("div-1").style.display = "block";
};
});
.row
{
width:100%;
}
.one-third
{
width:33.33333%;
float:left;
padding:30px 0;
}
.full-width
{
display:none;
width:100%;
text-align:center;
}
<div class=wrap>
<div class="row">
<div id="click" class="one-third">
Column 1-Click Me
</div>
<div class="one-third">
Column 2
</div>
<div class="one-third">
Column 3
</div>
</div>
<div class="full-width" id="div-1">Full width Div</div>
<div class="row">
<div class="one-third">
Column 1
</div>
<div class="one-third">
Column 2
</div>
<div class="one-third">
Column 3
</div>
</div>
Related
I am trying to display Cards next to one another (4 cards per row). Here is my my html for a Card:
<div class="HelloWorldCard">
<div class="cardwithlink">
<div class="row">
<div class="Hellocard cardwithlink style="height: 170px;">
<a href="//www.https://www.google.com/" title="Google home page" target="">
<div class="content">
<div class="HelloTopSection" style="height: 110px;">
<div class="HelloCardTitle">{{ title }}</div>
<div class="HelloCardExcerpt">{{ description }}</div>
</div>
</div>
</a>
</div>
</div>
</div>
</div>
<Script>
export default{
name: "HelloWordCard",
props:{
title: String,
description: String
},
};
I have about 100 cards that I want to display on my page. I can't just copy and past this html 100 times since that would be a waste of time. Is it possible to print out this block of html in a loop 100 times ?
The real issue I am having is that the cards are displaying 1 card on each row. I am trying to get them to display 4 on each row.
Your row should not be inside your card component.
It should be in a parent component holding the card, where you can apply #Srijan Katuwal's CSS. For example:
<template>
<div id="app">
<div class="row">
<HelloWorldCard
v-for="index in 100"
:key="index"
title="Test"
description="Test description"
/>
</div>
</div>
</template>
<script>
import HelloWorldCard from "./components/HelloWorldCard";
export default {
name: "App",
components: {
HelloWorldCard,
},
};
</script>
<style>
.row {
display: grid;
grid-template-columns: repeat(4, auto);
gap: 30px;
}
</style>
Your component now is:
<template>
<div class="Hellocard cardwithlink" style="height: 170px">
<a href="//www.https://www.google.com/" title="Google home page" target="">
<div class="content">
<div class="HelloTopSection" style="height: 110px">
<div class="HelloCardTitle">{{ title }}</div>
<div class="HelloCardExcerpt">{{ description }}</div>
</div>
</div>
</a>
</div>
</template>
<script>
export default {
name: "HelloWordCard",
props: {
title: String,
description: String,
},
};
</script>
You can see it in action here: https://codesandbox.io/s/hungry-hodgkin-2sklq?file=/src/App.vue:0-476
You can use v-for directive to show a div block for n number of times.
Vue offical documentation has similar example v-for
Also, to display 4 cards in a single row, you can use CSS grid or flex. A grid implementation can be done as below
.row {
display: grid;
grid-template-columns: repeat(4, auto);
gap: 30px;
}
You need to write following CSS to display cards next to each other
* {
box-sizing: border-box;
}
.row {
display: block;
width: 100%;
}
.card {
display: block;
float: left;
width: 25%;
padding: 10px;
border: 1px solid grey;
}
<div class="row">
<div class="card">Card Data</div>
<div class="card">Card Data</div>
<div class="card">Card Data</div>
<div class="card">Card Data</div>
<div class="card">Card Data</div>
<div class="card">Card Data</div>
</div>
I have 4 divs with bootstrap col-md-3 class. When clicked on any Div, I am expanding width of that div to 100%, showing expanded contents and hiding(display:none) other divs.
On close button, I want to reverse changes, so I am trying to assign 25% width, hinding expanded contents and making other divs visible(display:block).
But changes are not getting reflected.
function openTab(tab) {
var i, x, y;
x = document.getElementsByClassName("containerTab");
y = document.getElementsByClassName("OuterTab");
for (i = 0; i < x.length; i++)
{
if(i==tab-1)
{
y[i].style.width="100%";
y[i].style.transition= "width 0.5s ease-in";
x[i].style.maxHeight="5000px";
x[i].style.transition= "max-height 1s ease-in";
}
else
{
y[i].style.display="none";
}
}
}
function closeTab(tab)
{
var i, x, y,z, a;
x = document.getElementsByClassName("containerTab");
y = document.getElementsByClassName("OuterTab");
for (i = 0; i < x.length; i++)
{
if(i==tab-1)
{
y[i].style.width= "25%";
y[i].style.transition= "width 0.5s ease-in";
x[i].style.maxHeight = "0px";
x[i].style.transition= "max-height 1s ease-in";
}
else
{
y[i].style.display = "block";
}
}
}
.border1{border: 1px solid; border-radius: 5px;padding:2px}
.border2{border: 1px solid; border-radius: 7px;padding:10px}
.containerTab {
cursor: pointer;
color: black;
max-height: 0;
min-height:0;
overflow: hidden;
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class="container-fluid" style="padding:10px">
<div class="row">
<div class="col-md-3 col-xs-12 text-center OuterTab" onclick="openTab(1);" style="">
<div class="border1">
<div class="border2">
content 1
</div>
<div id="b1" class="containerTab" style="">
Expanded content 1
<div><button onclick="closeTab(1)">Close</button></div>
</div>
</div>
</div>
<div class="col-md-3 col-xs-12 text-center OuterTab" onclick="openTab(2);" style="">
<div class="border1">
<div class="border2">
content 2
</div>
<div id="b2" class="containerTab" style="width:100%;">
Expanded content 2
<div><button onclick="closeTab(1)">Close</button></div>
</div>
</div>
</div>
<div class="col-md-3 col-xs-12 text-center OuterTab" onclick="openTab(3);" style="">
<div class="border1">
<div class="border2">
content 3
</div>
<div id="b3" class="containerTab" style="width:100%;">
Expanded content 3
<div><button onclick="closeTab(1)">Close</button></div>
</div>
</div>
</div>
<div class="col-md-3 col-xs-12 text-center OuterTab" onclick="openTab(4);" style="">
<div class="border1">
<div class="border2">
content 4
</div>
<div id="b3" class="containerTab" style="width:100%;">
Expanded content 4
<div><button onclick="closeTab(1)">Close</button></div>
</div>
</div>
</div>
</div>
Instead of re-applying the individual styles. Apply the new styles by simply adding a CSS class. Then on the click of the Close button, simply remove that class, which will cause the affected elements to revert to their previous style.
addClass and removeClass in jQuery - not removing class
Got answer in this post. Seems the problem was due to event bubbling as close button was inside clickable div, both closetab tab and opentab events were getting called. Worked fine when moved "close" button outside div.
How do I Scroll an element (not the entire page) a specific amount of pixals for example 100px on every click of a button (not a has link because it needs to be a fixed amount of pixals each time) I use ReactJS 16.
You can use scrollBy on the element you want to scroll. A vanilla JS example:
let btn = document.getElementById('btn');
let box = document.getElementById('box');
btn.addEventListener('click', function() {
box.scrollBy({top:100, behavior: "smooth"});
});
#box {
width: 300px;
height: 100px;
overflow-y: scroll;
}
#inner-box {
width: 100px;
height: 1000px;
}
.content {
height: 50px;
display: block
}
<button id="btn">scroll</button>
<div id="box">
<div id="inner-box">
<div class="content">
content
</div>
<div class="content">
content
</div>
<div class="content">
content
</div>
<div class="content">
content
</div>
<div class="content">
content
</div>
<div class="content">
content
</div>
</div>
</div>
This is a ReactJS version:
class Scrollable extends React.Component {
constructor(props) {
super(props);
this.scroll = this.scroll.bind(this);
this.box = React.createRef();
}
scroll() {
this.box.current.scrollBy({top:100, behavior: "smooth"});
}
render() {
return (
<div>
<button onClick={this.scroll}>scroll</button>
<div id="box" ref={this.box}>
<div id="inner-box">
<div class="content">
content
</div>
<div class="content">
content
</div>
<div class="content">
content
</div>
<div class="content">
content
</div>
<div class="content">
content
</div>
<div class="content">
content
</div>
</div>
</div>
</div>
);
}
}
Demo at Codepen
I'm trying to have it where pressing "btn1" alone populates the sidebar. I tried $("#container").on("click", ".btn1", function() but it doesn't work.
$("#container").on("click", ".item", function() {
$("#title").text($(this).find(".title").text());
var itemImgSrc = $(this).find(".image").attr("src");
$("#image")
.css("background-image", 'url("' + itemImgSrc + '")')
.css("background-repeat", "no-repeat");
});
#container {
display: flex;
height: 100px;
}
.image {
height: 100px;
}
#image {
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<!-- Item 1 -->
<div class="item">
<button class="btn1"></button>
<div class="title">Dog</div>
<img class="image" src="http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg">
</div>
<!-- Item 2 -->
<div class="item">
<button class="btn1"></button>
<div class="title">Cat</div>
<img class="image" src="https://www.royalcanin.com/~/media/Royal-Canin/Product-Categories/cat-adult-landing-hero.ashx">
</div>
<!-- Sidebar Div -->
</div>
<div class="modal">
<h2 id="title"></h2>
<div id="image"></div>
</div>
.title and .image are not contained in .btn1. You need to go up to the containing .item and then find them.
$("#container").on("click", ".btn1", function() {
var item = $(this).closest(".item");
$("#title").text(item.find(".title").text());
var itemImgSrc = item.find(".image").attr("src");
$("#image")
.css("background-image", 'url("' + itemImgSrc + '")')
.css("background-repeat", "no-repeat");
});
#container {
display: flex;
height: 100px;
}
.image {
height: 100px;
}
#image {
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<!-- Item 1 -->
<div class="item">
<button class="btn1"></button>
<div class="title">Dog</div>
<img class="image" src="http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg">
</div>
<!-- Item 2 -->
<div class="item">
<button class="btn1"></button>
<div class="title">Cat</div>
<img class="image" src="https://www.royalcanin.com/~/media/Royal-Canin/Product-Categories/cat-adult-landing-hero.ashx">
</div>
<!-- Sidebar Div -->
</div>
<div class="modal">
<h2 id="title"></h2>
<div id="image"></div>
</div>
You could also use $(this).siblings(".title') and $(this).siblings(".image").
You need to change $(this) to $(.btn1).
$(this) being the button clicked works for .btn1 and not for .btn2, changing it from dynamic $(this) to always looking for .link in .btn1 should solve it.
Have you tried using $(this).parent().find(".title"). You could move up the heirarchy and get the element from there and then
$("#container").on("click", ".item", function() {
$("#title").text($(this).parent().find(".title").text());
var itemImgSrc = $(this).parent().find(".image").attr("src");
$("#image")
.css("background-image", 'url("' + itemImgSrc + '")')
.css("background-repeat", "no-repeat");
});
#container {
display: flex;
height: 100px;
}
.image {
height: 100px;
}
#image {
height: 100px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
<!-- Item 1 -->
<div class="item">
<button class="btn1"></button>
<div class="title">Dog</div>
<img class="image" src="http://cdn2-www.dogtime.com/assets/uploads/2011/01/file_23244_what-is-the-appenzeller-sennenhunde-dog-300x189.jpg">
</div>
<!-- Item 2 -->
<div class="item">
<button class="btn1"></button>
<div class="title">Cat</div>
<img class="image" src="https://www.royalcanin.com/~/media/Royal-Canin/Product-Categories/cat-adult-landing-hero.ashx">
</div>
<!-- Sidebar Div -->
</div>
<div class="modal">
<h2 id="title"></h2>
<div id="image"></div>
</div>
Also try using an index with the find method. it returns an array but i dont think that giving index is necessary when there is only one element.
something like this
$(this).parent().find(".item")[0].text();
I have a bootstrap row which will be populated by, let's say, blog post thumbnails.
<section class="container">
<div class="row thumbs">
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
</div>
<hr class="divider" />
<div class="navigation">navigation</div>
</section
I want to close a row, insert hr tag and open a new bootstrap row after every 4th post thumbnail.
<section class="container">
<div class="row thumbs">
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
</div>
<hr class="divider" />
<div class="row">
<div class="col-sm-3">content</div>
</div>
<hr class="divider" />
<div class="navigation">navigation</div>
</section>
Is there a way to do this with jquery?
Can do something like this:
var $mainElem = $('.row'),/* adjust selector to suit page*/
$parent = $mainElem.parent(),
/* remove children after 4th from existing row */
$items = $mainElem.children(':gt(3)').detach();
if ($items.length) {
/* create new row for every 4 items removed above */
for (var i = 0; i < $items.length; i = i + 4) {
var $row = $('<div class="row">').append($items.slice(i, i + 4));
$parent.append('<hr class="divider">').append($row);
}
}
DEMO
This worked best for me:
var $d = $('.thumbs');
var $p = $('.col-sm-3:gt(3)', $d);
if ($p.length) {
$('<div class="row thumbs">').insertAfter($d).append($p);
$('<hr class="divider">').insertAfter($d);
}
Depending on your motivation to wrap each set of columns in a new row, you can style every nth row with straight CSS.
In bootstrap, if you have extra columns that spillover past 12, they just wrap into a new line anyway, so having the new row is usually redundant, although you might have some external reason to keep it in your case.
Either way, here's a CSS solution that adds a page wide horizontal divider every 4 divs:
Demo in jsFiddle & Stack Snippets
.container .row.thumbs div:nth-child(4n) {
position: static;
}
.container .row.thumbs div:nth-child(4n):after {
content: ' ';
border-top: 1px solid black;
display: block;
position: absolute;
width: 95%;
margin-left: 2.5%;
left: 0;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.css" rel="stylesheet"/>
<section class="container">
<div class="row thumbs">
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
<div class="col-sm-3">content</div>
</div>
<div class="navigation">navigation</div>
</section>
Also, bear in mind that this won't be natively supported in < IE8