organise a dropped element into another one - javascript

I'm working on a project that works like that. I drag and drop some elements to some droppables and take the out again to the middle. Every droppable can have many dragged elements inside. it works fine when i work with one element, but whene it is more then one , it didn't , i didn't know how to make the two elements draggable and drop them both into the droppable and appears there fine . here is the funtion :
$(function() {
$( "#myDIV1,#myDIV2" ).draggable({ cursor: 'move'});
$( ".drop" ).droppable({
drop: function( event, ui ) {
$(ui.draggable).detach().css({top: 0,left: 0}).appendTo(this);
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
$( "#myDIV1,#myDIV2" ).css( "height", "50%" );
$( "#myDIV1,#myDIV2" ).css( "width", "50%" );
$( "#myDIV1,#myDIV2" ).find( "p" ).html( "cool!" );
},
out: function( event, ui ) {
$( this )
.addClass( "drop" )
.find( "p" )
.html( "Dropped! out" );
$( "#myDIV1,#myDIV2" ).css( "height", "400px" );
$( "#myDIV1,#myDIV2" ).css( "width", "370px");
$( "#myDIV1,#myDIV2" ).find( "p" ).html( "Drag me to my target" );
}
});
$( ".dropLeftRight" ).droppable({
drop: function( event, ui ) {
$(ui.draggable).detach().css({top: 0,left: 0}).appendTo(this);
$( this )
.addClass( "ui-state-highlight" )
.find( "p" )
.html( "Dropped!" );
$( "#myDIV1,#myDIV2" ).css( "height", "50%" );
$( "#myDIV1,#myDIV2" ).css( "width", "50%" );
$( "#myDIV1,#myDIV2" ).find( "p" ).html( "cool!" );
},
out: function( event, ui ) {
$( this )
.addClass( "drop" )
.find( "p" )
.html( "Dropped! out" );
$( "#myDIV1,#myDIV2" ).css( "height", "400px" );
$( "#myDIV1,#myDIV2" ).css( "width", "370px");
$( "#myDIV1,#myDIV2" ).find( "p" ).html( "Drag me to my target" );
}
});
});

Related

How to create a loop using jQuery

I want to execute the below code by creating a simple loop using jQuery, I can also change the classes if needed.
I want to shrink the code as much as possible.
$( ".btn1" ).click(function() {
$( this ).toggleClass( "act-btn1" );
});
$( ".btn2" ).click(function() {
$( this ).toggleClass( "act-btn2" );
});
$( ".btn3" ).click(function() {
$( this ).toggleClass( "act-btn3" );
});
$( ".btn4" ).click(function() {
$( this ).toggleClass( "act-btn4" );
});
$( ".btn5" ).click(function() {
$( this ).toggleClass( "act-btn5" );
});
$( ".btn6" ).click(function() {
$( this ).toggleClass( "act-btn6" );
});
$( ".btn7" ).click(function() {
$( this ).toggleClass( "act-btn7" );
});
$( ".btn8" ).click(function() {
$( this ).toggleClass( "act-btn8" );
});
$( ".btn9" ).click(function() {
$( this ).toggleClass( "act-btn9" );
});
$( ".btn10" ).click(function() {
$( this ).toggleClass( "act-btn10" );
});
$( ".btn11" ).click(function() {
$( this ).toggleClass( "act-btn11" );
});
$( ".btn12" ).click(function() {
$( this ).toggleClass( "act-btn12" );
});
for (let i = 0; i <= 12; i++) {
$( ".btn" + i ).click(function() {
$( this ).toggleClass( "act-btn" + i );
});
}
I don't know about your logic, And number of elements is dynamic or static. Anyway using simple loop like below may solve your problem.
for(let i = 1; i < 13; i++) {
$(`.btn${i}`).click(function() {
$(this).toggleClass(`act-btn${i}`);
});
}
The best way to do this would be to make a general class like .button and add it to every button, thun also make a general action class .btn-action, it would look somthing like this:
$('.button').on('click', function(){
$(this).toggleClass('btn-action');
})

.click() doesn't renew button state

