Как вернуть положение перетаскиваемого пользовательского интерфейса JQuery в зависимости от условия - PullRequest
30 голосов
/ 22 июня 2010

У меня есть элемент, который можно перетаскивать, и элемент, который можно сбрасывать. Как только перетаскиваемый элемент помещен в зону сброса, я пытаюсь выполнить следующий код jquery psuedo:

if(draggedelement == value){

$(draggedelement).hide();

}
else{

$(draggedelement).revert();

}

, где функция revert() перемещает перетаскиваемый объект обратно в исходное положение.

Как можно это сделать?

P.S. Мне известна опция перетаскивания «Возврат», однако она активируется только в том случае, если перетаскиваемый элемент не попадает в зону сброса.

Ответы [ 5 ]

75 голосов
/ 22 июня 2010

Для этого есть несколько встроенных опций, на вашем .draggable() установите для опции revert значение 'invalid', и он вернется, если не был успешно сброшен на предмет, подобный этому:

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

Затем в вашем .droppable() установите допустимое значение для сброса с помощью опции accept , например:

$("#droppable").droppable({ accept: '#draggable' });​

Все, что не соответствует этому селектору, сбрасывается, когда вы отпускаете, вы можете увидеть полную демонстрацию здесь . Опция accept также принимает функцию, если вам не нужна фильтрация селектора, например:

$("#droppable").droppable({ 
  accept: function(dropElem) {
    //dropElem was the dropped element, return true or false to accept/refuse it
  }
});​
8 голосов
/ 02 марта 2015

У меня был сценарий использования, когда мне нужно было запустить некоторую логику в методе drop-drop, чтобы определить, следует ли перетаскиваемому объекту вернуться.Для этого я использовал следующее:

$('.draggable-elements').draggable({
  revert: function() {
    if ($(this).hasClass('drag-revert')) {
      $(this).removeClass('drag-revert');
      return true;
    }
  }
});

$('.droppable-elements').droppable({
  drop: function(event, ui) {
    if ( % conditional logic check here % ) {
      return $(ui.draggable).addClass('drag-revert');
    }
  }
});

Мой пример использования - это таблица, в которой каждая ячейка является опускаемой, представляющей 5-минутный период.Мои перетаскиваемые объекты - это бронирования, которые начинаются в одной ячейке, но охватывают несколько ячеек подряд, чтобы обозначить время бронирования.

Я не хотел, чтобы перетаскиваемые объекты перекрывались, так как это означало бы двойное бронирование.Итак, после удаления я нахожу все перетаскиваемые объекты в строке, исключая только что перемещенный, и проверяю их на совпадения.Если есть совпадение, моя условная логика возвращает true, и я возвращаю перетаскиваемый объект.

Следующий этап - запуск вызова ajax для обновления базы данных, если логика на стороне сервера говорит, что перемещение недопустимо, я надеюсь вернутьсясостояние ошибки и вернуть перетаскиваемый.

PS это мой первый ответ, извините, если я сделал что-то не так.Советы о том, как обеспечить хорошие ответы, с радостью принятые.

Редактировать: Попробовав мой вызов AJAX, я понял, что у функции droppable.drop есть окно, позволяющее сделать свое дело до запуска функции draggable.revert.К тому времени, когда мой вызов AJAX возвратил false, окно прошло, и класс был добавлен слишком поздно для draggable.revert, чтобы среагировать.

Таким образом, я больше не полагаюсь на функцию draggable.revert,вместо этого действует исключительно на ответ AJAX и, если он ложный, использует animate () для возврата перетаскиваемого объекта в исходное положение, как показано ниже:

$( '.draggable-elements' ).draggable();

$( '.droppable-elements' ).droppable({
  drop: function( event, ui ) {
    var postData = {
      id: 1,
      ...
    };
    $.post( '/ajax/url', postData, function( response ) {
      var response = $.parseJSON( response );
      if ( response.status != 1 ) {
        return ui.draggable.animate( {left: 0, top: 0}, 500 );
      }
    }
  }
});

Вам может потребоваться, чтобы draggable.start / drag добавлял исходное левое и верхнее значения перетаскиваемого объекта в качестве атрибутов данных, но для меня вышеописанное работало нормально.

4 голосов
/ 22 июня 2010

Попробуйте добавить этот код в событие «drop».Вот демо .

HTML

<div class="draggable ui-widget-content correct"><p>1</p></div>
<div class="draggable ui-widget-content"><p>2</p></div>
<div class="draggable ui-widget-content"><p>3</p></div>
<div class="draggable ui-widget-content"><p>4</p></div>
<br style="clear: both">
<div id="droppable" class="ui-widget-header">
  <p>Drop me here</p>
</div>

Сценарий

$(function() {

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

 $("#droppable").droppable({
  activeClass: 'ui-state-hover',
  hoverClass: 'ui-state-active',
  // uncomment the line below to only accept the .correct class..
  // Note: the "drop" function will not be called if not ".correct"
  //  accept : '.correct',
  drop: function(event, ui) {
   // alternative method:
   // if (ui.draggable.find('p').text() == "1") {
   if (ui.draggable.is('.correct')) {
    $(this).addClass('ui-state-highlight').find('p').html('You got it!');
    // cloning and appending prevents the revert animation from still occurring
    ui.draggable.clone(true).css('position', 'inherit').appendTo($(this));
    ui.draggable.remove();
   } else {
    $('#droppable > p').html('Not that one!')
    setTimeout(function(){ $('#droppable > p').html('Drop here'); }, 1000);
   }
  }
 });

});

Как вы можете видеть в сценарии, вы можете искать.correct класс или текст внутри (закомментированная строка)

1 голос
/ 24 декабря 2014
$("#droppable").droppable({ 
    accept: function(dropElem) {
        //dropElem was the dropped element, return true or false to accept/refuse it
        if($(this).data('stoneclass') == dropElem.attr("id")){
            return true;
    }
}
});​

Это использовалось для принятия только одного перетаскиваемого объекта из группы перетаскиваемых объектов; на одну правильную каплю, в группе капель.

П. Извините за язык, если он не понятен =)

0 голосов
/ 08 января 2016

Я обнаружил, что если я просто установлю top: 0 и left: 0, элемент больше не будет перетаскиваемым. Чтобы «заставить» вернуться, я должен был сделать это:

$draggedObj.css({ top: 0, left: 0 })
$draggedObj.draggable( "destroy" )
$draggedObj.draggable({...whatever my draggable options are...});
...