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

时间:2018-10-12 08:13:08

标签: 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的新手,因此非常感谢您的帮助。如果我错过了任何事情,或者您需要进一步的信息,请询问。

2 个答案:

答案 0 :(得分:1)

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

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。)

XMLHttpRequest:

//  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)创建表

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

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

这属于我们所谓的模型-视图-控制器体系结构。 JSON文件为我们提供了汽车模型。 HTML表是该模型的视图。 javascript代码将其全部绑定为控制器。控制器获取模型,然后将模型转换为代表该模型的视图。每次模型更改时(将汽车添加到JSON文件),我们都可以请求控制器获取更新的模型(加载JSON文件)并更新视图。 (再次渲染表格)

//  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,因为这样做已经很好了。

答案 1 :(得分:1)

我实现了以下代码,该代码可用于我从日常库存报告中导出的JSON数据。

$(document).ready( function() {
      $.ajax({
        url: "data.json",
        method: "GET",
        dataType: "json",
        success: function(data) {
           var $tbody = $("table#data tbody");
           $.each(data, function(i, data) {
              var $tr = $("<tr></tr>");
              $tr.appendTo($tbody);
              var $td = $("<td></td>");
              $td.html(data.ProdCode)
                 .appendTo($tr);   
              $td = $("<td></td>");  
              $td.html(data.Model) 
                 .appendTo($tr); 
    	      $td = $("<td></td>"); 
              $td.html(data.StockStatus)
                 .appendTo($tr);   
           });
        },
        error: function(jqXHR, textStatus, errorThrown) {
          console.log("AJAX ERROR",textStatus,errorThrown,jqXHR);
        }
      });
    });