使用jquery根据4个输入的总和设置数字输入max

时间:2015-09-23 03:41:09

标签: javascript jquery html

我有4个输入字段,我需要所有字段的总数不超过100.我想设置要更改的字段的最大值。

我一直在尝试调整keyup()上的值,然后将当前其他字段的总数与最大值进行区分。似乎工作了一点然后停止。

JSfiddle example

var $fieldA = $('#acf-field_55dc6669f5235');
var $fieldB = $('#acf-field_55dc6699f5236');
var $fieldC = $('#acf-field_55dc66d3f5237');
var $fieldD = $('#acf-field_55dc6713f5238');
var total;

function getTotal() {
   total = parseInt($fieldA.val()) + parseInt($fieldB.val()) +      parseInt($fieldC.val()) + parseInt($fieldD.val());
}
$fieldA.change(function () {
   $this = $(this);
   var input = parseInt($this.val());

   var otherFields = parseInt($fieldB.val()) + parseInt($fieldC.val()) + parseInt($fieldD.val());
   var max = 100 - otherFields;

   $this.attr("max", max);
});
$fieldB.change(function () {
   $this = $(this);
   var input = parseInt($this.val());

   var otherFields = parseInt($fieldA.val()) + parseInt($fieldC.val()) + parseInt($fieldD.val());
   var max = 100 - otherFields;

   $this.attr("max", max);
});
$fieldC.keyup(function () {
    $this = $(this);
    var input = parseInt($this.val());

    var otherFields = parseInt($fieldA.val()) + parseInt($fieldB.val()) + parseInt($fieldD.val());
    var max = 100 - otherFields;

    $this.attr("max", max);

});
$fieldD.change(function () {
   $this = $(this);
   var input = parseInt($this.val());

   var otherFields = parseInt($fieldA.val()) + parseInt($fieldB.val()) + parseInt($fieldC.val());
   var max = 100 - otherFields;

   $this.attr("max", max);
});
getTotal;

6 个答案:

答案 0 :(得分:2)

我就是这样做的,详见代码中的注释:

$('.acf-is-appended').focus(function(){
   $(this).val('');  // clear the current input when it is focused
   var total = 0; // create a var to track the current total
   $('.acf-is-appended').each(function(){  // loop through each element
       total = total + Number($(this).val()); // add the current value to the running total
      $(this).attr('max', Number($(this).val())); // set each element's max to the currently held value
   });
   var remaining = 100 - total; // figure out how much is left before you hit 100
   $(this).attr('max', remaining); // set the max on the current element to match the remaining limit
});

// that will handle the stepper, note that the max wont prevent the user typing in a value higher than the limit
// if you want, you can also make it so typing in a greater value will default to the max value
$('.acf-is-appended').keyup(function(){
    if(Number($(this).val()) > Number($(this).attr('max'))){
        $(this).val($(this).attr('max'))
    }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="acf-field_55dc6669f5235" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc6669f5235]" value="30" placeholder="" type="number">
</div>
<div class="acf-input-wrap">
  <input id="acf-field_55dc6699f5236" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc6699f5236]" value="5" placeholder="" type="number">
</div>
<div class="acf-input-wrap">
  <input id="acf-field_55dc66d3f5237" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc66d3f5237]" value="15" placeholder="" type="number">
</div>
<div class="acf-input-wrap">
  <input id="acf-field_55dc6713f5238" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc6713f5238]" value="50" placeholder="" type="number">
</div>

答案 1 :(得分:1)

这个怎么样

$("input[type='number'].acf-is-appended").change(function () {
    $.each($("input[type='number'].acf-is-appended"), function (index, element) {
        var total = 0;
        $.each($("input[type='number'].acf-is-appended").not($(element)), function (innerIndex, innerElement) {
            total += parseInt($(innerElement).val());
        });
        if ($(element).val() > 100 - total) {
            alert("The total value for all inputs can not exceed 100");
            return false;
        } else {
            $(element).attr("max", 100 - total);
        }
    });
});

Fiddle Demo

答案 2 :(得分:0)

我已完全更改了您的代码,因此我将在下面逐行解释:

