Issue with HTML5 Drag and Drop - javascript

I am a bit new to javascript/web programming and I've been having some issues that should probably have simple solutions but that I am having an extreme amount of trouble with. I basically just want to drag text from a cell in one table to a cell in another table. My questions are as follows:
I cannot seem to make anything but an (a href) type link drag and drop. If I try to set the draggable=true option on a div it remains undraggable (in firefox). In my searches, I haven't really seen any fixes for firefox ( i have added css rules for webkit, however).
To work around this, I was trying to drag an (a href) -apologies for parentheses, there is a limit on the amount of link tags i can use - item from one table's cell to a text input field in another table's cell and its default action is to just drag the link. What I'd like it to drag would be the contents of the tag (e.g. for Some Text I'd like it to return "Some Text" or "draggable" or any other customizable text). I have tried handling this in the ondragstart/ondrop events through e.datatransfer.setData("Text", "My Custom Text") and e.datatransfer.getData("Text") however I still receive the same results. Would anybody have any suggestions for this? I have been looking at this for a while and cannot figure it out at all.
Thank you very much in advance for your help.
EDIT: I do not have access to the computer I was using atm but I'll try to get the basic gist of what I was doing across..
onDrop(e){ //onDrop is assigned to the drophandler of a text input field
var text = e.dataTransfer.getData('Text');
this.Text = text;
e.preventDefault();
}
onDragOver(e){
e.preventDefault();
}
onDragStart(e){
e.dataTransfer.setData('Text', 'My String');
}
....
<table>
<tr>
<td><a id="ident" href="#" draggable="true">Text Content</a></td>
</tr>
<table>
<table>
<tr>
<td><input ondrop="onDrop(e)" type="text" /></td>
</tr>
<table>

Here's a complete code sample I did that works, based on your skeleton above:
<html>
<head>
<title>drag and drop example</title>
<script type="text/javascript">
function onDrop(e){
e.preventDefault();
var text = e.dataTransfer.getData("text/plain");
var input = document.getElementById("destination");
input.value = text;
}
function onDragOver(e){
e.preventDefault();
}
function onDragStart(e){
e.dataTransfer.setData("text/plain", event.target.textContent);
}
</script>
</head>
<body>
<table>
<tr>
<td>
<span id="ident" draggable="true" ondragstart="onDragStart(event)">Text Content</span>
</td>
</tr>
<table>
<table>
<tr>
<td>
<input id="destination" ondragover="onDragOver(event)" ondrop="onDrop(event)" type="text" />
</td>
</tr>
<table>
</body>
</html>
Several things to note:
The format you pass to setData and getData needs to be "text/plain" not "Text" (see: http://dev.w3.org/html5/spec/dnd.html#dom-datatransfer-getdata)
You needed to actually call OnDragOver and OnDragStart (perhaps this was just missing from the sample you added from memory)
It would be good to give your input element an ID, as I did, so you can change the value to the dragged item
To read more about this topic, I wrote a blog you may find helpful: A Drag and Drop Planning Board with HTML5

Related

How to reload jquery on onclick event?

I've got a table row where it retrieves data from MySQL and I have included a .onclick function where it opens up a text editor with data inside, but the text editor is only opening for the first row and not the rest in the table.
This is the jQuery code: The first opens the text editor and the second switches the textarea for the text editor which is ckeditor.
<script type="text/javascript">
$(document).ready(function()
{
$(".trClass").click(function()
{
var id = $(this).attr('id');
$('#d_'+id).css("display", "block");
$('#table_id').css("display", "none");
});
});
window.onload = function()
{
CKEDITOR.replace("editor1");
};
</script>
and this here is echo for the table, I am using a foreach.
echo '
<tr class="trClass" id="'.$counter.'">
<td class="marker">
<i class="fa fa-align-left"></i>
</td>
<td class="title">
'.$article_title.'
</td>
<td class="content">
'.$article_content.'
</td>
</tr>
<section id="d_'.$counter.'" style="display:none;">
<textarea id="editor1">
<div style="width:468px;">
'.$article_content_full.'
</div>
</textarea>
</section>
';
$counter++;
}
I cannot figure out how to make the CKEDITOR.replace("editor1"); load for every table, I tried using .click function within it but it does not work as it doesn't load. Here is the problem, if you click on the first row it opens the text editor if you click on the second it does not; http://www.goo.gl/dQrLPN
Typically the id attribute should be unique for each element. Applying properties across multiple elements is usually accomplished with a class. Knowing this, CKEditor is probably just grabbing the first instance of an object with the given id (probably using document.GetElementById behind the scenes).
(According to the documentation, CKEDITOR.replace(var) will either take a DOM element, ID, or name.)
Given that, you have a couple of options. One is to defer loading the CKEditor until you actually click on the table row. This would look something like this... (note how each textarea has a unique id)
<section id="d_' . $counter . '" style="display:none;">
<textarea id="editor_'.$counter.'">
<div style="width:468px;">
'.$article_content_full.'
</div>
</textarea>
$(document).ready(function()
{
$(".trClass").click(function()
{
var id = $(this).attr('id');
$('#d_'+id).css("display", "block");
$('#table_id').css("display", "none");
CKEDITOR.replace('editor_'+id);
});
});
The second option would be to loop through all of the textarea elements and call replace on each one of them on-load. I wouldn't really recommend this, unless there's some specific reason you want to load everything up-front.
EDIT: Although this should fix your issue, you should look in to the HTML issues the other answerers have put forward. <section> doesn't belong as a child of <table> :-)
Try targeting the table and filtering by the rows using the .on() method.
$(document).ready(function()
{
$('#table_id').on('click','.trClass',function() {
var id = $(this).attr('id');
$('#d_'+id).css('display', 'block');
$('#table_id').css('display', 'none');
});
});
Details on .on() are here: https://api.jquery.com/on/
And as noted in the comments above, there are some overall issues with your HTML that you should probably fix before proceeding further.

