Accepting partial playlists via drag & drop in Spotify App - javascript

I'm working on a Spotify app and built a dropzone inside my application so users can drag music onto it. It works with songs, albums, and playlists. Whenever they drag this content over, their cursor shows a green plus sign and everything works.
Whenever a user selects just a few songs from an existing playlist, though, the dropzone refuses to accept them. No green plus sign is shown. Nothing is transferred to the dropzone.
Any thoughts?
var dropzone = document.querySelector('#dropzone');
dropzone.addEventListener('dragover', handleDragOver, false);
dropzone.addEventListener('drop', handleDrop, false);
function handleDragOver(e) {
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
return false;
}
function handleDrop(e) {
var droppedURI = e.dataTransfer.getData('Text');
// rest of code here.
}

From my attempts and research (googling) it seems it's not possible at all to drop more than one link into a dropzone. I don't get the point in that so I guess it's bug. However it is possible to drop multiple links onto the app's icon, and at least in my case that's good enough.
How I did it:
models.application.observe(models.EVENT.LINKSCHANGED, function(){
models.application.links.forEach(function(link){
// Use your already existing logic and do whatever your want to do with the links
// For example (assuming you already have a playlist object):
if( (link.split('/')[3] || link.split(':')[1]) === 'track' ){
playlist.add(link);
}
});
});
Hope this helps!

Related

automatically play next soundcloud

