Answered by:
Drag and Drop feature not working with table content?

Question
-
User1909155429 posted
I am attempting to add the following script to my repeater taken from: https://www.developer.com/lang/using-html5-drag-and-drop-in-asp.net.html
On implementation i get the following error messages:
// Error: Unable to get property 'style' of undefined or null reference
// javascript: WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("RepInbox$ctl01$LinkButton1", "", true, "", "", false, true))
The first relates to ondragstart event. and the other when i drop. The only difference from the original script is that i am using table tr element instead of Div?
<script type="text/javascript">
var srcElement;$(document).ready(function () {
$("#Button3").click(function () {
$("div .bag div").remove();
});$("#Button1").click(function () {
var data = new Array();
$("div .bag div").each(function (index) {
data[index] = "'" + this.innerHTML + "'";
});
$.ajax({
type: 'POST',
url: 'shoppingcart.aspx/PlaceOrder',
contentType: "application/json; charset=utf-8",
data: '{ products:[' + data.join() + ']}',
dataType: 'json',
success: function (results) { alert(results.d); },
error: function () { alert('error'); }
});
});$("tr .3-card-4").each(function () {
this.addEventListener('dragstart', OnDragStart, false);
});$("div .bag").each(function () {
this.addEventListener('dragenter', OnDragEnter, false);
this.addEventListener('dragleave', OnDragLeave, false);
this.addEventListener('dragover', OnDragOver, false);
this.addEventListener('drop', OnDrop, false);
this.addEventListener('dragend', OnDragEnd, false);
});})
function OnDragStart(e) {
this.style.opacity = '0.4';
srcElement = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text', $(this).find("header")[0].innerHTML);
}function OnDragOver(e) {
if (e.preventDefault) {
e.preventDefault();
}
$(this).addClass('highlight');
e.dataTransfer.dropEffect = 'move';
return false;
}function OnDragEnter(e) {
$(this).addClass('highlight');
}function OnDragLeave(e) {
$(this).removeClass('highlight');
}function OnDrop(e) {
if (e.preventDefault) {
e.preventDefault();
}
srcElement.style.opacity = '1';
$(this).removeClass('highlight');
var count = $(this).find("tr[data-product-name='" + e.dataTransfer.getData('text') + "']").length;
if (count <= 0) {
$(this).append("<div class='selectedproduct' data-product-name='" + e.dataTransfer.getData('text') + "'>" + e.dataTransfer.getData('text') + "</div>");
}
else {
alert("This product is already added to your cart!");
}
return false;
}function OnDragEnd(e) {
$("div .bag").removeClass('highlight');
this.style.opacity = '1';
}
</script><div align="center" >
<asp:Repeater ID="RepInbox" runat="server" onitemcommand="RepInbox_ItemCommand" OnItemDataBound="RepInbox_ItemDataBound" >
<HeaderTemplate >
<table id="Inbox" cellspacing="0" rules="all" border="0" class="w3-card-2" style="vertical-align:top" cellpadding="10" >
<tr >
<td width="15%" align="left" >
<strong>Remove</strong>
</td>
<td width="55%" align="left" >
<strong>Subject</strong>
</td>
<%-- <td width="15%" align="left">
<strong>Date</strong>
</td>--%>
<td width="15%" align="left" >
<strong>Type</strong>
</td>
<td width="15%" align="left">
<strong>Read Status</strong>
</td>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr class="w3-card-4" draggable="true" >
<td align="left" >
<asp:CheckBox ID="chkDeleted" Runat="server" Text="" ></asp:CheckBox>
</td>
<td align="left" >
<asp:LinkButton ID="LinkButton1" CommandArgument='<%#DataBinder.Eval(Container, "DataItem.MessageID")%>' runat="server"><%#DataBinder.Eval(Container,"DataItem.subject")%></asp:LinkButton>
<header><%#DataBinder.Eval(Container, "DataItem.MessageID")%> </header>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater><div class="bag">
<asp:Image runat="server" ID="img1" ImageUrl="CSS/Images_Project/Cart.jpg" />
<br /><br />
<input id="Button1" type="button" value="Place Order" />
<br />
<input id="Button3" type="button" value="Clear Cart" />
</div>
</div>Wednesday, September 2, 2020 9:11 PM
Answers
-
User1535942433 posted
Hi peterthegreat,
error message say Invalid data?SetData grammar:
void dataTransfer.setData(format, data);
Your codes of '$(this).find()' isn't data.This a control.You need to replace to:
$(this).find("input[type='hidden']").text.tostring()
Beside,The sample data types are: " text/plain" and " text/uri-list".
Another thing is it does not differentiate between string and numbers? when dragging data as text. so errors occur when saving data.
The format is a DOMStringrepresentation to be added to drag objectthe type of drag data.And the DOMString is a UTF-16 string.
Best regards,
Yijing Sun
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, September 22, 2020 7:22 AM
All replies
-
User1535942433 posted
Hi peterthegreat,
// Error: Unable to get property 'style' of undefined or null referencethis.style.opacity = '0.4';
srcElement = this;Accroding to your description and codes,as far as I think,your codes have three problems.
1.You are running the script too early before the document has been loaded and thus the srcElement can't be found.
The solution is probably to put this part of your script at the very end of your document so everything before it has already been loaded.
2.You need replace:
var srcElement;
to:
var srcElement="";
3.You need to use jQuery methods on your jQuery objects instead of the DOM properties you were using before.
Instead of:
this.style.opacity = '0.4';
Used:
$(this).css('opacity', '0.4');
javascript: WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("RepInbox$ctl01$LinkButton1", "", true, "", "", false, true))Accroding to your codes,I create a test and I get the different error with you.I have get this error:
jquery-3.2.1.min.js:2 Uncaught Error: Syntax error, unrecognized expression: tr[data-product-name='javascript:__doPostBack('RepInbox$ctl01$LinkButton1','')']
The problem is linkbutton intead of table.
If your problem is same with this,do you must need to use linkbutton?If you must to use,you could refer to below article to solve it:
https://forums.asp.net/t/1685043.aspx?Problem+with+javascript+__doPostBack+ctl00+lkbLogout+
Best regards,
Yijing Sun
Thursday, September 3, 2020 4:27 AM -
User1909155429 posted
I have changed my code to target the Linkbutton and nolonger get error messages!
The problem now is the code as highlighted in drop event does not work.It appears not able to find Linkbutton control. I have tested the count value remains zero?
<td align="left" >
<asp:LinkButton ID="LinkButton1" class="w3-card-4" draggable="true" CommandArgument='<%#DataBinder.Eval(Container, "DataItem.MessageID")%>' runat="server"><%#DataBinder.Eval(Container,"DataItem.subject")%></asp:LinkButton>
</td>function OnDrop(e) {
if (e.preventDefault) {
e.preventDefault();
}
$(this).removeClass('highlight');
var count = $(document.getElementById("LinkButton1")).find("LinkButton [data-product-name='" + e.dataTransfer.getData('text') + "']").length;
document.getElementById("LblRepCount").innerHTML = count;
if (count <= 0) {
$(document.getElementById("LinkButton1")).append("<div class='selectedproduct' data-product-name='" + e.dataTransfer.getData('text') + "'>" + e.dataTransfer.getData('text') + "</div>");
}
else {
alert("This product is already added to your cart!");
}
return false;
}Thursday, September 3, 2020 7:32 PM -
User1535942433 posted
Hi peterthegreat,
var count = $(document.getElementById("LinkButton1")).find("LinkButton [data-product-name='" + e.dataTransfer.getData('text') + "']").length;Accroding to your description and codes,I have find three prblems in your codes.
1.In the repeater,LinkButton id will be changed.You need to use id*=LinkButton1.
2.In the html,there aren't have linkbutton control.
3.There aren't data-product-name attribute.
I'm guessing you need to get linkbutton button 's count.I suggest you could do this:
function OnDrop(e) { if (e.preventDefault) { e.preventDefault(); } $(srcElement).css('opacity', '1'); $(this).removeClass('highlight'); var count = $('[id*=LinkButton1]').length; if (count <= 0) { $("#Inbox").append("<div class='selectedproduct' data-product-name='" + e.dataTransfer.getData('text') + "'>" + e.dataTransfer.getData('text') + "</div>"); } else { alert("This product is already added to your cart!"); } return false; }
Best regards,
Yijing Sun
Friday, September 4, 2020 7:12 AM -
User1909155429 posted
i tried to remedy without success. I set ID instead of data-product-name attribute.
I am dropping data into DIV class="bag" and not Inbox as you refer to! so if dragged Linkbutton text does not exist in getData method already i add to dataTransfer else notify user item already exists.So i cannot count the Linkbutton items in Inbox as your code suggests.
var controlID = $(this).attr('id');
var count = $(controlID).find("Linkbutton [ID='" + e.dataTransfer.getData('text') + "']").length;
document.getElementById("LblRepCount").innerHTML = count;
if (count <= 0) {
$( document.getElementById("LinkButton1").append("<div class='selectedproduct' ID='" + e.dataTransfer.getData('text') + "'>" + e.dataTransfer.getData('text') + "</div>");
}
else {
alert("This product is already added to your cart!");
}
return false;
}Friday, September 4, 2020 2:24 PM -
User1535942433 posted
Hi peterthegreat,
Accroding to your codes,there are three problems in your codes:
1.$(this) is the div "bag".However,your bag don't exist id.So you cann't get the controlID.
var controlID = $(this).attr('id');
2.You cann't find Linkbutton.Linkbutton control in html will be rendered as <a>.
var count = $(controlID).find("Linkbutton [ID='" + e.dataTransfer.getData('text') + "']").length;
3.Linbutton ID in repeater will be changed.So you need to use [id*=LinkButton1].
$( document.getElementById("LinkButton1")
I suggest you could press F12 and check your html elements and source.
Best regards,
Yijing Sun
Monday, September 7, 2020 8:07 AM -
User1909155429 posted
Thanks for the response.
I did manage eventually to get it to work, but only using html elements. I wanted to include a hidden control to store the id number that i dont want to show and linkbutton caused reference problems and also would not let me use the commandargument to pass it on server side on click event. So i use it to display text alone with header html element attribute set to my hidden id number.
I would like to know still how to reference a hidden asp control with the find method as in:
I used your code example -[id*=HiddebField1] without success?
function OnDragStart(e) {
$(this).css('opacity', '0.4');
srcElement = this;
e.dataTransfer.effectAllowed = 'move';
e.dataTransfer.setData('text', $(this).find("HiddenField[id*='HiddenField1']"));
i get error message:invalid argument?
Thanks again!
Monday, September 7, 2020 1:30 PM -
User1535942433 posted
Hi peterthegreat,
As far as I know,HiddenField control in html will be rendered as input and it's type is hidden.
So you could replace :
$(this).find("HiddenField[id*='HiddenField1']")
With:
$(this).find("input[type='hidden']")
Best regards,
Yijing Sun
Tuesday, September 8, 2020 8:28 AM -
User1909155429 posted
Another thing is it does not differentiate between string and numbers? when dragging data as text. so errors occur when saving data.
Wednesday, September 16, 2020 1:24 PM -
User1535942433 posted
Hi peterthegreat,
error message say Invalid data?SetData grammar:
void dataTransfer.setData(format, data);
Your codes of '$(this).find()' isn't data.This a control.You need to replace to:
$(this).find("input[type='hidden']").text.tostring()
Beside,The sample data types are: " text/plain" and " text/uri-list".
Another thing is it does not differentiate between string and numbers? when dragging data as text. so errors occur when saving data.
The format is a DOMStringrepresentation to be added to drag objectthe type of drag data.And the DOMString is a UTF-16 string.
Best regards,
Yijing Sun
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Tuesday, September 22, 2020 7:22 AM -
User1909155429 posted
You put me on the right path!
though i had to play around with the format to eventually get it to work.taking out the type syntax,probably an older version of the browser,i guess that does not support type? Also, i tested for string/object type and alerted user if present. I am pleased with the result
Thank for you help
Peter
Tuesday, September 22, 2020 2:45 PM