javascript - 使用 CSV 或 JS 文件填充 HTML 表中的特定 TD

标签 javascript jquery html csv import

我已经进行了搜索,但无法确定这是否可行。

我开发了一个 HTML 页面来显示多种产品的库存状态。目前,我每天手动编辑每个状态(状态与前一天相比发生了变化),并且我希望尽可能将其自动化。

例如,我目前有按制造商显示的 HTML 页面,每个产品和库存状态都在单独的表中。

.collapse{
    cursor: pointer;
    display: block;
    background: rgb(0, 156, 0);
    color: rgb(255, 255, 255);
    padding: 6px 12px;
    border: solid white;
}
.collapse:hover{
    color: rgb(231, 230, 229);
    font-weight: bold;
}
.collapse + input{
    display: none;
}
.collapse + input + div{
    display:none;
}
.collapse + input:checked + div{
    display:block;
}
<body>
    <div><label class="collapse" for="_bmw">BMW</label>
        <input id="_bmw" type="checkbox">
        <div><br>
            <table border="1" cellpadding="1" cellspacing="1">
                
                <thead>
                    <tr style="font-weight: bold">
                        <td style="width: 75px;">Product Code</td>
                        <td style="width: 200px;">Model</td>
                        <td style="width: 200px;">Stock Status</td>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>1000</td>
                        <td>M1</td>
                        <td>Available</td>
                    </tr>
                    <tr>
                        <td>1001</td>
                        <td>M3</td>
                        <td>Out of stock</td>
                    </tr>
                    <tr>
                        <td>1002</td>
                        <td>M5</td>
                        <td>Available</td>
                    </tr>
                </tbody>
            </table>
            <br>
        </div>
    </div>
    <div><label class="collapse" for="_ford" style="font-size: 17px;">Ford</label>
        <input id="_ford" type="checkbox">
        <div><br>
            <table border="1" cellpadding="1" cellspacing="1">
                <thead>
                    <tr style="font-weight: bold">
                        <td style="width: 75px;">Product Code</td>
                        <td style="width: 200px;">Model</td>
                        <td style="width: 200px;">Stock Status</td>
                    </tr>
                </thead>
                <tbody>
                    <tr>
                        <td>1003</td>
                        <td>Fiesta</td>
                        <td>Available</td>
                    </tr>
                    <tr>
                        <td>1004</td>
                        <td>Mondeo</td>
                        <td>Available</td>
                    </tr>
                    <tr>
                        <td>1004</td>
                        <td>Escort</td>
                        <td>End of life</td>
                    </tr>
                </tbody>
            </table>
            <br>
        </div>
    </div>
</body>

是否可以使用 javascript 或 jquery 在 HTML 表中执行产品代码查找并从库存状态 TD 中的 JS(或 CSV)文件返回值?

我已经创建了一个包含以下数据的 JS 文件,现在我只需要知道如何根据产品代码的查找来填充库存状态数据:-

[
 {
   "FIELD1": "1000",
   "FIELD2": "Available"
 },
 {
   "FIELD1": "1001",
   "FIELD2": "Out of stock"
 },
 {
   "FIELD1": "1002",
   "FIELD2": "Available"
 },
 {
   "FIELD1": "1003",
   "FIELD2": "Available"
 },
 {
   "FIELD1": "1004",
   "FIELD2": "Available"
 },
 {
   "FIELD1": "1005",
   "FIELD2": "End of life"
 },
]

我是 JS 和 JQuery 的新手,因此非常感谢您的帮助。如果我遗漏了任何内容或者您需要更多信息,请询问。

最佳答案

我会将其分解为单独的步骤:

1) JSON 文件

如果我们仔细选择 JSON 文件的格式,我们可以提供所有数据,甚至更多构建整个页面所需的数据。 因此,我会将我们拥有的所有汽车的所有信息都放在这个文件中,这样我们就不必在添加品牌或型号后更新 HTML 文件。

如果我们只在 JSON 文件中保留汽车的可用性,则需要更新 JSON 文件和 HTML 文件以添加品牌或类型。

可用性也最好用表示可用汽车数量的整数来表示,而不是字符串。如果它是一个字符串,我们需要解析该字符串以查看是否仍然有可用的汽车。

通过将汽车的 ID 与其产品代码分开,我们可以将产品代码保留为字符串,这样它就不仅可以包含数字,而且仍然可以轻松地对汽车进行排序。请记住,字符串的排序方式与整数不同:"10" < "9" === true10 < 9 === false 。否则,如果我们拥有一辆代码为“999”的汽车,这可能会导致问题。

另一个优点是,如果我们将其移动到数据库中,它可以很好地映射到表列。

[
    {
        "availability": 25,
        "brand": "bmw",
        "code": "1000",
        "id": 1,
        "model": "m1"
    },
    {
        "availability": null,
        "brand": "bmw",
        "code": "1001",
        "id": 2,
        "model": "m3"
    },
    {
        "availability": 10,
        "brand": "bmw",
        "code": "1002",
        "id": 3,
        "model": "m5"
    },
    {
        "availability": 7,
        "brand": "ford",
        "code": "1003",
        "id": 4,
        "model": "fiesta"
    },
    {
        "availability": 14,
        "brand": "ford",
        "code": "1004",
        "id": 5,
        "model": "mondeo"
    },
    {
        "availability": null,
        "brand": "ford",
        "code": "1005",
        "id": 6,
        "model": "escort"
    }
]

