Javascript Cloning and Moving DOM Elements to Mouse Position

So I was working with dragula, a super easy to use drag and drop library. However, I ran into an issue where when a user clicks the dragging element, I wanted everything in the background to collapse. This messed up the dragging element’s position in relation to where the mouse’s location. In most cases when you drag and drop an element, it hovers wherever your mouse is located. In my case, when I shifted everything, the element I wanted to drag was no longer located where I clicked but rather it moved and hovered in the wrong spot with the wrong offset from my mouse. In using this library, I didn’t have access to changing their inner coding offset logic, so I needed to come up with my own fix. In the end, I decided to hide their floating mouse DOM element and create my own, that I had control over. The following code shows how to do just that!

Happy coding! Let me know if you have any comments or improvements.

//call this function when we want to initiate the listener for moving the mouse
//For instance, call this function once the user starts dragging an element
//requires an event and element to be passed.
function startMouseMove(e, element) {
    $('.my-background-content').css( 'display', 'none' ); //collapse background elements
    const container = $(element).find('.item-to-clone').clone().appendTo('.my-container'); //clone the element you want to hover around mouse
    $(container).attr('id', 'cursor_element'); //give the clone element an id so we can reference it later
    $('#cursor_element').css({'position': 'fixed', 'top': e.pageY, 'left': e.pageX}); //set clone element's position to mouse's position
    $document.on('mousemove', moveElement); //bind mouse event
}
 
function moveElement(e) {
    const y = e.pageY; //get y position
    const x = e.pageX; //get x position
    $('#cursor_element').css({'top': y, 'left': x}); //move the position of the element to match mouse, whenever mouse moves
}
 
//call this function when we want to stop the listener for moving the mouse
//For instance, call this function once the user drops a dragging element
function stopMouseMove() {
    $('#cursor_element').remove(); //delete cloned element
    $('.my-background-content').css( 'display', '' ); //un-collapse background elements
    $document.unbind('mousemove', moveElement); //unbind mouse event
}

Note that $document and JQuery must be declared/injected into the controller for this to work.

The above code requires JQuery, but you could easily use vanilla Javascript. Check this out for event help and this out for DOM selection.

Creating a Sharepoint ‘Like’ through SOAP Requests

Sharepoint is not my most favorite environment to program in but I figure I’d share a cool javascript app I put together that communicates with Sharepoint’s SOAP API to add on to custom ‘like’ buttons (just like facebook!) With this feature, users can ‘like’ sharepoint items without going through the crazy sharepoint interface. This javascript can be added to a web interface, and users can ‘like’ items from there!

None of this garbage
None of this garbage

I wrote some javascript/jquery code that can easily retrieve the number of ‘likes’ for a sharepoint list item or list. The script basically queries Sharepoint’s built in social services for the tag count with SOAP POST calls.

Get Like Count

Here is the script to get ‘like’ count:


<script>

function GetLikeCountFromService(strURL) {

var count = 0;

//change the webMethod var to match up to the correct sharepoint _vti_bin location. (https://msdn.microsoft.com/en-us/library/office/Bb862916(v=office.12).aspx)

var webMethod = \'/_vti_bin/SocialDataService.asmx?op=GetTagTermsOnUrl\';

var soapEnv = "<soap:Envelope xmlns:xsi=\'http://www.w3.org/2001/XMLSchema-instance\' xmlns:xsd=\'http://www.w3.org/2001/XMLSchema\' xmlns:soap=\'http://schemas.xmlsoap.org/soap/envelope/\'> <soap:Body><GetTagTermsOnUrl xmlns=\'http://microsoft.com/webservices/SharePointPortalServer/SocialDataService\'> <url>" + strURL + "</url> <maximumItemsToReturn>1</maximumItemsToReturn> </GetTagTermsOnUrl> </soap:Body> </soap:Envelope>";



$.ajax({

type: "POST",

async: true,

url: webMethod,

data: soapEnv,

contentType: "text/xml; charset=utf-8",

dataType: "xml",

success: function(data, textStatus, XMLHttpRequest) {

count  = $(\'SocialTermDetail\', data).find(\'Count\').text();

}

});

return count;

}

</script>

Called by: GetLikeCountFromService(‘<LIST OR LIST ITEM URL>’)

Example: GetLikeCountFromService(‘http://mysharepoint/list/item’)

Here is the script to post ‘likes’ to an article. Once again it’s a nice javascript that can put into an HTML header or what not.

Emulate a ‘like’

Script to post a ‘like’:


function AddLikeCountFromService(strURL) {

//change the webMethod var to match up to the correct sharepoint _vti_bin location. (https://msdn.microsoft.com/en-us/library/office/Bb862916(v=office.12).aspx)

var webMethod = \'/_vti_bin/SocialDataService.asmx?op=GetAllTagTermsForUrlFolder\';

var soapEnv = "<soap:Envelope xmlns:xsi=\'http://www.w3.org/2001/XMLSchema-instance\' xmlns:xsd=\'http://www.w3.org/2001/XMLSchema\' xmlns:soap=\'http://schemas.xmlsoap.org/soap/envelope/\'><soap:Body><GetAllTagTermsForUrlFolder xmlns=\'http://microsoft.com/webservices/SharePointPortalServer/SocialDataService\'><urlFolder>"+strURL+"</urlFolder><maximumItemsToReturn>1</maximumItemsToReturn></GetAllTagTermsForUrlFolder></soap:Body></soap:Envelope>";

$.ajax({

type: "POST",

async: true,

url: webMethod,

data: soapEnv,

contentType: "text/xml; charset=utf-8",

dataType: "xml",

success: function(data, textStatus, XMLHttpRequest) {

var info  = ($(\'SocialTermDetail\', data).text()).split(" ");

var guid = (info[0]).substring(0, info[0].length - 1);

//change the webMethod var to match up to the correct sharepoint _vti_bin location. (https://msdn.microsoft.com/en-us/library/office/Bb862916(v=office.12).aspx)

webMethod = \'/_vti_bin/SocialDataService.asmx?op=AddTag\';

//In the soapEnv request, you can change the title field to anything. This is the title of the thing the user is liking.

soapEnv = "<soap:Envelope xmlns:xsi=\'http://www.w3.org/2001/XMLSchema-instance\' xmlns:xsd=\'http://www.w3.org/2001/XMLSchema\' xmlns:soap=\'http://schemas.xmlsoap.org/soap/envelope/\'> <soap:Body><AddTag xmlns=\'http://microsoft.com/webservices/SharePointPortalServer/SocialDataService\'><url>"+strURL+"</url><termID>"+guid+"</termID><title>I like it!</title><isPrivate>false</isPrivate></AddTag></soap:Body> </soap:Envelope>";

$.ajax({

type: "POST",

async: true,

url: webMethod,

data: soapEnv,

contentType: "text/xml; charset=utf-8",

dataType: "xml",

success: function(data, textStatus, XMLHttpRequest) {

}

});

}

});

Called By:

Example: AddLikeCountFromService(‘<LIST OR LIST ITEM URL>’)

AddLikeCountFromService(‘http://mysharepoint/list/item’)