I had a similar problem to this, and indeed had attempted a solution similar to @Sean M. However, this runs into a more bizarre problem if you have more than one library part on the page, especially if they are in different relatively positioned divs. Intiially I tried:
.ms-webpart-chrome {position: relative;}
#ms-dnd-dropbox {left: auto !important; top: 15px !important}
This results in almost correct behaviour, but behaves oddly if you try using more than one library between page refreshes. Dragging a document over any library will position the dropbox over that library correctly, but then dragging a document over any other library will render the dropbox in the position of the first library (albeit, with the size of the correct library).
The solution was to identify that dragdrop.js first looks to see if #ms-dnd-dropbox
exists somewhere on the page, set top and left if it does, or create it within the document library webpart that triggered the script. However, as @Sean M pointed out, if your webpart is in an element other than s4-workspace that has a non-static position, this will result in dragdrop.js having the wrong reference positions.
Since dragdrop.js looks for #ms-dnd-dropbox
first, why not just add it directly to the masterpage? There will only ever be one, and if it's hidden otherwise, it won't affect anything else. Just add:
<div id="ms-dnd-dropbox" style="display:none;">
<span class="ms-attractMode ms-noWrap" id="ms-dnd-dropboxText" style="line-height: 324px;">Drop here...</span>
</div>
as a direct child to s4-workspace, and dragdrop.js won't attempt to create a dropbox within any webparts: all dropboxes will return to their correct positions!
EDIT
So it appears that I was working with an older version of SharePoint at the time I wrote this, and that SharePoint has updated dragdrop.js in the meantime.
Dragdrop.js removed the odd "we'll build one dropbox wherever, and move it to all the others as they are dragged over" mechanism, and instead replaced it with "everyone who needs a dropbox gets their own." Unfortunately, this renders my previous solution useless. As was pointed out by @Kodz, dragging over the library would cause the dropbox to be created, but dropping a file or dragging off the box causes dropbox.js to throw an error.
Investigating further, the new version of dropbox.js creates a "relatedWP" attribute on the box, associating the box with a specific webpart; and thus each webpart receives it's own box. This attribute is necessary in the new version to identify the status of the current control. Unfortunately, the SharePoint update has not fixed the actual problem - that is, the bootstrap grid divs (or other, responsive design divs) have position: relative
attributes, and thus confuse the library in it's setting of top
and left
.
The strategy, though, remains the same: move the dropbox divs to #s4-workspace. Unfortunately, you can't hardcode it in the masterpage any longer. Instead, they need to be moved once they are created. Fortunately, they are all created simultaneously for all parts on the page, or at least are doing so currently. Unfortunately, they still are created on first dragover, rather than page load...
Moving them once created is simple:
$("#s4-workspace").append($(".ms-dnd-dropbox").detach());
will do the job. However, identifying when they are created is a little more difficult. Fortunately, there are some libraries that take advantage of DOM Mutation Observers to achieve this goal. I downloaded and installed into SharePoint Live Query, and added the following jQuery:
;(function() {
$(document).ready(function(){
$(".ms-webpart-chrome").livequery(".ms-dnd-dropbox", function() {
$("#s4-workspace").append($(".ms-dnd-dropbox").detach());
});
});
})();
This is not perfect; unfortunately the dropboxes are created visible, and so on first dragover, there is a slight flicker as the boxes return to the correct positions. All other dragovers will not have this issue; however.
I will also note that the livequery library should continue to find .ms-dnd-dropbox elements as they arise, and move them to the #s4-workspace, so even if the boxes are not created simultaneously on first dragover, this still should work.