Dynamic Tile create and Adjust in Available Width - javascript

I want to create a dynamic tile(div) based on number of users are available.
Like it is happen in microsoft team meetings.
Example -
when there is only user then div occupy full screen.
When there are two users then both the divs should get 50% width like
When there are 3 users then divs should occupy 25%,25% and 50% area of screen. Like
When there ate four, five and six user then it will occupy space as -
And so on. So the dynamic tile (div) can adjust the UI automatically atleast upto 12-16 tiles.
This also needs to be responsive.
Any help is really appreciated.

I made one to three users.
This is an example. using the current logic, you can do the rest yourself.
good luck.
var numUsers = $('#xusersx .user').length;
$('#xusersx').addClass('nowusers-' + numUsers);
body {
margin: 20px;
}
#xusersx {
display: flex;
width: 100%;
flex-wrap: wrap;
justify-content: space-between;
}
#xusersx>.user {
border: solid 4px black;
box-sizing: border-box;
}
#xusersx.nowusers-1>.user {
width: 100%;
height: 200px;
}
#xusersx.nowusers-2>.user, #xusersx.nowusers-3>.user {
width: calc(50% - 10px);
height: 200px;
}
#xusersx.nowusers-3 {
width: 50%;
}
#xusersx.nowusers-3>.user:last-child {
width: 100%;
height: 160px;
margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<div id="xusersx">
<div class="user"></div>
</div>
var numUsers = $('#xusersx .user').length;
$('#xusersx').addClass('nowusers-' + numUsers);
body {
margin: 20px;
}
#xusersx {
display: flex;
width: 100%;
flex-wrap: wrap;
justify-content: space-between;
}
#xusersx>.user {
border: solid 4px black;
box-sizing: border-box;
}
#xusersx.nowusers-1>.user {
width: 100%;
height: 200px;
}
#xusersx.nowusers-2>.user, #xusersx.nowusers-3>.user {
width: calc(50% - 10px);
height: 200px;
}
#xusersx.nowusers-3 {
width: 50%;
}
#xusersx.nowusers-3>.user:last-child {
width: 100%;
height: 160px;
margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<div id="xusersx">
<div class="user"></div>
<div class="user"></div>
</div>
var numUsers = $('#xusersx .user').length;
$('#xusersx').addClass('nowusers-' + numUsers);
body {
margin: 20px;
}
#xusersx {
display: flex;
width: 100%;
flex-wrap: wrap;
justify-content: space-between;
}
#xusersx>.user {
border: solid 4px black;
box-sizing: border-box;
}
#xusersx.nowusers-1>.user {
width: 100%;
height: 200px;
}
#xusersx.nowusers-2>.user, #xusersx.nowusers-3>.user {
width: calc(50% - 10px);
height: 200px;
}
#xusersx.nowusers-3 {
width: 50%;
}
#xusersx.nowusers-3>.user:last-child {
width: 100%;
height: 160px;
margin-top: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<div id="xusersx">
<div class="user"></div>
<div class="user"></div>
<div class="user"></div>
</div>

Related

How to stop resizing div element when it reaches the specific width?

