How to rearrange divs (moveup / movedown)

0

I need to insert text blocks and then have the freedom to reorder them.

In the first few inserts it works, then the divs begin to get lost and the first one jumps to the last one, for example, when in fact it should just descend a div.

You can copy the code in the editor that it will already work.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Moveup / Movedown</title>

<style type="text/css">
div {float:left; width:100%; max-width:900px}   
#ConteudoMateria {float:left; width:100%; max-width:900px}  
.DivPadrao {float:left; width:100%; font-family:arial; helvetica; font-size:14px; line-height:20px; margin-top:30px}    
textarea {width:100%; height:90px; font-family:arial, helvetica; font-size:14px; color:#333; padding:10px; box-sizing: border-box}
input[type="button"] {background-color:#333; font-size:13px; color:#fff; border:0px; height:30px; width:200px}
</style>

<script type="text/javascript" src="http://code.jquery.com/jquery-3.1.1.min.js"></script><scripttype="text/javascript">
function MoverBlocoConteudo(){
var selected=0;
var itemlist = $('#ConteudoMateria');
var len=$(itemlist).children().length; 

$(".MoveUp").click(function(e){
    e.preventDefault();
    selected = $(this).parents('.DivPadrao').index();

    if(selected>0) {
        jQuery($(itemlist).children().eq(selected-1)).before(jQuery($(itemlist).children().eq(selected)));
        selected=selected-1;
    }
});

 $(".MoveDown").click(function(e){
    e.preventDefault();
    selected = $(this).parents('.DivPadrao').index();

    if(selected < len) {
        jQuery($(itemlist).children().eq(selected+1)).after(jQuery($(itemlist).children().eq(selected)));
        selected=selected+1;
    }
});

}


function AddConteudo(){
var texto = $('#texto').val();
$('#texto').val('');
$('#ConteudoMateria').append('<div class="DivPadrao">'+ texto +'<br><a href="#" class="MoveUp">Mover p/ cima</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href="#" class="MoveDown">Mover p/ baixo</a></div>');
MoverBlocoConteudo();
}


$(document).ready(function(){
MoverBlocoConteudo();
});
</script>

</head>

<body>


<div><textarea id="texto"></textarea><br><br><input type="button" value="Adicionar texto" onclick="AddConteudo()" /></div>
<div id="ConteudoMateria"></div>


</body>
</html>
    
asked by anonymous 23.01.2017 / 19:42

1 answer

1

The first problem you have in your code is that you are re-adding the on-click event of all "moveUp" and "moveDown" each time you add anything; This causes each time you click on one of the buttons - this will trigger N times.

To solve this problem, you can use the event delegation : Instead of adding the on-click to each new creation of the up / down buttons does it at startup.

Both methods do the same, you can also pass these to a separate function that takes some arguments - namely the element index and whether to go up or down:

$(document).ready(function() {
  $("#ConteudoMateria").on('click', '.MoveUp, .MoveDown', function(e) {
    e.preventDefault();
    var index = $(this).parents('.DivPadrao').index();
    var isMoveUp = $(this).hasClass('MoveUp');
    MoverBlocoConteudo(index, isMoveUp)
  });
});

After that, we rewrote the MoverBlocoConteudo method to reflect our changes:

function MoverBlocoConteudo(index, moveUp) {
  var itemlist = $('#ConteudoMateria');
  var len = $(itemlist).children().length;

  var thisElement = jQuery($(itemlist).children().eq(index));
  var nextPosition = (moveUp) ? index - 1 : index + 1;

  if (moveUp) {
    jQuery($(itemlist).children().eq(nextPosition)).before(thisElement);
  } else if (!moveUp) {
    jQuery($(itemlist).children().eq(nextPosition)).after(thisElement);
  }
}

The method was changed to avoid repetition and improve the condition: Moves up when argument moveUp is true and goes down when moveUp is false. This argument comes from the existence (or lack) of class .MoveUp in the element clicked.

In the AdicionarConteudo method, the call to MoverBlocoConteudo is removed and done.

example in JSFiddle

    
24.01.2017 / 04:41