Yousef Salama
Yousef Salama

Reputation: 55

Drag and drop multiple selected cards || JQuery ui

I have 2 columns every column has 3 cards and every card has a checkbox.
my code run as drag and drop every card alone but i want to drag and drop multiple selected/checked cards in one movement and uncheck checkboxes when cards drop.
see live example or snippet to live preview.

$("#card-list").droppable({
  accept: $(".card").draggable({
      revert: true,
      opacity: .5
    }),
  drop: function( event, ui ){          
    var dropped = ui.draggable;
    $(this).append(dropped.clone().removeAttr('style'));
    dropped.remove();
  }
});
.card{
  width:80px;
  height:80px;
  color:#fff;
}
.right-list{
  background-color: #B91646 !important;
}
.left-list{
  background-color: #1F1D36 !important;
}
.form-check-input{
  position:absolute;
  top:0 !important;
  right:0 !important;
  left:0 !important;
  bottom:0 !important;
  margin:auto !important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
  <div class="col-6 d-flex flex-column align-items-center">
    <div class="card left-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
      
    </div>
    <div class="card left-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card left-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
  </div>
  <div class="col-6" id="card-list">
    <div class="card right-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card right-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card right-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

Upvotes: 0

Views: 793

Answers (1)

Twisty
Twisty

Reputation: 30903

Consider the following.

$(function() {
  function moveChecked(source, target) {
    var items = $(".card", source).filter(function(index) {
      return $("input", this).is(":checked");
    });
    items.css({
      top: "",
      left: ""
    }).appendTo(target);
    $("input", items).prop("checked", false);
  }
  
  $(".card").draggable({
    revert: "invalid",
    opacity: .5
  });

  $("#card-list").droppable({
    accept: ".card",
    drop: function(event, ui) {
      moveChecked($(".row > .d-flex"), this);

    }
  });
});
.card {
  width: 80px;
  height: 80px;
  color: #fff;
}

.right-list {
  background-color: #B91646 !important;
}

.left-list {
  background-color: #1F1D36 !important;
}

.form-check-input {
  position: absolute;
  top: 0 !important;
  right: 0 !important;
  left: 0 !important;
  bottom: 0 !important;
  margin: auto !important;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet" />
<div class="row">
  <div class="col-6 d-flex flex-column align-items-center">
    <div class="card left-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card left-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card left-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
  </div>
  <div class="col-6" id="card-list">
    <div class="card right-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card right-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card right-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

First, you cannot use accept in the way you attempted. Draggable should be initialized on it's own.

I created a function yet you can do all this in the drop call back if you like. The function basically knows to look for Checked items and move those from the Source to the Target. It then removes any Drag styling and unchecks the items.

If you like, you can use helper to build an item that reflects all the checked items.

See more: https://api.jqueryui.com/draggable/#option-helper

Update

$(function() {
  function hideChecked(target) {
    var items = $(".card", target).filter(function(index) {
      return $("input.form-check-input", this).is(":checked");
    });
    items.fadeOut("fast");
  }

  function moveChecked(source, target) {
    var items = $(".card", source).filter(function(index) {
      return $("input", this).is(":checked");
    });
    items.css({
      top: "",
      left: ""
    }).appendTo(target);
    $("input", items).prop("checked", false);
    items.show();
  }

  function makeHelper(event) {
    var helper = $("<div>", {
      class: "helper"
    });
    var count = $("#check-list input:checked").length;
    for (var i = 0; i < count; i++) {
      var offsetPos = "left+" + (i * 10) + " top+" + (i * 10);
      $("<div>", {
        class: "card left-list"
      }).html("&nbsp;").appendTo(helper).position({
        my: offsetPos,
        at: "left top",
        of: helper
      });
    }
    $(".card:last", helper).append("<input class='form-check-input' type='checkbox' checked />");
    return helper.get(0);
  }

  $("#check-list .card").draggable({
    appendTo: ".row",
    revert: function(dragObj) {
      if (dragObj === false) {
        $("#check-list .card").show();
        return true;
      } else {
        return false;
      }
    },
    opacity: .5,
    helper: makeHelper,
    start: function(event, ui) {
      hideChecked($("#check-list"));
    }
  });

  $("#card-list").droppable({
    accept: ".card",
    drop: function(event, ui) {
      moveChecked($(".row > .d-flex"), this);
    }
  });
});
.card {
  width: 80px;
  height: 80px;
  color: #fff;
}

.right-list {
  background-color: #B91646 !important;
}

.left-list {
  background-color: #1F1D36 !important;
}

.form-check-input {
  position: absolute;
  top: 0 !important;
  right: 0 !important;
  left: 0 !important;
  bottom: 0 !important;
  margin: auto !important;
}

.helper {
  position: relative;
}

.helper .card {
  position: absolute;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.0.2/css/bootstrap.min.css" rel="stylesheet" />
<div class="row">
  <div class="col-6 d-flex flex-column align-items-center" id="check-list">
    <div class="card left-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card left-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card left-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
  </div>
  <div class="col-6" id="card-list">
    <div class="card right-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card right-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
    <div class="card right-list mb-3">
      <input class="form-check-input" type="checkbox" value="" aria-label="...">
    </div>
  </div>
</div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap/5.1.3/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>

Reference: jQuery ui.draggable event/status on revert

Upvotes: 0

Related Questions