How to implement auto scroll vertically on Jquery Sortable Plugin?

712 Views Asked by At

I'm using Jquery-Sortable plugin as in here to build my menu project drap & drop just wordpress menubuilder.

Container height containing all menu items is fixed so that as the number of menu items exceed the container height, it is hard to drag the top item one to the bottom of container.

$(function() {
  $("ol.default").sortable({
    group: 'item'
  });
})
body.dragging,
body.dragging * {
  cursor: move !important;
}

.overflow {
  height: 200px;
  overflow-x: hidden;
  overflow-y: auto;
  margin-top: 20px;
}

.dragged {
  position: absolute;
  top: 0;
  opacity: 0.5;
  z-index: 2000;
}


/* line 10, jquery-sortable.css.sass */

ol.vertical {
  margin: 0 0 9px 0;
}


/* line 12, jquery-sortable.css.sass */

ol.vertical li {
  display: block;
  margin: 5px;
  padding: 5px;
  border: 1px solid #cccccc;
  color: #0088cc;
  background: #eeeeee;
}

ol.vertical li.placeholder {
  position: relative;
  margin: 0;
  padding: 0;
  border: none;
}

ol.vertical li.placeholder:before {
  position: absolute;
  content: "";
  width: 0;
  height: 0;
  margin-top: -5px;
  left: -5px;
  top: -4px;
  border: 5px solid transparent;
  border-left-color: red;
  border-right: none;
}

ol {
  list-style-type: none;
}

ol i.icon-move {
  cursor: pointer;
}

ol li.highlight {
  background: #333333;
  color: #999999;
}

ol li.highlight i.icon-move {
  background-image: url("../img/glyphicons-halflings-white.png");
}

ol.nested_with_switch,
ol.nested_with_switch ol {
  border: 1px solid #eeeeee;
}

ol.nested_with_switch.active,
ol.nested_with_switch ol.active {
  border: 1px solid #333333;
}

