Raviteja
Raviteja

Reputation: 3479

Glitch while animating the dynamically added elements

Glitch is seen when we add step and heading dynamically and try to swap their postion using up and down arrow for moving up and down respectively.

Html:

<div class="makeit_steps"></div>
<div class="row margin-top">
    <div class="col-md-12">
        <div class="col-md-2">
            <span class="glyphicon glyphicon-plus-sign"></span>
            <span id="add-step" class="add-new">Add Step</span>
        </div>
        <div class="col-md-2">
            <span class="glyphicon glyphicon-plus-sign"></span>
            <span id="add-heading" class="add-new">Add Heading</span>
        </div>
    </div>
</div>

JavaScript:

Adding step dynamically:

$('#add-step').click(function () {
$('.makeit_steps').append('<div class="row moving"><div class="col-md-12"><span class="steps">Step</span><span><textarea class="form-control" rows="3" cols="105"></textarea></span><span class="glyphicon glyphicon-circle-arrow-up"></span><span class="glyphicon glyphicon-circle-arrow-down"></span><span class="step_remove">X</span></div></div>');
$('.step_remove').click(function () {
    $(this).closest('.moving').remove();
});
$(".glyphicon-circle-arrow-up").click(function () {
    var $current = $(this).closest('.moving')
    var $previous = $current.prev('.moving');
    distance = $current.outerHeight();
    if ($previous.length !== 0) {

        $.when($current.animate({
            top: -distance
        }, 600),
        $previous.animate({
            top: distance
        }, 600)).done(function () {
            $previous.css('top', '0px');
            $current.css('top', '0px');
            $current.insertBefore($previous);
        });
    }
    return false;
});

$(".glyphicon-circle-arrow-down").click(function () {
    var $current = $(this).closest('.moving')
    var $next = $current.next('.moving');
    distance = $current.outerHeight();
    if ($next.length !== 0) {
        $.when($current.animate({
          top: distance
}, 600),
$next.animate({
    top: -distance
}, 600)).done(function () {
    $next.css('top', '0');
    $current.css('top', '0');
            $current.insertAfter($next);
            animating = false;
        });
    }
    return false;
});
});

Adding heading dynamically:

$('#add-heading').click(function () {
$('.makeit_steps').append('<div class="row moving"><div class="col-md-12"><span class="step_heading">Heading</span><span><input type="text" ></input></span><span class="glyphicon glyphicon-circle-arrow-up"></span><span class="glyphicon glyphicon-circle-arrow-down"></span><span class="step_remove">X</span></div></div>')
$('.step_remove').click(function () {
    $(this).closest('.row').remove();
});
var animating = false;
$(".glyphicon-circle-arrow-up").click(function () {
    if (animating) {
        return;
    }
    var $current = $(this).closest('.moving')
    var $previous = $current.prev('.moving');
    distance = $current.outerHeight(true);
    if ($previous.length !== 0) {

        animating = true;
        $.when($current.animate({
            top: -distance
        }, 600),
        $previous.animate({
            top: distance
        }, 600)).done(function () {
            $previous.css('top', '0px');
            $current.css('top', '0px');
            $current.insertBefore($previous);
            animating = false;
        });
    }

});
$(".glyphicon-circle-arrow-down").click(function () {
    if (animating) {
        return;
    }
    var $current = $(this).closest('.moving')
    var $next = $current.next('.moving');
    distance = $current.outerHeight();
    if ($next.length !== 0) {

        animating = true;
        $.when($current.animate({
            top: distance
}, 600),
$next.animate({
    top: -distance
}, 600)).done(function () {
    $next.css('top', '0');
    $current.css('top', '0');
            $current.insertAfter($next);
            animating = false;
        });
    }
});
});

CSS

.margin-top {
    margin-top:20px;
}
.glyphicon.glyphicon-circle-arrow-up, .glyphicon.glyphicon-circle-arrow-down {
    font-size:30px;
    margin-left:25px;
    cursor:pointer;
}
.add-new {
    color:#007acc;
    cursor:pointer;
}
.steps {
    font-size:16px;
    padding-left:30px;
    padding-right:20px;
}
.step_remove {
    font-size:16px;
    color:#007acc;
    margin-left:15px;
    cursor:pointer;
}
.step_heading {
    padding-left:15px;
    font-size:16px;
    padding-right:10px;
}
.makeit_steps {
    position: relative;
}
.makeit_steps .moving {
    position:relative;
}
.moving span {
    display:inline-block;
    vertical-align: middle;
}

Fiddle:Here

Upvotes: 0

Views: 64

Answers (1)

nshah143
nshah143

Reputation: 559

The problem with your code currently is that it is binding the click event multiple times on the up and down arrows (existing ones) whenever you create dynamically a new one.

In order to attach the click event only on the newly appended element you should make an object of the new element to be added and then you can use it further

var el = $('<div class="row moving"><div class="col-md-12"><span class="steps">Step</span><span><textarea class="form-control" rows="3" cols="105"></textarea></span><span class="glyphicon glyphicon-circle-arrow-up"></span><span class="glyphicon glyphicon-circle-arrow-down"></span><span class="step_remove">X</span></div></div>');
$('.makeit_steps').append(el);

After appending the new element the need is to assign the click event on up and down arrows for that , you should do this way

For Up arrow

$('.glyphicon glyphicon-circle-arrow-up',el).on('click',function(){

For down arrow

$('.glyphicon-circle-arrow-down',el).on('click',function(){

you can see the e1 object used when applying the click event. The above lines will search for the up and down arrows only within the new element appended and will assign the event.

The working demo is here - http://jsfiddle.net/m86p420h/7/

Upvotes: 1

Related Questions