Enable only one masonry tile open at a time - javascript

I have a masonry layout (using the library from here), that when a user clicks a tile, only one tile should be able to expand at a time. If the user clicks another tile, the previously opened tile should close. How can I check for any previously opened tiles, close them, and then open the newly selected tile?
// external js: masonry.pkgd.js
var grid = document.querySelector('.grid');
var msnry = new Masonry( grid);
grid.addEventListener( 'click', function( event ) {
// don't proceed if item was not clicked on
if ( !matchesSelector( event.target, '.grid-item' ) ) {
return;
}
// change size of item via class
event.target.classList.toggle('grid-item--gigante');
// trigger layout
msnry.layout();
});
.grid {
background: #eee;
width: 1200px;
margin: 0 auto;
}
.grid-holder {
background: #fff;
margin: 0 auto;
display: block;
}
.grid-item {
width: 375px;
height: 375px;
margin-bottom: 4%;
float: left;
border: 1px solid #ddd;
margin-right: 10px;
background-color: #eee;
box-shadow: 2px 2px 2px 2px #eee;
}
.grid-item--gigante {
max-width: 600px;
min-width: 100px;
width: 63%;
min-height: 375px;
height: auto;
margin-left: 8px;
background-color: rgba(215, 210, 203, 0.3) !important;
color: #666;
border: 1px solid #ddd;
padding: 0.5% 8% 2.5% 5%;
z-index: 2; /* above other items */
}
.grid-item:hover {
background: #a2c;
border-color: white;
cursor: pointer;
}
<script src="https://masonry.desandro.com/masonry.pkgd.js"></script>
<div class="grid">
<div class="grid-holder">
<div class="grid-item">Jim</div>
<div class="grid-item">Joe</div>
<div class="grid-item">John</div>
<div class="grid-item">James</div>
<div class="grid-item">Jack</div>
<div class="grid-item">Joseph</div>
</div>
</div>

You need to keep a reference to previously enlarged grid item.
Whenever the click event occurs, check if current event target is equal to previously enlarged grid item or not. If it is not, remove .grid-item--gigante class from previously enlarged grid item and update the reference to previously enlarged grid item to now point to event.target.
P.S. removed some CSS to make the example code snippet easy to understand.
var grid = document.querySelector('.grid');
var msnry = new Masonry(grid);
var previouslyEnlarged;
grid.addEventListener('click', function(event) {
if ( !matchesSelector( event.target, '.grid-item' ) ) {
return;
}
if (previouslyEnlarged == event.target) {
return;
} else if (previouslyEnlarged) {
previouslyEnlarged.classList.remove('grid-item--gigante');
}
previouslyEnlarged = event.target;
event.target.classList.toggle('grid-item--gigante');
msnry.layout();
});
.grid-holder {
background: #fff;
margin: 0 auto;
display: block;
}
.grid-item {
width: 50px;
height: 50px;
margin-bottom: 4%;
float: left;
border: 1px solid #ddd;
margin-right: 10px;
background-color: #eee;
box-shadow: 2px 2px 2px 2px #eee;
}
.grid-item--gigante {
width: 100px;
height: 100px;
margin-left: 8px;
background-color: rgba(215, 210, 203, 0.3) !important;
color: #666;
border: 1px solid #ddd;
padding: 0.5% 8% 2.5% 5%;
z-index: 2;
}
.grid-item:hover {
background: #a2c;
border-color: white;
cursor: pointer;
}
<script src="https://masonry.desandro.com/masonry.pkgd.js"></script>
<div class="grid">
<div class="grid-holder">
<div class="grid-item">Jim</div>
<div class="grid-item">Joe</div>
<div class="grid-item">John</div>
<div class="grid-item">James</div>
<div class="grid-item">Jack</div>
<div class="grid-item">Joseph</div>
</div>
</div>

Related

Saving position of drag and drop in javascript into a text or excel file?

