如何在一组复选框上动态删除和添加“欧芹多个”约束

问题描述

好的,我有一个用户提交的表单,需要或不需要,他们在列表中至少勾选一个电子邮件选项,具体取决于另一个复选框。

我使用的是 Parsley.js 2.8.2(我知道它有点落后)

<form method="POST" id="completeForm" action="/apI/Order/dispatch/{{ order.kOrder }}">
    <div class="alert alert-warning">
        <b>Instructions</b>
        <div class="form-check">
            <input type="checkBox" class="form-check-input" name="data[mail_order]" id="shipping" />
            <label class="form-check-label" for="shipping"><b>SHIPPING</b></label>
        </div>
        <div class="form-check">
            <input type="checkBox" class="form-check-input" name="data[collect]" id="collection" />
            <label class="form-check-label" for="collection"><b>COLLECTION</b></label>
        </div>
    </div>

    <label>Send Shipping Email to:</label>
    <div id="emailsList">
        <div class="form-check" style="margin-bottom: 0.5rem">
        
          <!-- THIS IS THE MULTIPLE I AM TRYING TO TOGGLE -->
          
          <input class="form-check-input billing" type="checkBox" data-parsley-multiple="selectOneEmail" data-parsley-mincheck="1" data-parsley-required data-parsley-error-message="Please choose at least one email address" id="send-contact-{{ list.contacts.order.billing.kContact }}" name="to_emails[{{ list.contacts.order.billing.kContact }}]"/>
          <label class="form-check-label" for="send-contact-{{ list.contacts.order.billing.kContact }}">
            <b>Billing: </b>{{ list.contacts.order.billing.firstname }} {{ list.contacts.order.billing.lastname }} &lt;{{ list.contacts.order.billing.email }}&gt;
          </label>
          <br/>
          <input class="form-check-input delivery" type="checkBox" data-parsley-multiple="selectOneEmail" id="send-contact-{{ list.contacts.order.delivery.kContact }}" name="to_emails[{{ list.contacts.order.delivery.kContact }}]"/>
          <label class="form-check-label" for="tracksend-contact-{{ list.contacts.order.delivery.kContact }}ingId">
            <b>Delivery: </b>{{ list.contacts.order.delivery.firstname }} {{ list.contacts.order.delivery.lastname }} &lt;{{ list.contacts.order.delivery.email }}&gt;
          </label>
        </div>
        
    </div>
 
    <button type=select>COMPLETE</button>
</form>

这是表格 - 我正在尝试将要求切换为“请至少选择一个电子邮件地址”

我目前正在使用这个脚本:

$(document).ready(function () {  
    $("form#completeForm").on("click","input[type=checkBox]#collection",CompleteOrder.ToggleCollection);
});
function ToggleCollection(event) {
    var el = $(event.target);
    var modal = el.closest("div.modal");
    var form = $("form#completeForm",modal);
    var Shipping = $("input#Shipping",modal);
    var enabled = el.prop("checked");
    
    var emailCheckBoxes = $("div#emailsList input[type=checkBox]",modal);
    
    //console.log("Collection",enabled,emailCheckBoxes);

    if(enabled) {
        FastShipping.prop("disabled",true);
        //emailCheckBoxes.prop("disabled",true);
        emailCheckBoxes.attr("required",false);

        $(emailCheckBoxes[0]).parsley().removeConstraint("mincheck");
        $(emailCheckBoxes[0]).parsley().removeConstraint("required");
        $(emailCheckBoxes[0]).parsley().removeError("errorMessage");

        emailCheckBoxes.each(function () {
            $(this).parsley().removeConstraint("multiple");
        });

        form.parsley().reset();
    } else {
        FastShipping.prop("disabled",false);
        //emailCheckBoxes.prop("disabled",false);
        emailCheckBoxes.prop("required",true);

        $(emailCheckBoxes[0]).parsley().addConstraint({ "mincheck": 1 });
        $(emailCheckBoxes[0]).parsley().addConstraint({ "required": true });
        $(emailCheckBoxes[0]).parsley().addError({ "errorMessage": "Please choose at least one email address" });

        emailCheckBoxes.each(function () {
            $(this).parsley().addConstraint({ "multiple": "selectOneEmail" });
        });
        
        form.parsley().reset();
    }
}

简单地说,我希望在 COLLECTION 复选框未选中时该要求处于活动状态,并在 COLLECTION 复选框选中时被禁用。

函数似乎没有错误地运行,但它并没有消除验证要求。如果我选中 COLLECTION 复选框,它仍然失败并在表单上询问“请至少选择一个电子邮件地址”。

由于 parsley.js 的文档相当少,我很挣扎,想知道是否还有其他人可以对此有所了解。还值得注意的是,存在电子邮件地址复选框数量超过 2 个的情况,因此需要支持 #emailsList div 中的任意复选框元素列表。

