Search code examples
jqueryhtmlace-editordroppable

Copying from Draggable to an Ace Editor Droppable


I'm attempting to add Drag & Drop functionality to Ace Editor. I'm using jQuery Droppable function to achieve this. I have the Drag functionality working, and the Ace Editor area appears as well. The Drop function is currently not working. My intended use for the drop function is to copy the text from the draggable div into the Ace Editor Area. The drop function works when I'm not using Ace Editor, as in when I drag a DIV to a droppable DIV it copies the content of the draggable just fine. So something is up with the implementation with Ace since the editor isn't getting populated with the draggable content. Here's my code. I have everything in one file for now, I intend to separate them once I understand Ace a bit better.

<!DOCTYPE html>
<html lang="en">

  <head>
    <title>Code Block Project</title>


    <style type="text/css" media="screen">

      #draggable {
        width: 202;
        height: 30px;
        padding: 0.5em;
        float: left;
        margin: 10px 10px 10px 0;
        border-style: solid;
        border-width: 2px;
      }

      #droppable {
        left: 0;
        width: 600px;
        height: 300px;
        padding: 0.5em;
        float: left;
        margin: 10px;
      }

    </style>

    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
    <script src="https://ajaxorg.github.io/ace-builds/src-noconflict/ace.js">
    </script>

    <script>


    </script>
    <script>
      $(function() {

        $("#draggable").draggable({
          revert: true
        });

        $("#droppable").droppable({

          activeClass: "ui-state-default",
          hoverClass: "ui-state-hover",
          accept: ":not(.ui-sortable-helper)",

          drop: function(event, ui) {
            $(this).find(".ui-widget-header").remove();
            $("<p>").append(ui.draggable.contents().clone()).appendTo(this);
          }


        });

        var editor = ace.edit("droppable");
        editor.setTheme("ace/theme/monokai");
        editor.getSession().setMode("ace/mode/python");
      });

    </script>


  </head>

  <body>

    <div id="droppable" class="ui-widget-header">
      <p> #Dragcodeblock </p>
    </div>

    <div id="draggable" class="ui-widget-content">
      <p> Hello World </p>
    </div>


  </body>

</html>


Solution

  • the code you show works, it just doesn't do anything visible since it adds text to a hidden dom node, if you want to change editor value, call editor.insert

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
      <title>Code Block Project</title>
    
    
      <style type="text/css" media="screen">
        #draggable,
        #draggable2 {
          width: 202;
          height: 30px;
          padding: 0.5em;
          float: left;
          margin: 10px 10px 10px 0;
          border-style: solid;
          border-width: 2px;
        }
        #droppable {
          left: 0;
          width: 600px;
          height: 300px;
          padding: 0.5em;
          float: left;
          margin: 10px;
        }
      </style>
    
      <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
      <script src="https://code.jquery.com/ui/1.12.0/jquery-ui.js"></script>
      <script src="https://ajaxorg.github.io/ace-builds/src-noconflict/ace.js">
      </script>
    </head>
    
    <body>
    
      <div id="droppable" class="ui-widget-header">
        &lt;p> #Dragcodeblock &lt;/p>
      </div>
    
      <div id="draggable" class="ui-widget-content">
        <p>Hello World</p>
      </div>
      <div id=draggable2 draggable=true>
        browser drag
      </div>
    </body>
    
    
    <script>
      $("#draggable").draggable({
        revert: true
      });
    
      $("#droppable").droppable({
    
        activeClass: "ui-state-default",
        hoverClass: "ui-state-hover",
        accept: ":not(.ui-sortable-helper)",
    
        drop: function(event, ui) {
          var pos = editor.renderer.screenToTextCoordinates(event.clientX, event.clientY)
          editor.session.insert(pos, ui.draggable.text())
          return true
        }
    
    
      });
    
      var editor = ace.edit("droppable");
      editor.setTheme("ace/theme/monokai");
      editor.getSession().setMode("ace/mode/python");
    
      document.getElementById("draggable2").addEventListener("dragstart", function(e) {
        e.dataTransfer.setData("text/plain", this.textContent)
      });
    </script>
    
    </html>

    You can also use html5 draggable attribute, in which case ace handles cursor automatically https://github.com/ajaxorg/ace/blob/master/lib/ace/mouse/dragdrop_handler.js