【问题标题】:Disable form fieldsets unless certain inputs are checked除非检查某些输入,否则禁用表单字段集
【发布时间】:2018-08-17 12:13:27
【问题描述】:

如何使每个字段集禁用复选框和单选输入,然后在选择某些输入后依次启用?

例如:最初,除第一个之外的所有字段集都被禁用。 用户在第一个字段集中选择输入后,将启用第二个。 以此类推。

与此相关,如何仅在检查第二个字段集中的单选输入后才显示计算值?

const calculator = document.querySelector("form");

const occasionPricing = {
	party: 20,
	birthday: 25,
	anniversary: 50,
	wedding: 100
}

const sizeIndexes = {
	six: 1,
	eight: 1.5,
	ten: 2,
	twelve: 2.5
}

const extrasPricing = {
	candles: 5,
	inscription: 10,
	decoration: 25,
	special: 50
}

function cakes() {	
	var cakes = Array.from(calculator.elements["cake"]).slice(0, 3);
	var raphael = calculator.elements["raphael"];

	function isChecked(checkbox) {
		return checkbox.checked;
	}

	var count = cakes.filter(isChecked).length;
	if (count) {
		count = count * 0.5 + 0.5;
		if (raphael.checked) {
			count += 1;
		}
		return count;
	}
	return 0;
}

function occasion() {
	var occasionCost = 0;
	var occasion = calculator.elements["occasion"];

	for (var i = 0; i < occasion.length; i++) {
		if (occasion[i].checked) {
			occasionCost = occasionPricing[occasion[i].value];
			break;
		}
	}
	return occasionCost;
}

function size() {
	var sizeIndex = 1;
	var size = calculator.elements["size"];

	for (var i = 0; i < size.length; i++) {
		if (size[i].checked) {
			sizeIndex = sizeIndexes[size[i].value];
			break;
		}
	}
	return sizeIndex;
}

function extras() {
	var extrasCost = 0;
	const extras = calculator.elements["extras"];

	for (var i = 0; i < extras.length; i++) {
		if (extras[i].checked) {
			extrasCost = extrasCost + extrasPricing[extras[i].value];
		}
	}
	return extrasCost;
}

function calculateTotal() {
	var totalCost = cakes() * occasion() * size() + extras();
	calculator.total.value = "$" + totalCost;
}
<form>

<fieldset>
	<legend>Select Cakes</legend>
	<label><input type="checkbox" name="cake" id="leonardo" onclick="calculateTotal()">Leonardo</label>
	<label><input type="checkbox" name="cake" id="donatello" onclick="calculateTotal()">Donatello</label>
	<label><input type="checkbox" name="cake" id="michelangelo" onclick="calculateTotal()">Michelangelo</label>
	<label><input type="checkbox" name="cake" id="raphael" onclick="calculateTotal()">Raphael</label>
	<p>If you select more than one cake, the other cakes are discounted 50%.</p>
	<p><small>Does not apply to Raphael.</small></p>
</fieldset>

<fieldset>
	<legend>Choose Occasion</legend>
	<label><input type="radio" name="occasion" value="party" onclick="calculateTotal()" required>Party</label><br>
	<label><input type="radio" name="occasion" value="birthday" onclick="calculateTotal()">Birthday</label><br>
	<label><input type="radio" name="occasion" value="anniversary" onclick="calculateTotal()">Anniversary</label><br>
	<label><input type="radio" name="occasion" value="wedding" onclick="calculateTotal()">Wedding</label><br>
</fieldset>

<fieldset>
	<legend>Choose Size</legend>
	<label><input type="radio" name="size" value="six" onclick="calculateTotal()" required>6-inch</label><br>
	<label><input type="radio" name="size" value="eight" onclick="calculateTotal()">8-inch</label><br>
	<label><input type="radio" name="size" value="ten" onclick="calculateTotal()">10-inch</label><br>
	<label><input type="radio" name="size" value="twelve" onclick="calculateTotal()">12-inch</label><br>
</fieldset>

<fieldset>
	<legend>Select Extras</legend>
	<label><input type="checkbox" name="extras" value="candles" onclick="calculateTotal()">Candles</label>
	<label><input type="checkbox" name="extras" value="inscription" onclick="calculateTotal()">Inscription</label>
	<label><input type="checkbox" name="extras" value="decoration" onclick="calculateTotal()">Decoration</label>
	<label><input type="checkbox" name="extras" value="special" onclick="calculateTotal()">Special Frosting & Icing</label>
</fieldset>

<input type="text" name="total">
<input type="submit" value="Submit" onclick="calculateTotal()">

