Brodey Broder Brodey Broder - 2 months ago 7
HTML Question

Sortable divs that slide over each other

I am trying to make a page with scrollable divs that slide away from each other when one of them is being clicked and dragged within a restricted box area. Another requirement is that it is angularized and that the divs only travel along the Y axis. Here is what I have so far, but for some reason the animation isn't working. Where am I going wrong?



app.controller('docMasterStepController', ['$scope', '$window', 'DocMasterSteps', 'DocMasterStepsUpdate', function ($scope, $window, DocMasterSteps, DocMasterStepsUpdate) {
var rowHeld = -1;
var lastShift;
var lastOff;
var turned = false;
var y = 0;
var backX = 0;
var backY = 0;
var emptySlot = -1;
var flip = 1;
var hideButtons = false;
var fresh = false;
var turnedAgain = 1;
var firstShift;
var dragged = 0;
var lastCheck;
var upDown;
var myPos;
var thisPos;
var timeout;
var s = $scope;
var matrix = [];

s.initialize = function(id)
{
DocMasterSteps.get({id: id}, function(resp){
s.doc = resp.doc;
s.dc = resp.dc;
s.steps = resp.steps;
s.hiddenButtons = [];
s.textbox = [];
for (var step in s.steps)
{
s.hiddenButtons[step] = true;
s.textbox[step] = s.steps[step].step_nomenclature;
}
s.$apply();
for (var step in s.steps)
s.renumber($('.draggable').get(step), false);
});
};

s.destroy = function(event, bool, index)
{
s.steps.splice(index, 1);
s.$apply();
s.targetRenumber(event, bool);
};

s.targetRenumber = function(event, bool)
{
s.renumber(event.target, bool);
};

s.setPosition = function(myPos)
{
matrix[myPos] = true
};

s.hideButtons = function(index)
{
s.hiddenButtons[index] = true;
};

s.showButtons = function(index)
{
s.hiddenButtons[index] = false;
};

s.moveCursor = function(event)
{
var target = event.target;
if (target.setSelectionRange)
{
target.setSelectionRange(9999, 9999)
}
target.value = target.value;
};

s.getFocus = function(down){
var downer = down.target;
var reminder = $(downer).attr('name');
$('div[name="' + reminder + '"]').get(0).previousElementSibling.focus();
};

s.getUp = function(up) {
var upper = up.target;
firstShift = $(upper).parent();
dragged = 0;
turnedAgain = 1;
fresh = false;
hideButtons = true;
rowHeld = $(upper).attr('name');
myPos = rowHeld;
emptySlot = rowHeld;
$(upper).css('z-index','75');
$($(upper).get(0).previousElementSibling).css('z-index','25');

backX = $(upper).css('left');
backY = $(upper).css('top');
};

s.getDown = function(down) {
var downer = down.target;
hideButtons = false;

var reminder = ~~$(downer).attr('name');
var lastReminder = ~~$($(lastOff).children()[1]).attr('name');

$(downer).css('z-index','50');
var myBox = $($(downer).get(0).previousElementSibling);
myBox.css('z-index','0');

$(".draggable").animate({
top: 0
}, { duration: 0, queue: false }, function() {
});

var holder = s.steps[reminder];
s.steps.splice(reminder, 1);
s.steps.splice(lastReminder, 0, holder);

holder = s.textbox[reminder];
s.textbox.splice(reminder, 1);
s.textbox.splice(lastReminder, 0, holder);

s.$apply();
for (var step in s.steps)
s.renumber($('.draggable').get(step), false);

$('div[name="' + lastReminder + '"]').get(0).previousElementSibling.focus();
};

s.renumber = function(dis, clear)
{
if(clear) {
$(dis).parent().css('display','none');
$(dis).parent().parent().parent().get(0).outerHTML+=$(dis).parent().parent().parent().get(0).outerHTML;
var j = 0;
}
for (var i = 0; i < $('.sNames').length; i++)
{
if (clear)
{
if((parseInt($(dis).parent().attr('class').split('s')[1])+1) == i)
{

$($('.textbox').get(i)).attr('value','');
$($('.fakeInput').get(i)).attr('name','i');
$($('.textbox').get(i)).attr('id','doc_step' + (0-i) + '_step_nomenclature');
$($('.textbox').get(i)).attr('name','doc_step[step_nomenclature][' + (0-i) + ']');
$($('.textbox').get(i)).focus();
}
}

$($('.sNames').get(i)).html('Step ' + (i + 1) + ':');
$($('.fakeInput').get(i)).attr('name',i);
$($('.textbox').get(i)).css('z-index',i);
$($('.fakeinput').get(i)).css('z-index',40+i);
$($($('.row').children().get(i)).children().get(2)).attr('class','buttons' + i);
}

matrix = [];
for (var i = 0; i < $('.sNames').length; i++)
{
matrix[i] = false;
}


$('.draggable').attr('class','draggable droppable');

$( ".draggable" ).draggable({
axis: "y",
refreshPositions: true
});

$(".draggable").animate({ top: 0 }, 0 );

$(".droppable").droppable({
tolerance: 'pointer',
greedy:true,
over: function(event, ui) {
thisPos = parseInt($($(event.target).children().get(1)).attr('name'));
//alert(thisPos);

dragged = ui.position.top;
if(!lastCheck)
{
upDown = ui.position.top > 0;
}
else {
upDown = dragged > lastCheck;
}
lastCheck = dragged;


//$(':animated').not($('.draggable').get(parseInt($($(lastShift).children().get(1)).attr('name')))).not(event.target).finish();
//$('.draggable').not().finish();


$window.clearTimeout(timeout);

//holdMe = $('[name=\"' + thisPos + '\"]').parent().html();
//timeout = setTimeout("$('[name=\"' + thisPos + '\"]').mouseup()", 3000);

;

lastShift = $(event.target);

if (!firstShift)
{
firstShift = lastShift;
}

if (lastShift && lastOff)
{
turned = lastShift.get(0) == lastOff.get(0);
}

fresh = true;

flip = upDown ? 1 : -1;
var child;

matrix[parseInt(thisPos)] = false;
if ((($(event.target).css('top') == '0px') || ($(event.target).css('top') == 'auto'))) {

if (parseInt(thisPos) > parseInt(myPos)) {

for (var i = thisPos; thisPos > parseInt(myPos); thisPos--)
{
$($($($('.row').get(thisPos)).children().get(0)).children().get(0)).animate({
top: -30
}, {duration: 300, queue: false}, function () {
});
}
} else if (parseInt(thisPos) < parseInt(myPos)) {
for (var i =thisPos; thisPos < parseInt(myPos); thisPos++)
{
$($($($('.row').get(thisPos)).children().get(0)).children().get(0)).animate({
top: 30
}, {duration: 300, queue: false}, function () {
});
}
}
else
{
$(event.target).animate({
top: 0
}, { duration: 300, queue: false }, function() {
});
}
}
else
{
$(event.target).animate({
top: 0
}, { duration: 300, queue: false }, function() {
});
}
},

out: function(event, ui) {
var higher;

lastOff = $(event.target);

var len = $('.draggable').length-2;

if (turned) // && (lastOff.get(0) != $('.draggable').get(1)) && (lastOff.get(0) != $('.draggable').get(len)))
{

$(event.target).animate({
top: 0
}, {duration: 300, queue: false}, function () {
});
}

}
});
}}]);

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form>
<h3>Title: <input class="titlebox" id="doc_master_nomenclature" name="doc_master[nomenclature]" value="<%= @doc.nomenclature %>" style="padding-left:4px;width:600px" /> </h3>
<div class="well" ng-controller="docMasterStepController" ng-init="initialize(<%= @id %>)">
<div class="contain" />
<div class="row" ng-repeat="step in steps" ng-hide="hiddenRows[$index]" ng-mouseover="setPosition($index)">
<div class="col-md-12" ng-mouseleave="hideButtons($index)" ng-mouseover="showButtons($index)">
<div class="draggable droppable" style="padding-left:42px,top:0px,left:0px;position:relative;width:650px;display:inline-block;">
<input class="textbox form-control required" id="doc_step{{step.id}}_step_nomenclature" name="doc_step[step_nomenclature][{{step.id}}]" ng-model="textbox[$index]" type="text" ng-focus="moveCursor($event)" style="padding-left:4px;z-index:0;width:600px;height:30px;position:relative;top:-2px;left:50px;" />
<div class="fakeInput" name="{{$index}}" ng-click="getFocus($event)" ng-mousedown="getUp($event)" ng-mouseup="getDown($event)" style="z-index:50;width:568px;height:30px;position:absolute;top:-2px;left:50px;"></div>
</div>
<div class="sNames" style="padding-left:6px;z-index:0;width:600px;height:30px;position:absolute;top:3px;left:0px;font-weight: 700" ng-bind="step.step_number + ': '"></div>
<div style="display:none" ng-hide="hiddenButtons[$index]">
<button class="btn btn-primary" style="margin-left: 10px;padding:3px 8px;" ng-click="targetRenumber($event, true)">
<a href="#added" style="color:white; font-size: small">Add Step After</a>
</button>
<button class="btn btn-danger" style="padding:3px 8px;" ng-click="destroy($event, false, $index)">
<a href="#removed" style="color:white; font-size: small">Remove Step</a>
</button>
<button class="btn btn-primary" style="padding:3px 8px;">Add Buys</button>
<button type="button" style="padding:3px 8px;" class="btn btn-primary" data-toggle="modal" data-target="#myModal">
Add Data Master
</button>
</div>
</div>
</div>
<h2 style="color:#31708f; visibility: hidden; margin-right: 420px; display:inline-block;" class="saved">
Saving...
</h2>
<input type="button" class="btn btn-warning" value="Cancel" style="margin-top:15px;" onclick="window.location.href = '../<%= @doc.id %>'" />
<input onclick="$('.saved').css('visibility','visible')" class="btn btn-primary" style="margin-top:15px;" id="commit" name="commit" type="submit" value="Save">
</div>
</form>




Answer

This is the wrong format. You are going to have to use directives:

app.directive('sortRows', ['$timeout', '$parse', function ($timeout, $parse) {
    return {
        link: function (scope, element, attrs) {
            var model = $parse(attrs.sortRows);
            scope.$watch(model, function (value) {
              // put sorting jquery in here
            }
        }
    };
}]);
Comments