我有多个复选框和多个文本输入。如果复选框被选中,则需要启用它旁边的文本输入

Posted

技术标签:

【中文标题】我有多个复选框和多个文本输入。如果复选框被选中,则需要启用它旁边的文本输入【英文标题】:I have multiple checkboxes and multiple text inputs. If a checkbox gets checked the text input next to it needs to be enabled 【发布时间】:2021-08-01 13:27:24 【问题描述】:

所以我有多个默认未选中的复选框。在每个复选框旁边,我都有一个禁用的文本输入。你可能已经知道我的目标是什么。我想在检查它旁边的复选框时启用文本输入。但是,这里有问题。

整个 html 是使用 javascript 构建的。所以我的脚本创建了所有的复选框和文本输入。这使我更难定位特定的复选框及其旁边的文本输入。我将在下面显示代码,以便您了解我在说什么。

HTML 代码

<fieldset>
    <legend>Order details</legend>
    <div class="container">
        <div class="row">
            <div class="span7" id="woodTypes">
            </div>
        </div>
    </div>
    <div class="span4 valid">
        <div id="orderMessages" hidden class="alert alert-error">
            <ul id="orderMessageList">
            </ul>
        </div>
    </div>
    <div class="span1"></div>
    </div>
    <div class="form-actions">
        <button id="send" class="btn btn-success" type="button">Send</button>
    </div>
    </div>
</fieldset>

JAVASCRIPT 代码

"use strict"
const woodList = document.getElementById('woodTypes');


async function readWoodTypes() 
    const response = await fetch("woodtypes.json");
    if (response.ok) 
        const woodtypes = await response.json();
        transferWoodTypes(woodtypes);
     else 
        console.log("Oops, something went wrong!");
    


function transferWoodTypes(woodtypes) 
    for (const woodtype of woodtypes) 
        addWoodtypeToList(woodtype);
    


function addWoodtypeToList(woodtype) 
    let divControlGroup = document.createElement('div');
    divControlGroup.className = "control-group";
    woodList.appendChild(divControlGroup);
    let label = document.createElement("label");
    label.className = "control-label";
    label.innerText = woodtype.name + ' ';
    divControlGroup.appendChild(label);
    let inputCheckBox = document.createElement("input");
    inputCheckBox.id = "chk_" + `$woodtype.name`;
    inputCheckBox.type = "checkbox";
    label.appendChild(inputCheckBox);
    let divControls = document.createElement("div");
    divControls.className = "controls";
    divControlGroup.appendChild(divControls);
    let divInput = document.createElement("div");
    divInput.className = "input-append";
    divControls.appendChild(divInput);
    let inputTekst = document.createElement("input");
    inputTekst.className = "inpbox input-mini";
    inputTekst.required = "";
    inputTekst.type = "number";
    inputTekst.min = "1";
    inputTekst.id = woodtype.name;
    inputTekst.name = woodtype.name;
    inputTekst.disabled = "true";
    divInput.appendChild(inputTekst);
    let span = document.createElement("span");
    span.className = "add-on";
    span.innerText = woodtype.unit;
    divInput.appendChild(span);

JSON 文件

[
    
        "name": "bangkirai",
        "unit": "pieces"
    ,
    
        "name": "birch",
        "unit": "pieces"
    ,
    
        "name": "pine",
        "unit": "pieces"
    ,
    
        "name": "oak",
        "unit": "pieces"
    ,
    
        "name": "chestnut",
        "unit": "pieces"
    ,
    
        "name": "limewood",
        "unit": "pieces"
    ,
    
        "name": "walnut",
        "unit": "pieces"
    ,
    
        "name": "rubberwood",
        "unit": "pieces"
    ,
    
        "name": "cedar",
        "unit": "kg"
    
]

如您所见,我完全使用 javascript 和来自 json 文件的数据来创建订单列表。

我已经尝试寻找解决方案好几天了,但我现在很绝望,所以我在这里发布它。

我认为我得到的最接近的是使用查询选择器 all 遍历每个复选框。

像这样:

let checkboxes = document.querySelectorAll("input[type='checkbox']")
for (const checkbox of checkboxes)  //do something with the checkbox

但这对我不起作用。

有人给我一些建议吗?

总而言之,如果选中了一个复选框,则应该启用它旁边的文本输入。

提前致谢:)

【问题讨论】:

【参考方案1】:

你可以添加这个:

let checkboxes = document.querySelectorAll("input[type='checkbox']");
for (const checkbox of checkboxes) 
  checkbox.addEventListener("change", function()  
      let classSelected = this.parentNode.childNodes[0].data;
      let input = document.querySelector("."+classSelected);
    input.disabled = !checkbox.checked;
  )