I'm currently working on my music blog, and I'm trying to make the widgets start when previous one finishes. I have both soundcloud and youtube widgets, but the priority is to implement this functionality for the soundcloud ones.
Each iframe has 2 class .widget &.soundcloud_widget for soundcloud and .widget & .youtube_widget for youtube. Finally, each widget gets an id "widget1", "widget2", etc... in the order of apparition.
The idea would be to get the event "SC.Widget.Events.FINISH" , to get the id of the corresponding widget, "increment" it, and then make the next one play.
Unfortunately, I'm struggling with javascript & the documentation of soundcloud, and I would really appreciate some help !
Thanks in advance
PS : here is the code that does the above, I have nothing else that is usable...
<script type="text/javascript">
function autoPlayInitiate () {
var i=1;
$("iframe[src^='https://w.soundcloud.com/']").addClass("widget soundcloud_widget");
$("iframe[src^='//www.youtube.com']").addClass("widget youtube_widget");
$('.widget').each(function(){
$(this).attr('id','widget'+i);
i++;
});
}
window.onload = autoPlayInitiate;
$(document).ready(function () {
var ScWidget = $('.soundcloud_widget');
}
</script>
So first off I think the simplest way for you to solve this problem is to pick one of the players (either youtube or soundcloud) and use there playlist features to showcase your sounds.
here is a live example of using a playlist in Sound Cloud you can play with
http://runnable.com/UuhEs3Yq2_8hAACT/embbed-soundcloud-widget-using-javascript
relevant code:
function embed (id) {
SC.oEmbed("http://soundcloud.com/" + id // user or playlist to embed
, { color: "ff0066"
, auto_play: true
, maxwidth: 500
, maxheight: 1000
, show_comments: true } // options
, document.getElementById("scWidget") // what element to attach player to
);
}
$(document).ready(
function () {
embed("dj-faze");
}
);
however if you wish to go the long route you will want to familiarize yourself with the widget API:
http://developers.soundcloud.com/docs/api/html5-widget#
the bind(eventName, listener) is what you would be most interested in
var iframeElement = document.querySelector('iframe');
var iframeElementID = iframeElement.id;
var widget = SC.Widget(iframeElement);
widget.bind(SC.Widget.Events.FINISH, function () {
alert('add code to play next song here')
});
I will try to put up a new example on runnable once the site has finished its maintenance

Get reference to original element when dropped

I am using HTML5 native drag and drop for dropping images into a div. Here is an example: http://jsbin.com/ipojuk/1/
The problem is, once dropped the same image should not be dropped again. How to prevent this from happening? For this purpose i have set a data-inplan attribute in image, and i was planning to set it to true once an image is dropped, but i can't find an easy way to get a reference to the original image in function dragDrop. I thought about using an id, but these images are created at runtime, and generating id's will be hard for me.
This will allow you to drop only one image per type (checking the src)
function dragDrop(e) {
if (e.stopPropagation) {
e.stopPropagation(); // Stops some browsers from redirecting
}
var $item = $(e.dataTransfer.getData('text/html'));
var exists = false;
$(".divRendezvous img").each(function()
{
if($(this).attr("src")==$item.attr("src"))
{
exists = true;
return;
}
});
if(!exists)
$item.appendTo(e.target);
return false;
}
jsBin: http://jsbin.com/ipojuk/12/edit

Drag and drop javascript event

I'm a java guy trying my hand in javascript and need some help. I came across an amazing tutorial on image uploads here Mozilla Tutorial and need some help figuring it out. I am currently working on the drag and drop image upload feature. Every time I drag an image onto my area the mouse turns green so it's activated. But then when I let go it should send me an alert that says one image was found. However it always just alerts 0. So the size of the array is 0. Any ideas? Thanks for taking a look. What I've tried with no success...
Copying and pasting the code from the tutorial into my javascript file exactly
Moving the code to add the listeners outside of a function and into a window onload
Every browser I have
...
function toggleStrideMedia()
{
if(getDisplay("strideMediaWrapper") == "" || getDisplay("strideMediaWrapper") == "none")
{
show("strideMediaWrapper");
getElement("strideMediaDropZone").addEventListener("dragenter", dragenter, false);
getElement("strideMediaDropZone").addEventListener("dragover", dragover, false);
getElement("strideMediaDropZone").addEventListener("drop", drop, false);
}
else
{
hide("strideMediaWrapper");
}
}
function dragenter(e)
{
e.stopPropagation();
e.preventDefault();
}
function dragover(e)
{
e.stopPropagation();
e.preventDefault();
}
function drop(e)
{
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
// THIS SHOULD BE GIVING ME A ONE BUT IT ALWAYS GIVES ME A ZERO INSTEAD
alert(files.length);
handleFiles(files);
}
.
UPDATE - Fiddle Results
UPDATE
The actual problem turned out to be that if you try to drag images directly from one web browser tab to this web based drag and drop interface, the event will fire but no files will be dropped. The asker noted this issue on OSX and I was able to replicate the same behavior in Windows 7.
Without seeing your HTML, it's hard to tell what you were having difficulty with. If the ondragover/ondragenter piece wasn't set up correctly then dropping won't work, but you wouldn't see an alert at all, you'd just see the browser render the image from the local filesystem. That also means that you're almost certainly successfully adding the drop event to the correct element.
Try this Fiddle and see if it works for you: http://jsfiddle.net/qey9G/4/
HTML
<div>
<div id="dropzone" style="margin:30px; width:500px; height:300px;
border:1px dotted grey;">
Drag & drop your file here...
</div>
</div>
JavaScript
var dropzone = document.getElementById("dropzone");
dropzone.ondragover = dropzone.ondragenter = function(event) {
event.stopPropagation();
event.preventDefault();
}
dropzone.ondrop= function drop(e)
{
e.stopPropagation();
e.preventDefault();
var dt = e.dataTransfer;
var files = dt.files;
alert(files.length);
}

Accept drag & drop of image from another browser window

In Javascript, I know how to set up a drag & drop target that accepts file uploads from the user's computer. How can I set up a drop target that accepts images that are dragged from another website? All I need to know is the URL of the image that they've dragged.
I know this is possible, since Google Docs accepts image drops from other websites. Any idea how they're doing it?
UPDATE:
It looks like there are differences between Chrome on Windows and MacOS. On Windows dataTransfer.getData('Text'); works but not on MacOS. dataTransfer.getData('URL'); should work on both.
OLD answer:
You could define a drop zone:
<div id="dropbox">DropZone => you could drop any image from any page here</div>
and then handle the dragenter, dragexit, dragover and drop events:
var dropbox = document.getElementById('dropbox');
dropbox.addEventListener('dragenter', noopHandler, false);
dropbox.addEventListener('dragexit', noopHandler, false);
dropbox.addEventListener('dragover', noopHandler, false);
dropbox.addEventListener('drop', drop, false);
function noopHandler(evt) {
evt.stopPropagation();
evt.preventDefault();
}
function drop(evt) {
evt.stopPropagation();
evt.preventDefault();
var imageUrl = evt.dataTransfer.getData('Text');
alert(imageUrl);
}
​
It is inside the drop event handler that we are reading the image data from the dataTransfer object as Text. If we dropped an image from some other webpage this text will represent the url of the image.
And here's a live demo.
function drop(evt) {
evt.stopPropagation();
evt.preventDefault();
var imageUrl = evt.dataTransfer.getData('URL'); // instead of 'Text'
alert(imageUrl);
}
Seems to work in Firefox, Safari, and Chrome on Mac. Also works in Firefox, IE, and Chrome in Windows.
Updated fiddle
Although you are able to accept the drag and drop of an image from another website, you are unable to do any processing of it (e.g. converting it to a base64 string using the canvas) (as of 21st August 2014) because of various cross-origin policy issues.
var dt = event.dataTransfer;
var url = dt.getData('url');
if (!url) {
url = dt.getData('text/plain');
if (!url) {
url = dt.getData('text/uri-list');
if (!url) {
// We have tried all that we can to get this url but we can't. Abort mission
return;
}
}
}
Even Google can't get around this - If you use gmail, you can drag and drop an image from another location in to the email body, but all this does is create an <img/> element with its src set to url (from the code above).
However, I've created a plugin that allows you to fake it cross-origin drag and drop. It requires a PHP backend.
Read the article I wrote on it here https://coderwall.com/p/doco6w/html5-cross-origin-drag-and-drop
Here's my solution to the problem: Dropzone js - Drag n Drop file from same page
Please do keep in mind that ability to drag an image from another domain depends on their CORS setup.
Some browsers use text/plain some use text/html as well
This code should pull any text or image source url on the latest Chrome, FF on Mac and PC.
Safari doesn't seem to give the URL so if someone knows how to get it let me know.
I'm still working on IE.
function getAnyText(theevent) {
//see if we have anything in the text or img src tag
var insert_text;
var location = theevent.target;
var etext;
var ehtml;
try {
etext = theevent.dataTransfer.getData("text/plain");
} catch (_error) {}
try {
ehtml = theevent.dataTransfer.getData("text/html");
} catch (_error) {}
if (etext) {
insert_text = etext;
} else if (ehtml) {
object = $('<div/>').html(ehtml).contents();
if (object) {
insert_text = object.closest('img').prop('src');
}
}
if (insert_text) {
insertText(insert_text,location);
}
}
As the other answers correctly state: It normally depends on the CORS-Settings of the server if drag & drop from another browser window is possible (Access-Control-Allow-Origin has to be set).
However I've just found out by chance that it's possible to drap & drop any images from a Firefox (current version 68.0.1) to a Chrome window (current version 76.0.3809) and process it in Javascript, regardless if CORS headers are set or not.
See working example (based on jsfiddle of Darin Dimitrov) which accepts and directly shows images from:
drag and drop from local computer (e.g. from file explorer)
drag and drop from other website, if CORS headers are set, e.g. an image from https://imgur.com/
drag and drop any images from Firefox window to Chrome window:
open jsfiddle demo in Chrome
open e.g. google image search in Firefox and search for any image
click on the image for bigger preview
drag & drop the preview image to the jsfiddle demo in Chrome
However this seems to be kind of a bug of Firefox and therefore I would not rely on this behaviour in an productive application.

HTML5 JavaScript POST file upload

Recently I've been looking into adding a simple HTML5 drag and drop to my already simple php file upload script.
I have read lots of tutorials and other solutions but I can't seem to understand the whole sending the file to server part.
From what I understand, XMLHttpRequest will send the data, but it will do it without reloading the page. This, I do not want. Currently the script I'm using will take the POST data and produce the file upload output, eg. server download link, thumbnail if image etc.
How can I have the drag and drop submit the POST data and either access the upload output or reload the page?
Edit:
I'm using the following for the drag and drop:
<div id="drop_zone">Drag and drop a file here</div>
<script>
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
var files = evt.dataTransfer.files; // FileList object.
uploadFile(files[0]); //<-- This is where most examples will use XMLHttpRequest to construct form and send data
}
function handleDragOver(evt) {
evt.stopPropagation();
evt.preventDefault();
document.getElementById('drop_zone').style.backgroundColor = "#faffa3";
evt.dataTransfer.dropEffect = 'copy'; // Explicitly show this is a copy.
}
function handleDragLeave(evt) {
document.getElementById('drop_zone').style.backgroundColor = "";
}
// Setup the dnd listeners.
var dropZone = document.getElementById('drop_zone');
dropZone.addEventListener('dragover', handleDragOver, false);
dropZone.addEventListener('drop', handleFileSelect, false);
dropZone.addEventListener('dragleave', handleDragLeave, false);
</script>
If you use JQuery or some other event-capable javascript library you should be able to catch the drag event and submit your form.
http://docs.jquery.com/UI/API/1.8/Draggable
http://api.jquery.com/on/
But no XMLHttpRequest involved...
After more reading and searching around I've come to the conclusion that what I originally wanted cannot be done.
The solution I am going with is to simply have a large transparent/hidden <input type="file"> covering the drop zone. The dropped filename will be read from the input with javascript and displayed in the drop zone. This of course will rely on the browser to support the drag and drop files into html file inputs.
From there my upload script will pretty much operate as if the user had used the visible file selector.
Apologies for not being too clear on what I wanted. I wasn't so sure myself. And thanks for the replies/comments.

Categories

Resources