【问题讨论】:

    标签: javascript html forms


    【解决方案1】:

    在字段集上创建一个 onchange 事件侦听器并触发启用下一个字段集的函数。查看工作的 sn-p

    const calculator = document.querySelector("form");
    
    const occasionPricing = {
      party: 20,
      birthday: 25,
      anniversary: 50,
      wedding: 100
    }
    
    const sizeIndexes = {
      six: 1,
      eight: 1.5,
      ten: 2,
      twelve: 2.5
    }
    
    const extrasPricing = {
      candles: 5,
      inscription: 10,
      decoration: 25,
      special: 50
    }
    
    function cakes() {
      var cakes = Array.from(calculator.elements["cake"]).slice(0, 3);
      var raphael = calculator.elements["raphael"];
    
      function isChecked(checkbox) {
        return checkbox.checked;
      }
    
      var count = cakes.filter(isChecked).length;
      if (count) {
        count = count * 0.5 + 0.5;
        if (raphael.checked) {
          count += 1;
        }
        return count;
      }
      return 0;
    }
    
    function occasion() {
      var occasionCost = 0;
      var occasion = calculator.elements["occasion"];
    
      for (var i = 0; i < occasion.length; i++) {
        if (occasion[i].checked) {
          occasionCost = occasionPricing[occasion[i].value];
          break;
        }
      }
      return occasionCost;
    }
    
    function size() {
      var sizeIndex = 1;
      var size = calculator.elements["size"];
    
      for (var i = 0; i < size.length; i++) {
        if (size[i].checked) {
          sizeIndex = sizeIndexes[size[i].value];
          break;
        }
      }
      return sizeIndex;
    }
    
    function extras() {
      var extrasCost = 0;
      const extras = calculator.elements["extras"];
    
      for (var i = 0; i < extras.length; i++) {
        if (extras[i].checked) {
          extrasCost = extrasCost + extrasPricing[extras[i].value];
        }
      }
      return extrasCost;
    }
    
    function calculateTotal() {
      var totalCost = cakes() * occasion() * size() + extras();
      calculator.total.value = "$" + totalCost;
    }
    
    function enableFieldset(element, event) {
      
      if (event.currentTarget.id == 'cakes') {
        var checked = false;
        var checkboxes = document.getElementsByName("cake");
        for (var i = 0; i < checkboxes.length; i++) {
          if (checkboxes[i].checked) {
            checked = true;
            break;
          }
        }
        if (checked) {
          document.getElementById(element).disabled = false;
        } else {
          document.getElementById(element).disabled = true;
        }
      } else {
        document.getElementById(element).disabled = false;
      }
    
    
    }
    <form>
    
      <fieldset id="cakes" onchange="enableFieldset('occasion',event)">
        <legend>Select Cakes</legend>
        <label><input type="checkbox" name="cake" id="leonardo">Leonardo</label>
        <label><input type="checkbox" name="cake" id="donatello">Donatello</label>
        <label><input type="checkbox" name="cake" id="michelangelo">Michelangelo</label>
        <label><input type="checkbox" name="cake" id="raphael">Raphael</label>
        <p>If you select more than one cake, the other cakes are discounted 50%.</p>
        <p><small>Does not apply to Raphael.</small></p>
      </fieldset>
    
      <fieldset id="occasion" onchange="enableFieldset('size', event)" disabled>
        <legend>Choose Occasion</legend>
        <label><input type="radio" name="occasion" value="party" onclick="calculateTotal()" required>Party</label><br>
        <label><input type="radio" name="occasion" value="birthday" onclick="calculateTotal()">Birthday</label><br>
        <label><input type="radio" name="occasion" value="anniversary" onclick="calculateTotal()">Anniversary</label><br>
        <label><input type="radio" name="occasion" value="wedding" onclick="calculateTotal()">Wedding</label><br>
      </fieldset>
    
      <fieldset id="size" onchange="enableFieldset('extras', event)" disabled>
        <legend>Choose Size</legend>
        <label><input type="radio" name="size" value="six" onclick="calculateTotal()" required>6-inch</label><br>
        <label><input type="radio" name="size" value="eight" onclick="calculateTotal()">8-inch</label><br>
        <label><input type="radio" name="size" value="ten" onclick="calculateTotal()">10-inch</label><br>
        <label><input type="radio" name="size" value="twelve" onclick="calculateTotal()">12-inch</label><br>
      </fieldset>
    
      <fieldset id="extras" disabled>
        <legend>Select Extras</legend>
        <label><input type="checkbox" name="extras" value="candles" onclick="calculateTotal()">Candles</label>
        <label><input type="checkbox" name="extras" value="inscription" onclick="calculateTotal()">Inscription</label>
        <label><input type="checkbox" name="extras" value="decoration" onclick="calculateTotal()">Decoration</label>
        <label><input type="checkbox" name="extras" value="special" onclick="calculateTotal()">Special Frosting & Icing</label>
      </fieldset>
    
      <input type="text" name="total">
      <input type="submit" value="Submit" onclick="calculateTotal()">

    【讨论】:

    • 这正是我想要的。只有在检查第二个字段集中的输入后,您将如何显示计算值?
    • 已经修改了sn-p。一探究竟!或者现在如果我想到它,只需删除蛋糕的计算成本。
    • 很好的答案@cdoshi,但有一个小问题......如果您选中然后取消选中 Cakes 中的某些内容,您仍然可以继续启用表单的其余部分。我相信 OP 希望使用它来确保选择所需的选项(客户端验证)。我相信您可以对现有答案进行细微更改以解决此“如果这是预期的结果”
    • 哦,我明白了。我的坏!
    • @Boletrone 添加了额外的逻辑来处理,以防再次取消选择所有蛋糕。我想你可以从这里开始 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    • 2022-01-06
    • 2019-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多