Search code examples
javascriptjqueryjquery-uijquery-append

Jquery - appending after re-registering


On this script I have drag and drop fieldsets (left menu - top). Drag multiple fieldsets into the right "working area". In those fieldsets is an area for dropping Fields (of which I have one, left menu - bottom). Drop "Field One" into any of the dropped Fieldset (under the line in the "Drop Fields Here" area) in the working area.

I want to then move that Field One from the Fieldset I dropped it into and into the other Fieldset in the working area. I have got the Field One draggable but I cannot get it to append to the new Fieldset.

I am not wanting to delete the Field and replace it with another clone from the left menu. I am new to jquery so my code may be a bit messy. Any help is greatly appreciated. Jsfiddle and code below.

I believe the code issue is between line 21-29...but I am not sure.

JsFiddle Link

 $(document).ready(function() {
 var fs_count = 0;
$("#drop-area").droppable({
accept: '.ui-draggable:not(.draggableField , .activeField)',
drop: function(event, ui) {
    fs_count++;
  var clone = $(ui.draggable).clone()
  clone.addClass('.connectedSortable')
  // clone.removeClass('.ui-draggable');
  if (clone.hasClass('dropped')) {
        return false;
    }
    clone.addClass('.connectedSortable').addClass('dropped').attr('id', 'fs_' + fs_count);
  $(this).append(clone);
  var fs_class = clone.attr('class');
  alert('You added a field with class ' + fs_class);      
  var fieldsDroppable = $('#drop-area .ui-draggable:last-child .fieldDroppable');
  fieldsDroppable.droppable({
  accept: '.draggableField , .activeField',
      drop: function(event, ui) {          
          var clone = $(ui.draggable).clone();  
          if (clone.hasClass('draggableField')) {  // If else to prevent clones reproducing in Fieldsets when moving from original Fieldset.
          clone.removeClass('ui-draggable , draggableField').addClass('activeField');
          $(this).append(clone);
                    }
                        else {
          // Append the div here? 
          }             
          var cloneClass = clone.attr('class');  // Temporary varialble for develpoment alert below
          alert('you dropped a field' + cloneClass);  // Temporary for development only

                        // Below re-register the "field" with jquery....not sure this is entirely correct.
          var fieldsDraggable = $('#drop-area .ui-draggable .fieldDroppable .activeField');
                fieldsDraggable.draggable();              
      }});
}  });
$(".fieldDroppable").droppable({
accept: '.draggableField , .activeField',
drop: function(event, ui) {
  var clone = $(ui.draggable).clone()
  $(this).append(clone);
}
  });
$(".ui-draggable").draggable({
opacity: 1.0,
helper: 'clone',
revert: 'invalid'
});
$(".draggableField").draggable({
opacity: 1.0,
helper: 'clone',
revert: 'false'
});  
$(".activeField").draggable();
$("#drop-area").sortable({ 
handle: '.drag-handle',
update: function () { //triggered when sorting stopped
var dataAuto = $("#drop-area").sortable("serialize", {
        key: "za",
        attribute: "id",
    });
        alert(dataAuto);  
}
});
$("#drop-area").disableSelection();
});

Solution

  • There will be a lot of work to do here, yet you can get over this hurdle like so:

    https://jsfiddle.net/Twisty/6trmrfoo/32/

    Basically, you want to assign a new .droppable() to a specific element in the field set when it is added to the #drop-area. I would advise using a function as you will do this a multitude of times.

    You can also make use of .data() to store a source value along with the draggable elements. I only did this for fields since that was the only pace it seemed like it was needed. You can updated this once it's dropped into a fieldset so that future drag-n-drop operations can be handled properly, we don't want to clone the object we move it.

    To move it, consider using .detach(). It'll detach the element from the current parent and can be used in chain to append or move into memory as a variable. Similar to .clone() just we're manipulating the actual object. .clone() is to "Copy & Paste" as .detach() is to "Cut & Paste".

    JavaScript

     $(function() {
       var fs_count = 0;
    
       function makeFieldTarget($fs) {
         $fs.droppable({
           accept: '.draggableField, .activeField',
           drop: function(event, ui) {
             var clone, cloneClass;
             if (ui.draggable.data("source") == "sidebar") {
               clone = $(ui.draggable).clone();
               clone.removeClass('draggableField').addClass('activeField');
               $(this).append(clone);
               cloneClass = clone.attr('class');
               console.log('DROPFIELD - you dropped a field from the side bar: ' + cloneClass);
               clone.data("source", "fieldset").draggable({
                 zIndex: 1000
               });
             }
             if (ui.draggable.data("source") == "fieldset") {
               clone = ui.draggable;
               clone.detach().attr("style", "").appendTo($(this));
               cloneClass = clone.attr('class');
               console.log('DROPFIELD - you dropped a field from a Field set: ' + cloneClass);
             }
           }
         });
       }
    
    
       $("#drop-area").droppable({
         accept: '.ui-draggable:not(.draggableField, .activeField)',
         drop: function(event, ui) {
           fs_count++;
           var clone = $(ui.draggable).clone()
           clone.addClass('connectedSortable');
           if (clone.hasClass('dropped')) {
             return false;
           }
           clone.addClass('connectedSortable dropped').attr('id', 'fs_' + fs_count);
           $(this).append(clone);
           var fs_class = clone.attr('class');
           console.log('DROPAREA - You added a field with class ' + fs_class);
           makeFieldTarget(clone.find(".fieldDroppable"));
           $("#drop-area").sortable("refresh");
         }
       });
    
       $(".ui-draggable").draggable({
         opacity: 1.0,
         helper: 'clone',
         revert: 'invalid'
       });
    
       $(".draggableField").data("source", "sidebar").draggable({
         opacity: 1.0,
         helper: 'clone',
         revert: 'false',
         zIndex: 1000
       });
    
       $("#drop-area").sortable({
         handle: '.drag-handle',
         placeholder: "drop-place-holder",
         items: ">div.dropped",
         update: function() { //triggered when sorting stopped
           var dataAuto = $("#drop-area").sortable("serialize", {
             key: "za",
             attribute: "id",
           });
           alert(dataAuto);
         }
       });
    
       $("#drop-area").disableSelection();
    
     });