Hi guys I've been working on this project that saves the position of the drag and drop and i was wondering if there is away to save is position to a text or excel file giving you the time of the move.
i.e DIV 1 was moved to A at 09:00, DIV 1 was moved from A to B at 09:15 if that makes sense.
Couldn't figure it out.
<html>
<head>
<\head>
<style>
#draggable1 {
position: fixed;
bottom: 0;
margin: 1px 0;
padding: 0 20px;
height: 20px;
width: 50px;
line-height: 20px;
border-radius: 1px;
background: #136a8a;
background: -webkit-linear-gradient(to right, #267871, #136a8a);
background: linear-gradient(to right, #267871, #136a8a);
color: #fff;
list-style: none;
}
.draggable {
width: 90px;
height: 90px;
padding: 0.5em;
float: left;
margin: 0 10px 10px 0;
}
#draggable,
#draggable2 {
margin-bottom: 20px;
}
#draggable {
cursor: n-resize;
}
#draggable3 {
cursor: move;
}
#containment-wrapper {
width: 700px;
height: 500px;
border: 1px solid #000;
padding: 5px;
}
h3 {
clear: left;
}
#box {
position: absolute;
width: 100px;
height: 100px;
background-color: #ccc;
}
<\style>
<body>
<ul class="drag-sort-enable">
<li0 id="draggable1" class="draggable ui-widget-content" input type="text" >659451</li0>
</body>`
<script>
var sPositions = localStorage.positions || "{}",
positions = JSON.parse(sPositions);
$.each(positions, function(id, pos) {
$("#" + id).css(pos)
})
$("#draggable1").draggable({
containment: "#containment-wrapper",
scroll: false,
stop: function(event, ui) {
positions[this.id] = ui.position
localStorage.positions = JSON.stringify(positions)
}
});
<\script>

is it possible for a function to connect to another function and gather information from an array JS

is it possible to make a function that is connected to another function that has an array this is a JS game Red Light Green Light the array is holding the text "Green Light, Red Light" I want to know if its possible to make another function that is taking information from my characters movement and when the green light or red light text appears for exapmple when green light appears nothing happens because its safe to move but when red light it appears you fail and a game over screen appears
var colors = ['Green light', 'Red light'];
(function () {
var words = ["Red light"]
i = 0;
setInterval(function(){ $('#words').fadeOut(function(){
$(this).html(colors[(i = (i + 1) % colors.length)]).fadeIn();
}); }, 4000)
})();
$(document).ready(function(){
var Block = function()
{
this.goalDistance = 1370;
this.distanceTraveled = 0;
go = false;
}
var block = new Block();
$('#green-button').click(function(){
console.log('GO!');
block.go = true;
animateBlock();
// this allows the block bob to move forward
});
$('#red-button').click(function(){
console.log('STOP!');
block.go = false;
// this allows the block bob to stop moving
});
function animateBlock()
{
if(block.go === true && block.distanceTraveled < block.goalDistance)
{
$('#block').animate({left:'+=10'},50);
block.distanceTraveled += 10;
setTimeout(function(){
animateBlock();
},50);
}
}
});
canvas{
border: 1px solid black;
width: 65%;
margin-top: 35px;
margin-inline-start: 5px;
border-inline-start-color: #ffffff;
}
body {
background-color: grey;
}
.container {
width: 20%;
max-width: 20px;
margin: auto;
}
.animated-heading {
display: flex;
align-items: center;
justify-content: center;
height: 1vh;
}
h1{
color: black;
}
#finish-line
{
position:absolute;
height:650px;
width:10px;
left:1670px;
top:135px;
background-color:black;
}
.buttons
{
margin-top: 1px;
float: left;
}
.light
{
width:150px;
height:50px;
margin-left:30px;
color:white;
font-size:2em;
}
#green-button
{
background-color:green;
border-radius: 12px;
display: inline-block; margin-right: 20px;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
width: 200px;
margin-left: 820px;
margin-right: 5px;
cursor: pointer
}
#red-button
{
background-color:red;
border-radius: 12px;
box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19);
width: 200px;
margin: 0 auto;
margin-right: 1px;
cursor: pointer
}
.block
{
position:relative;
width:40px;
height:39px;
background-image: url('./image/bob.jpg');
border: 1px solid black;
bottom:400px;
left:310px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<center><h1><span id="words"> Red light</span></h1></center>
<center><canvas id="myCanvas"></canvas></center>
<div class="container"></div>
<div class="animated-heading"></div>
<div class="block" id="block"></div>
<div id = 'finish-line'></div>
<div class="buttons">
<button class = "light" id="green-button" type="button">GO!</button>
<button class = "light" id="red-button" type="button">STOP!</button>
</div>

jQuery filter the displaying of divs issue

I'm using jQuery to filter the display of divs, when i click on the name of a color i want it to display only the div that is coresponding to that color, for the "red" example, it works fine, but not the blue and the green one, first of all i want to know the problem that is occuring, then the best way to fix it.
Thank you very much.
/* jQuery function*/
$(document).ready(function(){
$("#button_red").click(function(){
$("#green").fadeOut(200);
$("#blue").fadeOut(200);
$("#red").fadeIn(500);
});
$("#button_blue").click(function(){
$("#red").fadeOut(200);
$("#green").fadeOut(200);
$("#blue").fadeIn(500);
});
$("#button_green").click(function(){
$("#red").fadeOut(200);
$("#blue").fadeOut(200);
$("#green").fadeIn(500);
});
});
#colors_container{
background-color: white;
width: 100%;
height: 900px;
}
#colors_container #colors_buttons{
width: 450px;
height: 50px;
margin: 20px auto 10px auto;
background-color: purple;
}
#colors_container #colors_buttons a {
text-decoration: none;
float: left;
margin-right: 30px;
border : solid 2px red;
padding: 10px 10px 10px 10px ;
color: white;
}
#colors_container #colors{
width: 1060px;
height: 800px;
margin: 10px auto 10px auto;
background-color: yellow;
padding: 10px 10px 10px 10px;
}
#red , #blue , #green {
width: 250px;
height: 300px;
float: left;
margin-right: 10px;
margin-bottom: 10px;
}
#red{
background-color: red;
}
#blue{
background-color: blue;
}
#green{
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="colors_container">
<div id="colors_buttons">
ALL
<a id="button_red" href="#">Red</a>
<a id="button_blue" href="#">Blue</a>
<a id="button_green" href="#">Green</a>
</div>
<div id="colors">
<div id="red"></div>
<div id="blue"></div>
<div id="red"></div>
<div id="green"></div>
</div>
</div>
Because you have duplicated IDs (refer to id="red") I suggest to transform your IDs to class. Moreover I suggest a reduced event handler because the anchor text and your class names are similar:
$('#colors_buttons a').on('click', function(e) {
// get the button text (ALL, Red, Blue, Green), remove spaces and transform in lower case
var currColor = this.textContent.trim().toLocaleLowerCase();
// now in currColor variable we have a string like red or blue or green
// but this string corresponds to the class name of the divs....
if (currColor == 'all') {
$("#colors div").fadeIn(500);
} else {
// fade out all #colors divs not having such a class
$('#colors :not(.' + currColor + '').fadeOut(200);
// fade in the only one...
$("#colors ." + currColor).fadeIn(500);
}
})
#colors_container{
background-color: white;
width: 100%;
height: 900px;
}
#colors_container #colors_buttons{
width: 450px;
height: 50px;
margin: 20px auto 10px auto;
background-color: purple;
}
#colors_container #colors_buttons a {
text-decoration: none;
float: left;
margin-right: 30px;
border : solid 2px red;
padding: 10px 10px 10px 10px ;
color: white;
}
#colors_container #colors{
width: 1060px;
height: 800px;
margin: 10px auto 10px auto;
background-color: yellow;
padding: 10px 10px 10px 10px;
}
.red , .blue , .green {
width: 250px;
height: 300px;
float: left;
margin-right: 10px;
margin-bottom: 10px;
}
.red{
background-color: red;
}
.blue{
background-color: blue;
}
.green{
background-color: green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="colors_container">
<div id="colors_buttons">
ALL
<a id="button_red" href="#">Red</a>
<a id="button_blue" href="#">Blue</a>
<a id="button_green" href="#">Green</a>
</div>
<div id="colors">
<div class="red"></div>
<div class="blue"></div>
<div class="red"></div>
<div class="green"></div>
</div>
</div>

I'm struggling to get this jquery slide down and up to work

The div I'm animating in jquery is supposed to slide out to expand the width. I've gotten the width animation to work but after adding the slideDown and up code nothing works, the way it should work is:
Enquiries should be clicked and it expands and after it expands the. For slides down and when its clicked again, first the fork slides up and then the ENQUIRIES- shown goes back to its original width.
I'm not sure where my codes gone wrong as I'm new to jquery and java script. THANK YOU FOR ANY HELP!
//-----------ENQUIRY-FORM----------
$('#enquiry-shown').click(function() {
$(this).animate({
width: "950px",
borderRadius: "0px"
}, 1000);
setTimeout(function() {
$('#enquiry-form').slideDown('slow');
}, 1000);
function() {
if ($('#enquiry-form').is("visible") {
$('#enquiry-form').slideUp("slow");
else($('#enquiry-form').is("hidden") {
$('#enquiry-form ').slideDown("slow");
});
});
};
});
/*--------ENQUIRIES---------*/
#enquiry-container {
text-align: center;
margin-bottom: 25px;
}
#enquiry-shown {
background-color: white;
padding: 10px 0;
box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.3);
width: 210px;
border: solid 1px #d8d8d8;
border-radius: 50px;
margin: 0 auto;
}
#enquiry-name {
font-family: "calibri light";
font-size: 30px;
text-align: center;
margin: 0;
display: inline;
padding: 0 0 0 10px;
}
#enq-arrowdown {
width: 25px;
height: 16px;
float: right;
padding: 10px 19px 0 0;
display: inline-block;
}
#enquiry-form {
width: 950px;
height: 400px;
background-color: white;
margin: 0 auto;
display: none;
border-bottom: solid 1px #d8d8d8;
border-right: solid 1px #d8d8d8;
border-left: solid 1px #d8d8d8;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="enquiry-container">
<div id="enquiry-shown">
<h2 id="enquiry-name">Enquiries</h2>
<img id="enq-arrowdown" src="https://www.optimaltravel.ca/images/arrow.png">
</div>
<div id="enquiry-form">
</div>
</div>
I changed i few things in your js code, i used a class to define the condition when to slideup or down
See the result:
//-----------ENQUIRY-FORM----------
$('#enquiry-shown').click(function() {
var current = $(this)
if ($('#enquiry-shown').hasClass("active")) {
$('#enquiry-form').slideUp('slow', function() {
current.animate({
width: "210px",
borderRadius: "50px"
}, 1000);
});
$('#enquiry-shown').removeClass("active");
} else {
current.animate({
width: "100%",
borderRadius: "0px"
}, 1000, function() {
$('#enquiry-form').slideDown('slow');
});
$('#enquiry-shown').addClass("active");
}
});
/*--------ENQUIRIES---------*/
#enquiry-container {
text-align: center;
margin-bottom: 25px;
}
#enquiry-shown {
background-color: white;
padding: 10px 0;
box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.3);
width: 210px;
border: solid 1px #d8d8d8;
border-radius: 50px;
margin: 0 auto;
}
#enquiry-name {
font-family: "calibri light";
font-size: 30px;
text-align: center;
margin: 0;
display: inline;
padding: 0 0 0 10px;
}
#enq-arrowdown {
width: 25px;
height: 16px;
float: right;
padding: 0px 20px 0 0;
display: inline-block;
transition: all 1s;
transform: rotate(-90deg);
}
#enquiry-form {
width: 100%;
height: 100px;
background-color: white;
margin: 0 auto;
display: none;
border-bottom: solid 1px #d8d8d8;
border-right: solid 1px #d8d8d8;
border-left: solid 1px #d8d8d8;
}
#enquiry-shown.active img {
transform: rotate(0deg);
padding-top: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="enquiry-container">
<div id="enquiry-shown">
<h2 id="enquiry-name">Enquiries</h2>
<img id="enq-arrowdown" src="https://www.optimaltravel.ca/images/arrow.png">
</div>
<div id="enquiry-form">
This is the enquiry form
</div>
</div>
I don't know if u want to achieve this effect, but try this and give me feedback:
$('#enquiry-shown').click(function() {
if($('#enquiry-form').is(':visible')){
$('#enquiry-form').slideUp('slow', function(){
$('#enquiry-shown').animate({
width: "210px",
borderRadius: "50px"
}, 1000);
});
}
else if($('#enquiry-form').is(':hidden')){
$('#enquiry-shown').animate({
width: "950px",
borderRadius: "0px"
}, 1000, function(){
$('#enquiry-form').slideDown('slow');
});
}
});
You have a lot of syntax errors such as incorrectly matched brackets, missing parenthesis, missing function name, and using else when you should use else if.
When you fix all of them it looks like your click function already has some of your intended functionality.
Next I'd suggest removing the setTimeout in favor of jQuery's animate end handler, which you use by attaching a function to most animations.
Lastly you should refactor your code a little. I don't think is('visible') does what you think it does, but luckily there's a slideToggle method that does do what you want pretty easily.
Your click handler then needs to consider cases when the menu is already open and when it's not open and then act accordingly. For that you might consider using toggleClass and then checking which class it is with hasClass before deciding what animation to perform.
//-----------ENQUIRY-FORM----------
$('#enquiry-shown').click(function() {
if(!$(this).hasClass('closed')){ // if the form is not closed
$(this).animate({ // animate the form to open state
width: "950px",
borderRadius: "0px",
}, 1000, ()=>{
$("#enquiry-form").slideToggle()
});
}else{ // if the form is closed animate in reverse order
$("#enquiry-form").slideToggle(
()=>{
$(this).animate({
width : "210px",
borderRadius : "50px"
}, 1000);
}
)
}
$(this).toggleClass('closed'); // toggle the class
});
/*--------ENQUIRIES---------*/
#enquiry-container {
text-align: center;
margin-bottom: 25px;
}
#enquiry-shown {
background-color: white;
padding: 10px 0;
box-shadow: 0 10px 10px -5px rgba(0, 0, 0, 0.3);
width: 210px;
border: solid 1px #d8d8d8;
border-radius: 50px;
margin: 0 auto;
}
#enquiry-name {
font-family: "calibri light";
font-size: 30px;
text-align: center;
margin: 0;
display: inline;
padding: 0 0 0 10px;
}
#enq-arrowdown {
width: 25px;
height: 16px;
float: right;
padding: 10px 19px 0 0;
display: inline-block;
}
#enquiry-form {
width: 950px;
height: 400px;
background-color: white;
margin: 0 auto;
display: none;
border-bottom: solid 1px #d8d8d8;
border-right: solid 1px #d8d8d8;
border-left: solid 1px #d8d8d8;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="enquiry-container">
<div id="enquiry-shown">
<h2 id="enquiry-name">Enquiries</h2>
<img id="enq-arrowdown" src="https://www.optimaltravel.ca/images/arrow.png">
</div>
<div id="enquiry-form">
<div> Hello I am a form </div>
</div>
</div>

Prevent click action for div if the border of the div is clicked

I'm trying to build a replica of the Simon game with HTML, CSS and Javascript.
The design I have is nowhere near the final state, but I have the basic layout in place:
Each of the colored buttons (Green, Red, Yellow and Blue) have respective click events and I'm testing them out with console.log statements.
Here is the relevant section from the code:
$(document).ready(function() {
$('.center-buttons').click(function() {
event.stopPropagation();
console.log("Inner Click!");
});
$('#top-left').click(function() {
console.log('left click.');
});
$('#top-right').click(function() {
console.log('right click.');
});
$('#bottom-left').click(function() {
console.log('bleft click.');
});
$('#bottom-right').click(function() {
console.log('bright click.');
});
});
.main-area {
height: 700px;
width: 700px;
border-radius: 50%;
background-color: ;
margin: 0px auto;
padding: 20px;
}
.wrapper {
position: relative;
top: -5px;
}
.center-buttons {
height: 370px;
width: 370px;
border: 15px solid #444;
border-radius: 50%;
background-color: black;
margin: 0px auto;
position: relative;
top: -550px;
}
#top-row {
display: flex;
}
#bottom-row {
display: flex;
}
.main-button {
height: 310px;
width: 310px;
border: 20px solid #444;
}
#top-left{
background-color: #00994d;
border-radius: 100% 0 0 0;
right: 50%;
margin: 0px 5px 5px 0px;
}
#top-right{
background-color: #990000;
left: 50%;
border-radius: 0 100% 0 0;
margin: 0px 0px 5px 5px;
}
#bottom-left {
background-color: yellow;
left: 50%;
border-radius: 0 0 0 100%;
margin: 5px 5px 0px 0px;
}
#bottom-right {
background-color: #004d99;
left: 50%;
border-radius: 0 0 100% 0;
margin: 5px 0px 0px 5px;
}
<div class = 'main-area'>
<div class = 'wrapper'>
<div id = 'top-row'>
<div id = 'top-left' class = 'main-button'></div>
<div id = 'top-right' class = 'main-button'></div>
</div>
<div id = 'bottom-row'>
<div id = 'bottom-left' class = 'main-button'></div>
<div id = 'bottom-right' class = 'main-button'></div>
</div>
</div>
<div class = 'center-buttons'></div>
</div>
In the CSS, each colored button has a thick gray border.
The main question: When the borders of any of the buttons are clicked, is there a way to prevent the click event for the respective button from happening.
Thanks.
I have tried to achieve with my own HTML and CSS, but you can change accordingly.
If .parent is clicked, I am taking note of it and then checking it with .child click.
WORKING FIDDLE
HTML
<div class=parent>
<div class=child>
</div>
</div>
CSS
.parent{
display:table-cell;
width:300px;
height:300px;
vertical-align:middle;
text-align:center;
padding:15px;
background-color:red
}
.child{
display:inline-block;
width:300px;
height:300px;
background-color:blue
}
JQUERY
$(document).ready(function(){
var flag=false;
$(".parent").click(function(){
flag=true;
});
$(".child").click(function(e){
if(flag==false){
alert("CHILD IS ALIVE");
}
});
});
actually, border is not another html element but it belongs to div itself. so, there is no way to avoid a click on border if click event is applied on its div.
If you really need a border of that width, you can have a div inside a div,.
Keep the background color of outside div to your border color and color of inside div as red/green/blue/yellow.
Then you can apply click event on the inside div which will solve your problem

Categories