ol.nested_with_switch li,
ol.simple_with_animation li,
ol.default li {
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<script src="https://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js"></script>


<div class="overflow">
  <ol class="default vertical">
    <li>elem1</li>
    <li>elem2</li>
    <li>elem3</li>
    <li>elem4</li>
    <li>elem5</li>
    <li>elem6</li>
    <li>elem7</li>
    <li>elem8</li>
    <li>elem9</li>
    <li>elem10</li>
  </ol>
</div>

<div class="overflow">
  <ol class="default vertical">
    <li>elem1</li>
    <li>elem2</li>
    <li>elem3</li>
    <li>elem4</li>
    <li>elem5</li>
    <li>elem6</li>
    <li>elem7</li>
    <li>elem8</li>
    <li>elem9</li>
    <li>elem10</li>
  </ol>
</div>

I tried to search around for auto scroll solution but seem there was not much mentioned about this issue, while plugin github mentioned this issue but seemed it did not work for my case.

How could I fixed this? Please kindly help. Thanks

2

There are 2 best solutions below

2
Niladri On

style.css

body.dragging,
            body.dragging * {
              cursor: move !important;
            }

            .overflow {
              height: 200px;
              overflow-x: hidden;
              overflow-y: auto;
              margin-top: 20px;
            }

            .dragged {
              position: absolute;
              top: 0;
              opacity: 0.5;
              z-index: 2000;
            }


            /* line 10, jquery-sortable.css.sass */

            ol.vertical {
              margin: 0 0 9px 0;
            }


            /* line 12, jquery-sortable.css.sass */

            ol.vertical li {
              display: block;
              margin: 5px;
              padding: 5px;
              border: 1px solid #cccccc;
              color: #0088cc;
              background: #eeeeee;
            }

            ol.vertical li.placeholder {
              position: relative;
              margin: 0;
              padding: 0;
              border: none;
            }

            ol.vertical li.placeholder:before {
              position: absolute;
              content: "";
              width: 0;
              height: 0;
              margin-top: -5px;
              left: -5px;
              top: -4px;
              border: 5px solid transparent;
              border-left-color: red;
              border-right: none;
            }

            ol {
              list-style-type: none;
            }

            ol i.icon-move {
              cursor: pointer;
            }

            ol li.highlight {
              background: #333333;
              color: #999999;
            }

            ol li.highlight i.icon-move {
              background-image: url("../img/glyphicons-halflings-white.png");
            }

            ol.nested_with_switch,
            ol.nested_with_switch ol {
              border: 1px solid #eeeeee;
            }

            ol.nested_with_switch.active,
            ol.nested_with_switch ol.active {
              border: 1px solid #333333;
            }

            ol.nested_with_switch li,
            ol.simple_with_animation li,
            ol.default li {
              cursor: pointer;
            }

index.html

<!doctype html>
<html>
    <head>
        <title>Vertical Scroll in jquery vertical short</title>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
        <script src="https://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js"></script>
        <link rel="stylesheet" href="style.css"/>
        <script>
            (function(){
                $(function(){
                   $(function() {
                       window.posY = 0;
                       window.posX = 0;
                       window.dragStart = false;
                       window.dragCon_el = null;
                       window.dragCon_left = 0;
                       window.dragCon_top = 0;
                      $("ol.default").sortable({
                          pullPlaceholder: false,
                          vertical: true,
                          group: 'item',
                          onDrag: function($item, position, _super, event) {
                              if (window.dragStart && position.top >= window.dragCon_el.get(0).scrollTop + window.dragCon_el.height() + window.dragCon_top) {
                                      window.dragCon_el.get(0).scrollTo(
                                          window.dragCon_el.get(0).scrollLeft + ((position.left - posX) - (window.dragCon_left * 2)),
                                          window.dragCon_el.get(0).scrollTop + ((position.top - posY) - (window.dragCon_top * 2))
                                      );
                                   window.posX = event.pageX;
                                   window.posY = event.pageY;
                               }
                          },
                          onDragStart: function($item, container, _super, event) {
                              let $container = $item.closest('.overflow');
                              window.dragStart = true;
                              window.posY = event.pageY;
                              window.posX = event.pageX;
                              window.dragCon_el = $container;
                              window.dragCon_top = $container.offset().top;
                              window.dragCon_left = $container.offset().left;
                          },
                          onDrop: function($item, container, _super, event) {
                              window.dragStart = false;
                          }
                      });
                    }); 
                });
            })(jQuery)
        </script>
    </head>
    <body>
        <div class="overflow">
          <ol class="default vertical">
            <li>elem1</li>
            <li>elem2</li>
            <li>elem3</li>
            <li>elem4</li>
            <li>elem5</li>
            <li>elem6</li>
            <li>elem7</li>
            <li>elem8</li>
            <li>elem9</li>
            <li>elem10</li>
          </ol>
        </div>

        <div class="overflow">
          <ol class="default vertical">
            <li>elem1</li>
            <li>elem2</li>
            <li>elem3</li>
            <li>elem4</li>
            <li>elem5</li>
            <li>elem6</li>
            <li>elem7</li>
            <li>elem8</li>
            <li>elem9</li>
            <li>elem10</li>
          </ol>
        </div>
    </body>
</html>
6
Shridhar Sharma On

You need to use correct version of jQuery UI, try the snippet below

$("ol.default").sortable({
  onDrag: (item, position, sup, event) => {
    const container = $(item).parents('.overflow');
    const containerTop = container.offset().top;
    const containerBottom = containerTop + container.height();

    if (event.pageY > containerBottom) {
      container.scrollTop(container.scrollTop() + 10);
    } else if (event.pageY < containerTop) {
      container.scrollTop(container.scrollTop() - 10);
    }
  }
})
body.dragging,
body.dragging * {
  cursor: move !important;
}

.overflow {
  height: 200px;
  overflow-x: hidden;
  overflow-y: auto;
  margin-top: 20px;
}

.dragged {
  position: absolute;
  top: 0;
  opacity: 0.5;
  z-index: 2000;
}


/* line 10, jquery-sortable.css.sass */

ol.vertical {
  margin: 0 0 9px 0;
}


/* line 12, jquery-sortable.css.sass */

ol.vertical li {
  display: block;
  margin: 5px;
  padding: 5px;
  border: 1px solid #cccccc;
  color: #0088cc;
  background: #eeeeee;
}

ol.vertical li.placeholder {
  position: relative;
  margin: 0;
  padding: 0;
  border: none;
}

ol.vertical li.placeholder:before {
  position: absolute;
  content: "";
  width: 0;
  height: 0;
  margin-top: -5px;
  left: -5px;
  top: -4px;
  border: 5px solid transparent;
  border-left-color: red;
  border-right: none;
}

ol {
  list-style-type: none;
}

ol i.icon-move {
  cursor: pointer;
}

ol li.highlight {
  background: #333333;
  color: #999999;
}

ol li.highlight i.icon-move {
  background-image: url("../img/glyphicons-halflings-white.png");
}

ol.nested_with_switch,
ol.nested_with_switch ol {
  border: 1px solid #eeeeee;
}

ol.nested_with_switch.active,
ol.nested_with_switch ol.active {
  border: 1px solid #333333;
}

ol.nested_with_switch li,
ol.simple_with_animation li,
ol.default li {
  cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>

<script src="https://johnny.github.io/jquery-sortable/js/jquery-sortable-min.js"></script>


<div class="overflow">
  <ol class="default vertical">
    <li>elem1</li>
    <li>elem2</li>
    <li>elem3</li>
    <li>elem4</li>
    <li>elem5</li>
    <li>elem6</li>
    <li>elem7</li>
    <li>elem8</li>
    <li>elem9</li>
    <li>elem10</li>
  </ol>
</div>

<div class="overflow">
  <ol class="default vertical">
    <li>elem1</li>
    <li>elem2</li>
    <li>elem3</li>
    <li>elem4</li>
    <li>elem5</li>
    <li>elem6</li>
    <li>elem7</li>
    <li>elem8</li>
    <li>elem9</li>
    <li>elem10</li>
  </ol>
</div>