Putting value into Textbox upon clicking Div

I am currently trying to make a wallpaper changer for my page.
At the minute, I would like to put the URL of a wallpaper into a text box when it's respective DIV option in a CSS menu is clicked.
Here is my JQuery
$("div.bg8").click( function() {
var BackgroundURL = 'Styles/hongkongskyline.jpg';
var TheTextBox = document.getElementById('<%=BackgroundsTxt.ClientID%>');
TheTextBox.value= BackgroundURL;
alert('This has worked'); });
.. and my HTML...
<ul><li class="#cssmenu"><a>
<div id="bg8" runat="server">
<table style="height: 16px; width:33%;">
<tr>
<td>
<img src='Styles/hongkongskyline.jpg' width="34px" height="32px" /></td> <td>Hong Kong Skyline </td>
</tr>
</table>
</div>
</a></li></ul>
Unfortunately, nothing seems to be happening when I click the DIV..
Does anybody see any problems which I can't?
Many thanks.
Several problems here.
First, you aren't referring to your div's ID in your jQuery - you're referring to a class called bg8. Try this:
$("#bg8")...
Next, you're mixing in some native-dom stuff into your jQuery. Instead of
document.getElementById('<%=BackgroundsTxt.ClientID%>');
try
$("#<%=BackgroundsTxt.ClientID%>");
and make sure the ID is resolved by looking at the source to your page.
And lastly, to set the value of the textbox:
theTextBox.val(BackgroundURL);
Your whole function could be
$("#bg8").click( function() {
$("#<%=BackgroundsTxt.ClientID%>").val('Styles/hongkongskyline.jpg');
alert('This has worked');
});
My strategy is to test event handlers with simple alerts before moving on to the real logic.
your jQuery states $('div.bg8') , this calls for a div with the class bg8,
you have not set the class, but rather the id of your div as bg8
change this: $('div.bg8') to $('#bg8')
;)

html table with radio button copy paste into xls

