简体   繁体   English

使用javascript计算动态输入框的折扣

[英]Discount calculation of dynamic input box using javascript

I am trying to calculate discounted price which I am able to do without anyproblem for a single item. 我正在尝试计算折扣价格,我可以对单个项目没有任何问题。 I also have 'add more' button to add many item as I can. 我也有“添加更多”按钮,可以添加很多项目。 So here, I started facing problem in calculating the discounted price for these dynamically added input field. 因此,在这里,我开始在为这些动态添加的输入字段计算折价时遇到问题。

My default discount calculation script for single item is 我对单个商品的默认折扣计算脚本是

$('#discount_1').change(function(){
            var quantity=$('#qty_1').val();
           var percent=$('#discount_1').val();
            var price=$('#price_1').val();
            var tprice = price * quantity
            var discountpercent=percent / 100;
            var discountprice=(tprice * discountpercent );

            $('#total_1').val(tprice - discountprice);

        });

I tried changing it to the following 我尝试将其更改为以下内容

 $(":input[id^='discount_']").change(function(){
            var quantity=$(":input[id^='qty_']").val();
           var percent=$(":input[id^='discount_']").val();
            var price=$(":input[id^='price_']").val();
            var tprice = price * quantity
            var discountpercent=percent / 100;
            var discountprice=(tprice * discountpercent );

            $(":input[id^='total_']").val(tprice - discountprice);

        });

to calculate discount for all the item set having id attribute that starts with qty_ , which actually does not seem to work properly. 计算具有id属性(以qty_开头)的所有项目集的折扣,这实际上似乎无法正常工作。

here is my jsFiddle 这是我的jsFiddle

I've modified this to remove all id s. 我已对此进行了修改,以删除所有id This will clean up a lot of extra crap. 这将清理很多多余的废话。 Here is a fiddle: http://jsfiddle.net/B5T6R/1/ 这是一个小提琴: http : //jsfiddle.net/B5T6R/1/

The solution involved event delegation. 解决方案涉及事件委托。 The problem with $(":input[id^='discount_']").on('change' is that the future tr s don't exist yet , so there is nothing to bind to! $(":input[id^='discount_']").on('change'在于,将来的tr 尚不存在 ,因此没有什么可绑定的!

The solution is: 解决方案是:

$("#InputsWrapper").on('change', '.discount'

Which will listen for all future changes on the InputsWrapper table as a whole, not just to the discount elements. 它将侦听整个InputsWrapper表上的所有将来更改,而不仅是折扣元素。

The problem is that the selectors you are using will always select the first input that matches the selector. 问题在于您正在使用的选择器将始终选择与选择器匹配的第一个输入。

So, (":input[id^='qty_']") will always match the input on the first row. 因此,(“:input [id ^ ='qty_']”)将始终与第一行的输入匹配。

I suggest: 我建议:

  1. Rebind the "change" event evertime AddButton is clicked. 每次单击AddButton时,重新绑定“更改”事件。 This will require .unbind() as well. 这也将需要.unbind()。
  2. Add class "discount" to all discount inputs. 将类别“折扣”添加到所有折扣输入中。
  3. Change the selectors for quantity, price, etc to be relative to the input that was changed. 将数量,价格等选择器更改为相对于已更改的输入。

IE: IE:

$('.discount').unbind().change(function(){
  var $parentRow = $(this).parent().parent();
  var quantity=$(":input[id^='qty_']", $parentRow).val();
});

It's not a great idea to use all these id's: #qty_1, #qty_2, etc. Instead give all your inputs the same class names to hook into, for example: 使用所有这些ID(例如#qty_1,#qty_2等)不是一个好主意。相反,请为所有输入提供相同的类名称以供使用,例如:

<input class='discount' type='text' name='discount'/>
<input class='quantity' type='text' name='quantity'/>

Then use good ole Jquery to traverse the DOM and fetch the relevant data. 然后使用优质的ole Jquery遍历DOM并获取相关数据。 In this case you have to climb to the closest td and then back down to get the .quantity class, as so: 在这种情况下,您必须爬到最接近的td,然后下移以获得.quantity类,如下所示:

 $(".discount").change(function(){
        var quantity = $(this).closest('td').find('.quantity').val();
    });

Hope this helps. 希望这可以帮助。

You are running into a couple of problems. 您遇到了两个问题。

First, only the ":input[id^='discount_']" that exist on your page when the DOM is initialized have this change handler added to them - all new rows added via the the Add More Field link will not have this handler bound. 首先,仅在初始化DOM时在页面上存在的":input[id^='discount_']"上添加了此更改处理程序-通过“添加更多字段”链接添加的所有新行将没有此处理程序界。 You can get around this by attaching the handler to the container all of your fields are in via .on , so that every change event fired within that container will be checked against the selector specified. 您可以通过将处理程序附加到容器.on解决此问题,您可以通过.on来访问所有字段,以便针对指定的选择器检查该容器内触发的每个change事件。 I've forked your fiddle to demonstrate: http://jsfiddle.net/gLz9B/1/ 我已分叉了您的小提琴以进行演示: http : //jsfiddle.net/gLz9B/1/

$('#InputsWrapper').on("change", ":input[id^='discount_']", function(){
   ...
});

The second issue is that the qty_, total_, price_, and discount_ selectors you are using will return arrays, rather than being limited to the specific row where the change is occurring. 第二个问题是您使用的qty_,total_,price_和discount_选择器将返回数组,而不是局限于发生更改的特定行。 In my fiddle fork I did a string replace to get the unique number attached to the id of the element, and then build the ids of all of the other inputs rather than using =^ to select them. 在我的提琴琴叉中,我进行了字符串替换,以将唯一编号附加到元素的id上,然后构建所有其他输入的id,而不是使用= ^进行选择。 This is not the only way to limit your scope, but it works given your sample code. 这不是限制范围的唯一方法,但是在给出示例代码的情况下它可以工作。

var id = this.id.replace('discount_','');
var quantity=$("#qty_" + id).val();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM