Sorted Grid

JavaScript class to sort a grid constructed using an unordered list (like you would with materializecss)

by AJLeonardi

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@materializecss/[email protected]/dist/css/materialize.min.css">
<script src="https://cdn.jsdelivr.net/npm/@materializecss/[email protected]/dist/js/materialize.min.js"></script>
  <ul id='test' data-sortable_fields='[{"name": "name", "data_type": "string"}, {"name":"score_1","data_type":"number"}, {"name":"date","data_type":"date"}]' class="collection">
    <li class="collection-item">
      <div class="row valign-wrapper">
        <div class="col s2 strong" data-header="name">Name</div>
        <div class="col s2 strong" data-header="score_1">Score 1</div>
        <div class="col s2 strong"data-header="date">Date</div>
      </div>
    </li>
    <li class="collection-item" data-name="Anthony" data-score_1=20.1 data-date="06/30/2016">
      <div class="row valign-wrapper">
        <div class="col s2">Anthony</div>
        <div class="col s2">20.1</div>
        <div class="col s2">06/30/2016</div>
      </div>
    </li>
    <li class="collection-item" data-name="Jacob" data-score_1=20.2 data-date="10/15/2016">
      <div class="row valign-wrapper">
        <div class="col s2">Jacob</div>
        <div class="col s2">20.2</div>
        <div class="col s2">10/15/2016</div>
      </div>
    </li>
    <li class="collection-item" data-name="Brian" data-score_1=22 data-date="04/20/2011">
      <div class="row valign-wrapper">
        <div class="col s2">Brian</div>
        <div class="col s2">22</div>
        <div class="col s2">04/20/2011</div>
      </div>
    </li>
  </ul>

CSS

/* fallback */
@font-face {
  font-family: 'Material Icons';
  font-style: normal;
  font-weight: 400;
  src: url(https://fonts.gstatic.com/s/materialicons/v139/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2) format('woff2');
}

.material-icons {
  font-family: 'Material Icons';
  font-weight: normal;
  font-style: normal;
  font-size: 24px;
  line-height: 1;
  letter-spacing: normal;
  text-transform: none;
  display: inline-block;
  white-space: nowrap;
  word-wrap: normal;
  direction: ltr;
  -webkit-font-feature-settings: 'liga';
  -webkit-font-smoothing: antialiased;
}

.strong{
  font-weight: bold;
}

.sorted-column-asc{
    position: relative;
}
.sorted-column-desc{
    position: relative;
}
.sorted-column-asc::after{
    font-family: 'Material Icons';
    content: "arrow_drop_up";
    -webkit-font-feature-settings: 'liga';
    font-size: 25px;
    bottom: -1px;
    position:absolute;
}
.sorted-column-desc::after{
    font-family: 'Material Icons';
    content: "arrow_drop_down";
    -webkit-font-feature-settings: 'liga';
    font-size: 25px;
    bottom: -1px;
    position:absolute;
}

JavaScript

class SortedGrid {
    constructor(ul_element, default_sort_type, sorted_column_asc_css_class, sorted_column_desc_css_class) {
        const instance = this;
        this.ul_element = ul_element;
        this.sort_type_list = JSON.parse(ul_element.dataset.sortable_fields);
        this.li_list = ul_element.querySelectorAll('li');
        this.li_headers = null;

        this.sorted_column_asc_css_class = sorted_column_asc_css_class;
        this.sorted_column_desc_css_class = sorted_column_desc_css_class;

        this.sort_state = instance.constructSortState(this.sort_type_list, default_sort_type);

        for (var x = 0; x < this.sort_type_list.length; x++) {
            var curr_sort_type = this.sort_type_list[x].name;
            for (var i = 0; i < this.li_list.length; i++) {
                var li_item = this.li_list[i]
                var sort_thing_val = li_item.dataset[curr_sort_type];

                if (typeof sort_thing_val == 'undefined') {
                    this.li_headers = li_item.querySelectorAll('[data-header]');
                    for (var n = 0; n < this.li_headers.length; n++) {
                        var header_element = this.li_headers[n];
                        var header_type = header_element.dataset.header;
                        if (header_type == curr_sort_type) {
                            header_element.addEventListener("mouseup", function (e) {
                                var header = e.target.dataset.header
                                instance.sortList(header);
                            });
                        }
                    }
                }
            }
        }
        this.updateHeaders();
    }

    constructSortState(sort_type_list, default_sort_type) {
        var sts = {};
        for (var i = 0; i < sort_type_list.length; i++) {
            var sort_type = sort_type_list[i];
            if (sort_type.name == default_sort_type){
                var is_ascending = true;
                var...