I have an HTML table element, with rows containing not only plain-text characters, but also radio buttons, lists, etc.
What I would like to have, is when the user copy-pastes the content of the table into MS Excel (as plain text), the radio buttons should be replaced with their values (e.g.: "checked", and "unchecked"), lists elements should be replaced by their selected value, etc.
Is there a way to implement this in the browser?
(Preferably without using flash or java applet components)
Thanks,
krisy
You could use javascript (this will be easier with a framework like jquery) to modify the code that has been copied. The general procedure would be to set the radio buttons to be invisible and then add in text in their place based on their current value.
There are plenty of questions to help with the implementation details: https://stackoverflow.com/search?q=%5Bjavascript%5D+copied+text&submit=search
Update: Turns out you don't even need to remove the radio buttons, at least for my version of excel. Here is a working example (way over-commented to explain what's going on):
<!DOCTYPE html>
<html>
<head>
<style type='text/css'>
.radioCopyVal{
font-size: 0;
}
</style>
</head>
<body>
<form>
<table>
<tr>
<td><input type='radio' name='woots' id='oneWoot' checked/><span class='radioCopyVal'>Checked.</span></td>
<td><label for='oneWoot'>Woot.</label></td>
</tr>
<tr>
<td><input type='radio' name='woots' id='twoWoot' /><span class='radioCopyVal'>Not checked.</span></td>
<td><label for='twoWoot'>Woot. Woot.</label></td>
</tr>
</table>
</form>
<script src="jquery-1.7.2.min.js"></script>
<script type='text/javascript'>
$("#oneWoot").attr("checked", true); //on page load, make sure oneWoot is the default selection
$("input[name=woots]:radio").change(function(){ //anytime the radio buttons of name woots are changed...
$(".radioCopyVal").remove(); //remove the old radioCopyVal spans (to be replaced with new ones)
$("input[name=woots]:radio").each(function() { //for each radio button in name woots
if ($(this).attr("checked")) { //if the button is checked, add a span saying 'Checked.' after it. css is used to hide the span
$(this).after('<span class="radioCopyVal">Checked.</span>');
}else {
$(this).after('<span class="radioCopyVal">Not checked.</span>');
}
})
});
</script>
</body>
</html>
Not possible I'm afraid. But you could do like this:
Have a link that leads to a javascript and the script will hide these items and show their values in plain text so this operation can be reversed.
This can be easily done using JQuery:
This shows the radio value:
$("input:radio").each(function() {
if ($(this).attr("checked")) {
$(this).after('<span class="value">checked</span>');
}
else {
$(this).after('<span class="value">unchecked</span>');
}
}).css("display", "none");
I left a span class so that these values then can be hided easily using script.

Input Data To SharePoint RichText Control By WinForms WebBrowser Control

I need to edit the value in an SP Rich Text field via the WinForms web browser control. Most other controls (input tags) are easy to get and we can change the value quite simply. However, not so simple with Rich Text. I headed over to:
http://blog.drisgill.com/2007_05_01_archive.html
and got some ideas. At first, I tried creatign a javascript function and adding it to the page:
function GetRichTextRange(strBaseElementID)
var docEditor=RTE_GetEditorDocument(strBaseElementID);
if (docEditor == null)
{ return; }
var selection = docEditor.selection;
var range = selection.createRange();
return range;
}
However, every time I call this, I always get a null value back. So I tried this instead:
object docEditor = document.InvokeScript("RTE_GetEditorDocument", new object[] { fieldName });
IHTMLDocument2 doc = (IHTMLDocument2)docEditor;
IHTMLSelectionObject selection = doc.selection;
IHTMLTxtRange textRange = (IHTMLTxtRange)selection.createRange();
textRange.pasteHTML(value);
Well, now I am getting an error on the second line: "Unable to cast object of type 'System.DBNull' to type 'mshtml.IHTMLDocument2"
I am not even sure if I am casting to the correct object type anyway, but in any case, it seems what I am getting back from the RTE_GetEditorDocument function is of System.DBNull.
All I want to do is say something like myRichTextHtmlElement.SetAttribute("value", html); but that obviously cannot be done.
To make things worse, I am completely new to javascript and I'm more of a WinForms guy, so my HTML is not exactly hot stuff. Below is the HTML for my RichText field:
<tr>
<td nowrap="true" valign="top" width="190px" class="ms-formlabel">
<h3 class="ms-standardheader">
<nobr>RichText</nobr>
</h3>
</td>
<td valign="top" class="ms-formbody">
<!-- FieldName="RichText"
FieldInternalName="RichText"
FieldType="SPFieldNote"
-->
<span dir="none">
<div class='ms-rtestate-field ms-rtefield' style=''>
<div id='ctl00_m_g_29d60052_5630_4981_8452_850a87a50b56_ctl00_ctl05_ctl07_ctl00_ctl00_ctl04_ctl00_ctl00_TextField_inplacerte_label'
style='display:none'>Rich text editor
</div>
<div class=' ms-rtestate-write ms-rteflags-0'
id='ctl00_m_g_29d60052_5630_4981_8452_850a87a50b56_ctl00_ctl05_ctl07_ctl00_ctl00_ctl04_ctl00_ctl00_TextField_inplacerte'
style='min-height:84px'
aria-labelledby='ctl00_m_g_29d60052_5630_4981_8452_850a87a50b56_ctl00_ctl05_ctl07_ctl00_ctl00_ctl04_ctl00_ctl00_TextField_inplacerte_label'
contentEditable='true' >
<div class="ExternalClassD74B4D64D01941CDB34619757AAA30D8">
<html>
<body>
<h4>A Definition List:</h4>
<dl>
<dt>Coffee</dt>
<dd>Black hot drink</dd>
<dt>Milk</dt>
<dd>White cold drink</dd>
</dl>
</body>
</html>
</div>
</div>
<div style="clear:both;"></div>
</div>
<span dir="ltr">
<input name="ctl00$m$g_29d60052_5630_4981_8452_850a87a50b56$ctl00$ctl05$ctl07$ctl00$ctl00$ctl04$ctl00$ctl00$TextField_spSave"
type="HIDDEN"
id="ctl00_m_g_29d60052_5630_4981_8452_850a87a50b56_ctl00_ctl05_ctl07_ctl00_ctl00_ctl04_ctl00_ctl00_TextField_spSave" />
</span>
</span>
</td>
</tr>
Anyone got any ideas? Thanks!
do you have to use a winforms webbrowser control? One could use whatever html code editor they wanted in a winform and capture the results and use the sharepoint web services or object model(depending on use case) to update the item as an alternative option.
Well, after a lot of pulling hair out, I got the answer and it was simpler than I thought. Once I got the correct HtmlElement (the div with id ".....TextField_inplacerte") then all I needed to do was this:
HtmlElement element = document.GetRichTextFieldCell(fieldName);
if (element != null)
{
element.InnerHtml = value;
element.SetAttribute("value", value);
}
I probably don't need the SetAttribute bit, so I will attempt the same thing later without that line.
Thanks anyway guys. :-)

