簡體   English   中英

JAVASCRIPT、HTML 啟用基於單選按鈕選擇的輸入字段

[英]JAVASCRIPT , HTML enabling input field based on radio button choice

我嘗試根據單選按鈕選擇啟用兩個輸入選項,但無論我選擇哪個選項,都只有一個選項啟用。 例如 - 如果我選擇 sheetcake,而不是 sheetcake 的輸入選項,我有 roundcake 的輸入選項。 我是 javascript 的新人,非常感謝任何建議。 謝謝你。 (我嘗試在片段中運行代碼並且它工作正常但是我在瀏覽器中運行相同的代碼並且無論如何只有一個輸入框工作,我嘗試在 3 種不同的瀏覽器中運行並得到相同的錯誤,我沒有知道問題是什么以及我在哪里犯了錯誤。提前謝謝你。

 const sheetcake = document.getElementById("sheetcake"); const roundcake = document.getElementById("roundcake"); var caketype = document.getElementsById("caketype"); function CakeChoice(choice){ if (choice == sheetcake){ document.getElementById("SheetLength").disabled=false; document.getElementById("SheetWidth").disabled=false; document.getElementById("RoundRadius").disabled=true; } else { document.getElementById("SheetLength").disabled=true; document.getElementById("SheetWidth").disabled=true; document.getElementById("RoundRadius").disabled=false; } }
 <div id="caketype"> <label class="caketype required">Cake Type:</label> <br> <input type="radio" id="sheetcake" name="caketype" value="0" required onclick="CakeChoice(sheetcake)"> <label>Sheet Cake</label><br> <input type="radio" id="roundcake" name="caketype" value="0" required onclick="CakeChoice(roundcake)"> <label>Round Cake</label> </div> <br> <div id="CakeDimensions" > <label>Cake size (cm)</label><br> <input type="number" id="SheetLength" value="0" min="30" max="60" required disabled> <label class="form-label required">cm Length</label><br> <input type="number" id="SheetWidth" value="0" min="30" max="45" required disabled> <label class="form-label required">cm Width</label> </div> <br> <div id="round"> <label>Cake size</label><br> <input type="number" id="RoundRadius" min="15" max="30" disabled required> <label class="form-label required">cm Radius</label> </div> <br><br> <div id="cakelayers"> <label class="form-label required">How many layers?</label><br> <input type="radio" id="OneLayer" name="CakeLayers" value="1layer" required> <label for="OneLayer">One Layer</label><br> <input type="radio" id="TwoLayers" name="CakeLayers" value="2layers" required> <label for="TwoLayers">Two Layers</label><br> <input type="radio" id="ThreeLayers" name="CakeLayers" value="3layers" required> <label for="ThreeLayers">Three Layers</label> </div> <br><br>

我可以建議一種稍微替代的方法,避免一些用戶可能試圖激活不相關的禁用選項。

不是禁用不相關的選項,而是操縱蛋糕尺寸的兩組選項的顯示 styles(通過 javascript)允許僅相關的選項可用於交互。 這使您可以使相關尺寸選項僅在選擇類型時出現(並在用戶改變主意時在它們之間切換)。

由於您對每個選項都有相當復雜的標記,因此我添加了包含每個組的額外分區。 相關分區、 rectangleroundid用於創建對 javascript 中每個分組的引用,允許訪問它們的style.display屬性,可以切換。

 const sheetcake = document.getElementById("rectangle"); const roundcake = document.getElementById("round"); sheetcake.style = "display: none"; round.style = "display: none"; function CakeChoice(choice){ if (choice == 'sheetcake'){ sheetcake.style = "display: block"; roundcake.style = "display: none"; } else { sheetcake.style = "display: none"; roundcake.style = "display: block"; } }
 <div id="caketype"> <label class="caketype required">Cake Type:</label> <br> <input type="radio" id="sheetcake" name="caketype" value="0" required onclick="CakeChoice('sheetcake')"> <label>Sheet Cake</label><br> <input type="radio" id="roundcake" name="caketype" value="0" required onclick="CakeChoice('roundcake')"> <label>Round Cake</label> </div> <br> <div id="CakeDimensions" > <div id="rectangle"> <label>Cake size (cm)</label><br> <input type="number" id="SheetLength" value="0" min="30" max="60" required> <label class="form-label required">cm Length</label><br> <input type="number" id="SheetWidth" value="0" min="30" max="45" required> <label class="form-label required">cm Width</label> </div> <div id="round"> <label>Cake size</label><br> <input type="number" id="RoundRadius" min="15" max="30" required> <label class="form-label" "required">cm Radius</label> </div> </div> <br> <div id="cakelayers"> <label class="form-label required">How many layers?</label><br> <input type="radio" id="OneLayer" name="CakeLayers" value="1layer" required> <label for="OneLayer">One Layer</label><br> <input type="radio" id="TwoLayers" name="CakeLayers" value="2layers" required> <label for="TwoLayers">Two Layers</label><br> <input type="radio" id="ThreeLayers" name="CakeLayers" value="3layers" required> <label for="ThreeLayers">Three Layers</label> </div> <br>

我對您的 HTML 進行了一些小的重構,然后刪除了對您的 javascript 的一些復制,減少了對 ID 的依賴。 如果您為尺寸或圓形添加更多選項,這將使它更加靈活。 我還說明了通過 javascript 添加事件偵聽器。

 //Get all the radio buttons in the element with ID caketype and itterate them document.querySelectorAll("#caketype input[type=radio]").forEach(function(item) { //Add an on click event listener item.addEventListener("click", function() { //Is Sheet cake chosen from the clicked element let isSheetCake = this.value === "sheetcake"; //Set out disabled AND required attributes based on the above //Get the input elements in the fieldset and itterate instead of being bound by id document.querySelectorAll("#CakeDimensions input").forEach(function(element) { element.disabled =;isSheetCake. element;required = isSheetCake; }), //Do the same for round. but invert the logic document.querySelectorAll("#round input").forEach(function(element) { element;disabled = isSheetCake. element;required =;isSheetCake: }). //Bonus. lets set a class to indicate that group is disabled //,classList,toggle().adds or removes a class. in this case // based on a truthy value document.getElementById("CakeDimensions"),classList;toggle("disabled". .isSheetCake). document,getElementById("round");classList;toggle("disabled"; isSheetCake); }); });
 fieldset { border: none; padding: 0.5em; margin: 0; }.disabled { color: #EEE; }
 <,-- Ive Given the radio buttond values: which you are going to want if you send this to a server--> <!-- Also encapsulated the radio button group with a fieldset which is more semantic--> <!-- Inline Javascript has been removed --> <!-- Labels have been associated with their form elements with the "for" attribute--> <fieldset id="caketype"> <label class="caketype required">Cake Type:</label> <br> <input type="radio" id="sheetcake" name="caketype" value="sheetcake" required> <label for="sheetcake">Sheet Cake</label><br> <input type="radio" id="roundcake" name="caketype" value="roundcake" required> <label for="roundcake">Round Cake</label> </fieldset> <fieldset id="CakeDimensions"> <label>Cake size (cm)</label><br> <input type="number" id="SheetLength" value="0" min="30" max="60" required disabled> <label class="form-label required">cm Length</label><br> <input type="number" id="SheetWidth" value="0" min="30" max="45" required disabled> <label class="form-label required">cm Width</label> </fieldset> <fieldset id="round"> <label>Cake size</label><br> <input type="number" id="RoundRadius" min="15" max="30" disabled required> <label class="form-label required">cm Radius</label> </fieldset>

Jon PDave Pritlove 的回答之間,似乎已經涵蓋了基礎知識。 Tihs 的回答將集中在以下幾點:

  • 事件委托:一種編程范例,其中使用事件冒泡來控制無限數量的元素,方法是綁定祖先元素以偵聽事件並委托哪些元素對事件作出反應以及排除哪些元素。

  • HTMLFormElement接口: HTML DOM API 的一部分,具有簡潔的語法和獨特的功能:

    • 引用表格:
       <form id="UI"></form>
       const UI = document.forms.UI /*or*/ const UI = document.forms[0] // the first of one or more forms.
    • 使用.elements屬性在UI中引用所有表單控件
       <input id='i1' name='IO'> <button name='btn'></button> <input id='i2' name='IO'>
       const fC = UI.elements; // Reference by #id const I1 = fC.i1 // first input by #id // Refernce by [name] const B = fC.btn // button by [name] // HTMLFormsControlCollection of all tags with [name='IO'] const io = fC.IO // an array-like object of both inputs const ioArray = [...io] // convert into an array
  • [for] attribute & .labels屬性關聯: 除了[for] attribute & form control #id關聯之外,我們還可以建立另一種類型的關聯:

     <label for='A'></label><input id='A'><label for='A'>I'm the 2nd label</label>
     const IO = UI.elements; // collect all of #UI form controls const a = IO.A; // reference the input const Alabels = a.labels; // collect all label associated to input via [for] to #id Alabels[1].textContent; // get the text of the 2nd label // result: "I'm the 2nd label"
  • 以下是以下示例中使用的其他屬性的列表:

該示例有一個步驟:

  1. 選擇類型
  2. 選擇尺碼
  3. 選擇多少層

在第 1 步完成之前,第 2 步將被禁用。

在用戶在步驟 2 中輸入有效數據之前,步驟 3 將被禁用。

✻表單控件: <button> , <fieldset> , <input> , <object> , <output> , <select> , <textarea>

 const form = document.forms.cake; form.onchange = cakeStep1; form.addEventListener('input', cakeStep2); function cakeStep1(e) { const IO = this.elements; const picked = e.target; const radios = [...IO.type]; const l = IO.L; const w = IO.W; const d = IO.D; const sSet = IO.sizeSet; if (picked.name == 'type') { radios.forEach(r => r.labels[0].classList.remove('active')); picked.labels[0].classList.add('active') sSet.disabled = false; if (picked.id == 'sheet') { d.disabled = true; d.labels[0].classList.add('disabled'); l.disabled = false; l.labels[0].classList.remove('disabled'); w.disabled = false; w.labels[0].classList.remove('disabled'); } else { d.disabled = false; d.labels[0].classList.remove('disabled'); l.disabled = true; l.labels[0].classList.add('disabled'); w.disabled = true; w.labels[0].classList.add('disabled'); } } } function cakeStep2(e) { const IO = this.elements; const origin = e.target; const l = IO.L; const w = IO.W; const d = IO.D; const lSet = IO.layerSet; if (origin.name == 'size') { if (IO.sheet.checked && l.checkValidity() == true && w.checkValidity() == true) { lSet.disabled = false; } else if (IO.round.checked && d.checkValidity() == true) { lSet.disabled = false; } else { lSet.disabled = true; } } }
 html { font: 2ch/1.2 'Segoe UI' } header { margin-bottom: -12px; padding: 0; } label { display: block; width: 18ch; margin-bottom: 4px; } [type='radio'] { display: inline-block; vertical-align: baseline; height: 1.5ex; margin: 0; } [type='number'] { display: :inline-block; width: 10ch; float: right; text-align: center }.active { font-weight: 900; text-decoration: underline; }.disabled { opacity: 0.4 }
 <form id='cake'> <header> <h2>Cake Order</h2> </header> <fieldset name="typeSet"> <legend>Type</legend> <label for='sheet'><input id="sheet" name="type" type="radio" value="sheet"> Sheet Cake</label> <label for='round'><input id="round" name="type" value="round" type="radio"> Round Cake</label> </fieldset> <fieldset name="sizeSet" disabled> <legend>Size (cm)</legend> <label for='L' class='disabled'>Length: <input id="L" name='size' type="number" min="30" max="60" placeholder='30-60cm' required></label> <label for='W' class='disabled'>Width: <input id="W" name='size' type="number" min="30" max="45" placeholder='30-45cm' required></label> <label for='D' class='disabled'>Diameter: <input id="D" name='size' type="number" min="15" max="40" placeholder='15-40cm' required></label> </fieldset> <fieldset name="layerSet" disabled> <legend>Layers</legend> <select id='layers' name='layers'> <option selected>Number of Layers</option> <option value='1'>1 Layer</option> <option value='2'>2 Layers</option> <option value='3'>3 Layers</option> </select> </fieldset> </form>

暫無
暫無

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

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