我已经搜索了一下,但是看不到是否可行。
我已经开发了一个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的新手,因此非常感谢您的帮助。如果我错过了任何事情,或者您需要进一步的信息,请询问。
答案 0 :(得分:1)
我将其分解为单独的步骤:
1)JSON文件
如果我们仔细选择JSON文件的格式,则可以提供所有数据,甚至还可以提供构造整个页面所需的更多数据。 因此,我会将与我们拥有的所有汽车有关的所有信息都放在此文件中,这样我们就不必在添加品牌或型号后更新HTML文件。
如果仅在JSON文件中保留汽车的可用性,则需要更新JSON文件和HTML文件以添加品牌或类型。
可用性也最好用一个整数来表示,该整数代表可用的汽车数量,而不是字符串。如果它是一个字符串,我们将需要解析该字符串以查看是否还有可用的汽车。
通过从产品代码中分离出汽车的ID,我们可以将产品代码保留为字符串,这样它不仅可以包含数字,还可以保持一种简单的方式来对我们的汽车进行排序。请记住,字符串的排序方式不同于整数:"10" < "9" === true
和10 < 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);
}
});
});