<html>
<head>
<title>Experimental Drag and Drop - RJM Programming - July, 2023 ... thanks to https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setData</title>
<script type=text/javascript>
var clonedata='', clonedatatwo='', pos3=0, pos4=0, secs=0, score=0, tdid='';

function cloneize() {
if (navigator.userAgent.toLowerCase().indexOf('firefox') > -1){
document.getElementById('source').setAttribute('contenteditable',false);
document.getElementById('strongs').innerHTML='';
}
if (clonedata != document.getElementById('source').innerHTML) {
clonedata=document.getElementById('source').outerHTML.replace(' id=', ' data-id=');
if (!document.getElementById('callback')) { document.getElementById('clone').style.display='inline-block'; }
}
setTimeout(cloneize, 100);
}

function bodyev() {
if (document.getElementById('clone').innerHTML.indexOf(' ...') == -1) {
document.getElementById('clone').innerHTML+=' ... Double click (or right click) where you want clone to be';
}
document.body.ondblclick=function(e) {
e = e || window.event;
e.preventDefault();

if (e.touches) {
if (e.touches[0].pageX) {
pos3 = e.touches[0].pageX;
pos4 = e.touches[0].pageY;
} else {
pos3 = e.touches[0].clientX;
pos4 = e.touches[0].clientY;
}
console.log('pos3=' + pos3 + ',pos4=' + pos4);
} else if (e.clientX || e.clientY) {
pos3 = e.clientX;
pos4 = e.clientY;
} else {
pos3 = e.pageX;
pos4 = e.pageY;
}

if (clonedata.indexOf(' style="') != -1) {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(' style="', ' style="position:absolute;left:' + pos3 + 'px;top:' + pos4 + 'px;');
} else if (clonedata.indexOf(" style='") != -1) {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(" style='", " style='position:absolute;left:" + pos3 + "px;top:" + pos4 + "px;");
} else {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(' ', ' style="position:absolute;left:' + pos3 + 'px;top:' + pos4 + 'px;" ');
}
};

document.body.oncontextmenu=function(e) {
e = e || window.event;
e.preventDefault();

if (e.touches) {
if (e.touches[0].pageX) {
pos3 = e.touches[0].pageX;
pos4 = e.touches[0].pageY;
} else {
pos3 = e.touches[0].clientX;
pos4 = e.touches[0].clientY;
}
console.log('pos3=' + pos3 + ',pos4=' + pos4);
} else if (e.clientX || e.clientY) {
pos3 = e.clientX;
pos4 = e.clientY;
} else {
pos3 = e.pageX;
pos4 = e.pageY;
}

if (clonedata.indexOf(' style="') != -1) {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(' style="', ' style="position:absolute;left:' + pos3 + 'px;top:' + pos4 + 'px;');
} else if (clonedata.indexOf(" style='") != -1) {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(" style='", " style='position:absolute;left:" + pos3 + "px;top:" + pos4 + "px;");
} else {
document.getElementById('scratchpad').innerHTML+=clonedata.replace(' ', ' style="position:absolute;left:' + pos3 + 'px;top:' + pos4 + 'px;" ');
}
};

}

function andlaterstill() {
if (tdid != '') {
document.getElementById(tdid).innerHTML=document.getElementById(tdid).innerHTML.substring(0,1);
} else if (document.getElementById('mytable').innerHTML.indexOf(clonedatatwo) != '') {
document.getElementById('target').innerHTML=document.getElementById('target').innerHTML.split('</table>')[0] + '</table>';
}
if (document.getElementsByTagName('div')[0].innerHTML.indexOf(clonedatatwo) != -1) {
document.getElementsByTagName('div')[0].innerHTML=document.getElementsByTagName('div')[0].innerHTML.replace(clonedatatwo,'');
} else if (document.getElementsByTagName('div')[0].innerHTML.indexOf(clonedatatwo.replace('dragging','')) != -1) {
document.getElementsByTagName('div')[0].innerHTML=document.getElementsByTagName('div')[0].innerHTML.replace(clonedatatwo.replace('dragging',''),'');
} else if (document.body.innerHTML.split('<table')[0].indexOf(clonedatatwo.replace('dragging','')) != -1) {
document.body.innerHTML=document.body.innerHTML.replace(document.body.innerHTML.split('<table')[0], document.body.innerHTML.split('<table')[0].replace(clonedatatwo.replace('dragging',''),''));
} else if (document.body.innerHTML.split('<table')[0].indexOf(clonedatatwo) != -1) {
document.body.innerHTML=document.body.innerHTML.replace(document.body.innerHTML.split('<table')[0], document.body.innerHTML.split('<table')[0].replace(clonedatatwo,''));
}
tdid='';
}

function andlater() {
var squares=document.getElementsByTagName('td');

for (var ii=1; ii<=9; ii++) {
if (squares[eval(-1 + ii)].innerHTML.indexOf('<') != -1) {
tdid='' + squares[eval(-1 + ii)].id;
}
}
console.log('tdid=' + tdid);
setTimeout(andlaterstill, 100);
}

function scramble() {
if (!document.getElementById('callback')) {
var iso=0, sofar=',';
var squares=document.getElementsByTagName('td');
secs++;
document.getElementById('score').innerHTML='Score: ' + score + '/' + secs + ' seconds';

for (var ii=1; ii<=9; ii++) {
iso=eval(1 + Math.min(8,Math.floor(Math.random() * 9)));
while (sofar.indexOf(',' + iso + ',') != -1) {
iso=eval(1 + Math.min(8,Math.floor(Math.random() * 9)));
}
squares[eval(-1 + ii)].innerHTML='' + iso + squares[eval(-1 + ii)].innerHTML.substring(1);
sofar+='' + iso + ',';
}
}
}

