首页 > 解决方案 > 如何使用 js/html 对表格进行排序

问题描述

我有一张桌子:

Name | Department | status 

我在单击时按字母顺序对名称进行了排序,但现在我在状态单元格中创建了一个下拉列表,其中显示诸如内部/外部之类的值,并且我想在单击其中一个过滤器时对表格进行排序我只想查看其中的人/出去。我当前的 JS 函数:

function sortStatusDesc() {
   var table, rows, switching, i, x, y, shouldSwitch;
   table = document.getElementById("myTable");
   switching = true;

   while (switching) {
      switching = false;
      rows = table.rows;

      for (i = 1; i < (rows.length - 1); i++) {
         shouldSwitch = false;
         x = rows[i].getElementsByTagName("th")[2];
         y = rows[i + 1].getElementsByTagName("th")[2];

         if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
            shouldSwitch = true;
            break;
         }
      }
      if (shouldSwitch) {
         rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
         switching = true;
      }
   }
}

它按字母顺序排序。

标签: javascripthtml

解决方案


以下代码段显示了任何属性的排序。单击其中一个属性标题会更改排序。

以同样的方式,您可以创建过滤。不是使用 对特定属性的 source_data 进行排序,而是data.sort()data.filter()所有具有正确值的条目进行排序。

//	Name of the data we're rendering.
const source_name = 'Locations';
//	Source data we want to create a table from.
const source_data = [
  { "id": 1, "name": "production hall", 	"department": "production", 	"status": "inside"	},
  { "id": 2, "name": "spare parts room",	"department": "production", 	"status": "inside"	},
  { "id": 3, "name": "warehouse",		"department": "production", 	"status": "inside"	},
  { "id": 4, "name": "loading bay",		"department": "production", 	"status": "outside"	},
  { "id": 5, "name": "offices HR",		"department": "administration",	"status": "inside"	},
  { "id": 6, "name": "offices QA",		"department": "administration",	"status": "inside"	},
  { "id": 7, "name": "security lounge",	        "department": "administration",	"status": "outside"	}
];
//  Create the table.
//  For this example, we'll use string manipulation to create the HTML.
//  For complex layouts a templating system is better.	
const render = ( name, data ) => {
  //	Always include a header for the name.
  //	When there's 0 rows, we'll still know what the table shows.
  const labels = data.length
    ? '<tr>' + Object.keys( data[ 0 ]).map( name => `<th data-attr="${ name }">${ name }</th>` ).join( '' ) + '</tr>'
    : '';
  //	Actual header for the properties of our data.
  const header = `<tr><th colspan="${ data.length || 1 }">${ name }</th></tr>${ labels }`;
  //	One row for each entry in our data.
  const rows = data.map( entry => (`<tr id="entry_${ entry.id }">` + Object.values( entry ).map( value => `<td>${ value }</td>` ).join( '' ) + '</tr>' )).join( '' );
  //	Merge it all together.
  const table = `<table><thead>${ header }</thead><tbody>${ rows }</tbody></table>`;
  //	Render into the page.
  document.querySelector( '#output' ).innerHTML = table;
};
//	Sort of the property.
const sort = ( data, property ) => {
  //  Sort the data on the property in alphabetical order.
  return data.sort(( first, second ) => {
    if ( first[ property ] < second[ property ] ) return -1;
    else if ( first[ property ] > second[ property ] ) return 1;
    else return 0;
  });
};
//	Add click events to the header so that clicking a header will sort the rows.
const add_sorting = function( table ) {
  Array
    .from( table.querySelectorAll( 'th' ))
    .forEach( header => header.addEventListener( 'click', create_table ));
};
//	Main function
const create_table = event => {
  // We'll reuse this function both manually and through clicking
  const property = event && event.target
    ? event.target.getAttribute( 'data-attr' )
    : event;
  const collection = sort( source_data, property );
  render( source_name, collection );
  add_sorting( document.querySelector( 'table' ));
};
create_table( 'name' );
th, td {
  border: 1px solid grey;
}
<div id="output"></div>


推荐阅读