输入字段显示在默认选中框

时间:2016-11-13 13:18:45

标签: javascript html checkbox

我正在处理一个表单,我们可以选择将产品分配给对象,或者在这种情况下是用户。根据我们的数据库中提供的值在代码中检索和使用,默认情况下,此用户可能拥有这些特定产品之一。

if($Pants=="1"){
   echo "<input type='checkbox' onclick='PantsInput(this);' checked>Pants<br>";
}
else {
   echo "<input type='checkbox'> Pants<br>";
}

如果选中此复选框,则会创建一个用于创建文本输入字段的JavaScript。它可以工作,但只有我继续并手动选择它。

我想要完成的是让脚本识别是否已经选中了复选框。仍然可以手动执行此操作,但如果已选中复选框,则字段在加载时显示会很棒。

这是脚本:

function PantsInput(cbox) {
      if (cbox.checked) {
        var input = document.createElement("input");
        input.type = "text";
        input.value = "1";
        input.name = "AmountPants"
        var div = document.createElement("div");
        div.id = cbox.name;
        div.innerHTML = "Amount of pants: ";
        div.appendChild(input);
        document.getElementById("pantsinput").appendChild(div);
      } else {
        document.getElementById(cbox.name).remove();
      }
    }

这是一个JSFiddle,显示了我正在努力的方面: https://jsfiddle.net/orqweyzc/

此框已经过检查,但只有在您继续操作并取消选中并自行重新检查时,该字段才会显示。我尝试了一些不同的DOM活动,但似乎无法做到。

3 个答案:

答案 0 :(得分:1)

您已点击复选框注册了PantsInput,这意味着在您点击它之前它不会自动运行。因此,为了实现这一目标,您必须强行称之为。

if($Pants=="1"){
   echo "<input type='checkbox' onclick='PantsInput(this);' name='checkbox1' checked>Pants<br>";
   echo "<script>PantsInput(document.getElementsByName('checkbox1')[0])</script>";
}
else {
   echo "<input type='checkbox'> Pants<br>";
}

希望这会有所帮助!!

答案 1 :(得分:1)

你可以做这样的事情

window.addEventListener('load', function() {
  var inputs = document.querySelectorAll('input');
  
  for (var i = 0; i < inputs.length; i++) {
    
    switch (inputs[i].getAttribute("data-type")) {
        
      case 'pants':      
      case 'shirts':
        inputs[i].addEventListener('click', function(e) {
          if (e.target.checked) {
            addElement(e.target);
          } else {
            document.getElementById(e.target.name).remove();
          }
        })
        
        if (inputs[i].checked) {
          addElement(inputs[i]);
        }
        break;
        
    }
  }
})

function addElement(t) {
  var vals = t.getAttribute('data-text').split('|');
  var input = document.createElement("input");
  input.type = "text";
  input.value = vals[0];
  input.name = vals[1];
  var div = document.createElement("div");
  div.id = t.name;
  div.innerHTML = vals[2];
  div.appendChild(input);
  document.getElementById(vals[3]).appendChild(div);
}
<p>Clothing</p>
<input type="checkbox" name="check1" checked data-type="pants" 
       data-text="1|AmountPants|Amount of pants: |pantsinput" />Pants
<br>
<input type="checkbox" name="check2" data-type="shirts" 
       data-text="2|AmountShirts|Amount of shirts: |shirtinput" />Shirt
<br>

<p id="pantsinput"></p>
<p id="shirtinput"></p>

答案 2 :(得分:1)

解决问题的最简单方法是设置一种方法,通过该方法可以在页面加载时触发您正在侦听的事件,以生成<input>元素。要做到这一点,您需要添加以下内容:

// creating the event that we're listening for:
var clickEvent = new Event('click');