function scoreingame() {
if (!document.getElementById('callback')) { setInterval(scramble, 1000); }
}

</script>
<style>
div {
margin: 0.5em 0;
padding: 2em;
}

#target,
#source {
border: 1px solid black;
padding: 0.5rem;
}

.dragging {
background-color: pink;
}

td {
border: 1px dotted green;
}

</style>
</head>
<body onload="cloneize(); score=(location.search.split('score=')[1] ? eval('' + decodeURIComponent(location.search.split('score=')[1].split('&')[0])) : 0); secs=(location.search.split('secs=')[1] ? eval('' + decodeURIComponent(location.search.split('secs=')[1].split('&')[0])) : 0); if (eval(score + secs) != 0) { document.getElementById('score').innerHTML='Score ' + score + '/' + secs; } ">
<h1>Experimental Drag and Drop <button id="mybut" onclick="scoreingame();">Game</button></h1>
<h3>RJM Programming - July, 2023</h3>
<h3 id="score"></h3>
<h4>Thanks to <a target=_blank title='https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setData' href='//developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setData'>https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer/setData</a></h4>
<div>
<p id="source" draggable="true" contenteditable="true" style="background-color:#f0f0f0;">
Select this <strong id=strongs>editable</strong> element, drag it to the drop zone and then release the selection
to move the element.
</p>
</div>
<div id="target">Drop Zone
<table style="width:90%;height:30%;" id="mytable">
<tr><td id="td11">1</td><td id="td12">2</td><td id="td13">3</td></td>
<tr><td id="td21">4</td><td id="td22">5</td><td id="td23">6</td></td>
<tr><td id="td31">7</td><td id="td32">8</td><td id="td33">9</td></td>
</table>
</div>

<button id="reset">Reset example</button> <button id="clone" style="display:none;" onclick="bodyev();">Clone content</button>
<div id=scratchpad></div>
<script type=text/javascript>

const source = document.querySelector("#source");
source.addEventListener("dragstart", (ev) => {
console.log("dragStart");
// Change the source element's background color
// to show that drag has started
ev.currentTarget.classList.add("dragging");
// Clear the drag data cache (for all formats/types)
ev.dataTransfer.clearData();
// Set the drag's format and data.
// Use the event target's id for the data
ev.dataTransfer.setData("text/plain", ev.target.id);
});
source.addEventListener("dragend", (ev) =>
ev.target.classList.remove("dragging")
);

const target = document.querySelector("#target");
target.addEventListener("dragover", (ev) => {
console.log("dragOver");
ev.preventDefault();
});
target.addEventListener("drop", (ev) => {
console.log("Drop");
ev.preventDefault();
// Get the data, which is the id of the source element
const data = ev.dataTransfer.getData("text");
const source = document.getElementById(data);

console.log('' + ev.target.id);
if (!document.getElementById('callback')) {
if (('' + ev.target.id).substring(0,2) == 'td' && secs > 0) {
score+=eval(ev.target.innerHTML.substring(0,1));
}
} else if (document.getElementById('callback')) {
secs++;
if (('' + ev.target.getAttribute('data-answer')) == ('' + document.getElementById('source').getAttribute('data-answer'))) {
score++;
document.getElementById('score').innerHTML='Score: ' + score + '/' + secs + '';
} else {
document.getElementById('score').innerHTML='Score: ' + score + '/' + secs + '';
alert('Correct answer was ' + document.getElementById('source').getAttribute('data-answer'));
}
location.href=document.getElementById('callback').value + '?score=' + score + '&secs=' + secs;
}
if (1 == 2) {
clonedatatwo=document.getElementById('source').outerHTML;
document.getElementById('mytable').innerHTML=document.getElementById('mytable').innerHTML.replace(clonedatatwo, '');
ev.target.innerHTML=ev.target.innerHTML.substring(0,1) + clonedatatwo;
} else if (secs > 0 && (9 == 9 || ('' + ev.target.id).substring(0,2) == 'td')) {
clonedatatwo=document.getElementById('source').outerHTML;
andlater();
//document.getElementById('mytable').innerHTML=document.getElementById('mytable').innerHTML.replace(clonedatatwo, '');
//ev.target.innerHTML=ev.target.innerHTML.substring(0,1) + clonedatatwo;
//document.getElementById('target').appendChild(source);
if (('' + ev.target.id).substring(0,2) != 'td') {
document.getElementById('target').insertAdjacentHTML('beforeend', clonedatatwo);
} else {
ev.target.insertAdjacentHTML('beforeend', clonedatatwo);
}
} else {
ev.target.appendChild(source);
}

if (ev.touches) {
if (ev.touches[0].pageX) {
pos3 = ev.touches[0].pageX;
pos4 = ev.touches[0].pageY;
} else {
pos3 = ev.touches[0].clientX;
pos4 = ev.touches[0].clientY;
}
console.log('pos3 = ' + pos3 + ',pos4 = ' + pos4);
} else if (ev.clientX || ev.clientY) {
pos3 = ev.clientX;
pos4 = ev.clientY;
console.log('pos3 = ' + pos3 + ' ,pos4 = ' + pos4);
} else {
pos3 = ev.pageX;
pos4 = ev.pageY;
console.log('pos3 = ' + pos3 + ', pos4 = ' + pos4);
}

});

const reset = document.querySelector("#reset");
reset.addEventListener("click", () => document.location.reload());

</script>

</body>
</html>