FAndrew FAndrew - 6 months ago 24
jQuery Question

Jqueryui multiple select d&d containment

Hy all, I implemented Jqueryui drag and drop and Jqueryui selectable, and I can move 2 objects if I select both of it. My problem is when I am doing this, the containment parent works just on clicked element and the other selected element can move out from parent. Here is my Draggable and Selectable imlementation:

Draggable: {
init: function(el, options) {

if (options == undefined) {
options = {
containment: "parent"
};
}
$(el).draggable(options, {
scroll: false,
snap: '.gridlines',
snapTolerance: $('.grid').attr('data-size') / 2,
revert: "invalid",

drag: function(event, ui) {
selectedComponent = $(this);
},
start: function(event, ui) {
if ($(this).hasClass("ui-selected")){
selected = $(".ui-selected").each(function() {
var el = $(this);
el.data("offset", el.offset());
});
}
else {
selected = $([]);
$(".playground").find('.existing-component').removeClass("ui-selected");
}

offset = $(this).offset();
},
stop: function(event, ui) {
$('.gridlines').removeClass('highlighted');
$('.obstacles').remove();

if (!$(this).hasClass('ui-selected')) $(this).addClass('ui-selected')
}

});
},
update: function(el, optionName, optionValue) {


$(el).resizable( "option", optionName, optionValue );
}
},
Selectable: {
init: function(el) {
$(el).selectable({
filter: '.existing-component',
selecting: function (event, ui) {
$(event.target).children('.ui-selecting').find('.existing-component').removeClass('ui-selecting');
},
stop: function(event, ui) {
var selectedItems = $('.ui-selected', this);
if (selectedItems.length >= 2) {
$('.ui-selected').addClass('ui-selecting-multiple');
}
},
selected: function(event, ui) {
selectedComponent = $(ui.selected);
}
});

$(el).find('.existing-component').click( function(e){
if (!e.shiftKey) {
$(el).find('.existing-component').removeClass("ui-selected ui-selecting-multiple");
$(el).find('.existing-component').attr('style', function(i, style)
{
return style.replace('z-index: 999', '');
});
$(this).addClass("ui-selecting");
} else {
if ($(this).hasClass("ui-selected")) {
$(this).removeClass("ui-selected ui-selecting-multiple");
}
else {
$(this).addClass("ui-selecting");

}
}

$(el).data("ui-selectable")._mouseStop();

e.stopPropagation();
});
}
}


How could I apply containment:parent to all selected component?

Answer

I didn`t find any solution for my problem because of it I implement my own solution, on multiselect I calculate the elements mostly on left,top,bottom,right (multipleMinL,multipleMinT,multipleMaxB,multipleMaxR) and I reinitialize each multiselected component with calculated values:

$('.ui-selecting-multiple').each(function() {
    left = (multipleMinL.offset().left - multipleMinL.position().left) + $(this).offset().left - multipleMinL.offset().left;
    top =  (multipleMinT.offset().top - multipleMinT.position().top) + $(this).offset().top - multipleMinT.offset().top;
    width = $(this).offset().left + ($(this).parent().outerWidth() - multipleMaxR.position().left - multipleMaxR.outerWidth());
    height = $(this).offset().top + ($(this).parent().outerHeight() - multipleMaxB.position().top - multipleMaxB.outerHeight());
    Draggable.init($(this), {containment: [left,top,width,height]});
});

and on other action before ui-selecting-multiple class is removed I reinitialize each component with

Draggable.init('.ui-selecting-multiple', containment:'parent');

This works for me, if someone got a better solution please post it.

Comments