谢谢

解决方法

您正在以旧方式(Parsley 1.x)添加约束。 另外,您没有正确阅读文档。例如,您没有将正确的对象传递给 addError()

示例如下:

$("#collection").on("change",ToggleCollection);

$("#myModal").modal("show");

const modal = $("div.modal");
const emailCheckBoxes = $("div#emailsList input[type=checkbox]",modal);
const form = $("form#completeForm",modal);
form.parsley();

function ToggleCollection(event) {
  var el = $(event.target);
  var enabled = el.prop("checked");

  if (enabled) {
    $("form").parsley().destroy();

    emailCheckBoxes.first().removeAttr("data-parsley-mincheck");
    emailCheckBoxes.first().removeAttr("data-parsley-required");
    emailCheckBoxes.first().parsley().removeError("error1");
    emailCheckBoxes.prop("checked",false);
    emailCheckBoxes.attr("disabled",true);

    form.parsley();
  } else {
    emailCheckBoxes.first().attr("data-parsley-mincheck","2");
    emailCheckBoxes.first().attr("data-parsley-required",true);
    emailCheckBoxes.first().parsley().addError("error1",{
      message: "Please choose at least one email address",});
    emailCheckBoxes.attr("disabled",false);

    form.parsley().reset();
  }
}
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1.0" />
    <title>Document</title>
    <link
      rel="stylesheet"
      href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
      integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
      crossorigin="anonymous"
    />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script
      src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"
      integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q"
      crossorigin="anonymous"
    ></script>
    <script
      src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
      integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
      crossorigin="anonymous"
    ></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/parsley.js/2.8.2/parsley.min.js"></script>
  </head>
  <body>
    <div id="myModal" class="modal" tabindex="-1" role="dialog">
      <div class="modal-dialog" role="document">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title">Modal title</h5>
            <button
              type="button"
              class="close"
              data-dismiss="modal"
              aria-label="Close"
            >
              <span aria-hidden="true">&times;</span>
            </button>
          </div>
          <div class="modal-body">
            <form
              method="POST"
              id="completeForm"
              action="/api/order/dispatch/{{ order.kOrder }}"
            >
              <div class="alert alert-warning">
                <b>Instructions</b>
                <div class="form-check">
                  <input
                    type="checkbox"
                    class="form-check-input"
                    name="data[mail_order]"
                    id="shipping"
                  />
                  <label class="form-check-label" for="shipping"
                    ><b>SHIPPING</b></label
                  >
                </div>
                <div class="form-check">
                  <input
                    type="checkbox"
                    class="form-check-input"
                    name="data[collect]"
                    id="collection"
                  />
                  <label class="form-check-label" for="collection"
                    ><b>COLLECTION</b></label
                  >
                </div>
              </div>

              <label>Send Shipping Email to:</label>
              <div id="emailsList">
                <div class="form-check" style="margin-bottom: 0.5rem">
                  <!-- THIS IS THE MULTIPLE I AM TRYING TO TOGGLE -->

                  <input
                    class="form-check-input billing"
                    type="checkbox"
                    data-parsley-multiple="selectOneEmail"
                    data-parsley-mincheck="1"
                    data-parsley-required
                    data-parsley-error-message="Please choose at least one email address"
                    id="send-contact-{{ list.contacts.order.billing.kContact }}"
                    name="to_emails[{{ list.contacts.order.billing.kContact }}]"
                  />
                  <label
                    class="form-check-label"
                    for="send-contact-{{ list.contacts.order.billing.kContact }}"
                  >
                    <b>Billing: </b>{{ list.contacts.order.billing.firstname }}
                    {{ list.contacts.order.billing.lastname }} &lt;{{
                    list.contacts.order.billing.email }}&gt;
                  </label>
                  <br />
                  <input
                    class="form-check-input delivery"
                    type="checkbox"
                    data-parsley-multiple="selectOneEmail"
                    id="send-contact-{{ list.contacts.order.delivery.kContact }}"
                    name="to_emails[{{ list.contacts.order.delivery.kContact }}]"
                  />
                  <label
                    class="form-check-label"
                    for="tracksend-contact-{{ list.contacts.order.delivery.kContact }}ingId"
                  >
                    <b>Delivery: </b>{{ list.contacts.order.delivery.firstname
                    }} {{ list.contacts.order.delivery.lastname }} &lt;{{
                    list.contacts.order.delivery.email }}&gt;
                  </label>
                </div>
              </div>

              <button type="select">COMPLETE</button>
            </form>
          </div>
          <div class="modal-footer">
            <button type="button" class="btn btn-primary">Save changes</button>
            <button
              type="button"
              class="btn btn-secondary"
              data-dismiss="modal"
            >
              Close
            </button>
          </div>
        </div>
      </div>
    </div>

  </body>
</html>