I tried to make a site with a resizable sidebar using jquery-resizable.js. What I want to do is making stop resizing once it reaches the specific width. However, it keeps moving even though it is already over the min-width value. I found the ResizeObserver to detect the changing width values and tried to change the div element's CSS values like resize:none; but it didn't work.
How could I stop resizing once it reaches a certain width value?
Here are my codes.
$(".panel-left").resizable({
handleSelector: ".splitter",
resizeHeight: false,
resizeHeightFrom:'center',
});
var ro = new ResizeObserver(entries => {
for (let entry of entries) {
const cr = entry.contentRect;
console.log('Element:', entry.target);
console.log(`Element size: ${cr.width}px x ${cr.height}px`);
console.log(`Element padding: ${cr.top}px ; ${cr.left}px`);
if (cr.width <= 330) {
console.log("its too small");
cr.css('resize', 'none');
}
}
});
ro.observe(document.querySelector('.panel-right'));
.panel-container {
display: flex;
flex-direction: row;
border: 1px solid silver;
overflow: hidden;
}
.panel-left {
flex: 0 0 auto;
padding: 10px;
width: 900px;
/* min-height: 100%; */
min-width: 650px;
white-space: nowrap;
background: #8E44AD;
color: white;
}
.panel-right {
flex: 1 0 auto;
padding: 10px;
width: 300px;
/* min-height: 100%; */
min-width: 350px;
background: #34495E;
color: #fff;
overflow-x: hidden;
}
.splitter {
flex: 0 0 auto;
width: 8px;
background: url(images/vsizegrip.png) center center no-repeat #ccc;
min-height: 100%;
cursor: col-resize;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.jqueryscript.net/demo/jQuery-Plugin-To-Generate-Resizable-DOM-Elements-Resizable/src/jquery-resizable.js"></script>
<div class="panel-container el" style="height:100%;">
<div class="panel-left resizable">
left panel
</div>
<div class="splitter">
</div>
<div class="panel-right" id="panelRight">
right panel
</div>
</div>
What you try do do is possible with max-width like #JHeth mentioned.
You can set the min-width to set the minimum width of your div and max-width to stop on the pixel size you want.
.panel-left {
min-width: 50px;
max-width: 200px;
width: 50%;
}
See the example below:
$(".panel-left").resizable({
handleSelector: ".splitter",
resizeHeight: false,
resizeHeightFrom:'center',
});
.panel-container {
display: flex;
flex-direction: row;
border: 1px solid silver;
overflow: hidden;
width: 100%;
}
.panel-left {
flex: 0 0 auto;
padding: 10px;
min-height: 100vh;
min-width: 50px;
max-width: 200px;
white-space: nowrap;
background: #8E44AD;
color: white;
width: 50%;
}
.panel-right {
flex: 1 0 auto;
padding: 10px;
min-height: 100vh;
background: #34495E;
color: #fff;
overflow-x: hidden;
}
.splitter {
flex: 0 0 auto;
width: 8px;
background: url(images/vsizegrip.png) center center no-repeat #ccc;
min-height: 100%;
cursor: col-resize;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://www.jqueryscript.net/demo/jQuery-Plugin-To-Generate-Resizable-DOM-Elements-Resizable/src/jquery-resizable.js"></script>
<div class="panel-container el" style="height:100%;">
<div class="panel-left resizable">
left panel
</div>
<div class="splitter">
</div>
<div class="panel-right" id="panelRight">
right panel
</div>
</div>

Scrollable CSS div with fixed parent element

I am building a mobile application which will have a scrollable element in the middle of the screen. Currently when I try and scroll the entire app moves. I would like the all other elements to remain fixed while my element scrolls.
Here is my main React App:
class MobileServices extends Component {
render() {
return (
<div className={style.app}>
<div className={style.mobileHeader}>
<div className={style.logoBox}>
Logo Here
</div>
<div className={style.contactBox}>
</div>
</div>
<div className={style.mainContent}>
<div className={style.contentOne}></div>
<div className={style.contentTwo}></div>
<div className={style.contentThree}></div>
</div>
</div>
);
}
}
Here is the CSS:
html, body {
margin: 0;
/* height: 100% */
}
.app {
background-color: green;
background-size : cover;
background-attachment: fixed;
height: 100vh;
width: 100vw;
overflow: hidden;
}
.contactBox {
margin: 1rem;
padding: 1rem;
}
.contentOne {
background-color: blue;
display: flex;
height: 10rem;
width: 100vw
}
.contentTwo {
background-color: red;
display: flex;
height: 10rem;
width: 100vw
}
.logoBox {
border: 2px solid white;
margin: 1rem;
padding: 2rem;
}
.mainContent {
flex: 1;
display: flex;
overflow: scroll;
margin-top: 4rem;
height: 10rem;
width: 300vw;
overflow-x: auto;
}
.mobileHeader {
display: flex;
justify-content: space-between;
width: 100%;
}
I have tried making the app class fixed, but that only prevented me from being able to scroll at all.
body, html {
width: 100%;
height: 100%;
overflow: hidden;
}
.app {
// your css and
display: flex;
flex-direction: column;
}
.mainContent {
flex-grow: 1;
overflow: auto;
// rest of your css
}
Optional, you can set your mobielHeader to have position: sticky

How to overlap images using flexbox while maintaing it's ability responsive design

click here to see my code
The goal here is to perfectly overlap the images.
The eyes (blue ovals) should display on the face (peach circle). I'm using chrome as my browser. But hope it will display the same on any browser used.
Like so (minus the nose):
What I tried:
changing the position of the images from relative to absolute (With one image set as absolute I should have been able to move it anywhere I wanted on the page.)
setting align-self: flex-start (Sometimes browsers have weird default setting. I was told this might override a chrome default that was stopping me from moving the image.)
setting align-self: center (This was also an attempt to override a chrome default)
I can't figure out how to overlap the two images let alone add any code to my CSS file that will move the images.
function setDefaultImage(){
var defaultImage = document.getElementById(img_face).src = "https://drive.google.com/file/d/1_seSuUcgJgd5qQTUcreDuYo_zfVpRzsa/view?usp=sharing";
}
.flex-container {
display: flex;
background-color: darkred;
flex-direction: row;
flex-wrap: wrap;
justify-content: center;
}
.flex-container > div {
background-color: black;
margin: 1%;
padding: 5%;
width:38%;
}
img{
align-self: flex-start;
text-align: center;
width: 100%;
}
.img_face{
position: absolute;
top: 0;
z-index: 1;
}
.img_eyes{
position: absolute;
top: 0;
z-index: 2;
}
<!DOCTYPE html>
<html>
<body>
<div class="flex-container">
<div id = "left">
<button type="reset" id="reset" class="button" onclick = setDefaultImage()>Reset</button>
</div>
<div id = "right">
<img id="img_face" src="white_face.png" alt="White Face" >
<img id="img_eyes" src="blue_eyes.png" alt="Blue Eyes" >
</div>
</div>
Here's a couple different approaches with room for tinkering to help your learning. Happy Holidays!
hiUser = (val) => {
const box1 = document.getElementById('box1'),
box2 = document.getElementById('box2'),
blah = `${val}px`;
box1.style.height = blah;
box1.style.width = blah;
box2.style.height = blah;
box2.style.width = blah;
}
div {
display: flex;
align-items: center;
/* default initial values */
height: 100px;
width: 100px;
margin-top: 2rem;
}
span {
background-color: blue;
height: 20%;
width: 10%;
border-radius: 50%;
margin-bottom: 30%;
}
figure, #box1 {
position: relative;
background-color: wheat;
border-radius: 50%;
margin: 0;
}
figure {
height: 100%;
width: 100%;
}
#box1 {
justify-content: space-around;
}
#box1 span {
margin-right: 20%;
}
#box1 span:first-child {
margin-left: 20%;
margin-right: 0;
}
figure:before, figure:after {
content: '';
display: block;
position: absolute;
top: 25%;
background-color: blue;
height: 20%;
width: 10%;
border-radius: 50%;
}
figure:before {
left: 30%;
}
figure:after {
right: 30%;
}
label {
display: block;
margin: 2rem 0 1rem 0;
}
Slide to change size:
<input type="range"
name="fu"
min="0"
max="500"
onchange="hiUser(this.value)"
oninput="hiUser(this.value)">
<label>Flex;</label>
<div id="box1">
<span></span>
<span></span>
</div>
<label>Pseudo;</label>
<div id="box2">
<figure></figure>
</div>

