好的,我会尽量解释清楚。我创建了一个包含 3 列的数据库的搜索:类别、OEM 编号和价格。我想让当用户输入 OEM 编号时,它将显示类别和 OEM 编号作为结果,然后结果可点击以显示整行、类别、OEM 编号和价格。我也希望这样,如果他们只输入部分 OEM 编号,它将列出包含该部分编号的所有 OEM 编号,然后他们单击正确的完整 OEM 编号,以便显示类别、OEM 编号和价格原始设备制造商编号。这是我目前的代码,它只是让他们输入 OEM 编号并返回整行,或者如果他们输入部分编号,则返回所有结果,包括页面上的部分编号。我希望显示价格的页面上只有一个条目。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="js/jquery-2.2.2.min.js"></script>
<script src="js/bootstrap.min.js"></script>
<link href="css/bootstrap.min.css" rel="stylesheet">
<title>AJAX Search Example</title>
<script>
function fetch() {
// (A) GET SEARCH TERM
var data = new FormData();
data.append('search', document.getElementById("search").value);
data.append('ajax', 1);
// (B) AJAX SEARCH REQUEST
var xhr = new XMLHttpRequest();
// (CHANGE1) USING ONREADYSTATECHNAGE INSTEAD OF ONLOAD
xhr.onreadystatechange = function (event) {
// (CHANGE2) we will check if ajax process has completed or not it goes from 1,2,3,4 means end.
if(this.readyState == 4){
// (CHANGE2) when ready state comes to 4 we then check what response status was it if it is 200 good else error.
if(this.status == 200){
// (CHANGE3) MOVED ALL YOUR CODE HERE
// (CHANGE4) we need to use responseText instead of response because JSON comes as string that is why we are parsing it to be converted into array
var results = JSON.parse(this.responseText);
//I have added just a measure to check what the out put is you can remove it latter. open dev console to get the result.
console.log(results);
wrapper = document.getElementById("results");
wrapper.innerHTML = "";
var rows = "";
if (results.length > 0) {
// (CHANGE5) UPDATED data ref with results
for (i = 0; i < results.length; i++) {
let line = document.createElement("div");
//it is just as simple to create id only it must start with alaphabet not number
line.id=`res${[i]}`;
//we created span tag to display price and this is what we will change. on that span we will create a data-price attribute which will hold orginial price and we will run claulcations using that number
//BIG CHANGE
//BIG CHANGE
//since after parsing invidual record will be in Js object so we dont need to access them like array results[i]['item']
//we access them with dot notation results[i].item
rows += `<tr id=res${[i]}><td>${results[i].category}</td><td>${results[i].oemnumber}</td><td>$<span data-price='${results[i].price}'>${results[i].price}</span>
select discount >>
<a href="#70">%70</a>
<a href="#60">%60</a>
<a href="#50">%50</a> <a href="#50">100%</a></td></tr>`;
}
wrapper.innerHTML = `<table class="table">
<thead><th>Category</th><th>OEM</th><th>Price</th></thead><tbody>${rows}</tbody></table>`;
// (CHANGE6) We moved event listeners here so any newly added elements will be updated.
//get all the links and apply event listener through loop
var links = document.querySelectorAll('a');
for ( ii = 0; ii < links.length; ii++) {
links[ii].addEventListener("click", function(event) {
//capture link value and get number to be converted to percentage
var percentage = event.target.innerText.match(/\d+/)[0]/100;
//capture the data-price which is within same div as anchor link
var pricetarget = event.target.parentElement.querySelector('[data-price]');
//get value of data-price
var actualprice= pricetarget.dataset.price;
//run math and chnage the value on display
pricetarget.innerHTML=(actualprice*percentage).toFixed(2);
});
}
} else { wrapper.innerHTML = "No results found"; }
} else {
//if reponse code is other ethan 200
alert('INTERNET DEAD OR AJAX FAILED ');
}
}
};
// (CHANGE7) We moved open event to end so everything is ready before it fires.
xhr.open('POST', "2-search.php");
xhr.send(data);
return false;
};
</script>
</head>
<body>
<!-- (A) SEARCH FORM -->
<form ID='myForm' onsubmit="return fetch();">
<h1>SEARCH FOR CATALYTIC CONVERTER</h1>
<input type="text" id="search" required/>
<input type="submit" value="Search"/>
</form>
<!-- (B) SEARCH RESULTS -->
<div id="results"></div>
</body>
</html>
简单地总结一下,我希望第一个结果只返回结果中的 2 列、类别和 OEM 编号。然后我希望这些结果是可点击的并返回整个单行,所有 3 列。感谢您提供的任何帮助。
答案 0 :(得分:0)
避免调用全局函数 fetch
,还有一个内置的浏览器函数也称为 fetch
,它更像是一个更好的 XMLHttpRequest
。
让我们将 fetch
函数重命名为 getData
,以免混淆。
接下来它会获取数据并尝试更新您的 DOM,这使得调试和找出问题所在变得更加困难。
您正在设置 document.getElementById("results").innerHTML
,这会起作用,但也会导致回流相当缓慢。您可能想直接设置 DOM,或者使用像 Lit 或 React(或许多其他库中的任何一个)这样的库来为您处理。
通过用虚拟数据替换 AJAX fetch,我可以测试这个,它在一个片段中工作......
async function getData() {
// (A) GET SEARCH TERM
const data = new FormData();
data.append('search', document.getElementById("search").value);
data.append('ajax', 1);
const wrapper = document.getElementById("results");
wrapper.innerHTML = "Loading...";
// This is the better API to use
//const response = await fetch(...);
//if(!response.ok) return;
//const results = await response.json();
// But let's use a dummy
const results = [{
category: 'foo',
oemnumber: 1,
price: 1
},
{
category: 'bar',
oemnumber: 2,
price: 2
}
];
let rows = "";
if (results.length > 0) {
for (i = 0; i < results.length; i++) {
let line = document.createElement("div");
line.id = `res${[i]}`;
rows += `<tr id=res${[i]}><td>${results[i].category}</td><td>${results[i].oemnumber}</td><td>$<span data-price='${results[i].price}'>${results[i].price}</span>
select discount >>
<a href="#70">%70</a>
<a href="#60">%60</a>
<a href="#50">%50</a> <a href="#50">100%</a></td></tr>`;
}
wrapper.innerHTML = `<table class="table">
<thead><th>Category</th><th>OEM</th><th>Price</th></thead><tbody>${rows}</tbody></table>`;
const links = document.querySelectorAll('a');
for (ii = 0; ii < links.length; ii++)
links[ii].addEventListener("click", function(event) {
const percentage = event.target.innerText.match(/\d+/)[0] / 100;
const pricetarget = event.target.parentElement.querySelector('[data-price]');
const actualprice = pricetarget.dataset.price;
pricetarget.innerHTML = (actualprice * percentage).toFixed(2);
});
} else
wrapper.innerHTML = "No results found";
};
document.getElementsByTagName('form')[0].addEventListener('submit', e => {
e.preventDefault();
getData();
return false;
});
<!-- (A) SEARCH FORM -->
<form ID='myForm'>
<h1>SEARCH FOR CATALYTIC CONVERTER</h1>
<input type="text" id="search" required/>
<input type="submit" value="Search" />
</form>
<!-- (B) SEARCH RESULTS -->
<div id="results"></div>
这听起来像是在描述一个主从列表,其中选择一行会显示一个包含更多信息的详细信息面板。通常,您希望将其拆分,以便在您始终重置结果列表时将细节呈现在结果列表之外。