PDA

View Full Version : Drag and Drop Images



treeleaf20
01-22-2011, 10:45 PM
All,
I'm trying to create a calendar application that users can upload pictures and then put them on a calendar. I'd like to display all of the images and then drag them from one pane to the calendar. I'd like it to be something similar to the following link:

http://www.vistaprint.com/studio/calendars/add-photos.aspx?pf_id=389&combo_id=69997&ag=true&uei=122453&filter=9:10013||1,26:10080||1,3:10086||1&xnav=previews&xnid=button&rd=2

Does anyone have any scripts that can do the drag and drop or could you possibly give me an idea on where to start with something like this? I really appreciate the help in advance!

Thanks!

venegal
01-23-2011, 04:27 AM
You could look into jQueryUI. It provides basic drag and drop functionality.

treeleaf20
01-23-2011, 05:07 AM
Thank you very much and I looked into that. I do have a question on this one:

http://jqueryui.com/demos/droppable/#photo-manager

If you look at the source. How can I alter it so that I can have multiple trashes? I altered this:


var $gallery = $( "#gallery" ),
$cover = $( "#cover" ),
$trash = $( "#trash" );


To include a new one called #cover, and I also copied the original trash code:


$trash.droppable({
accept: "#gallery > li",
activeClass: "ui-state-highlight",
drop: function( event, ui ) {
deleteImage( ui.draggable );
}
});


I basically just changed the $trash to make it $cover like this:


$cover.droppable({
accept: "#gallery > li",
activeClass: "ui-state-highlight",
drop: function( event, ui ) {
deleteImage( ui.draggable );
}
});


I also updated the CSS which places the trash box and copied the <div> that had trash and chagned it to the cover as well:


<div id="cover" class="ui-widget-content ui-state-default">
<h4 class="ui-widget-header"><span class="ui-icon ui-icon-trash">Cover</span> Cover</h4>
</div>


When I drag it to the cover it goes automatically to the trash. Any ideas how to add another <div> to be able to drag to the trash and another <div> that I created? Sorry, probably a simple question but first time using the Jquery. Thanks for the help in advance!

venegal
01-23-2011, 05:39 AM
When you make $cover doppable, that doesn't mean dropped items automatically end up there, it just means that *something* happens, and that something is defined in the 'drop' option. In this case, the function deleteImage is called, which is set up to put the image inside $trash.

You could add a parameter to deleteImage specifying where the image is actually supposed to end up and change the code accordingly.

treeleaf20
01-23-2011, 05:20 PM
So I got that part to work but now would like to be able to drag from the trash to the cover as well. The code for that is:



$cover.droppable({
accept: "#gallery > li,
activeClass: "ui-state-highlight",
drop: function( event, ui ) {
deleteImage( ui.draggable, event.target );
}
});

I tried to make it like the following to also accept make the cover droppable from the trash but it won't work.


$cover.droppable({
accept: "#gallery > li", "#trash > li",
activeClass: "ui-state-highlight",
drop: function( event, ui ) {
deleteImage( ui.draggable, event.target );
}
});


I also tried and this didn't work either:


$cover.droppable({
accept: "#gallery > li, #trash > li",
activeClass: "ui-state-highlight",
drop: function( event, ui ) {
deleteImage( ui.draggable, event.target );
}
});


Any ideas how to add multiple components to the accept? Thanks in advance!

treeleaf20
01-23-2011, 05:27 PM
Also, just another question about this. Eventually, I'm going to want to know what is in each <div> at the end. So if there are like three images in the <div> then I'd like to know what those images are so I could store them in the database. Within PHP I know I can put these in a form but since I'm assigning them with the Jquery I'd like to submit the results and know what is in each <div> to be able to write these to a database. Any ideas on how this could be accomplished then? Thanks in advance for this as well.

venegal
01-24-2011, 06:22 AM
Any ideas how to add multiple components to the accept? Thanks in advance!

It would definitely have to be the second snippet. That looks ok, though, so if it doesn't work, please give a link to the non-working example, so someone can have a look.

As for the getting the info into your database:

That doesn't have much to do with jQuery; you can do it by populating hidden fields of some form and submitting it, or with AJAX. Both of those sure get very easy using jQuery, though.

You can get to the info very easy, too; something like

$.map($trash.find('img'), function (img) {return img.attr('src')});
should get you an array containing the URLs of all the images in $trash.

treeleaf20
01-24-2011, 04:36 PM
Thanks, you can find the URL at:

http://steps4stellar.com/jquery/development-bundle/demos/droppable/calendar.html

I try and drag it from the trash to the cover and it doesn't work. As far as the code you provided, thank you. So if I have a submit button, how could I call that code to be executed to return me the results I need? Thanks for the continued help.

venegal
01-24-2011, 04:54 PM
You have the wrong selector. If you look at the DOM after you've dragged something to the trash, you'll see that the dropped <li> is no direct child of $trash. So, change '#trash > li' to '#trash li'.

