在更改事件期间,单选按钮影响了错误的表单



我有一个包含多个表单的页面,每个表单上都有一个更改侦听器,每个单选按钮都可以在更改时提交表单。除了,它提交了错误的表格。我浏览了页面上的源代码,没有找到任何不匹配的标签(也许有人知道一个好的 html linter 以防万一?

这是我拥有的最相关的JS:

  var AcceptanceBtns = this.AcceptanceBtns = function (accBtnForm) {
    this.acceptanceBtnForm = accBtnForm;
    this.labels = this.acceptanceBtnForm.find("label.approval-buttons");
    this.radios = this.labels.find("input.radio-btn");
    this.checkedRadio = this.radios.filter(':checked');
    this.styleCheckedBtn();
  }
  AcceptanceBtns.prototype.confirmBtns = function () {
    var that = this;
    this.styleAcceptBtn()
    this.radios.on("change", function() {
      console.log("going");
      var radio = $(this);
      var label = radio.parent();
      that.styleBtnsOnChange(label)
      that.radios.off();
      that.acceptanceBtnForm.submit();
    });
  };
  AcceptanceBtns.prototype.startListening = function () {
    if (this.acceptanceBtnForm.length === 0) { return; }
    this.confirmBtns();
    this.submitResponse();
  };
  var AcceptAffiliateBtns = this.AcceptAffiliateBtns = function (formEl) {
    AB.call(this, formEl);
  };
  AcceptAffiliateBtns.prototype = Object.create(AB.prototype);
  AcceptAffiliateBtns.prototype.constructor = AcceptAffiliateBtns;
$(document).on("page:change", function () {
  if (typeof aab === 'undefined') {
    var aab = {};
  } else {
    $.each(aab, function (key, val) { val.stopListening(); });
  }
  $('form.accepting-affiliates').each(function (i, el) {
    aab[i.toString()] = new AcceptAffiliateBtns ($(el));
    aab[i.toString()].startListening();
  });
});

调试时,我在控制台中检查并that on change 事件中引用了第一种形式,尽管更改范围之外的this是正确的(并且有一些 js 样式,如您所见,它适用于所有按钮)。因此,要么无线电btn正在更改第一种形式,要么变量在实例之间混淆

我意识到几年前我遇到了这个问题,所以我回到那个项目看看我做了什么。这对谷歌来说是一个难题,所以我会自己回答,供未来的搜索者使用。

JS不是问题,它与标签和单选按钮有关(不确定表单中的其他标签)。如果单击标签,即使单选按钮嵌套在其中,标签似乎也会检查其for属性,然后找到具有匹配id的第一个单选按钮。由于单选按钮都相同,因此它会更改第一种形式的单选按钮。因此,您只需要确保每个标签和收音机都有唯一的for/id

// var x = randomNumber(); 
<label for="aab_" + x>
  <input id="aab_" + x selected="selected" type="radio" value="true" checked="checked" name="foo[bar]" />Accept
</label>
// var y = randomNumber();     
<label for="aab_" + y>
  <input id="aab_" + y selected="selected" type="radio" value="false" name="foo[bar]" />Reject
</label>
Rails solution:
<%= f.collection_radio_buttons(:bar, [[true, 'Accept'],[false, 'Reject']],
:first, :last, { selected: true }) do |b| %>
  <%= b.label(for: "aab_#{b.object_id}") {
    b.radio_button(id: "aab_#{b.object_id}") + b.text } %>
<% end %>
重命名

var that = this不是治愈的方法。您的that必须在使用时根据现有元素进行评估。在任何loop中,您的that表示最后使用的this。已知的治疗方法是将thisthat包裹在瓶盖中。

问题是您对多个元素使用具有相同 id 的标签标签:

// var x = randomNumber(); 
<label for="aab_" + x>
  <input id="aab_" + x selected="selected" type="radio" value="true" checked="checked" name="foo[bar]" />Accept
</label>
// var y = randomNumber();     
<label for="aab_" + y>
  <input id="aab_" + y selected="selected" type="radio" value="false" name="foo[bar]" />Reject
</label>

解决方案是不使用标签标签,因为标签它需要一个唯一的 ID。

最新更新