// using document.querySelectorAll('input[type=checkbox]:checked')
// to return the nodeList of <input> elements whose 'type' attribute
// is equal to 'checkbox' which are also checked, and passing that
// nodeList to Array.from() to convert the Array-like nodeList into
// an Array, allowing us to use Array methods:
Array.from(document.querySelectorAll('input[type=checkbox]:checked'))

  // Array.prototype.forEach() allows us to iterate over every node
  // in the Array of nodes:
  .forEach(function(input){
  // 'input': a reference to the current <input> element in the
  // Array of <input> elements over which we're iterating.

    // firing the clickEvent (created above) from the <input>
    // element, causing the event-handler to be fired:
    input.dispatchEvent(clickEvent);
  });

function PantsInput(cbox) {
  if (cbox.checked) {
    var input = document.createElement("input");
    input.type = "text";
    input.value = "1";
    input.name = "AmountPants"
    var div = document.createElement("div");
    div.id = cbox.name;
    div.innerHTML = "Amount of pants: ";
    div.appendChild(input);
    document.getElementById("pantsinput").appendChild(div);
  } else if (document.getElementById(cbox.name)) {
    document.getElementById(cbox.name).remove();
  }
}

function ShirtInput(cbox) {
  if (cbox.checked) {
    var input = document.createElement("input");
    input.type = "text";
    input.value = "2";
    input.name = "AmountShirt"
    var div = document.createElement("div");
    div.id = cbox.name;
    div.innerHTML = "Amount of shirts: ";
    div.appendChild(input);
    document.getElementById("shirtinput").appendChild(div);
  } else if (document.getElementById(cbox.name)) {
    document.getElementById(cbox.name).remove();
  }
}

var clickEvent = new Event('click');
Array.from(document.querySelectorAll('input'))
  .forEach(function(input) {
    input.dispatchEvent(clickEvent);
  });
<p>Clothing</p>
<input type="checkbox" name="check1" checked onclick="PantsInput(this);" />Pants
<br>
<input type="checkbox" name="check2" onclick="ShirtInput(this);" />Shirt
<br>

<p id="pantsinput"></p>
<p id="shirtinput"></p>

JS Fiddle demo

请注意,因为我们正在遍历DOM中的元素,所以此代码必须在元素创建之后运行并存在于DOM中,这最容易通过放置{在结束<script>标记之前{1}}。

现在,虽然问题表面上已经解决了,但你仍然有两个相同的函数,所以如果我们可以重构那个使用相同的函数来产生稍微不同的结果,基于被检查的元素,那应该是更有意义。

此外,使用内联事件处理程序被认为是不好的做法,并且“突兀的JavaScript”会让您更难以及将来需要更新时维护代码的人。此外,我们会使用</body><input>元素与<input>元素相关联。

因此,在下文中,我们将使用JavaScript来绑定事件处理程序,我们将重构代码,以便我们只使用一个函数:

<label>

// using a single named function (the name of which tries to
// convey the functionality):
function amountsOf() {

  // caching the 'this' (passed automatically from the
  // EventTarget.addEventListener() method (later in
  // the code):
  var changed = this,

  // caching the textContent of the <input> element's
  // parentNode (the <label> element), with the leading
  // and trailing white-space removed courtesy of
  // String.prototype.trim():
    inputName = changed.parentNode.textContent.trim(),

  // creating a new <input> element:
    input = document.createElement("input"),

  // creating a new <label> element:
    label = document.createElement('label'),

  // creating text for the <label> element, via the creation
  // of a new TextNode:
    text = document.createTextNode("Amount of " + inputName + ": "),

  // finding the element to which the content should be
  // appended, or from which it should be removed:
    contentTo = document.getElementById(inputName.toLowerCase() + 'input');

  // if the current <input> element is checked:
  if (changed.checked) {

    // we append the textNode to the <label>:
    label.appendChild(text);

    // then append the <input> to the <label>:
    label.appendChild(input);

    // setting the type property/attribute of the <input>:    
    input.type = "text";

    // setting the current value of the <input> from the
    // (valid) custom data-inputvalue attribute added to
    // the <input>, though honestly I don't think this
    // adds any benefit to the user of the site:
    input.value = changed.dataset.inputvalue;

    // setting the <input> element's name property:
    input.name = "Amount" + inputName;

    // appending the <label> to the element to which
    // content should be added:
    contentTo.appendChild(label);
  } else {

    // finding the <label> element within the <p>
    // to which content was added, and removing
    // it:
    contentTo.querySelector('label').remove();
  }
}

