Jquery-ui: drag and drop inventory with stackable items

Hello to all,

I am creating a drop & drag inventory panel for my web game, but I have not been able to get it to work with stacked items. I've simplified my entire inventory to be less confusing.

FIrst off, let me explain how I can expect it to work:

  • Each element .item

    can be dropped to any free one .inv_slot

    .
  • If I try to remove an element .item

    on another .item

    that does not contain a class .stackable

    , it just activates the draggable function revert()

    .
  • if i try to delete an element .item

    on .item

    that has a class .stackable

    it will only delete the clone / helper. (Later on, I'll add a function that increases the size of the element stack.)

Now, what's wrong with the example below:

  • in case of an accidental fall .item

    on the border or between two slots, the .inv_slot

    return animation is not activated. However, it works, but doing so does the .item element out of bounds #panel

    .

  • Also if I accidentally dropped .item

    between two elements .inv_slot

    it will behave as if it .item

    was dropped onto an element .stackable

    . This way it will delete the clone instead of reverting prev to it. position. (Most likely a problem with the selector in the drop method :)

  • If I put an element down .stackable

    on top of another element .stackable

    , it doesn't update the cursor. It seems to be stuck in drag mode which activates the "pointer" cursor.

Now here's an example (partially working):

$(document).ready(function() {
	//var prev_el = '';
	var item_isStackable = "";
	
	$( ".item").draggable({
		scroll: true,
		revert: function(isValidEl)
		{
			if(isValidEl)
			{
				return false;
			}else{
				return true;
			}
		},
		helper: "clone",
		cursor: "pointer",
		stack: false,
		zIndex: 27,
		drag: function(event, ui)
		{
			item_isStackable = $(this).hasClass("stackable");
		},
	});
	$( ".inv_slot" ).droppable({
		accept: ".item",
		drop: function( event, ui ) { 
			var item = $(this).find(".item"); 
			if(item.length == 0) /// See if there any items already in the currently selected inventory slot  // 
			{
				console.log("Inserting");
				ui.draggable.detach().appendTo($(this)); // if none, insert the item into athe free slot /// 
			}
			else if(item_isStackable == true && item.hasClass("stackable")){
					console.log("Increasing "); 
					ui.draggable.detach(); /// If yes, just destroy the clone /// 
			}else{
				console.log("reverting back");
				// in case it not .inv_slot , revert the item back to it previous position //
				ui.draggable.animate(ui.draggable.data().origPosition,"slow"); 	
			}
		}
	});
});
      

#panel
{
	width: 340px;
	height: 44px;
	border: 1px solid #000;
	padding: 4px;
}

.inv_slot
{
	z-index: 22;
	position: relative;
	width: 40px;
	height: 40px;
	border: 1px solid red;
	float: left;
}

.inv_slot .slot_pos{
	z-index: 24;
	position: absolute; 
	margin-left: 50%; 
	left: -4px; top: 2px;
}

.item
{
	position: relative;
	z-index: 25;
	margin: 4px;
	width: 30px;
	height: 30px;
	border: 1px solid blue;
}

.item.stackable
{
	border: 1px solid green;
}
      

<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.js"></script>


<div id="panel">
		<div class="inv_slot">
			<div class="item stackable" ></div>
			<span class="slot_pos">0</span>
		</div>
		
		<div class="inv_slot">
			<div class="item"> </div>
			<span class="slot_pos">1</span>
		</div>
		
		<div class="inv_slot">
			<div class="item stackable"> </div>
			<span class="slot_pos">2</span>
		</div>
		
		<div class="inv_slot"><span class="slot_pos">3</span> </div>
		<div class="inv_slot"><span class="slot_pos">4</span> </div>
		<div class="inv_slot"><span class="slot_pos">5</span> </div>
		<div class="inv_slot"><span class="slot_pos">6</span> </div>
		<div class="inv_slot"><span class="slot_pos">7</span> </div>
</div>
      

Run code


I spent a couple of hours without any progress, so I would really appreciate it if someone could help me with this.

Thanks in advance, Alex.

+3


source to share


1 answer


What happens when you drag the box to the border next to it, it removes itself because it tries to put itself. You need to change the second part of the instruction if

:

else if(item_isStackable == true && item.hasClass("stackable") && ui.draggable.filter(function() { var d = this; return item.filter(function() { return d == this; }).length > 0; }).length === 0)

      

To fix the cursor pointer issue:



.item
{
    position: relative;
    z-index: 25;
    margin: 4px;
    width: 30px;
    height: 30px;
    border: 1px solid blue;
    cursor: default !important; /* Add this property. */
}

      

Fiddle.

+1


source







All Articles