2) 获取文件

我们有两种机制来做到这一点。要么老XMLHttpRequest()如果我们必须兼容旧浏览器。或者fetch()新浏览器的 API。 这个选择将决定我们是否必须使用回调或 promise 。 (除非我们将 XMLHttpRequest 版本也转换为 Promise。)

XMLHttp请求:

//  The path where we can find the JSON file.
const PATH_CARS = 'http://path/to/cars.json';
//  A getJSON function that will create an ajax request to the provided URL.
const getJSON = ( url, callback ) => {
    //  Create a new XMLHttpRequest.
    //  https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
    const request = new XMLHttpRequest();
    //  Open the request before setting other properties. ( IE11 )
    request.open( 'GET', url );
    //  When the request gets the file, we want to run the callback.
    //  The responseText will be the JSON string inside our json file.
    request.onload = function() {
        callback( request.responseText );
    };
    request.send();
};
//  Use the function to get the file.
//  Parse and log the contents of the file once it arrives.
getJSON( PATH_CARS, function( response ) {
    // cars will be a string here. We want the actual JS object represented by the JSON string
    const cars = JSON.parse( response );
    console.log( cars );
});

获取:

//  The path where we can find the JSON file.
const PATH_CARS = 'http://path/to/cars.json';
//  Same thing, but using the fetch API for browsers that support it.
//  https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
//  The fetch API uses promises instead of callbacks to handle the results.
//  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
fetch( PATH_CARS )
    .then( response => response.json())
    .then( cars => {
        console.log( cars );
    });

3) 创建表格

我们将稍微改变一下逻辑。我们不需要使用来自文件的值来更新固定的 HTML,而是可以从 JSON 文件创建整个表,以便所有更新都已在表中。

如果我们需要再次更新表格,我们可以重新渲染整个表格,而不是尝试将 HTML 节点与 JSON 中的正确值进行匹配。对于大量汽车(想想 1000 辆以上)来说,这不会那么快,但仍然比单独更新每辆车快得多。

这属于我们所说的模型- View - Controller 架构。 JSON 文件为我们提供了汽车的模型。 HTML 表是该模型的 View 。 JavaScript 代码将它们作为 Controller 绑定(bind)在一起。 Controller 获取模型,并将模型转换为表示该模型的 View 。每次模型发生变化(向 JSON 文件添加汽车)时,我们都可以请求 Controller 获取更新的模型(加载 JSON 文件)并更新 View 。 (再次渲染表格)

//  We need to create a table for each brand.
//  We need to create a table row for each car model of that type.
//  For big projects, one would use a templating language to create the HTML.
//  For something as small as thing, we can resort to simple string manipulation.
const createTables = brands => {
    //  Loop over all the brands, creating a table for each brand.
    //  I'll use a reduction this time, to show the difference and similarities between reduce() and the forEach() we used in the previous step.
    const tables = brands.reduce(( html, brand ) => {
        //  Copy the header, replacing the brand name.
        const header = `<table><thead><tr><th colspan="3">${ brand.name }</th></tr><tr><th>Product Code:</th><th>Model:</th><th>In Stock:</th></tr></thead><tbody>`;
        //  Loop over the cars and create a row for each car.
        //  Since we create the same amount of rows as we have cars inside the array, we can use .map()
        const rows = brand.cars.map( car => {
            //  Since we changed the availability to a number, we hve to recreate the string for it.
            //  This allows us to easily change the label without having to change the logic in multiple places
            const availability_label = Number.isInteger( car.availability )
                ? `${ car.availability } in stock.`
                : 'End of life.';
            return `<tr><td>${ car.code }</td><td>${ car.model }</td><td>${ availability_label }</td></tr>`;
        });
        //  Append the current header, car rows and the closing tags to the previous HTML, then return.
        return html += `${ header }${ rows.join('') }</tbody></table>`;
    }, '');
    //  Return the HTML string. We could also just return the reduction directly, wihtout using th tables variable in between.
    return tables;
};

4)将它们放在一起

使用我们在示例中创建的所有技术和函数,我们现在拥有创建整个应用程序的一切。我添加了另一个辅助函数,将所有汽车分组到其品牌中,因此创建表格更容易、更清晰。

我在下面的示例中模拟了 JSON 文件的获取,以便我们可以实际运行代码。在您自己的代码中,您将使用真正的 fetch() 或 XMLHttpRequest() 代码。

//  FAKE FETCH, DO NOT USE IN THE REAL CODE
const fetch = url => Promise.resolve({json: () => JSON.parse('[{"availability":25,"brand":"bmw","code":"1000","id":1,"model":"m1"},{"availability":null,"brand":"bmw","code":"1001","id":2,"model":"m3"},{"availability":10,"brand":"bmw","code":"1002","id":3,"model":"m5"},{"availability":7,"brand":"ford","code":"1003","id":4,"model":"fiesta"},{"availability":14,"brand":"ford","code":"1004","id":5,"model":"mondeo"},{"availability":null,"brand":"ford","code":"1005","id":6,"model":"escort"}]')});


