トップへ(mam-mam.net/)

A Copy‑and‑Paste JavaScript & CSS Table with Ascending/Descending Column Sorting

Japanese

Sortable Table with One‑Click Column Sorting

This table allows you to sort column values in ascending or descending order simply by clicking the header row.
It is built with lightweight JavaScript and CSS, and can be added to your project with a simple copy and paste.
Smooth and efficient, it’s ideal for business tools and data list displays.

Name Age Position Income
Ishii 37 Director 90,000
Yamada 34 Staff 90,000
Kawasaki 29 Producer 70,000
Nishida 29 Staff 70,000
Sato 18 Director 50,000
Ishikawa 21 Staff 53,000

Source Code

This is the CSS, JavaScript, and HTML you can use simply by copying and pasting.

<style>
table.sortableTable{
  border-collapse:collapse;
  padding:0;
}
table.sortableTable>thead>tr>th{
  cursor:pointer;
  border-top:2px solid #EED;
  border-bottom:3px solid #CCB;
  border-right:1px solid #AA9;
  border-left:1px solid #FFF;
  background-color: #EED;
  margin:0;
  padding:0.1em 1.2em 0.1em 0.1em;
  position:relative;
}

table.sortableTable>thead>tr>th::after{
  position:absolute;
  right:0;
  top:0;
  bottom:0;
  content:"";
}
table.sortableTable>thead>tr>th.up::after{
  position:absolute;
  right:0;
  top:0;
  bottom:0;
  content:"▼";
}
table.sortableTable>thead>tr>th.down::after{
  position:absolute;
  right:0;
  top:0;
  bottom:0;
  content:"▲";
}
table.sortableTable>thead>tr>th:hover{
  border-top:2px solid #FFC83C;
}
table.sortableTable>tbody{
  background-color:#FFF;
}
table.sortableTable>tbody>tr>td{
  margin:0px;
  padding:2px;
  border:1px solid #EEE; /* Bottom border for each row */
}
</style>
<script>
class TMamSortableTable{
  // Constructor
  constructor(){
    this.elms=[];
    let el=document.querySelectorAll(".sortableTable");
    let ct=0;

    for(let i=0;i<el.length;i++){
      if(el[i].tHead){
        this.elms[ct]=[];
        this.elms[ct].elm=el[i];
        this.elms[ct].col=-1;
        this.elms[ct].sort=0;
        this.elms[ct].rows=[];

        // Add click events to header cells
        for(let j=0;j<this.elms[ct].elm.tHead.children[0].children.length;j++){
          this.elms[ct].elm.tHead.children[0].children[j].addEventListener(
            "click", this.sortTable.bind(this,ct,j)
          );
        }

        // Store all body rows
        for(let j=0;j<this.elms[ct].elm.tBodies[0].children.length;j++){
          this.elms[ct].rows[j]=this.elms[ct].elm.tBodies[0].children[j];
        }

        ct++;
      }
    }
  }

  // Sort the table and reinsert rows
  sortTable(tnum,colnum){
    this.remove_rows(tnum);

    let arr=[];
    let clr=this.elms[tnum].rows;

    for(let i=0;i<clr.length;i++){
      arr.push({"idx":i,val:clr[i].children[colnum].innerText});
    }

    // Determine sort direction
    if(this.elms[tnum].col!==colnum){
      this.elms[tnum].col=colnum;
      this.elms[tnum].sort=1;
    }else{
      this.elms[tnum].sort=-this.elms[tnum].sort;
    }

    // Ascending
    if(this.elms[tnum].sort===1){
      arr.sort(function(a,b){
        if(a.val>b.val){ return 1; }
        else if(a.val<b.val){ return -1; }
        else{ return 0; }
      });
    }
    // Descending
    else{
      arr.sort(function(a,b){
        if(a.val>b.val){ return -1; }
        else if(a.val<b.val){ return 1; }
        else{ return 0; }
      });
    }

    // Reinsert rows in sorted order
    for(let i=0;i<arr.length;i++){
      this.elms[tnum].elm.tBodies[0].appendChild(this.elms[tnum].rows[arr[i].idx]);
    }

    // Update header sort indicators
    let hd=this.elms[tnum].elm.tHead.children[0];
    for(let i=0;i<hd.children.length;i++){
      hd.children[i].classList.remove("down");
      hd.children[i].classList.remove("up");
    }

    if(this.elms[tnum].sort===1){
      hd.children[colnum].classList.add("up");
    }else{
      hd.children[colnum].classList.add("down");
    }
  }

  // Remove all rows
  remove_rows(tnum){
    while(this.elms[tnum].elm.tBodies[0].firstElementChild){
      this.elms[tnum].elm.tBodies[0].removeChild(
        this.elms[tnum].elm.tBodies[0].firstElementChild
      );
    }
  }
}

let MamSortableTable;
window.addEventListener("DOMContentLoaded",function(){
  MamSortableTable=new TMamSortableTable;
});
</script>