(function(d) {
  // get all the fields by their ids
  var fieldA = d.getElementById('acf-field_55dc6669f5235'),
      fieldB = d.getElementById('acf-field_55dc6699f5236'),
      fieldC = d.getElementById('acf-field_55dc66d3f5237'),
      fieldD = d.getElementById('acf-field_55dc6713f5238');

  // save them into an array to facilitate the iterations
  var arr = [fieldA, fieldB, fieldC, fieldD];
  
  // declare the aux variables
  var totalMax = 100, currentTotal, rest;

  // update when the page loads
  updateMaxValues();
  
  // add the event handlers to call the update when some value has changed
  arr.forEach(function(field, index) {
    field.addEventListener('input', updateMaxValues);
  });

  // function that will be called when the page loads, and after any of the textboxes are changed
  function updateMaxValues() {
    // calculates the current total values
    currentTotal = Number(fieldA.value) + Number(fieldB.value) + Number(fieldC.value) + Number(fieldD.value);
    // calculates the rest
    rest = totalMax - currentTotal;

    for (var i = 0; i < arr.length; i++) {
      // changes all the max attributes to its current value + the rest available
      arr[i].setAttribute('max', Number(arr[i].value) + rest);
    }
    
    // that's only something to show how many values are left
    d.querySelector('p').innerHTML = 'Total: ' + currentTotal + '/' + totalMax;
  }
})(document);
<div class="acf-input-wrap">
  <input id="acf-field_55dc6669f5235" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc6669f5235]" value="30" placeholder="" type="number">
</div>
<div class="acf-input-wrap">
  <input id="acf-field_55dc6699f5236" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc6699f5236]" value="5" placeholder="" type="number">
</div>
<div class="acf-input-wrap">
  <input id="acf-field_55dc66d3f5237" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc66d3f5237]" value="15" placeholder="" type="number">
</div>
<div class="acf-input-wrap">
  <input id="acf-field_55dc6713f5238" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc6713f5238]" value="50" placeholder="" type="number">
</div>
<p>Total: </p>

PS:我已将所有代码都放入IIFE中,因此我们不会对全局范围进行规范。根据谷歌的说法:

  

立即调用的函数表达式(或IIFE,发音为“iffy”)是一种JavaScript设计模式,它使用JavaScript的函数范围生成词法范围。

(function() {
  // your code goes here
})();

答案 3 :(得分:0)

尝试jQuery inputpropertychange处理程序:

&#13;
&#13;
var acfs;

$(function() {
  acfs = $('input[type=text][id^=acf-field_55dc6669f523]'); //cache all once
  acfs.on('input propertychange', checkSum);
});

var max = 100;

var checkSum = function(e) {
  this.value = this.value.replace(/\D/g, ''); //only digits
  var sum = 0;
  var fn = function() {
    sum += +this.value || 0; // parse individual text-box value to int
  };
  acfs.each(fn);
  if (max < sum) // above limit
    this.value = ''; //erase input
};
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id='acf-field_55dc6669f5235' type='text' />
<input id='acf-field_55dc6669f5236' type='text' />
<input id='acf-field_55dc6669f5237' type='text' />
<input id='acf-field_55dc6669f5238' type='text' />
&#13;
&#13;
&#13;

答案 4 :(得分:0)

尝试使用input活动,.get()Array.prototype.map()Array.prototype.reduce()Math.maxArray.prototype.sort()

如果所有input元素的总值大于MAX100,则减少在元素集合中具有最大价值的input值;如果event.target inputchange事件是具有最大值的元素,则减少具有下一个最大值的元素的值

    var inputs = $("input[id^=acf]"),
        MAX = 100;
    inputs.on("input", function (e) {
        var input = inputs.get(),
            vals = input.map(function (el) {
                return Number(el.value)
            }),
            total = vals.reduce(function (a, b) {
                return a + b
            })
        , el = inputs.sort(function (a, b) {
            return a.value > b.value
        });

        if (total > MAX) {
            $(el).eq($(el[el.length - 1]).is(e.target) 
              ? el.length - 2 
              : el.length - 1)
             .val(function (i, val) {
                return Number(val) - (total % MAX)
            });
        }
    });
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="acf-input-wrap">
  <input id="acf-field_55dc6669f5235" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc6669f5235]" value="30" placeholder="" type="number">
</div>
<div class="acf-input-wrap">
  <input id="acf-field_55dc6699f5236" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc6699f5236]" value="5" placeholder="" type="number">
</div>
<div class="acf-input-wrap">
  <input id="acf-field_55dc66d3f5237" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc66d3f5237]" value="15" placeholder="" type="number">
</div>
<div class="acf-input-wrap">
  <input id="acf-field_55dc6713f5238" class="acf-is-appended" min="" max="100" step="any" name="acf[field_55dc6713f5238]" value="50" placeholder="" type="number">
</div>

jsfiddle https://jsfiddle.net/q478ujfr/9/

答案 5 :(得分:-1)

$fieldC.keyup更改为$fieldC.change