//  The path where we can find the JSON file.
const PATH_CARS = 'http://path/to/cars.json';
//  Same thing, but using the fetch API for browsers that support it.
//  https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API
//  The fetch API uses promises instead of callbacks to handle the results.
//  https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
const getCars = url => fetch( url )
  .then( response => response.json())
  .catch( error => console.error( error ));
//  We need to group all the different cars into their respective brands.
const groupBrands = cars => {
  // Create a temporary object we'll use to store the different brands.
  const brands = {};
  //  Loop over all the car models, grouping them into the correct brand.
  cars.forEach( car => {
  //  Extract the brand name from the car item.
  const brand = car.brand;
  //  If we haven't seen this brand yet, add it to the different brands as an array.
  if ( !brands.hasOwnProperty( brand )) brands[ brand ] = [];
    //  Push the car model to the brand.
    brands[ brand ].push( car );
  });
  //  We now have an object containign all the cars grouped by brand.
  //  It would be easier however, if we had ana rray we can loop over easily.
  //  So transform the object back into an array.
  //  We loop over the entries array of the object to extarct the name and cars at the same time, then wrap them back into an object.
  return Object.entries( brands ).map(([ name, cars ]) => ({ name, cars }));
  //  This entire step can be done in one expression by using array.reduce() instead of array.forEach()
  //  We could also just return the object and loop over the entries in the render function.
  //  My personal preference is to always use an array to represent multiples of something:
  //  A 'collection' of 'brand' objects with each brand containing a 'collection' of 'car' objects.
  //  We could also already do this grouping inside the JSON file itsself, but I preferred to keep the JSON file itsself simple for this example.
};
//  We need to create a table for each brand.
//  We need to create a table row for each car model of that type.
//  For big projects, one would use a templating language to create the HTML.
//  For something as small as thing, we can resort to simple string manipulation.
const createTables = brands => {
//  Loop over all the brands, creating a table for each brand.
//  I'll use a reduction this time, to show the difference and similarities between reduce() and the forEach() we used in the previous step.
const tables = brands.reduce(( html, brand ) => {
  //  Copy the header, replacing the brand name.
  const header = `<table><thead><tr><th colspan="3">${ brand.name }</th></tr><tr><th>Product Code:</th><th>Model:</th><th>In Stock:</th></tr></thead><tbody>`;
  //  Loop over the cars and create a row for each car.
  //  Since we create the same amount of rows as we have cars inside the array, we can use .map()
  const rows = brand.cars.map( car => {
    //  Since we changed the availability to a number, we hve to recreate the string for it.
    //  This allows us to easily change the label without having to change the logic in multiple places
    const availability_label = Number.isInteger( car.availability )
        ? `${ car.availability } in stock.`
        : 'End of life.';
    return `<tr><td>${ car.code }</td><td>${ car.model }</td><td>${ availability_label }</td></tr>`;
  });
  //  Append the current header, car rows and the closing tags to the previous HTML, then return.
  return html += `${ header }${ rows.join('') }</tbody></table>`;
  }, '');
  //  Return the HTML string. We could also just return the reduction directly, wihtout using th tables variable in between.
  return tables;
};
//  We have a JSON file, we can fetch that file, we can create tables from the contents, time to put it all together.
//  Fetch the JSON file.
getCars( PATH_CARS )
  //  Group the cars into brands.
  .then( groupBrands )
  //  Create a table for each group.
  .then( createTables )
  //  Render the tables into the page.
  .then( html => {
    const tableHook = document.querySelector( '#cars' );
    if ( tableHook ) tableHook.innerHTML = html;
    // else throw new Error(); something went wrong.
  })
  //  Catch any errors encountered.
  .catch( error => console.error( error ));
<html>
<head>
  <title>Car Stocks</title>
</head>
<body>
  <div id="cars"></div>
</body>
</html>

5) 升级

上面的很多代码都可以写得更短,但我故意使用更长的版本,以将需要学习的新东西的数量降到最低。在不支持 Promise 的情况下,可以使用回调编写相同的代码。在内部,功能大部分保持不变。

我将让您自行重新添加 CSS,因为这已经运行良好。

关于javascript - 使用 CSV 或 JS 文件填充 HTML 表中的特定 TD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52775127/

相关文章:

javascript - 多表单场景下如何保存之前输入的内容?

javascript - 按下按键时获取特定列的值

javascript - 使用 jQuery 将 HTML 附加到 iframe

jquery - 我想禁用 Jquery tablednd

Javascript 按钮重定向

html - Firefox 忽略了我的 margin-bottom CSS 属性。在 Chrome 中运行良好

javascript - 在选定的输入字段下方显示一个 div?没有 JQuery

javascript - 反转平面坐标数组

javascript - 使用 ramda sortWith 进行不区分大小写的排序

javascript - 在 IE6 中带有背景颜色的 iFrame