使用 JavaScript 的成本计算器 - 高级
Cost Calculator using JavaScript - Advanced
所以我有一个 HTML 表单,它有两个下拉菜单和一个按钮。一个下拉菜单有 'package type',由 'Gold'、'Silver' 和 'Bronze' 组成。第二个下拉菜单有 'months' 和 12 个选项(最多 12 个月),然后是一个计算按钮。
现在,这是我希望我能解释清楚的一点...
如果您 select 'Silver' 和“1 个月”,费用为 £150.00。
如果您 select 'Silver' 和“2 个月”,费用为 225.00 英镑。
如果您 select 'Silver' 和“3 个月”,则费用为 £300.00。
依此类推(最多 12 个月)。所以上面的逻辑是第一个月 150.00 英镑,然后是额外月份 75 英镑。
但是如果你决定要一个'Gold'包,它会是这样的:
如果您 select 'Gold',并且“1 个月”,费用为 £199.00。
如果 select 'Gold' 和“2 个月”,费用为 298.50 英镑。
如果您 select 'Gold' 和“3 个月”,费用为 £398.00。
依此类推(最多 12 个月)。所以上面的逻辑是第一个月 199.99 英镑,然后是额外月份 99.50 英镑。
'Bronze' 也类似,除了 1 个月是 75.00 英镑,2 个月是 112.50 英镑(逻辑是第一个月 75.00 英镑,其他月份 37.50 英镑)。
我希望这是有道理的?下面是表单的 HTML,我知道它不起作用,但这只是为了尝试解释...
<form name="costcalculator">
<div class="package-type">
<select name="packageType" id="packageType">
<option value="199.00" label="Gold">Gold</option>
<option value="150.00" label="Silver">Silver</option>
<option value="75.00" label="Bronze">Bronze</option>
</select>
</div>
<div class="months">
<select name="months" id="months-bronze">
<option value="£75.00" label="1 month">1 month Bronze</option>
<option value="£112.50" label="2 months">2 months Bronze</option>
</select>
</div>
<div class="months">
<select name="months" id="months-silver">
<option value="£150.00" label="1 month">1 month Silver</option>
<option value="£225.00" label="2 months">2 months Silver</option>
</select>
</div>
<div class="months">
<select name="months" id="months-gold">
<option value="£199.00" label="1 month">1 month Gold</option>
<option value="£298.50" label="2 months">2 months Gold</option>
</select>
</div>
<button type="button" onclick="calculatePrice();showDiv();">Calculate</button>
</form>
我目前拥有的(有效的)如下,但它没有做我需要做的事情,这只是硬编码了成本,所以无论包类型如何,成本都是相同(除了每个包裹的初始成本不同):
<form name="costcalculator">
<div class="package-type">
<select name="packageType" id="packageType">
<option value="199.00" label="Gold">Gold</option>
<option value="150.00" label="Silver">Silver</option>
<option value="75.00" label="Bronze">Bronze</option>
</select>
</div>
<div class="months">
<select name="months" id="months">
<option value="100.00" label="1 month">1 month</option>
<option value="200.75" label="2 months">2 months</option>
<option value="275.25" label="3 months">3 months</option>
<option value="349.00" label="4 months">4 months</option>
<option value="369.99" label="5 months">5 months</option>
<option value="450.00" label="6 months">6 months</option>
</select>
</div>
<button type="button" onclick="calculatePrice();showDiv();">Calculate</button>
</form>
和JavaScript如下:
function calculatePrice(costcalculator){
var elt = document.getElementById("packageType");
var package = elt.options[elt.selectedIndex].value;
var elt = document.getElementById("months");
var months = elt.options[elt.selectedIndex].value;
package = parseFloat(package);
months = parseFloat(months);
var total = package+months;
document.getElementById("TotalPrice").value=total;
}
所以我认为上面的工作代码我已经快到了,但我越深入,就越意识到它还差得远。
它只需要一种方法,当用户 select 在第一个下拉菜单中输入包裹类型时,包含月份的第二个下拉菜单将(在幕后)填充紧邻用户 select 月数之前的新成本,然后如果用户随后决定 select 与上一个不同的套餐,第二个下拉菜单将再次刷新,但成本不同在后台。
根据 04FS 的评论,这是一个使用简单数据结构的简单解决方案。数据结构以包名为键,方便查找。它有基本价格(第一个月),然后是其他月份的价格,所以可以很容易地计算出总价。
HTML 标记:
<form name="costcalculator">
<div class="package-type">
<select name="packageType" id="packageType" onchange="setMonths(this.value)">
<option value="gold">Gold</option>
<option value="silver">Silver</option>
<option value="bronze">Bronze</option>
</select>
</div>
<div class="months">
<select name="months" id="months">
<option value="1">1 month</option>
<option value="2">2 months</option>
<option value="3">3 months</option>
<option value="4">4 months</option>
<option value="5">5 months</option>
<option value="6">6 months</option>
<option value="7">7 months</option>
<option value="8">8 months</option>
<option value="9">9 months</option>
<option value="10">10 months</option>
<option value="11">11 months</option>
<option value="12">12 months</option>
</select>
</div>
<button type="button" onclick="calculatePrice()">Calculate</button>
<div id="price"></div>
</form>
Javascript代码:
var costs = {
'gold': {'basePrice': 199.99, 'pricePerMonth' : 99.5, 'maxMonths': 12},
'silver': {'basePrice': 150, 'pricePerMonth' : 75, 'maxMonths': 12},
'bronze': {'basePrice': 75, 'pricePerMonth' : 37.5, 'maxMonths': 2}
};
function setMonths(package)
{
var maxMonths = costs[package].maxMonths;
document.getElementById("months").innerHTML = ''; // Clear all options
for (var i = 1; i<=maxMonths; i++){
var opt = document.createElement('option');
opt.value = i;
opt.innerHTML = i + (i > 1 ? ' months' : ' month');
document.getElementById('months').appendChild(opt);
}
}
function calculatePrice()
{
var package = document.getElementById('packageType').value;
var months = document.getElementById('months').value;
var price = costs[package].basePrice + (costs[package].pricePerMonth * (months - 1));
document.getElementById('price').innerHTML = price.toFixed(2);
}
工作样本:
或者,你可以去,比如:
//data model
var membershipPlans = {
silver: {'1mo': 150, '2mo': 225, '3mo': 300},
gold: {'1mo': 199, '2mo': 298.5, '3mo': 398}
};
//don't punish me for that with downvotes , please :)
Array.prototype.unique = function() {
const resArr = [];
this.forEach(entry => {
if(resArr.indexOf(entry) == -1) resArr.push(entry);
})
return resArr;
};
//populate the view with possible options
const inputFields = {
package: document.getElementById('package'),
duration: document.getElementById('duration')
};
const cost = document.getElementById('cost');
inputFields.package.innerHTML = Object.keys(membershipPlans).sort().reduce((options, option) => options+=`<option value="${option}">${option}</option>`,'<option value="" selected disabled></option>');
inputFields.duration.innerHTML = Object.values(membershipPlans).map(entry => Object.keys(entry)).flat().unique().reduce((options, option) => options+=`<option value="${option}">${option}</option>`,'<option value="" selected disabled></option>');
//listen for input changes and display the cost
Object.values(inputFields).forEach(inputField => {
inputField.addEventListener('change', ()=>
cost.innerHTML = Object.values(inputFields).every(inputField => inputField.value !='') ? membershipPlans[inputFields.package.value][inputFields.duration.value]+' £' : '- £')
});
<div id="wrapper">
<span>Pick your </span>
<br>
<label>package:</label>
<select id="package" class="calcInput"></select>
<label>duration:</label>
<select id="duration" class="calcInput"></select>
<br>
<span>Your cost is:</span>
<br>
<span id="cost">- £</span>
</div>
所以我有一个 HTML 表单,它有两个下拉菜单和一个按钮。一个下拉菜单有 'package type',由 'Gold'、'Silver' 和 'Bronze' 组成。第二个下拉菜单有 'months' 和 12 个选项(最多 12 个月),然后是一个计算按钮。
现在,这是我希望我能解释清楚的一点...
如果您 select 'Silver' 和“1 个月”,费用为 £150.00。
如果您 select 'Silver' 和“2 个月”,费用为 225.00 英镑。
如果您 select 'Silver' 和“3 个月”,则费用为 £300.00。
依此类推(最多 12 个月)。所以上面的逻辑是第一个月 150.00 英镑,然后是额外月份 75 英镑。
但是如果你决定要一个'Gold'包,它会是这样的:
如果您 select 'Gold',并且“1 个月”,费用为 £199.00。
如果 select 'Gold' 和“2 个月”,费用为 298.50 英镑。
如果您 select 'Gold' 和“3 个月”,费用为 £398.00。
依此类推(最多 12 个月)。所以上面的逻辑是第一个月 199.99 英镑,然后是额外月份 99.50 英镑。
'Bronze' 也类似,除了 1 个月是 75.00 英镑,2 个月是 112.50 英镑(逻辑是第一个月 75.00 英镑,其他月份 37.50 英镑)。
我希望这是有道理的?下面是表单的 HTML,我知道它不起作用,但这只是为了尝试解释...
<form name="costcalculator">
<div class="package-type">
<select name="packageType" id="packageType">
<option value="199.00" label="Gold">Gold</option>
<option value="150.00" label="Silver">Silver</option>
<option value="75.00" label="Bronze">Bronze</option>
</select>
</div>
<div class="months">
<select name="months" id="months-bronze">
<option value="£75.00" label="1 month">1 month Bronze</option>
<option value="£112.50" label="2 months">2 months Bronze</option>
</select>
</div>
<div class="months">
<select name="months" id="months-silver">
<option value="£150.00" label="1 month">1 month Silver</option>
<option value="£225.00" label="2 months">2 months Silver</option>
</select>
</div>
<div class="months">
<select name="months" id="months-gold">
<option value="£199.00" label="1 month">1 month Gold</option>
<option value="£298.50" label="2 months">2 months Gold</option>
</select>
</div>
<button type="button" onclick="calculatePrice();showDiv();">Calculate</button>
</form>
我目前拥有的(有效的)如下,但它没有做我需要做的事情,这只是硬编码了成本,所以无论包类型如何,成本都是相同(除了每个包裹的初始成本不同):
<form name="costcalculator">
<div class="package-type">
<select name="packageType" id="packageType">
<option value="199.00" label="Gold">Gold</option>
<option value="150.00" label="Silver">Silver</option>
<option value="75.00" label="Bronze">Bronze</option>
</select>
</div>
<div class="months">
<select name="months" id="months">
<option value="100.00" label="1 month">1 month</option>
<option value="200.75" label="2 months">2 months</option>
<option value="275.25" label="3 months">3 months</option>
<option value="349.00" label="4 months">4 months</option>
<option value="369.99" label="5 months">5 months</option>
<option value="450.00" label="6 months">6 months</option>
</select>
</div>
<button type="button" onclick="calculatePrice();showDiv();">Calculate</button>
</form>
和JavaScript如下:
function calculatePrice(costcalculator){
var elt = document.getElementById("packageType");
var package = elt.options[elt.selectedIndex].value;
var elt = document.getElementById("months");
var months = elt.options[elt.selectedIndex].value;
package = parseFloat(package);
months = parseFloat(months);
var total = package+months;
document.getElementById("TotalPrice").value=total;
}
所以我认为上面的工作代码我已经快到了,但我越深入,就越意识到它还差得远。
它只需要一种方法,当用户 select 在第一个下拉菜单中输入包裹类型时,包含月份的第二个下拉菜单将(在幕后)填充紧邻用户 select 月数之前的新成本,然后如果用户随后决定 select 与上一个不同的套餐,第二个下拉菜单将再次刷新,但成本不同在后台。
根据 04FS 的评论,这是一个使用简单数据结构的简单解决方案。数据结构以包名为键,方便查找。它有基本价格(第一个月),然后是其他月份的价格,所以可以很容易地计算出总价。
HTML 标记:
<form name="costcalculator">
<div class="package-type">
<select name="packageType" id="packageType" onchange="setMonths(this.value)">
<option value="gold">Gold</option>
<option value="silver">Silver</option>
<option value="bronze">Bronze</option>
</select>
</div>
<div class="months">
<select name="months" id="months">
<option value="1">1 month</option>
<option value="2">2 months</option>
<option value="3">3 months</option>
<option value="4">4 months</option>
<option value="5">5 months</option>
<option value="6">6 months</option>
<option value="7">7 months</option>
<option value="8">8 months</option>
<option value="9">9 months</option>
<option value="10">10 months</option>
<option value="11">11 months</option>
<option value="12">12 months</option>
</select>
</div>
<button type="button" onclick="calculatePrice()">Calculate</button>
<div id="price"></div>
</form>
Javascript代码:
var costs = {
'gold': {'basePrice': 199.99, 'pricePerMonth' : 99.5, 'maxMonths': 12},
'silver': {'basePrice': 150, 'pricePerMonth' : 75, 'maxMonths': 12},
'bronze': {'basePrice': 75, 'pricePerMonth' : 37.5, 'maxMonths': 2}
};
function setMonths(package)
{
var maxMonths = costs[package].maxMonths;
document.getElementById("months").innerHTML = ''; // Clear all options
for (var i = 1; i<=maxMonths; i++){
var opt = document.createElement('option');
opt.value = i;
opt.innerHTML = i + (i > 1 ? ' months' : ' month');
document.getElementById('months').appendChild(opt);
}
}
function calculatePrice()
{
var package = document.getElementById('packageType').value;
var months = document.getElementById('months').value;
var price = costs[package].basePrice + (costs[package].pricePerMonth * (months - 1));
document.getElementById('price').innerHTML = price.toFixed(2);
}
工作样本:
或者,你可以去,比如:
//data model
var membershipPlans = {
silver: {'1mo': 150, '2mo': 225, '3mo': 300},
gold: {'1mo': 199, '2mo': 298.5, '3mo': 398}
};
//don't punish me for that with downvotes , please :)
Array.prototype.unique = function() {
const resArr = [];
this.forEach(entry => {
if(resArr.indexOf(entry) == -1) resArr.push(entry);
})
return resArr;
};
//populate the view with possible options
const inputFields = {
package: document.getElementById('package'),
duration: document.getElementById('duration')
};
const cost = document.getElementById('cost');
inputFields.package.innerHTML = Object.keys(membershipPlans).sort().reduce((options, option) => options+=`<option value="${option}">${option}</option>`,'<option value="" selected disabled></option>');
inputFields.duration.innerHTML = Object.values(membershipPlans).map(entry => Object.keys(entry)).flat().unique().reduce((options, option) => options+=`<option value="${option}">${option}</option>`,'<option value="" selected disabled></option>');
//listen for input changes and display the cost
Object.values(inputFields).forEach(inputField => {
inputField.addEventListener('change', ()=>
cost.innerHTML = Object.values(inputFields).every(inputField => inputField.value !='') ? membershipPlans[inputFields.package.value][inputFields.duration.value]+' £' : '- £')
});
<div id="wrapper">
<span>Pick your </span>
<br>
<label>package:</label>
<select id="package" class="calcInput"></select>
<label>duration:</label>
<select id="duration" class="calcInput"></select>
<br>
<span>Your cost is:</span>
<br>
<span id="cost">- £</span>
</div>