Scroll Horizontally on hover only runs once?

I'm trying to make a simple scroll left and right div on hover. I'm really not sure what I'm doing wrong, I hover, but it only moves the 50 specified in the if statement. Do I need to add some kind of loop while I'm still hovering? Any help would be greatly appreciated.
Basically, I want to be able to hover over the two black boxes right and left and while it's hovered move right or left, when I remove the mouse it should stop.
$("#left").hover(function() {
var leftPos = $('#wrapper').scrollLeft();
$("#wrapper").animate({
scrollLeft: leftPos - 50
}, 1);
});
$("#right").hover(function() {
var leftPos = $('#wrapper').scrollLeft();
$("#wrapper").animate({
scrollLeft: leftPos + 50
}, 1);
});
html,
body {
background-color: #eeeeee;
margin: 0;
overflow-x: scroll;
overflow-y: hidden;
}
#left {
position: absolute;
width: 10vw;
height: 100vh;
top: 0;
left: 0;
z-index: 1;
background-color: black;
}
#right {
position: absolute;
width: 10vw;
height: 100vh;
top: 0;
right: 0;
z-index: 1;
background-color: black;
}
#wrapper {
width: 100%;
height: 100vh;
white-space: nowrap;
overflow-y: hidden;
overflow-x: scroll;
}
#inner_wrap {
width: 4000px;
height: 100vh;
align-items: center;
display: flex;
}
#firstcontent {
align-items: center;
display: flex;
vertical-align: middle;
color: white;
float: left;
margin-left: 20vw;
width: 400px;
height: 250px;
background-color: #2d2d2d;
}
.thumbone {
width: 400px;
height: 250px;
background-color: lightgrey;
display: inline-block;
}
.thumbtwo {
width: 400px;
height: 250px;
background-color: grey;
display: inline-block;
}
<script src="https://corporate3.bdjobs.com/js/jquery.min.js"></script>
<div id="left"></div>
<div id="right"></div>
<div id="wrapper">
<div id="inner_wrap">
<div id="firstcontent">hover or scroll</div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
</div>
</div>
Link to script
jsfiddle
[also a side note, why does this work only on jsfiddle and no where else?]
Your issue is because the mouseenter and mouseleave events (which underpin the hover() logic) only fire once, when the mouse enters/leaves the targeted element. If you want to repeatedly perform an action whilst the element is over those elements you'll need to implement your own logic.
To achieve this you can use an interval within the mouseenter handler of the hover() to repeatedly shift the scroll position of the required element. Then in the mouseleave you can clear that timer.
Also note that you can DRY up your code by using a common class on both elements along with a data attribute to govern the movement increment per tick of the interval. Try this:
var timer;
$('.hover-scroll').hover(function() {
var increment = $(this).data('pos');
timer = setInterval(function() {
var leftPos = $("#wrapper").scrollLeft();
$("#wrapper").animate({
scrollLeft: leftPos + increment
}, 1);
}, 50);
}, function() {
clearInterval(timer);
});
html,
body {
background-color: #eeeeee;
margin: 0;
overflow-x: scroll;
overflow-y: hidden;
}
#left {
position: absolute;
width: 10vw;
height: 100vh;
top: 0;
left: 0;
z-index: 1;
background-color: black;
}
#right {
position: absolute;
width: 10vw;
height: 100vh;
top: 0;
right: 0;
z-index: 1;
background-color: black;
}
#wrapper {
width: 100%;
height: 100vh;
white-space: nowrap;
overflow-y: hidden;
overflow-x: scroll;
}
#inner_wrap {
width: 4000px;
height: 100vh;
align-items: center;
display: flex;
}
#firstcontent {
align-items: center;
display: flex;
vertical-align: middle;
color: white;
float: left;
margin-left: 20vw;
width: 400px;
height: 250px;
background-color: #2d2d2d;
}
.thumbone {
width: 400px;
height: 250px;
background-color: lightgrey;
display: inline-block;
}
.thumbtwo {
width: 400px;
height: 250px;
background-color: grey;
display: inline-block;
}
<script src="https://corporate3.bdjobs.com/js/jquery.min.js"></script>
<div id="left" class="hover-scroll" data-pos="-50"></div>
<div id="right" class="hover-scroll" data-pos="50"></div>
<div id="wrapper">
<div id="inner_wrap">
<div id="firstcontent">hover or scroll</div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
<div class="thumbone"></div>
<div class="thumbtwo"></div>
</div>
</div>
If you want to speed up or slow down the scroll, change the delay on the interval