"use strict"
const woodList = document.getElementById('woodTypes');
let woodtypes = [
    "name": "bangkirai",
    "unit": "pieces"
  ,
  
    "name": "birch",
    "unit": "pieces"
  ,
  
    "name": "pine",
    "unit": "pieces"
  ,
  
    "name": "oak",
    "unit": "pieces"
  ,
  
    "name": "chestnut",
    "unit": "pieces"
  ,
  
    "name": "limewood",
    "unit": "pieces"
  ,
  
    "name": "walnut",
    "unit": "pieces"
  ,
  
    "name": "rubberwood",
    "unit": "pieces"
  ,
  
    "name": "cedar",
    "unit": "kg"
  
]

transferWoodTypes(woodtypes);

function transferWoodTypes(woodtypes) 
  for (const woodtype of woodtypes) 
    addWoodtypeToList(woodtype);
  


function addWoodtypeToList(woodtype) 
  let divControlGroup = document.createElement('div');
  divControlGroup.className = "control-group";
  woodList.appendChild(divControlGroup);
  let label = document.createElement("label");
  label.className = "control-label";
  label.innerText = woodtype.name + ' ';
  divControlGroup.appendChild(label);
  let inputCheckBox = document.createElement("input");
  inputCheckBox.id = "chk_" + `$woodtype.name`;
  inputCheckBox.type = "checkbox";
  label.appendChild(inputCheckBox);
  let divControls = document.createElement("div");
  divControls.className = "controls";
  divControlGroup.appendChild(divControls);
  let divInput = document.createElement("div");
  divInput.className = "input-append";
  divControls.appendChild(divInput);
  let inputTekst = document.createElement("input");
  inputTekst.className = "inpbox input-mini" + " " + woodtype.name;
  inputTekst.required = "";
  inputTekst.type = "number";
  inputTekst.min = "1";
  inputTekst.id = woodtype.name;
  inputTekst.name = woodtype.name;
  inputTekst.disabled = "true";
  divInput.appendChild(inputTekst);
  let span = document.createElement("span");
  span.className = "add-on";
  span.innerText = woodtype.unit;
  divInput.appendChild(span);


let checkboxes = document.querySelectorAll("input[type='checkbox']");
for (const checkbox of checkboxes) 
  checkbox.addEventListener("change", function() 
    let classSelected = this.parentNode.childNodes[0].data;
    let input = document.querySelector("." + classSelected);
    input.disabled = !checkbox.checked;
  )
<fieldset>
  <legend>Order details</legend>
  <div class="container">
    <div class="row">
      <div class="span7" id="woodTypes">
      </div>
    </div>
  </div>
  <div class="span4 valid">
    <div id="orderMessages" hidden class="alert alert-error">
      <ul id="orderMessageList">
      </ul>
    </div>
  </div>
  <div class="span1"></div>
  </div>
  <div class="form-actions">
    <button id="send" class="btn btn-success" type="button">Send</button>
  </div>
  </div>
</fieldset>

【讨论】:

这会将事件添加到文档中的每个输入复选框,而不仅仅是本节中的复选框, 是的,但那是 OP 的第一次尝试和他建议的功能。【参考方案2】:

当您创建每个复选框输入时,您可以将其设置为在当时被选中/取消选中时执行某些操作。

为每个复选框元素添加一个 onchange 事件处理程序。如果选中,则将下一个兄弟元素(即您感兴趣的输入)设置为启用,如果未设置,则将启用设置为 false。

将此添加到您创建和设置复选框元素的位置:

    inputCheckBox.onchange = "this.nextElementSibling.enabled = this.checked";

它在你的函数中:

function addWoodtypeToList(woodtype) 
    let divControlGroup = document.createElement('div');
    divControlGroup.className = "control-group";
    woodList.appendChild(divControlGroup);
    let label = document.createElement("label");
    label.className = "control-label";
    label.innerText = woodtype.name + ' ';
    divControlGroup.appendChild(label);
    let inputCheckBox = document.createElement("input");
    inputCheckBox.id = "chk_" + `$woodtype.name`;
    inputCheckBox.type = "checkbox"; 
    //ADD THIS NEXT LINE
    inputCheckBox.onchange = "this.nextElementSibling.enabled = this.checked";
    label.appendChild(inputCheckBox);
    let divControls = document.createElement("div");
    divControls.className = "controls";
    divControlGroup.appendChild(divControls);
    let divInput = document.createElement("div");
    divInput.className = "input-append";
    divControls.appendChild(divInput);
    let inputTekst = document.createElement("input");
    inputTekst.className = "inpbox input-mini";
    inputTekst.required = "";
    inputTekst.type = "number";
    inputTekst.min = "1";
    inputTekst.id = woodtype.name;
    inputTekst.name = woodtype.name;
    inputTekst.disabled = "true";
    divInput.appendChild(inputTekst);
    let span = document.createElement("span");
    span.className = "add-on";
    span.innerText = woodtype.unit;
    divInput.appendChild(span);

