Excerpt from the jQuery UI API Documentation for droppable:
drop( event, ui )
- event
- ui
- draggable:
A jQuery object representing the draggable element.
- helper:
A jQuery object representing the helper that is being dragged.
- position:
Current CSS position of the draggable helper as { top, left } object.
- offset:
Current offset position of the draggable helper as { top, left } object.
You already knew that this
is the droppable, now you have access to the draggable
too. What jQuery calls the helper
is the element following the cursor. By default those are the same thing, but you could have the draggable stay in place until you drop it while a ghostly clone follows your cursor.
While you could give a class to the draggable and then check for it in the drop event with something like this…
const categories = ["paris", "ny", "london", "barcelona"];
$(function() {
$("#answers div").draggable();
$("#box div").droppable({
drop: function(event, ui) {
const $this = $(this);
if (categories.some(c => $this.hasClass(c) && ui.draggable.hasClass(c))) {
$this
.addClass("ui-state-highlight")
.find("p")
.html("Valid :)");
} else {
$this
.addClass("ui-state-highlight")
.find("p")
.html("Invalid :(");
}
}
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>QUIZ</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
</head>
<body>
<h1>QUIZ</h1>
<div id="answers">
<div class="barcelona">
<p> Antoni Gaudi </p>
</div>
<div class="paris">
<p> Champ Elysees </p>
</div>
<div class="london">
<p> Tate Modern </p>
</div>
<div class="ny">
<p> Fifth Avenue </p>
</div>
</div>
<div id="box">
<div class="paris">
<p> PARIS </p>
</div>
<div class="ny">
<p> NY </p>
</div>
<div class="london">
<p> LONDON </p>
</div>
<div class="barcelona">
<p> BARCELONA </p>
</div>
</div>
</body>
</html>
I would suggest thinking long term however. Eventually, I imagine you’ll want to store puzzles in JavaScript.
[
{ category: "Paris", answers: ["Champ Elysees", "Montmartre"] },
{ category: "NY", answers: ["Big Apple", "Broadway"] }
]
Then you could build the HTML for the puzzles automatically and store the draggable
and droppable
widgets in each category. Something like this:
categories.forEach(c => {
c.droppable = createDroppable(c.category);
c.draggables = c.answers.map(answer => createDraggable(answer));
});
You could then compare the draggable and droppable by identity without relying on attributes. I’m not super familiar with jQuery but I believe this can be done with the is
method.
// in the drop event
const category = categories.find(c => $(this).is(c.droppable));
if (category.draggables.some(answer => ui.draggable.is(answer)) {
// this answer is valid!
}
You can use ui.draggable
to find the class and check if that includes in the current element:
$( function() {
$( "#answers div" ).draggable();
$( "#box div" ).droppable({
drop: function( event, ui ) {
var dropped = $(this).attr('class').split(' ')[0];
if(ui.draggable.attr('class').split(' ').includes(dropped)){
$( this )
.addClass("ui-state-highlight")
.find("p")
.html("Dropped!");
}
}
});
});
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<h1>QUIZ</h1>
<div id = "answers">
<div class = "barcelona"><p> Antoni Gaudi </p></div>
<div class = "paris"><p> Champ Elysees </p></div>
<div class = "london"><p> Tate Modern </p></div>
<div class = "barcelona"><p> Sagrada Familia </p></div>
<div class = "paris"><p> Montmartre </p></div>
<div class = "ny"><p> Fifth Avenue </p></div>
<div class = "barcelona"><p> Paella </p></div>
<div class = "barcelona"><p> La Rambla </p></div>
<div class = "london"><p> Piccadilly Circus </p></div>
<div class = "paris"><p> Mona Lisa </p></div>
<div class = "ny"><p> Empire State Building </p></div>
<div class = "ny"><p> Broadway </p></div>
<div class = "paris"><p> Musée d'Orsay </p></div>
<div class = "ny"><p> Wall Street </p></div>
<div class = "london"><p> Camden Town </p></div>
<div class = "ny"><p> Big Apple </p></div>
<div class = "barcelona"><p> La Boqueria </p></div>
</div>
<div id = "box">
<div class = "paris"><p> PARIS </p></div>
<div class = "ny"><p> NY </p></div>
<div class = "london"><p> LONDON </p></div>
<div class = "barcelona"><p> BARCELONA </p></div>
</div>
Though it would better to use custom attribute as suggested in the comment:
$( function() {
$( "#answers div" ).draggable();
$( "#box div" ).droppable({
drop: function( event, ui ) {
var dropped = $(this).data('city');
if(ui.draggable.data('city') == dropped){
$( this )
.addClass("ui-state-highlight")
.find("p")
.html("Dropped!");
}
}
});
});
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<h1>QUIZ</h1>
<div id = "answers">
<div data-city="barcelona"><p> Antoni Gaudi </p></div>
<div data-city="paris"><p> Champ Elysees </p></div>
<div data-city="london"><p> Tate Modern </p></div>
<div data-city="barcelona"><p> Sagrada Familia </p></div>
<div data-city="paris"><p> Montmartre </p></div>
<div data-city="ny"><p> Fifth Avenue </p></div>
<div data-city="barcelona"><p> Paella </p></div>
<div data-city="barcelona"><p> La Rambla </p></div>
<div data-city="london"><p> Piccadilly Circus </p></div>
<div data-city="paris"><p> Mona Lisa </p></div>
<div data-city="ny"><p> Empire State Building </p></div>
<div data-city="ny"><p> Broadway </p></div>
<div data-city="paris"><p> Musée d'Orsay </p></div>
<div data-city="ny"><p> Wall Street </p></div>
<div data-city="london"><p> Camden Town </p></div>
<div data-city="ny"><p> Big Apple </p></div>
<div data-city="barcelona"><p> La Boqueria </p></div>
</div>
<div id="box">
<div data-city="paris"><p> PARIS </p></div>
<div data-city="ny"><p> NY </p></div>
<div data-city="london"><p> LONDON </p></div>
<div data-city="barcelona"><p> BARCELONA </p></div>
</div>
I’m trying to make kind of quiz game using html, css, jquery, eventually javascript.
At the moment i want to make if statement, to check if dropped element is dropped in the right div (city). I had an idea to make it with classes and check if they’re the same. Is it event possible and proper?
My question is – how can I compare classes of two dives?
$(function() {
$("#answers div").draggable();
$("#box div").droppable({
drop: function(event, ui) {
$(this)
.addClass("ui-state-highlight")
.find("p")
.html("Dropped!");
}
});
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>QUIZ</title>
<link href='style.css' rel='stylesheet'>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
</head>
<body>
<h1>QUIZ</h1>
<div id="answers">
<div class="barcelona">
<p> Antoni Gaudi </p>
</div>
<div class="paris">
<p> Champ Elysees </p>
</div>
<div class="london">
<p> Tate Modern </p>
</div>
<div class="barcelona">
<p> Sagrada Familia </p>
</div>
<div class="paris">
<p> Montmartre </p>
</div>
<div class="ny">
<p> Fifth Avenue </p>
</div>
<div class="barcelona">
<p> Paella </p>
</div>
<div class="barcelona">
<p> La Rambla </p>
</div>
<div class="london">
<p> Piccadilly Circus </p>
</div>
<div class="paris">
<p> Mona Lisa </p>
</div>
<div class="ny">
<p> Empire State Building </p>
</div>
<div class="ny">
<p> Broadway </p>
</div>
<div class="paris">
<p> Musée d'Orsay </p>
</div>
<div class="ny">
<p> Wall Street </p>
</div>
<div class="london">
<p> Camden Town </p>
</div>
<div class="ny">
<p> Big Apple </p>
</div>
<div class="barcelona">
<p> La Boqueria </p>
</div>
</div>
<div id="box">
<div class="paris">
<p> PARIS </p>
</div>
<div class="ny">
<p> NY </p>
</div>
<div class="london">
<p> LONDON </p>
</div>
<div class="barcelona">
<p> BARCELONA </p>
</div>
</body>
</html>