// using document.querySelectorAll() to find all <input>
// elements of type=checkbox, and passing that nodeList
// to Array.from(), to convert the Array-like NodeList
// into an Array, to enable the use of Array methods:
Array.from(document.querySelectorAll('input[type=checkbox]'))

  // her we use Array.forEach() to iterate over the Array of
  // <input> elements, using an Arrow function syntax;
  // 'input' is a reference to the current <input> node of 
  // the Array, and we then pass that to the Arrow function,
  // which binds the amountsOf() function (though note the
  // deliberate absence of parentheses) as the 'change'
  // event-handler for the current <input> element:
  .forEach(input => input.addEventListener('change', amountsOf))


// here we create a new Event, in order to fire the named
// 'change' event on those elements that have the checked
// attribute/property:
var changeEvent = new Event('change');

// here we create an Array of all the <input> elements of
// type=checkbox, which are currently checked:
Array.from(document.querySelectorAll('input[type=checkbox]:checked'))

  // we iterate over that Array of elements using the
  // anonymous method (though we could use an Arrow
  // function instead):
  .forEach(function(input) {
    // 'input' is a reference to the current <input>
    // element in the array of <input> elements over
    // which we're currently iterating:

    // here we fire the 'change' event on those
    // found checked <input> elements:
    input.dispatchEvent(changeEvent);
  });
function amountsOf() {
  var changed = this,
    inputName = changed.parentNode.textContent.trim(),
    input = document.createElement("input"),
    label = document.createElement('label'),
    text = document.createTextNode("Amount of " + inputName + ": "),
    contentTo = document.getElementById(inputName.toLowerCase() + 'input');
  if (changed.checked) {
    label.appendChild(text);
    label.appendChild(input);

    input.type = "text";
    input.value = changed.dataset.inputvalue;
    input.name = "Amount" + inputName;

    document.getElementById(inputName.toLowerCase() + 'input').appendChild(label);

  } else {
    contentTo.querySelector('label').remove();
  }
}

Array.from(document.querySelectorAll('input[type=checkbox]'))
  .forEach(input => input.addEventListener('change', amountsOf))


var changeEvent = new Event('change');
Array.from(document.querySelectorAll('input[type=checkbox]:checked'))
  .forEach(function(input) {
    input.dispatchEvent(changeEvent);
  });
label {
  display: block;
}

JS Fiddle demo

请注意,您的HTML和JavaScript函数都有一些更改。

我们将<p>Clothing</p> <label> <input type="checkbox" name="check1" data-inputvalue="1" checked />Pants</label> <label> <input type="checkbox" name="check2" data-inputvalue="2" />Shirts</label> <p id="pantsinput"></p> <p id="shirtsinput"></p>元素中的<input>元素包装到html中,以便点击<label>元素的文本可以关注或更改关联的<label>元素(为了更好的用户界面)。我更新了'衬衫'段落的<input>,从'shirtinput'到'shirtsinput',只是为了保持id结构的一致性,因为我们只使用了一个函数。鉴于用户可能想要选择多件衬衫,这也具有语义意义。

在JavaScript函数中,我完全删除了id元素,因为<div>不能是<div>元素的子元素,并且创建的<p>元素是现在无论如何包裹在<input>

此外,我没有对JavaScript中新创建的<label>元素的值进行硬编码,而是将这些值移动到HTML中的自定义<input>属性中,data-*属性。虽然我保持了你的价值观和插入,但我真的不确定这给用户带来了什么好处;当然,默认应该是data-inputvalue1,因为衬衫或裤子的数量完全取决于他们(我认为0可能是更好的选择,否则他们会'不太可能在第一时间点击1

参考文献:

参考书目: