如何让部分搜索返回单列结果,然后让结果可点击以显示该结果的整行?

时间:2021-05-19 19:17:02

标签: javascript html sql

好的,我会尽量解释清楚。我创建了一个包含 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 列。感谢您提供的任何帮助。

1 个答案:

答案 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>

这听起来像是在描述一个主从列表,其中选择一行会显示一个包含更多信息的详细信息面板。通常,您希望将其拆分,以便在您始终重置结果列表时将细节呈现在结果列表之外。