0

I need to create a web application where the user drags and drops a task name, then the corresponding task name has to appear in a table.

When this happens a new row has to be added when the drop occurs.

I have used javascript for drag and drop and to add the new row.

My code works in chrome and firefox but not in IE. Why?

here is a sample of my code.

<script type = "text/javascript">

var trNumber = 1;

function addTimeSheetRow(){
    var timeSheetBody = document.getElementById("timeSheetBody");
    var trow = document.createElement("tr");

    trow.innerHTML = "<th ondragstart='return false;' ondrop='return false;'></th>" +
    "<th ondrop='drop(event)' ondragover='allowDrop(event)' value='' class='dropTexts'></th>" +
    "<td><input name=" + getTrDayNames("Mon") + " type='text' value='' size='2'/></td>" +
    "<td><input name=" + getTrDayNames("Tue") + "  type='text' value='' size='2'/></td>" +
    "<td><input name=" + getTrDayNames("Wed") + "  type='text' value='' size='2'/></td>" +
    "<td><input name=" + getTrDayNames("Thu") + "  type='text' value='' size='2'/></td>" +
    "<td><input name=" + getTrDayNames("Fri") + "  type='text' value='' size='2'/></td>" +
    "<td><input name=" + getTrDayNames("Sat") + "  type='text' value='' size='2'/></td>" +
    "<td><input name=" + getTrDayNames("Sun") + "  type='text' value='' size='2'/></td>" +
    "<td class='total'><input type='text' value='0' size='2' readonly='readonly'/></td>"; 

    timeSheetBody.appendChild(trow);

    $("tbody#timeSheetBody td input:not(.intial)").each(function() {
        $(this).keyup(function(){
            newSum.call(this);
            colSum.call(this);

        });
    });

    document.getElementsByName("trNumber")[0].value = trNumber;
}

function allowDrop(ev)
{
    //ev.preventDefault();
    ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
}
function drag(ev)
{
    ev.dataTransfer.setData("Text",ev.target.id);
    //var projectElement = ev.target.parentNode;
    //ev.dataTransfer.setData("Text", projectElement.getAttribute("id"));
    //alert(projectElement.getAttribute("id"));
}

function drop(ev)
{
    //ev.preventDefault();
    ev.preventDefault ? ev.preventDefault() : ev.returnValue = false;
    var data = ev.dataTransfer.getData("Text");
    var taskName =document.getElementById(data).innerHTML;
    //alert(taskName);
    var trTaskName = "tr" + trNumber + "TaskName";
    ev.target.innerHTML = taskName + "<input name=" + trTaskName + " type='hidden' value='" + taskName + "' size='2' class='intial'/>";


    var projectName = document.getElementById(data).parentNode.getAttribute("id");
    //alert(projectName);
    var projectTextBox = ev.target.parentNode.children[0];
    var trProjectName = "tr" + trNumber + "ProjectName";
    projectTextBox.innerHTML = projectName + "<input name=" + trProjectName + " type='hidden' value='" + projectName + "' size='2' class='intial'/>";


    trNumber = trNumber + 1;

    addTimeSheetRow();
}
10
  • 1
    What version of IE? Native drag and drop only works on IE 9+ Commented Aug 19, 2013 at 12:22
  • Any errors in the JS console? Commented Aug 19, 2013 at 12:22
  • Hard to say, but by the error type(don't working only in IE and table handling) I'd give a shot that is something related to tbody tags. Commented Aug 19, 2013 at 12:25
  • i tried to check errors in IE it is not recognising the <th> tags Commented Aug 19, 2013 at 12:42
  • how you kept 2 th and other td, It should be all td or th its html is not correct Commented Aug 19, 2013 at 12:44

3 Answers 3

1

You can solve this by making a custom .innerHTML (yes it's a lot of work) or otherwise modifying the .innerHTML property/function. I made this code to make sure that still-referenced child element data is preserved when clearing the .innerHTML (another problem with IE's .innerHTML), but it can be adapted to solve the IE tables problem.

if (/(msie|trident)/i.test(navigator.userAgent)) {
 var innerhtml_get = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerHTML").get
 var innerhtml_set = Object.getOwnPropertyDescriptor(HTMLElement.prototype, "innerHTML").set
 Object.defineProperty(HTMLElement.prototype, "innerHTML", {
  get: function () {return innerhtml_get.call (this)},
  set: function(new_html) {
   var childNodes = this.childNodes
   for (var curlen = childNodes.length, i = curlen; i > 0; i--) {
    this.removeChild (childNodes[0])
   }
   innerhtml_set.call (this, new_html)
  }
 })
}

var mydiv = document.createElement ('div')
mydiv.innerHTML = "test"
document.body.appendChild (mydiv)

document.body.innerHTML = ""
console.log (mydiv.innerHTML)

http://jsfiddle.net/DLLbc/9/
http://jsfiddle.net/DLLbc/12/

Sign up to request clarification or add additional context in comments.

1 Comment

I made a change: try jsfiddle.net/DLLbc/12 for specific bug detection, if you don't have mutation observers loaded before this code runs. You can also try stackoverflow.com/questions/20661996/…
1

It's a known bug: You can set the innerHTML of tables only when you create the table in IE. But document.createElement and other dom manipulations should work fine. Alternatively you could use a js lib for compatibility.

3 Comments

the drag and drop works, but the new row is not getting added in IE9
Hasn't this bug been fixed in IE8+? May be it's a quirks mode issue?
can you explain wat is a quirks mode issue?
0

FOR NORMAL JS:

A known and no so hard to do fix is to create all elements, not to create a string with all content and add it.

The same way you created the tr, create tds, etc.

In your case might not be so nice to do because of the large structure but...

FOR A BETTER WAY OF LIVING:

Use jQuery/prototype/mootools or whatever other lib you like.

2 Comments

it would become a tedious job.. is there an alternative other than using innerHTML?
Native... no. As Floste said, or as I said in answer... use a lib. I suggest jQuery. Makes your life much easier. Or if you want you can create your own function to do that, and pass an array of strings (or a string if you feel like breaking it into parts) as parameters. Or maybe if you have the option just ignore IE 7 (if I remember right this is fixed in IE 8 (I'm sure about 9, not sure about 8)).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.