这是一个收费计算器的示例,该计算器将根据用户选择和回答的内容运行实时收费统计(jQuery)。我试图弄清楚如何创建许多IF语句,以计算基于两个下拉列表和一个文本框字段的费用。
我想要完成的是一个jQuery IF函数,它用一个onChange="calculateTotal()"计算,当用户选择出生月份(计算月份)时,这将计算从现在到下一个生日的几个月。但是我需要基于车辆下坠(车体)的IF函数,而输入的重量(ew)将决定价格。喜欢下面的例子和下面的片段。
例如(三种情况):
1如果从现在起选择4-12个月,以及重量在2499以下的2dr车辆,运行费用计算器将增加28.10的价格。
2如果从现在起选择4-12个月,以及重量在2500到3499之间的2dr车辆,价格将被添加到运行费用计算器36.10。
3如果从现在起选择4-12个月,以及重量大于3500的2dr车辆,则运行费用计算器将增加价格46.10。
所以长话短说,我想要一个计算onChange="calculateTotal()"和var titleFees = getProofOfOwnership() + (New IF Function);的IF函数,它取决于(车体)选择和(ew)进入&那么如果(monthsToGo)等于4乘12,它这样和这样的价格。如果(monthsToGo)是1,2,3,13,14或15,那么价格将按比例分配,因此它也会有自己的价格。
如果是1个月,他们要求用户支付当月和全年13个月的费用,但如果是2个月,则让用户选择2个月或14个月,与3个月或15个月相同(如计算月份减少),但一旦支付4个月(无论4至12个月,他们都支付全额)。
可怕的是,我必须找出50个不同的组合,所以希望我能很容易地理解我对jQuery知识的极度缺乏。
如有任何帮助,将不胜感激:)
http://jsfiddle.net/fzy9yev3/15/
请参阅下面的片段:
//Calculate Months
(function() {
var monthsToGo;
var Fee = makeStruct("monthSect vehicleBody ewSect price");
var fees = [
new Fee(/*monthSect*/2, /*vehicleBody*/0, /*ewSect*/0, /*price*/45.10),
new Fee(3, 1, 0, 55.10),
new Fee(4, 2, 0, 65.10),
new Fee(13, 3, 0, 75.10),
new Fee(14, 4, 0, 85.10),
new Fee(15, 5, 0, 95.10)
];
$(document).ready(function() {
$('#month2, #month3').hide();
});
$(document).on('change', '#ownership input', function(){
calculateTotal();
//statedropDown($(this).val());
});
$(document).on('change', '#month1', function() {
// ignore blank options
if ($(this).val() == '') { return; }
var vehicle = $('#vehiclebody').val();
var ew = $('#ew').val();
var ewSect = 0;
var monthSect = 0;
var titleFees = 0;
if(vehicle == '' || ew == ''){
alert('Please enter Vehicle Type and/or Empty Weight');
$(this).val('');
return;
}
var today = new Date();
var birthdate = new Date();
birthdate.setMonth($('#month1').val());
monthsToGo = (today.getMonth() < birthdate.getMonth())
? birthdate.getMonth() - today.getMonth()
: (12 - today.getMonth()) + birthdate.getMonth()
;
$('#month2').hide();
$('#month3').hide();
if (monthsToGo == 1) {
this.monthsToGo = 13;
alert(this.monthsToGo);
} else if (monthsToGo == 2) {
$('#month2').show();
} else if (monthsToGo == 3) {
$('#month3').show();
} else {
this.monthsToGo = monthsToGo;
alert(this.monthsToGo);
}
if(monthsToGo >= 4 || monthsToGo <= 12){
monthSect = 4;
//Set monthsToGo to 4 if it is in this range for the linked list so
//categorizing is easier
//6 possibilities for dates -- 2, 3, 4, 13, 14, 15
}
else monthSect = monthsToGo;
switch(vehicle){
case 0://2dr
case 2://4dr
case 4://convertible
case 5://van
if(ew < 2500) ewSect = 0;
else if(ew >= 2500 && ew < 3500) ewSect = 1;
else if(ew >= 3500) ewSect = 2;
break;
case 1://pickup
if(ew < 2000) ew = 0;
else if(ew >= 2000 && ew <= 3000) ewSect = 1;
else if(ew > 3000 && ew <= 5000) ewSect = 2;
break;
case 3://trucks
if(ew > 5000 && ew < 6000) ewSect = 0;
else if(ew >= 6000 && ew < 8000) ewSect = 1;
else if(ew >= 8000 && ew < 10000) ewSect = 2;
else if(ew >= 10000 && ew < 15000) ewSect = 3;
else if(ew >= 15000 && ew < 20000) ewSect = 4;
else if(ew >= 20000 && ew <= 26000) ewSect = 5;
else if(ew > 26000 && ew < 35000) ewSect = 6;
else if(ew >= 35000 && ew < 44000) ewSect = 7;
else if(ew >= 44000 && ew < 55000) ewSect = 8;
else if(ew >= 55000 && ew < 62000) ewSect = 9;
else if(ew >= 62000 && ew < 72000) ewSect = 10;
else if(ew >= 72000 && ew <= 8000) ewSect = 11;
break;
}
console.log('Month Section (monthSect): ' + monthSect + '; Vehicle: ' + vehicle + '; EW Section (ewSect): ' + ewSect);
for(var i = 0; i < fees.length; i++){
console.log('infor');
if(fees[i].monthSect == monthSect && fees[i].vehicleBody == vehicle && fees[i].ewSect == ewSect) {
titleFees = getProofOfOwnership() + fees[i].price;
console.log('Title Found! ' + titleFees);
$('#totalPrice').text('Estimated Transfer Fees $' + titleFees);
break;
}
}
});
$('#month2, #month3').on('change', function() {
this.monthToGo = $(this).val();
alert(this.monthToGo);
});
}($))
//Fee Calculator
//Setting Proof of Ownership Prices
//Set up an associative array
var title_prices = new Array();
title_prices["MCO"]=68.25;
title_prices["FL Title"]=78.25;
title_prices["OOS Title"]=88.25;
// Proof of Ownership Radio Buttons
function getProofOfOwnership()
{
var proofOfOwnership=0;
//Get a reference to the form id="form"
var theForm = document.forms["form"];
//Get a reference to the title the user Chooses name=ownerShip":
var ownerShip = theForm.elements["ownership"];
//Here since there are 4 radio buttons ownerShip.length = 4
//We loop through each radio buttons
for(var i = 0; i < ownerShip.length; i++)
{
//if the radio button is checked
if(ownerShip[i].checked)
{
proofOfOwnership = title_prices[ownerShip[i].value];
//If we get a match then we break out of this loop
//No reason to continue if we get a match
break;
}
}
//We return the proofOfOwnership
return proofOfOwnership;
}
function calculateTotal()
{
var titleFees = getProofOfOwnership();
var divobj = document.getElementById('totalPrice');
divobj.style.display='block';
divobj.innerHTML = "Estimated Transfer Fees $"+titleFees;
}
function hideTotal()
{
var divobj = document.getElementById('totalPrice');
divobj.style.display='none';
}
function makeStruct(names) {
var names = names.split(' ');
var count = names.length;
function constructor() {
for (var i = 0; i < count; i++) {
this[names[i]] = arguments[i];
}
}
return constructor;
}<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<form name="form">
<div id="ownership">
<label class='radiolabel'><input type="radio" name="ownership" required="yes" message="Please select proof of ownership." value="MCO"/>Manufacturer's Statement of Origin </label><br/>
<label class='radiolabel'><input type="radio" name="ownership" value="FL Title"/>Florida Certificate of Title </label><br/>
<label class='radiolabel'><input type="radio" name="ownership" value="OOS Title"/>Out-of-state Certificate of Title </label>
</div>
<br/>
<br/>
<label for='month1'> Calculate Months:</label>
<select name="month1" id="month1" size="1">
<option value="">Choose a Month</option>
<option value="0">January</option>
<option value="1">February</option>
<option value="2">March</option>
<option value="3">April</option>
<option value="4">May</option>
<option value="5">June</option>
<option value="6">July</option>
<option value="7">August</option>
<option value="8">September</option>
<option value="9">October</option>
<option value="10">November</option>
<option value="11">December</option>
</select>
<select name="month2" id="month2" size="1">
<option value="">Choose an Option</option>
<option value="2">2</option>
<option value="14">14</option>
</select>
<select name="month3" id="month3" size="1">
<option value="">Choose an Option</option>
<option value="3">3</option>
<option value="15">15</option>
</select>
<br/>
<select name="vehiclebody" id="vehiclebody" required="yes" message="Please select body." size="1">
<option value="">Choose a Vehicle</option>
<option value="0">2Dr</option>
<option value="1">Pickup</option>
<option value="2">4dr</option>
<option value="3">Truck</option>
<option value="4">Convertible</option>
<option value="5">Van</option>
</select>
<label for="ew">Empty Weight:</label>
<input type="text" name="ew" id="ew"/>
<br/>
<br/>
<div id="totalPrice"></div>
</form>
发布于 2014-11-02 18:01:19
我建议采取一种方法,不仅可以清理代码,还可以简化计算、测试、验证和添加新功能。稍微清理一下就可以大大简化应用程序的扩展和调试,但更重要的是,对于您的情况,一点点清理将帮助您计算正在寻找的值,并以直接的方式解决您的问题。
建议01:组织您的代码
现在,您有一些函数试图同时做太多的工作。如果函数保持简单,并让每个函数“专门化”于特定的内容,那么测试和调试它们就更容易了。例如,在您的on.("change")处理程序中,您的$("#month1")下拉列表中,您试图同时完成所有操作,这是您遇到麻烦的地方。相反,您需要为您的.on("change")下拉列表分配一个#month1处理程序,这将确定是否需要显示#month2或#month3,然后指定一个单独的.on("change")处理程序来收集这两个下拉列表中的值。当你在做的时候,你会想要将任何“专门的”功能分解到它自己的函数中,以保持代码的整洁。
#month1 --更改处理程序的一个示例,它只是试图一次做太多的事情:
$(document).on('change', '#month1', function() {
// 1. Stop if Empty Weight or Vehicle Type are Blank
// 2. Get the user's birth month
// 3. Calculate the number of months until the user's Birthday
// 4. Calculate the monthSect value
// 5. Calculate the ewSect value
// 6. Lookup the Proof of Ownership Fees
// 7. Lookup prorated Title Fees
});相反,让这一个函数尝试在一个地方预置所有这些任务,最好是将任何“专门”功能转移到每个都有明确目的的简单、可理解的函数中。您可以创建如下函数名:
// Lookup the Prorated Fee
getProratedFeeFromFeeList(monthSect, vehicleBody, ewSect);
// Get the "Payment Plan Details" based on user's birth month
getPaymentPlanDetailsBasedOnBirthMonth(birthMonth);
// Lookup the ewSect (Empty Weight Section)
getWeightSectionFromVehicleClassAndEmptyWeight(vehicleClass, emptyWeight);注意:我喜欢使用长的、描述性的函数名,这样函数的用途就非常清楚,从而提高了代码的可读性。如果您使用的代码编辑器具有良好的代码完成功能,像这样的长函数名称不会增加大量额外的输入,但对我来说,我个人喜欢高可读性和自文档化代码的好处。
建议02:将表单值保存在一个地方。
继续建议1,因为您的表单意味着有一个“实时统计”,如果您已经设置了一个系统来随时保存窗体值的快照,那么它将为您省去很多麻烦。您可以通过Javascript对象轻松地做到这一点。
--这很方便,原因有几个:
calculateTotal()函数中“计算”,因为您只需查询这一个对象就可以将值插入到您的方程中。因此,我将创建一个名为FC (简称“费用计算器”)的全局对象来存储运行费用计算所需的所有值。创建这样的“费用计算器对象”:
var FC = FC || {};现在,这个FC对象将对访问FC范围的所有函数可用。向FC对象添加值可以通过以下两种方式之一完成:
// First method: In FC's Declaration
var FC = { monthSect: 0, vehicleBody: null };
// Second Method: Using dot notation
var FC = {};
FC.monthSect = 0;
FC.vehicleBody = null;注意:请记住,始终可以使用点表示法为已经声明的对象赋值,因此这两种方法的组合是完全有效的。
现在可以使用点表示法从FC对象中更新和读取值,例如:
// Get the monthSect variable
var monthSect = FC.monthSect;
// Assign or update FC.monthSect
FC.monthSect = someNewValue; 我对你问题的解决办法
使用上面提到的一些建议,这就是我解决您的问题的方法:
步骤01:每个表单输入侦听更改、更新FC并调用calculateTotal()
// When the user updates the #month2 or #month3 dropdown
// Update FC.monthSect
$(document).on('change', '#month2, #month3', function() {
FC.monthSect = $(this).val();
calculateTotal();
});
// When someone updates the Empty Weight value
// update FC.emptyWeight
$(document).on('change blur keyup', '#ew', function() {
var emptyWeight = $(this).val();
FC.emptyWeight = emptyWeight ? emptyWeight : null;
var vehicle = $('#vehiclebody').val();
if (vehicle && emptyWeight) {
FC.ewSect = FCUtils.getWeightSectionFromVehicleClassAndEmptyWeight(FC.vehicleBody, FC.emptyWeight);
FCUtils.getProratedFeeFromFeeList(FC.monthSect, FC.vehicleBody, FC.ewSect);
}
calculateTotal();
});
// When the user updates the #month1 drop-down
// Update FC.monthSect and assign FC.proratedPrice
$(document).on('change', '#month1', function() {
// Reset to the defaults
$("#month2").hide();
$("#month3").hide();
FC.monthSect = null;
// ignore blank options
if ($(this).val() == '') {
calculateTotal();
return;
};
var selecteduserBirthday = $(this).val();
var paymentPlanDetails = FCUtils.getPaymentPlanDetailsBasedOnBirthMonth(selecteduserBirthday);
var monthsToGo = paymentPlanDetails.monthsUntilBirthday;
if (paymentPlanDetails.paymentPlan == "2or14months") {
$("#month2").show();
} else if (paymentPlanDetails.paymentPlan == "3or15months") {
$("#month3").show();
}
// Assign FC.monthSect if monthSect = 4-12 | 1 | 13
if (monthsToGo >= 4 && monthsToGo <= 12) {
FC.monthSect = 4;
} else if (monthsToGo == 1 || monthsToGo == 13) {
FC.monthSect = 13;
}
FCUtils.getProratedFeeFromFeeList(FC.monthSect, FC.vehicleBody, FC.ewSect);
calculateTotal();
});注意:您可能已经注意到,一些函数名前面加上了FCUtils__,这是我附加了所有“实用程序”函数的一个对象。您不一定需要在自己的程序中这样做,您可以像通常那样编写函数并调用它们,但是在我的示例应用程序中,我使用了一个名为http://addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript的设计模式,它帮助分组公共功能,也是提高代码可读性的又一步。
步骤02:在FC中查询calculateTotal()对象
既然表单输入是独立的,而且它们都知道如何在FC对象上更新各自的值,那么calculateTotal()函数所需要做的就是查询要计算的值的FC对象:
function calculateTotal() {
var titleFees = FC.rvPrice +
FC.titlePrice +
FC.lienPrice +
FC.purchaseDatePrice +
FC.IRFPrice +
FC.proratedPrice +
FC.specialFee;
FC.totalPrice = titleFees;
// Now you can update the browser with this data
$("#totalPrice").text(titleFees);
}因为calculateTotal()函数是在表单的每个“更改”事件上调用的,所以它给表单带来了“活的”感觉。您还可以在此功能中更新应用程序的其他部分。
你可以review a jsfiddle where I put all these ideas into practice here。我添加了一个HUD (显示在右上角的“黑匣子”),它将为您提供一个包含在FC对象中的数据的实时快照。如果HUD阻碍了事情的发展,只需“点击拖动”它在屏幕周围移动它就可以了。
希望这能有所帮助!祝好运!
发布于 2014-10-29 22:30:11
当你不想用手输入一个巨大的if --否则--(尤其是如果重复的话),你就走在正确的轨道上了。(在最后一行中已经遗漏了一个"0“,有时是">”,有时是">=“:-)。
您可以做的是设置一个方法,以保存不同的阈值和值时,该阈值被打破。所以,编写代码不是用例,而是algo。您甚至可以获得更多的创造性,例如,将this.get = function(wt)更改为this.get = function(wt, default_value)并插入默认值。诸若此类。
var LevelFinder = function(){
this.range = []; // always sorted when new values added
this.add = function( over_wt, sel_value ) {
this.range.push({over_wt:over_wt, sel_value:sel_value});
this.range.sort(function(x,y){return x.over_wt - y.over_wt;});
};
this.get = function(wt){
var x, i;
for ( i = 0; i < this.range.length; ++i ) {
if ( this.range[i].over_wt > wt ) {
if ( i > 0 ) x = this.range[i-1].sel_value;
return x;
}
}
return this.range[i-1].sel_value;
}
} ;
var ewFinder = new LevelFinder();
ewFinder.add(10000, 3);
ewFinder.add(20000, 5);
ewFinder.add(26000, 6);
ewFinder.add(15000, 4); // this is entered out of sequence but will get sorted by the adder
ewFinder.get(17000); // produces 4 in console
ewFinder.get(22000); // 5
ewFinder.get(0); // undefined
ewFinder.get(999000); // 6HTH。
https://stackoverflow.com/questions/26596109
复制相似问题