Is it possible to have this div expand as its content expands?

The difficult issue is that I need this CSS rule: html {height: 100%} in order to make my first page work. See prototype.
This allows the login div to be centered based on the height of the window.
However, the second page now is stuck at this height and does not expand as I populate the content using ajax. Either click on the star in this link or see below.
You can see where the dotted line stops is the original rendering of the window at 100%.
If I remove the height of 100% it will expand but then the SignOn page is broken as it has no height.
Note: React is controlling the changing from page to the other using a simple conditional in the JSX based on the application state.
Should I alter the CSS height for HTML based on application state or is there a better way to do this?
A better question, might be, that after the content in the div changes, shouldn't the div expand to reflect this?
Relevant CSS
html{
width: 100%;
height: 100%;
}
body{
background-image: url('_images/bg_paper.jpg');
height: 100%;
width: 100%;
}
#app{
width: 100%;
height: 100%;
}
#contents{
width: 100%;
height: 100%;
}
#top-1{
position: fixed;
width: 100%;
height: 40px;
background: rgba(255, 255, 255, 0.8);
border-top: 3px solid #000000;
border-bottom: 1px solid #bbbbbb;
z-index: 1000;
}
#top-2{
position: relative;
width: 90%;
height: 100%;
margin: 0 auto;
border-left: 1px dotted #888888;
border-right: 1px dotted #888888;
}
#container-1{
position: relative;
display: inline-block;
width: 100%;
height: 100%;
top: 44px;
}
#container-2{
position: relative;
width: 90%;
height: 100%;
margin: 0 auto;
border-left: 1px dotted #888888;
border-right: 1px dotted #888888;
}
.body{
display: none;
position: relative;
width: 100%;
height: 100%;
}
I think using flex is much easier to deal with this kind of situations.
You can set your main container as flex and play with the justify and align properties to center the elements.
The problem here is that you got a fixed positioned element as a toolbar that goes out of flow, so we will set margin-top to the next element respectively to the fixed element's height.
another issue is that you want to center the login component when its parent isn't at the same height as the view port, this can be handled with a min-height:100vh to the main container.
Here is a very basic demonstration of the above:
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
login: true,
items: [
'item 1',
'item 2',
'item 3',
'item 4',
]
};
}
addITem = e => {
const { items } = this.state;
const nextItem = `item ${items.length + 2}`;
this.setState({ items: [...items, nextItem] });
}
loginView = e => {
this.setState({ login: true });
}
login = e => {
this.setState({ login: false });
}
render() {
const { items, login } = this.state;
return (
<div className="container">
<div className="toolbar">
<div className="title">This is a fixed toolbar, click to add items</div>
<button className="btn" onClick={this.addITem}>+</button>
<button className="btn" onClick={this.loginView}>Login</button>
</div>
{login ?
<div className="login-wrapper">
<div className="login">
<label>Login</label>
<input placeHolder="user name" />
<input type="password" placeHolder="password" />
<button className="btn" onClick={this.login}>Go</button>
</div>
</div>
:
<div className="items">
{items.map(item => <div className="item">{item}</div>)}
</div>
}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
.container {
display: flex;
flex-direction: row;
min-height: 100vh;
}
.toolbar {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
border: 1px solid #ccc;
padding: 10px;
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 999;
background-color: #333;
color: #fff;
}
.title {
padding: 10px;
}
.btn {
padding: 5px;
width: 100px;
margin: 0 15px;
}
.items {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-top: 65px;
align-content: baseline;
}
.item {
display: flex;
justify-content: center;
align-items: center;
height: 50px;
width: 250px;
box-shadow: 0 0 3px 1px #333;
margin: 5px;
padding: 5px;
}
.login-wrapper{
display: inline-block;
margin: auto;
}
.login {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Categories

Resources