I am trying to write a quiz, but once an answer is correct, the button of that answer is also shown to be correct when there's another question. I've tried everything to fix it but I just don't have a clue what the problem is.
JSFIDDLE: http://jsfiddle.net/bz6v5nbv/1/
Bug reconstruction: Take answer C (correct) at the first question and again C (this time it's actually B) at the second one. Even though B would be correct, C is green, when clicked.
$( document ).ready( function() {
var q = [];
q[1] = [3, "1", "Musik", "Welches Hotel ist sehr musikalisch?", "Hotel California",
"Riu Hotel", "Tokio Hotel", "Hotel Mama"];
q[2] = [2, "1", "Musik", "Was sitzt in einer Konservendose, singt und liest Nachrichten vor?",
"ein Schwammoli", "ein Radioli", "ein Tivoli", "ein Tivoli"];
q[3] = [4, "1", "Musik", "dd",
"ein Schwammoli", "ein Radioli", "ein Tivoli", "ein Tivoli"];
var fill = function( data ) {
//buttons get filled with data from the array
$( "#number" ).html( data[1]);
$( "#cat" ).html( data[2]);
$( "#ques span" ).html( data[3]);
$( "#answ .answ:nth-child(1) button" ).html( data[4]);
$( "#answ .answ:nth-child(2) button" ).html( data[5]);
$( "#answ .answ:nth-child(3) button" ).html( data[6]);
$( "#answ .answ:nth-child(4) button" ).html( data[7]);
$( "#answ .answ:nth-child(" + data[0] + ") button" ).attr( "data-state", "true" );
//images are set, depending on the true/false state of the button
$( "#answ .answ button" ).each( function() {
$( this ).click( function() {
var button = $(this);
$(this).css( "background-image", "url(images/btnBgLogged.png)" );
$(this).css( "border-image-source", "url(images/btnLogged.png)" );
button.click( function() {
if ( button.data( "state" ) == true ) {
button.css( "background-image", "url(images/btnBgTrue.png)" );
button.css( "border-image-source", "url(images/btnTrue.png)" );
} else {
button.css( "background-image", "url(images/btnBgFalse.png)" );
button.css( "border-image-source", "url(images/btnFalse.png)" );
}
setTimeout( next, 3000 );
});
});
})
}
var clear = function() {
$( "#answ .answ:nth-child(1) button" ).removeAttr( "style" );
$( "#answ .answ:nth-child(2) button" ).removeAttr( "style" );
$( "#answ .answ:nth-child(3) button" ).removeAttr( "style" );
$( "#answ .answ:nth-child(4) button" ).removeAttr( "style" );
$( "#answ .answ:nth-child(1) button" ).removeAttr( "data-state" );
$( "#answ .answ:nth-child(2) button" ).removeAttr( "data-state" );
$( "#answ .answ:nth-child(3) button" ).removeAttr( "data-state" );
$( "#answ .answ:nth-child(4) button" ).removeAttr( "data-state" );
}
var count = 1;
function next() {
clear();
fill( q[count] );
count++;
}
next();
});
In my opinion there are multiple problems in your code. First of all, it's not a matter of binding and unbinding events, it's a problem of rebinding a new click event each time you call your fill method, you should extract your click listener from this function. conception problem :)
You also shouldn't check the presence of data-state, but instead you should check its value, more efficient.
$( document ).ready( function() {
var q = [];
q[1] = [3, "1", "Musik", "Welches Hotel ist sehr musikalisch?", "Hotel California",
"Riu Hotel", "Tokio Hotel", "Hotel Mama"];
q[2] = [2, "1", "Musik", "Was sitzt in einer Konservendose, singt und liest Nachrichten vor?",
"ein Schwammoli", "ein Radioli", "ein Tivoli", "ein Tivoli"];
q[3] = [4, "1", "Musik", "dd",
"ein Schwammoli", "ein Radioli", "ein Tivoli", "ein Tivoli"];
var fill = function( data ) {
$( "#number" ).html( data[1]);
$( "#cat" ).html( data[2]);
$( "#ques span" ).html( data[3]);
$( "#answ .answ:nth-child(1) button" ).html( data[4]);
$( "#answ .answ:nth-child(2) button" ).html( data[5]);
$( "#answ .answ:nth-child(3) button" ).html( data[6]);
$( "#answ .answ:nth-child(4) button" ).html( data[7]);
$( "#answ .answ button" ).attr( "data-state", "0" );
$( "#answ .answ:nth-child(" + data[0] + ") button" ).attr( "data-state", "1" );
}
var clear = function() {
$( "#answ .answ button" ).removeAttr( "class" );
$( "#answ .answ button" ).removeAttr( "data-state" );
}
var count = 1;
function next() {
clear();
fill( q[count] );
count++;
}
next();
$( "#answ" ).on('click', '.answ button', function(){
var button = $(this);
console.log(button.attr( "data-state" ));
if(button.hasClass('clicked')){
newClass = ( 1 == button.attr( "data-state" ) ) ? 'good' : 'bad';
button.removeClass('clicked').addClass(newClass);
setTimeout( next, 3000 );
}
else {
button.addClass('clicked');
}
});
});
Working demo here :)
You do not unbind the events so you keep adding events to the button. So you can either call off when you run the clear() method or you can just unbind it right before you add the click.
$( this ).off("click").on("click", function() { ... }
and
button.off("click").on("click", function() { ... });
You should use jquery .on instead of .click it is appropriate for binding dynamic element like:
$('#answ').on('click', 'button', function() {});
Line 29 should read
if ( button.attr( "data-state" ) == "true" ) {
check the updated fiddle
The others have a point though, you are creating listeners for the click handler over and over again.
$( this ).click( function() {
// replace with
$( this ).on('click'
and you dont need this:
button.click( function() {
since you already applyed click event on all buttons
I've set you comments in code for this fix on JSFiddle:
https://jsfiddle.net/Lhu7poqu/
Now you have click once, after adding new background and waiting for re-rendering new question, all button events are unbinded and added again on next question.
Hope this helps.

Something wrong with my toggleclass

There is something wrong with my jQuery script. It kinda works, but when I try to toggle between the classes it works at first.
the script changes classes just like it's supposed to. but when i try to do it again,
I have to click the link and then somewhere else, and then it works again.
I want to be able do repeat the whole procedure over and over without having to click two extra times.
var clickOnSettings = true;
$(".settings_link").click(function () {
event.preventDefault();
if (clickOnSettings) {
$("#coverup").toggleClass("cover1");
$("#settingani").toggleClass("settings1");
clickOnSettings = false;
}
});
$("#coverup").click(function () {
if (!clickOnSettings) {
$("#coverup").toggleClass("cover2");
$("#settingani").toggleClass("settings2");
clickOnSettings = true;
}
});
created a jsfiddle:
http://jsfiddle.net/5dzt1v6f/13/
If you toggle 'cover1', you basically toggle between having and not having 'cover1' on the element. That does not imply that you automatically get cover2 when you remove cover1.
You have to do that yourself. Fortunately, toggleClass has a second parameter that accepts a boolean. This allows you to easily toggle classes on or off based on your conveniently introduced boolean.
Furthermore, this makes the click handler for both elements the same:
var clickOnSettings = false;
$( ".settings_link, #coverup" ).click(function() {
event.preventDefault();
clickOnSettings = ! clickOnSettings;
//Toggle all classes.
$( "#coverup" ).toggleClass( "cover1", clickOnSettings);
$( "#settingani" ).toggleClass( "settings1", clickOnSettings);
$( "#coverup" ).toggleClass( "cover2", !clickOnSettings);
$( "#settingani" ).toggleClass( "settings2", !clickOnSettings);
});
http://jsfiddle.net/5dzt1v6f/20/
Why don't you just use addClass and removeClass for what you want to do.
var clickOnSettings = true;
$( ".settings_link" ).click(function() {
event.preventDefault();
if (clickOnSettings) {
$( "#coverup" ).addClass( "cover1" );
$( "#settingani" ).addClass( "settings1" );
$( "#coverup" ).removeClass( "cover2" );
$( "#settingani" ).removeClass( "settings2" );
clickOnSettings = false;
}
});
$( "#coverup" ).click(function() {
if (!clickOnSettings) {
$( "#coverup" ).addClass( "cover2" );
$( "#settingani" ).addClass( "settings2" );
$( "#coverup" ).removeClass( "cover1" );
$( "#settingani" ).removeClass( "settings1" );
clickOnSettings = true;
}
});
http://jsfiddle.net/5dzt1v6f/15/
I fixed it!
Not the prettiest code. But this worked I needed to have another class for the settingani and not for the coverup. So I had to do it like this:
var clickOnSettings = 1;
$( ".settings_link" ).click(function() {
event.preventDefault();
if (clickOnSettings == 1) {
$( "#settingani" ).removeClass( "settings0" );
$( "#coverup" ).addClass( "cover1" );
$( "#settingani" ).addClass( "settings1" );
clickOnSettings = 3;
}
});
$( ".settings_link" ).click(function() {
event.preventDefault();
if (clickOnSettings == 2) {
$( "#coverup" ).removeClass( "cover2" );
$( "#settingani" ).removeClass( "settings2" );
$( "#coverup" ).addClass( "cover1" );
$( "#settingani" ).addClass( "settings1" );
clickOnSettings = 3;
}
});
$( "#coverup" ).click(function() {
if (clickOnSettings == 3) {
$( "#coverup" ).removeClass( "cover1" );
$( "#settingani" ).removeClass( "settings1" );
$( "#coverup" ).addClass( "cover2" );
$( "#settingani" ).addClass( "settings2" );
clickOnSettings = 2;
}
});
Thanks for all the help! =)

How to add a class to a div when a certain image is dropped onto it?

So far I have it so if an image/section is dragged onto another div it will change the image of the div, but how can I have it so if a certain image/section with the class is dropped onto the div then it'll add a class to it and if another image/section is dropped onto it then another class is added?
So far I have this for the drag and drop:
$(function() {
$( "#draggable" ).draggable({
drag: function(event, ui) {
$( this )
.addClass( "choppedonion" )
.find( "section" )
.html( "" );
}
});
$( "#droppable" ).droppable({
drop: function( event, ui ) {
$( this )
.addClass( "fullbowl" )
.find( "div" )
.html( "" );
}
});
});
On the drop event you can reference the draggable element with ui.draggable. Then you can check if the element has the class you're looking for:
$( "#droppable" ).droppable({
drop: function( event, ui ) {
$( this )
.addClass( "fullbowl" )
.find( "div" )
.html( "" );
var $draggable = $(ui.draggable);
if( $draggable.hasClass('oneClass')) {
$draggable.addClass('addedClass');
}
if( $draggable.hasClass('otherClass')) {
$draggable.addClass('otherAddedClass');
}
}
});
Here's a quick demo.

Jquery slider change to perform a function

I am trying to perform a calculation and set an input value when the slider is moved. I can't get it to work, any help much appreciated. please see my code below:
if (modalContentCall[objname].private_use == true) {
$(this).append($('<div>').load('Content_for_injection.htm #private_use',function(){
$('#inputamount').change(function() {
var isinputamount = parseInt($('#inputamount').val());
});
$( "#slider-range-max" ).slider({
range: "max",
min: 0,
max: 100,
value: 0,
slide: function( event, ui ) {
$( "#slideramount" ).val( ui.value );
if (isinputamount > 0) {
$( "#actualamount" ).val( ui.value/100*isinputamount );
}
else $( "#actualamount" ).val(0);
}
});
$( "#slideramount" ).val( $( "#slider-range-max" ).slider( "value" ) );
$( "#actualamount" ).val( $( "#slider-range-max" ).slider( "value" ) );
Most of this code is standard UI code and works fine. I have added:
if (isinputamount > 0) {
$( "#actualamount" ).val( ui.value/100*isinputamount );
}
else $( "#actualamount" ).val(0);
}
and:
$( "#actualamount" ).val( $( "#slider-range-max" ).slider( "value" ) );
I want to take the input added to #inputamount multiply by the slider value (when this is moved) divided by 100 (to get a percentage decimal 1/100) to give a resulting number in #actualamount.
I can't seem to get it to work.
This issue was solved by using a global variable, I changed the 4th line of code in my question from this
var isinputamount = parseInt($('#inputamount').val());
to this
window.isinputamount = parseInt($('#inputamount').val());
It now works fine.

Categories

Resources