簡體   English   中英

jQuery IF語句根據兩個下拉列表和一個文本框字段計算費用

[英]jQuery IF statements to calculate fees based on two drop downs and a textbox field

這是一個費用計算器的示例,它將根據用戶選擇和回答的內容運行實時計費(jQuery)。 我試圖弄清楚如何根據兩個下拉菜單和一個文本框字段創建許多IF語句來計算費用。

我想要實現的是一個jQuery IF函數,當用戶選擇出生月份(計算月份)時,用onChange="calculateTotal()"計算,這將計算從現在到下一個生日的幾個月。 但我需要根據車輛下降(車身)和輸入的重量(ew)來確定IF功能,這三項將決定價格。 如下面的示例和下面的代碼段。

例如(三種情況):
[1]如果選擇從現在起4-12個月,以及重量低於2499的2dr車輛,價格將是28.10加到運行費用計算器上。
[2]如果選擇從現在起4-12個月,以及重量在2500和3499之間的2dr車輛,價格將是36.10加到運行費用計算器上。
[3]如果選擇從現在起4-12個月,以及重量大於3500的2dr車輛,價格將是46.10加到運行費用計算器上。

長話短說我想要一個IF函數來計算onChange="calculateTotal()"var titleFees = getProofOfOwnership() + (New IF Function); 取決於(車體)選擇&(ew)輸入然后IF(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&nbsp;&nbsp;</label><br/> <label class='radiolabel'><input type="radio" name="ownership" value="FL Title"/>Florida Certificate of Title&nbsp;&nbsp;</label><br/> <label class='radiolabel'><input type="radio" name="ownership" value="OOS Title"/>Out-of-state Certificate of Title&nbsp;&nbsp;</label> </div> <br/> <br/> <label for='month1'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;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> 

我建議采用一種方法,不僅可以清理代碼,還可以使計算,測試,驗證和添加新功能變得更容易。 稍微清理一下可以使您的應用程序更容易擴展和調試,但更重要的是,對於您的情況,一點點清理將幫助您計算您正在尋找的值並解決您的問題直截了當的方式。


建議#01:組織您的代碼

現在你有一些功能試圖一次做太多。 如果你保持簡單並讓每個函數“特化”特定的東西,函數就更容易測試和調試。 例如,在$("#month1")下拉列表的on.("change")處理程序中,您正在嘗試一次執行所有操作,這是您遇到麻煩的地方。 相反,您需要為#month1下拉列表分配.on("change")處理程序,這將決定是否需要顯示#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對象輕松完成此操作。

這很方便,原因如下:

  1. 它使所有表單值“全局可用” 而不會混淆全局命名空間
  2. 它使您的表單值易於在calculateTotal()函數中“計算”,因為您只需要查詢此一個對象以獲取插入等式的值。
  3. 您可以隨時獲得整個表單的“實時快照”。 這對於將表單結果測試,調試,驗證或打印到控制台或瀏覽器非常方便。
  4. 它允許您在不中斷工作流程的情況下不斷向費用計算器應用添加功能/值。
  5. 通過始終擁有完整快照,可以更輕松地發現功能中的錯誤,並查看各個輸入如何影響其他輸入或整體計算。

因此,我將創建一個名為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 ,這是我已將所有“實用程序”函數附加到的對象。 您不一定需要在自己的程序中執行此操作,您可以像平常一樣編寫函數並調用它們,但在我的示例應用程序中,我使用了一種名為The Revealing Module Pattern的設計模式 ,它有助於分組常用功能,是使代碼更具可讀性的又一步。

步驟#02:在calculateTotal()查詢FC對象

現在您的表單輸入是自包含的,並且他們都知道如何更新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()函數,因此它會使您的表單具有“實時”感覺。 您還可以在此功能中更新應用的其他部分。

您可以查看一個jsfiddle,我將所有這些想法付諸實踐 我添加了一個HUD(出現在右上角的“黑匣子”),它將始終為您提供FC對象中包含的數據的實時快照。 如果HUD妨礙了事情,只需在屏幕上“點擊拖動”它就可以將其移開。

希望這可以幫助! 祝好運!

當你不想手工輸入一個巨大的IF-ELSE時,你就是在正確的軌道上 - 如果它重復的話。 (你在最后一行中已經錯過了一個“0”,有時它是“>”,有時是“> =”:-)。

您可以做的是設置一種方法來保存不同的閾值和違反閾值時的值。 所以代碼不是用例而是算法。 您甚至可以獲得更多創意,例如將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); // 6

HTH。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM