MartynW
MartynW

Reputation: 709

Preventing element moving too far up DOM in jquery

I am trying to write a form where a user can move items up and down to reorder the inputs. The items come from a symfony collection which too much to show here but the basic idea is shown below.

I took the js from Move containing elements up and down with jquery. It moves them up and down but ideally I would like to:

  1. Prevent the top item from moving further beyond the top or bottom text.
  2. Hide the up arrow for the topmost item and the down arrow for the bottom item (I guess doing this would actually solve 1?).

I'm fairly new to js and can't quite figure the solution.

Thanks in advance for any help - please let me know if I can make things clearer. I have a working jsfiddle here jsfiddle

$('.js-up').click(function() {
  $(this).parents('div.js-item').insertBefore($(this).parents('div.js-item').prev());
});

$('.js-down').click(function() {
  $(this).parents('div.js-item').insertAfter($(this).parents('div.js-item').next());
});
<link href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="top">
  Can't go above here
</div>
<div class="js-item form-row">
  1. Moveable text
  <div class="col-sm-1">
    <a href="#" class="js-up btn btn-primary float-right" title="up"><i class="fas fa-arrow-up"></i></a>
  </div>
  <div class="col-sm-1">
    <a href="#" class="js-down btn btn-primary float-right" title="down"><i class="fas fa-arrow-down"></i></a>
  </div>
</div>
<div class="js-item form-row">
  2. Moveable text
  <div class="col-sm-1">
    <a href="#" class="js-up btn btn-primary float-right" title="up"><i class="fas fa-arrow-up"></i></a>
  </div>
  <div class="col-sm-1">
    <a href="#" class="js-down btn btn-primary float-right" title="down"><i class="fas fa-arrow-down"></i></a>
  </div>
</div>
<div class="js-item form-row">
  3. Moveable text
  <div class="col-sm-1">
    <a href="#" class="js-up btn btn-primary float-right" title="up"><i class="fas fa-arrow-up"></i></a>
  </div>
  <div class="col-sm-1">
    <a href="#" class="js-down btn btn-primary float-right" title="down"><i class="fas fa-arrow-down"></i></a>
  </div>
</div>

<div class="bottom">
  Can't go below here
</div>

Upvotes: 0

Views: 32

Answers (1)

Taplar
Taplar

Reputation: 24965

Just add the parent selector to prev() and next(). If the prev/next element does not match that selector, nothing moves.

function itemMoved () {
  $('.first-item, .last-item').removeClass('first-item last-item');
  $('div.js-item')
    .first().addClass('first-item').end()
    .last().addClass('last-item');
}

$('.js-up').click(function() {
  $(this).parents('div.js-item').insertBefore($(this).parents('div.js-item').prev('div.js-item'));
  itemMoved();
});

$('.js-down').click(function() {
  $(this).parents('div.js-item').insertAfter($(this).parents('div.js-item').next('div.js-item'));
  itemMoved();
});

itemMoved();
.first-item .fa-arrow-up, .last-item .fa-arrow-down {
  display: none;
}
<link href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="top">
  Can't go above here
</div>
<div class="js-item form-row">
  1. Moveable text
  <div class="col-sm-1">
    <a href="#" class="js-up btn btn-primary float-right" title="up"><i class="fas fa-arrow-up"></i></a>
  </div>
  <div class="col-sm-1">
    <a href="#" class="js-down btn btn-primary float-right" title="down"><i class="fas fa-arrow-down"></i></a>
  </div>
</div>
<div class="js-item form-row">
  2. Moveable text
  <div class="col-sm-1">
    <a href="#" class="js-up btn btn-primary float-right" title="up"><i class="fas fa-arrow-up"></i></a>
  </div>
  <div class="col-sm-1">
    <a href="#" class="js-down btn btn-primary float-right" title="down"><i class="fas fa-arrow-down"></i></a>
  </div>
</div>
<div class="js-item form-row">
  3. Moveable text
  <div class="col-sm-1">
    <a href="#" class="js-up btn btn-primary float-right" title="up"><i class="fas fa-arrow-up"></i></a>
  </div>
  <div class="col-sm-1">
    <a href="#" class="js-down btn btn-primary float-right" title="down"><i class="fas fa-arrow-down"></i></a>
  </div>
</div>

<div class="bottom">
  Can't go below here
</div>

Upvotes: 2

Related Questions