How to split HTML code with javascript or JQuery

I'm making a website using JSP and servlets and I have to now break up a list of radio buttons to insert a textarea and a button. I have got the button and textarea to hide and show when you click on the radio button it shows the text area and button. But this only appears at the top and when there are hundreds on the page this will become awkward so i need a way for it to appear underneath. Here is what my HTML looks like when complied:
<form action="addSpotlight" method="POST">
<table>
<tr><td><input type="radio" value="29" name="publicationIDs" ></td><td>A System For Dynamic Server Allocation in Application Server Clusters, IEEE International Symposium on Parallel and Distributed Processsing with Applications, 2008</td> </tr>
<tr><td><input type="radio" value="30" name="publicationIDs" ></td><td>Analysing BitTorrent's Seeding Strategies, 7th IEEE/IFIP International Conference on Embedded and Ubiquitous Computing (EUC-09), 2009</td> </tr>
<tr><td><input type="radio" value="31" name="publicationIDs" ></td><td>The Effect of Server Reallocation Time in Dynamic Resource Allocation, UK Performance Engineering Workshop 2009, 2009</td> </tr>
<tr><td><input type="radio" value="32" name="publicationIDs" ></td><td>idk, hello, 1992</td> </tr>
<tr><td><input type="radio" value="33" name="publicationIDs" ></td><td>sad, safg, 1992</td> </tr>
<div class="abstractWriteup"><textarea name="abstract"></textarea>
<input type="submit" value="Add Spotlight"></div>
</table>
</form>
Now here is what my JSP looks like:
<form action="addSpotlight" method="POST">
<table>
<%int i = 0; while(i<ids.size()){%>
<tr><td><input type="radio" value="<%=ids.get(i)%>" name="publicationIDs" ></td><td><%=info.get(i)%></td> </tr>
<%i++; }%>
<div class="abstractWriteup"><textarea name="abstract"></textarea>
<input type="submit" value="Add Spotlight"></div>
</table>
</form>
Thanks in Advance
Dean
You can easily move DOM nodes around using Node#insertBefore. (That link is to MDC, but it's a standard method and well-supported.)
Here's an example using Prototype, but you can do it with jQuery or other libraries, or just straight DOM methods like the one linked above (it's just more hassle without a library):
// Called at some point during page init to hook up the event handler
function hookRadioButtons() {
var form;
form = $('theForm'); // Assuming you put an ID on the form
form.observe('click', radioButtonClick);
}
// Event handler for radio button clicks
function radioButtonClick(event) {
var btn, div;
// Get the (extended) DOM element for the button
btn = event.findElement('input[type=radio]');
if (btn) {
// Get the (extended) DOM element for the div
div = $('theDiv'); // Assuming you gave the div an ID
// Starting from the button, go `up` to the table cell,
// then over to the following cell, and then insert the
// div at the top of it
btn.up('td').next().insert({
top: div
});
// Show the div (if it's hidden)
div.show();
}
}
That's completely off the cuff and untested (and full of assumptions), it's just to give you an idea.
you can use after(html) or before(html) you only need to add to every radiobutton a unique value but you already did that with value="<%=ids.get(i)%>"
something like this?
$("input[value='PutIdHere']").parent().after(htmlContent);
Move the div "abstractWriteup" to after the closing table tag. It's invalid code to have it inside a table without a containing row and cell anyway, and this will ensure that it appears below the table.
EDIT
I realise I may have misunderstood - you want the div to appear below the radio button which has been clicked, don't you?
You can't put <div> inside a table. It's invalid and browsers may render it in odd ways, like, as you said, as the top.
You would have to either:
close the table, put the div and then if you need more rows after that open a second table. To ensure two tables have the same row widths, you can set table-layout: fixed on the tables and add <col> elements with explicit widths for the non-liquid columns. Or,
include the textarea/submit in a new <tr><td>.
Having said that, I don't know why you're using a table here when you aren't really doing anything with the columns. A simple <div> for each radio would be easier to handle.
Since you will also only ever have one radio ticked, you can re-use the same textarea/submit elements, and just move them to the right row onclick. With JavaScript disabled they'll just stay at the bottom.
<form id="publications" method="post" action="...">
<% for(int i= 0; i<ids.size(); i++) { %>
<div>
<input type="radio" name="publicationIDs" value="<%= ids.get(i) %>" id="pid_<%= ids.get(i) %>">
<label for="pid_<%= ids.get(i) %>">
<%= info.get(i).replaceAll("&", "&").replaceAll("<", "<").replaceAll("\"", """) %>
</label>
</div>
<% } %>
<div id="abstractsubmit">
<textarea name="abstract"></textarea>
<input type="submit" value="Add Spotlight">
</div>
</form>
Note: <label> added, for better usability (can click on name to select radio). replaceAll here is acting as a poor man's HTML encoder. You need an HTML encoder every time you output text into HTML, otherwise characters like < in the text will mess up the page, and potentially create cross-site-scripting security holes.
Unfortunately, in an appalling oversight, the original version of JSP didn't include an HTML encoder. Many, many libraries for web-related software have one you can use to avoid having to write out all these replaceAll​s. Also, if you're using JSP 2.0+, you should consider using JSTL c: tags rather than scriptlets. <c:out> gives you an output-with-HTML-encoding behaviour by default.
Example script to move the abstract element about:
<script type="text/javascript">
var radios= document.getElementById('publications').elements.publicationIDs;
function update() {
// Get div containing selected radio
//
var selected= null;
for (var i= radios.length; i-->0;)
if (radios[i].checked)
selected= radios[i].parentNode;
// Move abstract div just after it
//
var a= document.getElementById('abstractsubmit');
if (selected===null) {
a.style.display= 'none';
} else {
a.style.display= 'block';
selected.parentNode.insertBefore(a, selected.nextSibling);
}
}
// Bind to all radios, and reflect initial form selectedness state
//
for (var i= radios.length; i-->0;)
radios[i].onclick= function() { setTimeout(update, 0); };
update();
</script>
setTimeout is used here because the onclick event fires before the radio have been selected to reflect the click, so update can't yet read which radio is chosen. The right thing to do would be to use onchange instead, but unfortunately that doesn't fire at a useful time in IE, so onclick is what we're left with.
update is run at the start because when you're doing forms you can never be sure what your initial state is. Browsers often try to remember form fields when returning to a page, which may result in a radio unexpectedly being ticked at start of play.
(You could make this a little shorter with jQuery. But not massively shorter.)

Categories