【讨论】:

这看起来最有希望。晚上回家后测试一下。如果它有效,会及时通知您:) 感谢您的努力:) 不幸的是,这也没有完成这项工作。它以某种方式停止创建数据,因此在创建第一个输入后停止我的代码 您的浏览器控制台是否出现错误 - 这似乎是代码停止的唯一原因。 哦,快速更新:我让它工作了。你的线路很好,但由于某种原因没有工作。当我把它放在一个事件监听器中时,它开始工作了。所以是的,不知道为什么没有事件监听器它就不能工作,但我想这是为你编码的:p 这可能是时间问题,因为 html 是在什么时候构建的,它会看到更改事件?无论如何,很高兴你有前进的道路。【参考方案3】:

您需要将更改处理程序添加到复选框。 像这样:

/* Add this event handler */
inputCheckBox.addEventListener('change', (event) => 
      let closestInp = event.currentTarget.parentElement.parentElement.querySelectorAll('.inpbox');
      closestInp[0].disabled = !event.currentTarget.checked; 
);
/********/

这是一个工作示例:

"use strict"
const woodList = document.getElementById('woodTypes');
readWoodTypes();

function readWoodTypes() 
    const result = [
    
        name: "bangkirai",
        unit: "pieces"
    ,
    
        name: "birch",
        unit: "pieces"
    ,
    
        name: "pine",
        unit: "pieces"
    ,
    
        name: "oak",
        unit: "pieces"
    ,
    
        name: "chestnut",
        unit: "pieces"
    ,
    
        name: "limewood",
        unit: "pieces"
    ,
    
        name: "walnut",
        unit: "pieces"
    ,
    
        name: "rubberwood",
        unit: "pieces"
    ,
    
        name: "cedar",
        unit: "kg"
    
];

transferWoodTypes(result);
    /*const response = await fetch("woodtypes.json");
    if (response.ok) 
        const woodtypes = await response.json();
        transferWoodTypes(woodtypes);
     else 
        console.log("Oops, something went wrong!");
    */


function transferWoodTypes(woodtypes) 
    for (const woodtype of woodtypes) 
        addWoodtypeToList(woodtype);
    


function addWoodtypeToList(woodtype) 
    let divControlGroup = document.createElement('div');
    divControlGroup.className = "control-group";
    woodList.appendChild(divControlGroup);
    let label = document.createElement("label");
    label.className = "control-label";
    label.innerText = woodtype.name + ' ';
    divControlGroup.appendChild(label);
    let inputCheckBox = document.createElement("input");
    inputCheckBox.id = "chk_" + `$woodtype.name`;
    inputCheckBox.type = "checkbox";
    /* Add this event handler */
    inputCheckBox.addEventListener('change', (event) => 
          let closestInp = event.currentTarget.parentElement.parentElement.querySelectorAll('.inpbox');
          closestInp[0].disabled = !event.currentTarget.checked; 
    );
    /********/
    label.appendChild(inputCheckBox);
    let divControls = document.createElement("div");
    divControls.className = "controls";
    divControlGroup.appendChild(divControls);
    let divInput = document.createElement("div");
    divInput.className = "input-append";
    divControls.appendChild(divInput);
    let inputTekst = document.createElement("input");
    inputTekst.className = "inpbox input-mini";
    inputTekst.required = "";
    inputTekst.type = "number";
    inputTekst.min = "1";
    inputTekst.id = woodtype.name;
    inputTekst.name = woodtype.name;
    inputTekst.disabled = "true";
    divInput.appendChild(inputTekst);
    let span = document.createElement("span");
    span.className = "add-on";
    span.innerText = woodtype.unit;
    divInput.appendChild(span);
<fieldset>
    <legend>Order details</legend>
    <div class="container">
        <div class="row">
            <div class="span7" id="woodTypes">
            </div>
        </div>
    </div>
    <div class="span4 valid">
        <div id="orderMessages" hidden class="alert alert-error">
            <ul id="orderMessageList">
            </ul>
        </div>
    </div>
    <div class="span1"></div>
    </div>
    <div class="form-actions">
        <button id="send" class="btn btn-success" type="button">Send</button>
    </div>
    </div>
</fieldset>

【讨论】:

以上是关于我有多个复选框和多个文本输入。如果复选框被选中,则需要启用它旁边的文本输入的主要内容,如果未能解决你的问题,请参考以下文章

如果选中任一复选框,则启用和禁用文本字段

iCheck 检查复选框是不是被选中

如果选中复选框,则获取下一个输入[文本]

如果选中相邻复选框,则输入字段验证

如果选中复选框,则打开输入文本(JQuery)

选中多个复选框时验证其他