0

我的基本设置是我有一个隐藏的表单,直到通过单击进行选择,例如“成员、非成员、员工等”。单击选择后,表单将显示,其中的计费区域也将隐藏,直到表单总额超过 0 美元。

现在我遇到的问题是,一旦点击了 5 个选项中的 4 个,总数应该立即大于 0 美元。既然如此,计费部分应该自动触发,但我无法让我的第二个函数(进行计算的那个)监听 onclick 事件或 on change 事件的第一个函数。有没有一种方法可以在我的每个“if”语句中,最后我放入“执行计算函数”之类的代码?

像这样的东西:

if(section == 'Member') {
            var base_cost = 150;

            $("#commentTable,#ClinicStaff,#IMSNonMember,#Resident,#Student").fadeOut('slow', function() {
                // Animation complete.
            });
            $("#commentTable, #IMSMember").fadeIn('slow', function() {
                // Animation complete
            });
            $("input[name=SectionChosen]").val('Member');// Section selected, pass as hidden field for processing
                    ***$runNextFunction();***

        }

我试着做:$(" 'input[name^=PROD]', 'base_cost ").change(function() {

看看我是否可以让函数监视输入和基本成本字段的变化。但它不想触发。这是我的完整设置:

jQuery(function(ready){

    jQuery('.showForm').click(function(){

        var section = $(this).attr('target');
        var base_cost = ''; // reset base cost
        $("input[name=TOTAL]").val('');// Reset the Total field to 0 to hide the billing form again
        $("input[name^=PROD]").val('');// matches those that begin with 'PROD' and clears them
        $("input[name=SectionChosen]").val('');// Reset the section choice


        if(section == 'Member') {
            var base_cost = 150;

            $("#commentTable,#ClinicStaff,#IMSNonMember,#Resident,#Student").fadeOut('slow', function() {
                // Animation complete.
            });
            $("#commentTable, #IMSMember").fadeIn('slow', function() {
                // Animation complete
            });
            $("input[name=SectionChosen]").val('Member');// Section selected, pass as hidden field for processing

        }
        else if(section == 'Clinic') {
            var base_cost = 150;

            $("#commentTable,#IMSMember,#IMSNonMember,#Resident,#Student").fadeOut('slow', function() {
                // Animation complete.
            });
            $("#commentTable, #ClinicStaff").fadeIn('slow', function() {
                // Animation complete
            });
            $("input[name=SectionChosen]").val('Clinic');// Section selected, pass as hidden field for processing
        }
        else if(section == 'Nonmember') {
            var base_cost = 250;

            $("#commentTable,#IMSMember,#ClinicStaff,#Resident,#Student").fadeOut('slow', function() {
                // Animation complete.
            });
            $("#commentTable, #IMSNonMember").fadeIn('slow', function() {
                // Animation complete
            });
            $("input[name=SectionChosen]").val('Nonmember');// Section selected, pass as hidden field for processing
        }
        else if(section == 'Resident') {
            var base_cost = 75;

            $("#commentTable, #IMSMember,#ClinicStaff,#IMSNonMember,#Student").fadeOut('slow', function() {
                // Animation complete.
            });
            $("#commentTable, #Resident").fadeIn('slow', function() {
                // Animation complete
            });
            $("input[name=SectionChosen]").val('Resident');// Section selected, pass as hidden field for processing
        }
        else if(section == 'Student') {
            var base_cost = 0;

            $("#commentTable,#IMSMember,#ClinicStaff,#IMSNonMember,#Resident").fadeOut('slow', function() {
                // Animation complete.
            });
            $("#commentTable, #Student").fadeIn('slow', function() {
                // Animation complete
            });
            $("input[name=SectionChosen]").val('Student');// Section selected, pass as hidden field for processing
        }


        // Calculate order Total
        $('input[name^=PROD]').change(function() { 

            // Total cost of order, is equal to base cost + any additional selectoins made below
            var order_total = base_cost;

            // Run through all the form fields
            $('input[name^=PROD]').each(function(i) {

                // Get the current field and its name
                var form_name = $(this).attr('name');

                // If so, extract the price from the name
                var item_price = parseFloat(form_name.substring(form_name.lastIndexOf("_") + 1));

                // Get the quantity
                var item_quantity = parseInt($(this).val(), 10);

                // Update the order total
                if (item_quantity >= 0) {
                    order_total += item_quantity * item_price
                }

            });

            // Display the total rounded to two decimal places
            $('input[name=TOTAL]').val((Math.round(order_total*100)/100).toFixed(2));

            // Show the billing portion if total is not 0
            if (order_total > 1) {
                // show the section with the billing portion
                $("#BillingPortion").show();
            }
            else {
                // hide billing portion if total is 0
                $("#BillingPortion").hide();
            }
        });


    });
});

正如您从此处的 jsFiddle中看到的那样,表单有效,如果您单击一个选择,然后通过在客人中插入一个数字来添加更多“成本”,然后显示计费部分。但这还不够好,因为如果他们不想要任何客人,帐单部分仍应显示他们的基本成本是否大于 0 美元。

如果有人能指出我正确的方向,那就太好了。

此外,我在 jQuery 方面还很缺乏经验,所以我确信我的代码可以变得更加 DRY,并且对你们中的一些人来说可能看起来很糟糕,但至少这是一个开始。

4

2 回答 2

3

好吧,我继续对您的代码进行了一些重构。这是结果。

部分链接的标记

您正在使用链接在表单之间切换。但是,链接本身(通过您的 JavaScript 代码)间接设置了一个名为SectionChosen. 您可以更清楚地表明单击链接代表一个选择,并且该选择也是表单数据的一部分。因此,使用一组单选框来选择一个选项比使用一组语义上不相关的链接更合适。由于单选框是带有 a和 a的适当input元素,因此它们可以替换您原来的隐藏输入。奖励:您甚至不需要任何 JavaScript 来设置值,因为所选单选框的值将被提交!namevalueSectionChosen

<label><input type="radio" name="SectionChosen" value="Member" /> I am an IMS Member Physician</label>
<label><input type="radio" name="SectionChosen" value="Clinic" /> I am a Clinic/Hospital Administrators or Clinic Staff</label>
...

检索基本成本

在处理程序中,您尝试设置一个根据单击的链接click调用的局部变量来计算总数。base_cost问题是您将新的处理程序绑定到input'schange事件,堆叠在先前选择的链接中先前绑定的处理程序上。看起来它正在工作,但实际上您正在计算大量总数,只有最后一个绑定处理程序产生最终输出值。

实际上,基本成本是所选部分的属性,并且在切换部分和更改表单输入时都应该很容易访问。做到这一点的一个好方法是将每个选择的基本成本作为属性存储在单选框上。data-*专门针对此类自定义数据需求引入了属性:

<input type="radio" name="SectionChosen" value="Member" data-base-cost="150" />

然后可以通过以下方式检索基本成本:

var base_cost = $(...).data('base-cost');

要从当前选定的部分获取基本成本,只需查找当前选定的单选框:

var base_cost = $('input[name=SectionChosen]:checked').data('base-cost');

这里的所有都是它的!您不再需要change从处理程序中绑定处理click程序,因为您可以在标记本身中找到基本成本。这意味着您只需要change在 DOM 准备好时绑定处理程序一次,因为它应该是。

进一步改进

总是有更多改进的空间。例如,您可以为实际的表单部分提供data-section与部分名称匹配的属性,而不是id. 这样,您可以更轻松地选择需要隐藏的部分和需要显示的部分。无需写下相同的 ID 选择器列表,您只需选择类似.section[data-section="Member"]and之类的东西.section:not([data-section="Member"])。哎呀,该data-section值甚至可以来自所选的单选框本身,您甚至不再需要一棵长if...else if树!

于 2013-02-11T14:55:20.707 回答
1

有几件事。通过在处理程序中进行$('input[name^=PROD]').change绑定,您click将在每次触发处理程序时添加相同的处理click程序。这意味着在第二次单击时,当您更改输入时,它将触发两次。这可能不是你想要的。

其次,为什么不将计算总数的部分抽象为您可以在click处理程序中调用的单独函数。

function calculateTotal() {
    // your code to calculate the total and make part of the UI visible if more than
    // $0.
}

然后你也可以让你的change处理程序调用它:

 $('input[name^=PROD]').change(function() { 
     calculateTotal();
 }
于 2013-02-11T14:16:09.267 回答