Load more custom widget with scroll

by jmeile

HTML

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
<div id="jm-list-thesis">
  <h2>Thesis</h2>
  <div>Thesis 1</div>
  <div>Thesis 2</div>
  <div>Thesis 3</div>
  <div>Thesis 4</div>
  <div>Thesis 5</div>
  <div>Thesis 6</div>
  <div>Thesis 7</div>
  <div>Thesis 8</div>
  <div>Thesis 9</div>
  <div>Thesis 10</div>
  <div>Thesis 11</div>
  <div>Thesis 12</div>
  <div>Thesis 13</div>
  <div>Thesis 14</div>
  <div>Thesis 15</div>
  <div>Thesis 16</div>
  <div>Thesis 17</div>
  <div>Thesis 18</div>
  <div>Thesis 19</div>
  <div>Thesis 20</div>

  <div>Thesis 21</div>
  <div>Thesis 22</div>
  <div>Thesis 23</div>
  <div>Thesis 24</div>

  <div>Thesis 25</div>
  <div>Thesis 26</div>
  <div>Thesis 27</div>
  <div>Thesis 28</div>

  <div>Thesis 29</div>
  <div>Thesis 30</div>
  <div>Thesis 31</div>
  <div>Thesis 32</div>
  
  <div>Thesis 33</div>
  <div>Thesis 34</div>
  <div>Thesis 35</div>
  <div>Thesis 36</div>
  
  <div>Thesis 37</div>
  <div>Thesis 38</div>
</div>
<br/><br/>
<div id="jm-list-conference">
  <h2>Conference</h2>
  <div>Conference 1</div>
  <div>Conference 2</div>
  <div>Conference 3</div>
  <div>Conference 4</div>
  
  <div>Conference 5</div>
  <div>Conference 6</div>
  <div>Conference 7</div>
  <div>Conference 8</div>
  <div>Conference 9</div>
  <div>Conference 10</div>
  <div>Conference 11</div>
  <div>Conference 12</div>
  <div>Conference 13</div>
  <div>Conference 14</div>
  <div>Conference 15</div>
  <div>Conference 16</div>
  <div>Conference 17</div>
  <div>Conference 18</div>
  <div>Conference 19</div>
  <div>Conference 20</div>

  <div>Conference 21</div>
  <div>Conference 22</div>
  <div>Conference 23</div>
  <div>Conference 24</div>

  <div>Conference 25</div>
  <div>Conference 26</div>
  <div>Conference 27</div>
  <div>Conference 28</div>

  <div>Conference 29</div>
  <div>Conference 30</div>
  <div>Conference 31</div>
  <div>Conference 32</div>
  
 ...

CSS

/* This is optional. It is only to give the lists a fixed width */
.jm-show-more, .my-custom-class {
  width: 400px;
  margin: 20px auto;
  font: normal 13px/100% sans-serif;
}

.jm-show-more {
  color: #444;
}

.my-custom-class {
  color: #ffffff;
}

.my-custom-class h2 {
  color: #000000;
}

/* The following styles are also optional and are to illustrate how to style
 * the widget. This styling can be also achieve by using the ids from each
 * widget instance, for example:
 * ""#jm-list-thesis" > div will only style the widget with the id:
 * jm-list-thesis
 */
.jm-show-more > div,
.my-custom-class > div {
  padding: 10px;
  border-width: 0 1px 1px 0;
  border-style: solid;
  margin-bottom: 5px;
}

.jm-show-more > div {
  border-color: #c5c5c5;
  box-shadow: 0 1px 1px #cccccc;
  background-color: #f1f1f1;
  
  /* This will show bullets inside the items */
  display: list-item;
  list-style-type: disc;
  list-style-position: inside;
}

.my-custom-class > div {
  border-color: #0000dd;
  box-shadow: 0 1px 1px #0000cc;
  background-color: #0000cc;
}

.jm-show-more > button,
.my-custom-class > button {
  cursor: pointer;
  padding: 10px;
  text-align: center;
  border-width: 0 1px 1px 0;
  border-style: solid;
  margin-left: 2px;
  
  /* I found transitions annoying, so, I removed them */
  /*
  transition: all 600ms ease-in-out;
  -webkit-transition: all 600ms ease-in-out;
  -moz-transition: all 600ms ease-in-out;
  -o-transition: all 600ms ease-in-out;
  */
}

.my-custom-class > button {
  background-color: #0000cc;
  color: #ffffff;
  border-color: #0000dd;
  box-shadow: 0 1px 1px #0000ee;
}

.my-custom-class > button:hover {
  background-color: #0000ff;
}

.jm-show-more > button {
  background-color: #dddddd;
  color: #454545;
  border-color: #c5c5c5;
  box-shadow: 0 1px 1px #ccc;
}

.jm-show-more > button:hover {
  background-color: #ededed;
  color: #2b2b2b;
}


/* To access an specific button, then you can use the css selector
 * :nth-last-child
 * 
 * For...

JavaScript

/* I used the following as a refference while implementing a custom jQuery
 * Widget:
 * - Extending Widgets with the Widget Factory
 *   https://learn.jquery.com/jquery-ui/widget-factory/extending-widgets/
 * - How To Use the Widget Factory
 *   https://learn.jquery.com/jquery-ui/widget-factory/how-to-use-the-widget-factory/
 * - Chapter 9. Extending widgets with the widget factory
 *   https://livebook.manning.com/book/jquery-ui-in-action/chapter-9/17
 * - Widget Factory (Example)
 *   https://jqueryui.com/widget/#default
 * - Widget Factory (Methods and properties)
 *   https://api.jqueryui.com/jQuery.widget/
 */

/* Here I'm saying that my widget is inside the "custom" namespace, which is
 * useful in order to avoid breaking the jQuery namespaces. Then I give it the
 * name "jmShowMore"
 */
$.widget("custom.jmShowMore", {
 
  // Here I added some options for the Widget
  options: {
    // Number of items to show
    pagination: 6,
    
    /* The following option is the css class for styling the widget.
     * Please note that I didn't add a class for the items (div elements inside
     * the container because you can easily style them by only using css, just
     * do:
     * .jm-show-more > div { ... your styles here ... }
     *
     * The same applies for the header:
     * .jm-show-more > h2 { ... your styles here ... }
     *
     * And event for the buttons:
     * .jm-show-more > button { ... your styles here ... }
     *
     * To access an specific button, then you can use the css selector
     * :nth-last-child
     * 
     * For example, we now that the buttons have the following DOM order:
     * <collapse> <show more> <show all>
     *
     * So, for styling the the <collapse> button, you have to access the third
     * button from the last position of the container, which is: 
     * .jm-show-more > :nth-last-child(3)
     *
     * The last position button, <show all> is then:
     * .jm-show-more > :nth-last-child(1)
     */
   ...