【问题标题】:Submit button is ignoring required attributes提交按钮忽略了必需的属性
【发布时间】:2020-01-14 20:21:04
【问题描述】:

免责声明:这是我的第一个 HTML、CSS、JavaScript 项目。请原谅这里的任何误用词汇。

我正在为用户制作一个基本的网络表单,以进行一些通过失败检查。我将所有单选按钮设置为必需。我修改的基本项目的实现跳过了按钮部分,而是使用onclick 函数将任何非空白值转换为 JSON 列表。然后我编写了一些 JavaScript 来允许用户下载该列表。

在调试时,我意识到提交按钮忽略了所需的属性,但我正在使用的新清除所有按钮正确地确认了它们。

我目前正在调试 4 种方法,但决定咨询更有经验的人会教我更好的基础知识。

还有一个本地存储 JavaScript,如果有人需要查看它,我可以编辑它。

$(document).ready(function() {
  $("#btn").click(function(e) {
    var jsonData = {};
    var formData = $("#myform").serializeArray();
    $.each(formData, function() {
      if (jsonData[this.name]) {
        if (!jsonData[this.name].push) {
          jsonData[this.name] = [jsonData[this.name]];
        }
        jsonData[this.name].push(this.value || '');
      } else {
        jsonData[this.name] = this.value || '';
      }
    });
    console.log(jsonData);
    e.preventDefault();

    function download(content, fileName, contentType) {
      var a = document.createElement("a");
      var file = new Blob([content], {
        type: contentType
      });
      a.href = URL.createObjectURL(file);
      a.download = fileName;
      a.click();
    }
    download(JSON.stringify(jsonData), 'list.json', 'json');
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="myform" type="post">
  <fieldset>
    <legend>Some label </legend>
    <div class="elements">
      <label for="name">1) Test 1:</label>
      <input required="required" type="radio" value="pass" name="usb1" size="20" /> [PASS]
      <input required="required" type="radio" value="fail" name="usb1" size="20" /> [FAIL]
    </div>
    <p></p>
    <div class="elements">
      <label for="name">2) Test 2:</label>
      <input required="required" type="radio" value="pass" name="usb2" size="20" /> [PASS]
      <input required="required" type="radio" value="fail" name="usb2" size="20" /> [FAIL]
    </div>
    <!-- ignores required fields -->
    <div class="submit">
      <input type="submit" id="btn" name="btn" class="btn" value="Submit" />
    </div>
    <!-- Works same as above as far as I'm aware -->
    <button type="button" id="btn" name="btn" class="btn">Submit</button>
    <!-- //working correctly -->
    <button type="button" id="clr" name="clr" class="clr">Clear</button>
  </fieldset>
</form>

【问题讨论】:

  • 按钮点击与提交无关
  • 我从不理解使用所需单选按钮的愿望。单选按钮应该用于在多个选项之间进行选择,其中一个是默认选项。所以应该有三个单选按钮:未知、通过、失败,未知是默认值。验证将是必须检查通过或失败,而不是未知。然后,如果人们在准备好之前不小心检查了通过或失败,他们就可以撤销他们的选择。
  • @HereticMonkey 我认为如果您正在运行自己的表单验证(出于数据完整性目的,这可能是最佳实践),您提出的建议是一种处理方式。但是,DOM 上的表单中内置了验证触发器,单选按钮组上的 required 属性就是其中之一。如果可能的话,我宁愿在我的代码中没有额外的输入来维护和调试,个人。但我认为我们已经完全进入了这里的意见领域。

标签: javascript html


【解决方案1】:

这里的主要问题是您正在收听的事件。 click 事件不会冒泡导致表单提交,因为您正在调用 preventDefault。即使表单不完整,您的代码仍会运行。

但是,如果您改为在 ID 为 myForm 的表单上侦听 submit 事件,这仍会触发验证。查看有关提交事件的这篇文章:https://developer.mozilla.org/en-US/docs/Web/API/HTMLFormElement/submit_event

改变这个:

$("#btn").click(function(e){

到这里:

$("#myform").submit(function(e){

作为旁注,您还应该为每个输入添加一个标签(至少出于可访问性目的)。我在下面的 sn-p 中包含了一个带有注释的示例。这是一篇关于在标签上使用 for 属性的有用文章:https://developer.mozilla.org/en-US/docs/Web/API/HTMLLabelElement/htmlFor

有关更多参考,请参阅这些其他 SO 问题和答案:

How to use the "required" attribute with a "radio" input field

preventDefault() stops form validation

        $(document).ready(function() {
        /* Change the selector from listening on the click event of the button to the submit event of the form */
            $("#myform").submit(function(e){
                e.preventDefault();
                var jsonData = {};
                var formData = $("#myform").serializeArray();
                // console.log(formData);
                $.each(formData, function() {
                    if (jsonData[this.name]) {
                        if (!jsonData[this.name].push) {
                            jsonData[this.name] = [jsonData[this.name]];
                        }
                        jsonData[this.name].push(this.value || '');
                    } else {
                        jsonData[this.name] = this.value || '';
                    }
                });
                console.log(jsonData);
                


                function download(content, fileName, contentType) {
                    var a = document.createElement("a");
                    var file = new Blob([content], {type: contentType});
                    a.href = URL.createObjectURL(file);
                    a.download = fileName;
                    a.click();
                }


                download(JSON.stringify(jsonData), 'list.json', 'json');
            });
        });
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="myform" type="post">
  <fieldset>
    <legend>Some label </legend>
    <div class="elements">
    <!-- unrelated, but the for attribute should equal the id of the element for which it is a label, and for accessiblity purposes, its best that each input has it's own label -->
      <span>1) Test 1:</span>
      <label for="usb1-pass"><input id="usb1-pass" required type="radio"  value="pass" name="usb1"  size="20"  /> [PASS]</label>
      <label for="usb1-fail"><input id="usb1-fail" required type="radio"  value="fail" name="usb1"  size="20"  /> [FAIL]</label>
    </div>
    <p></p>
    <div class="elements">
      <span>2) Test 2:</span>
      <label for="usb2-pass"><input id="usb2-pass" required type="radio"  value="pass" name="usb2"  size="20"  /> [PASS]</label>
      <label for="usb2-fail"><input id="usb2-fail" required type="radio"  value="fail" name="usb2"  size="20"  /> [FAIL]</label>
    </div>
    <!-- with the change in how you listen, this will work -->
    <div class="submit">
       <input type="submit" id="btn" name="btn" class="btn" value="Submit" />
    </div>
    <!-- This won't work as a submit button 
    <button type="button" id="btn" name="btn" class="btn">Submit</button>
    -->
    <!-- //working correctly -->
    <button type="button" id="clr" name="clr" class="clr">Clear</button>
    <!--<span class="elements">Press "Ctrl + Shift + J" to see sent JSON in console: <span>-->
  </fieldset>
</form>

【讨论】:

  • 哇,非常感谢。非常明确的答案,我非常感谢。我也去看看那些文章!
  • 祝您的编码之旅好运!
【解决方案2】:

type=button&lt;button&gt; 不会尝试使用所需的参数进行验证,它需要是type=submit,你也不需要required=required,你可以直接输入required

如果您只想让required 参数起作用,您可以这样做

<!DOCTYPE html>
<html>
  <head>
    <title>SO question</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
  </head>

  <body>
    <canvas id="slot"> </canvas>
    <form id="myform" type="post">
      <fieldset>
        <legend>Some label</legend>
        <div class="elements">
          <label for="name">1) Test 1:</label>
          <input required type="radio" value="pass" name="usb1" size="20" /> [PASS]
          <input required type="radio" value="fail" name="usb1" size="20" /> [FAIL]
        </div>
        <p></p>
        <div class="elements">
          <label for="name">2) Test 2:</label>
          <input required type="radio" value="pass" name="usb2" size="20" /> [PASS]
          <input required type="radio" value="fail" name="usb2" size="20" /> [FAIL]
        </div>
        <!-- Works same as above as far as I'm aware -->
        <button type="submit" id="btn" name="btn" class="btn">Submit</button>
      </fieldset>
      <script>
        $(document).ready(function() {
          $('#btn').click(function(e) {
            var jsonData = {};
            var formData = $('#myform').serializeArray();
            $.each(formData, function() {
              if (jsonData[this.name]) {
                if (!jsonData[this.name].push) {
                  jsonData[this.name] = [jsonData[this.name]];
                }
                jsonData[this.name].push(this.value || '');
              } else {
                jsonData[this.name] = this.value || '';
              }
            });
            console.log(jsonData);
          });
        });
      </script>
    </form>
  </body>
</html>

在此方法之后,您仍然可以使用$("#btn").click() 来构建您的对象或任何其他逻辑。好处是内置 HTML &lt;form&gt; 验证,坏处是您仍然需要处理空输入,但它为您提供了选择。

【讨论】:

  • 调整 type=submit 也不会按预期评估属性。
  • 如果带有required 参数的input 位于form 的内部,并且type=submitbutton 的格式相同,那么它确实有效。
  • 一旦代码中只剩下一个type=submit input/button,这将不适用于上面的JS。它与正在收听的事件有关 onclick 而不是 onsubmit
  • 与表单中有多少按钮无关。只需一个按钮即可查看我编辑的代码。
猜你喜欢
  • 1970-01-01
  • 2015-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多