继众里寻它後,我们想继续看是否有各个栏位都符合关键字的结果(真命天菜/女神?),这需要根据输入的资料的阵列大小自动调整输入的栏位和对应function的数目,而这功能我问Google大神并没有得到明确的答案,但想想是可以实现的,分成3个部分,分别为生成输入栏位、比对有输入值得栏位做filter,以及调整输入栏位的宽度(如果资料表格会根据内容调整宽度)。
首先我们要修正上次的filterTable这个function,将原本input和table这两个argument改为,并在function内用getElementById取得HTML上的内容,这样就不用外面再包一层(原本filterTable_data()是拗口的写法),第二是再增加一个hold的argument,再原本if (txtValue.indexOf(filter) > -1)的条件中,再增加if (!hold)的条件,当两个条件都达到时,才会有display = "",这是避免在多个条件时,在其中一个条件达成时,会洗掉其他条件的没达成(display = "none"):
function filterTable(inputId, tableId, index, hold) {
let input = document.getElementById(inputId);
let table = document.getElementById(tableId);
// Declare variables
let filter, tr, td, i, txtValue;
filter = input.value;
tr = table.getElementsByTagName("tr");
// Loop through all table rows, and hide those who don't match the search query
for (i = 1; i < tr.length; i++) {
td = tr[i].getElementsByTagName("td")[index];
if (td) {
txtValue = td.textContent || td.innerText;
if (txtValue.indexOf(filter) > -1) {
if (!hold) {
tr[i].style.display = "";
}
} else {
tr[i].style.display = "none";
}
}
}
}
接下来是生成输入栏位,我们可以使用在day2生成表格的做法,而同样我们会生成表格,并根据原本表格的栏位的宽度写入属性,这样输入栏位就会对齐(如果原本表格是自动根据内容调整宽度),然後在cell中写入输入,如同在单一输入时的写法,但要额外带着栏位标号以做区分。总结,用JavaScript写表格,用表头格式(与下放表格的表头外观会一致),每个cell()根据资料的表格读取宽度并填入,cell写入输入(我在一开始将固定的文字拆成string1~string5,对应到上方的注解,让後面loop中的code比较乾净):
function genTableFilter(outputId, tableId, keyName) {
//<input type="text" id="filterInput_data" onkeyup="filterTable_multi('filterInput_data', 'searchTable_data', 'dataTable', 0)" placeholder="Search ..." class="form-control"/>
const string1 = "<input type=\"text\" id=\"filterInput_";
const string2 = "\" onkeyup=\"filterTable_multi(\'filterInput_";
const string3 = "\', \'";
const string4 = "\', ";
const string5 = ")\" placeholder=\"Search ...\" class=\"form-control\"/>";
let table = document.getElementById(tableId);
td = table.getElementsByTagName("tr")[0].getElementsByTagName("th");
let content = "<thead><tr>";
for (let i = 0; i < td.length; i++) {
//content += "<th>" + cell + "</th>" ;
let cellWidth = table.rows[0].cells[i].offsetWidth;
content += "<th width=" + cellWidth + ">" + string1 + keyName + i;
content += string2 + keyName + i + string3 + outputId + string3 + tableId + string4 + i;
content += string5 + "</th>";
}
content += "</tr></thead>";
document.getElementById(outputId).innerHTML = content;
}
再来是比对有输入值的栏位做filter,我们逻辑是这样:如果输入栏位有修改值(onkeyup触发),则会依序对所有栏位都读取值,如果有值(!= "")则做filter(filterTable这个function),而只有第一个hold为false,也就是会将符合条件的display设为"",这样可以清除之前的设定,而之後的所做filter的hold为true,则不会洗掉前面判断display = "none"的结果。若loop後hold还是false,表示所有栏位都没有输入值,则同样做一次filter,将所有display = "none"清回display = "",而最後呼叫的adjuctTableWidthByTable则是下一段所要说明调整宽度的function:
function filterTable_multi(inputId, searchId, tableId, index) {
let table = document.getElementById(tableId);
td = table.getElementsByTagName("tr")[0].getElementsByTagName("th");
let hold = false;
for (let i = 0; i < td.length; i++) {
let inputId_other = inputId.replace(/(\d+)$/, i);
if (document.getElementById(inputId_other).value != "") {
filterTable(inputId_other, tableId, i, hold);
hold = true;
}
}
if (!hold) {filterTable(inputId, tableId, index, hold);}
adjuctTableWidthByTable(tableId, searchId);
}
如果资料表格会根据内容调整宽度,则我们在做filter时由於资料变了,则表格的宽度也可能变动,这样输入栏位可能会不对齐,这在使用时会有不协调的感觉。我们同样可以用之前在生成栏位的方式,再用loop依序抓一次资料表格的宽度,然後调整输入栏位宽度的属性:
function adjuctTableWidthByTable(refTableId, targetTableId) {
let refTable = document.getElementById(refTableId);
let tarTable = document.getElementById(targetTableId);
td = refTable.getElementsByTagName("tr")[0].getElementsByTagName("th");
for (let i = 0; i < td.length; i++) {
let cellWidth = refTable.rows[0].cells[i].offsetWidth;
//console.log(cellWidth);
tarTable.getElementsByTagName("tr")[0].getElementsByTagName("th")[i].width = cellWidth;
//console.log(tarTable.rows[0].cells[i].offsetWidth);
}
}
最後我以节录一开始的Bootstrap所附的表格资料做测试,因为资料的内容长度不一致,可以看出第三个调整宽度的功能的结果。
两栏filter输入结果:
无符合条件结果:
无输入条件结果:
>>: Day05 测试写起乃 - Shoulda Matchers
之前在添加资料时,都是手动去资料库添加,这样很不合理,也没有效率 如果只是为了方便,当然可以使用以下...
大家好~ 接着一起来介接 API 吧! 今天先从 Google Calendar API 开始~ 上...
在Day 20有稍微提到中断机制,我们稍微深入说明一下,中断其实也是种不浪费资源的方式,如果处理器一...
用新版Visual studio 2019开启旧版SQL Server 2012的mdf档时,却出现...
注:发文日和截图的日期不一定是同一天,所以价格计算上和当日不同,是很正常的。 但今日无法交易,所以委...