I don't know what exactly you want to submit, or how you want to process the submitted data on the server side, but if you look into $.post(), I'm sure you can figure out how to accomplish what you want.

treeleaf20
01-24-2011, 05:03 PM
Thanks, that did the trick. Basically what I'm trying to accomplish is have a gallery div and then have about 12 other divs. I want the user to be able to drag the images from the gallery and put them in the divs that they want. Once they are done, I'd like the user to be able to submit them and basically capture each of the images in the div to my database. I'm going to try and limit each div to only contain one image but need to look into how I can accomplish that as well. Thanks for your help!

treeleaf20
01-24-2011, 08:12 PM
Also, I tried to do this:


function checkDiv(){
$.map($trash.find('img'),
function (img) {
alert(img.attr('src'))
});
}


I try and call it by using:

<input name="button" type="button" value="Check Div" onClick="checkDiv()";>


It gets the function because I had an alert in there but it won't give me an alert for the images. Am I doing something wrong? Thanks in advance.

venegal
01-25-2011, 08:37 AM
That looks ok to me. Are you sure you are defining the checkDiv function within the same closure where $trash is defined?

If you want any further help on this, please update your live site. It's hard to tell what the problem could be without seeing it in action.

treeleaf20
01-25-2011, 03:57 PM
Yeah I tried to move the code up and I'm thinking I'm doing it right but it doesn't even seem to go to the checkDiv function. Here is a link:

http://steps4stellar.com/jquery/development-bundle/demos/droppable/calendar_jquery.html

Thanks for the help.

venegal
01-25-2011, 04:04 PM
You are defining checkDiv within the DOM ready handler, so it doesn't exist globally and can't be called from the button's onclick.

Please use Firebug or another Javascript debugger, so you can catch those errors yourself (it will say something like 'Uncaught ReferenceError: checkDiv is not defined').

treeleaf20
01-25-2011, 04:08 PM
Thanks, I'll download the Firebug. Could you explain what you mean by:

You are defining checkDiv within the DOM ready handler, so it doesn't exist globally and can't be called from the button's onclick.

Sorry, still new to this part of things.

venegal
01-25-2011, 05:04 PM
You have

$(function() {

// something

function checkDiv(){
// something
}

//something

}


in there. Which means that you define checkDiv within another function (the one that's being called as soon as the DOM is ready). If you define something within a function, it will only exist within that function. That's why calling it from outside won't work.

You have to define it outside (globally). But that means that you can't use $trash inside checkDiv, because that doesn't exist globally either, so you'll have to change that to $('#trash') (which will look through the DOM for an element with the id 'trash').

treeleaf20
01-25-2011, 05:32 PM
Thanks for the explanation. I moved it outside the function and it now gets to check the div. However it still won't give me an alert for the image that is inside the trash div. Sorry for being difficult during this process, really appreciate the help though!

venegal
01-25-2011, 06:14 PM
Please use Firebug or another Javascript debugger! It's frustrating to remote-debug errors that could easily have been avoided.

It would tell you that '#trash' has no method 'find'.

That's because you didn't use $('#trash'), like suggested in my previous post this would be a jQuery object, which does implement 'find' but '#trash', a string that doesn't.

treeleaf20
01-26-2011, 03:31 AM
Sorry, I'm not 100% sure how to debug in Firebug. I've never used it. I was trying to debug this though and it seems to be ok. I looked and I moved one image into the trash div and I tried to debug this. It gives me the src as: "http://localhost/xampp/photoperfect/jquery/development-bundle/demos/droppable/images/high_tatras4_min.jpg"

Which is the correct one and when I hover over the the src in Firebug it highlights the image which is what I want. However it won't show me the img src in the alert. I'm really sorry if I wasn't debugging it correctly but I think I did it right. Would you mind taking another look? I really do appreciate you helping me out with all of this. Thank you in advance.

venegal
01-26-2011, 09:37 AM
I don't know what you're talking about there, currently you don't have any alerts in your code.

Essentially, though, I think it would help you much more to read up on important concepts instead of playing trial and error ping pong with me.

First of all, read this short text about programming by coincidence (http://pragprog.com/the-pragmatic-programmer/extracts/coincidence) and keep it in mind.

Then find a good Javascript tutorial. You need to know about basic concepts such as variable scope, so errors like defining a function within another function, although you need it to be global, won't happen. Or why, actually, you don't want it to be global at all, and how to avoid that.

Then find a jQuery tutorial (http://docs.jquery.com/Tutorials) and study it. It's silly to add some custom getElementsByClassName function to your code when you already got jQuery in there.

And, arguably the most important thing, read some tutorial on how to generally debug a program. That doesn't really have to have anything to do with Firebug, it's just so you know what debugging really means and how to do it basic concepts such as breakpoints, error console, stack trace.

If you've done that and still run into a problem you can't solve by yourself, feel free to come back here for help. But chances are you won't need to.