如何在禁用的 fieldset 中启用一个按钮

38

我想禁用Fieldset内的所有元素,但启用其中的一些按钮。 演示:

<fieldset ng-disabled="true">
    <legend>Personalia:</legend>
    Name: <input type="text"><br>
    Email: <input type="text"><br>
    Date of birth: <input type="text">

    <input type="button" value="See More (Enable this!!) " ng-click="ButtonClicked1()" ng-disabled="false"/>
    Somethingelse: <input type="text">
    <input type="button" value="View Details " ng-click="ButtonClicked2()"/> 
</fieldset>

你想在 fieldset 中只启用按钮吗? - Sudarshan Kalebere
根据情况,您可以使用非输入元素,如锚点、跨度等,并将其样式化为按钮。 - Amitesh
4个回答

12
我有三种解决方案:
解决方案1:使用<details><summary> 在你的例子中,你应该使用<details><summary> 元素:

label {
  display: block;
}
<fieldset disabled>
  <legend>
    Personalia:
  </legend>

  <label>Name: <input></label>
  <label>Email: <input></label>
  <label>Date of birth: <input></label>

  <label>Somethingelse: <input></label>

  <details>
    <summary>View Details</summary>
    <p>A more detailed description</p>
  </details>
</fieldset>

解决方案2:将按钮放在<legend>标签内

如果您不想公开更详细的信息,但是想要切换fieldset的禁用状态,那么您可以将切换按钮放在<legend>标签中。

const fieldset = document.querySelector("fieldset");
const toggleButton = document.getElementById("toggle-button");

toggleButton.addEventListener("click", (event) => {
  fieldset.disabled = !fieldset.disabled;
  toggleButton.textContent = fieldset.disabled ? "Enable" : "Disable";
  toggleButton.setAttribute("aria-pressed", `${!fieldset.disabled}`);
});
label {
  display: block;
}
<fieldset disabled>
  <legend>
    Personalia:
    <button id="toggle-button" aria-pressed="true">
      Enable
    </button>
  </legend>

  <label>Name: <input></label>
  <label>Email: <input></label>
  <label>Date of birth: <input></label>

  <label>Somethingelse: <input></label>
  <button>This may be disabled</button> 
</fieldset>

解决方案3:使用“假”按钮

如果您的用例完全不同,您可以使用aria角色来“伪造”一个按钮role="button"(请参见ARIA button role)。记得添加必要的辅助功能,以使这个按钮对于没有显示屏或鼠标的用户是可点击的。重要的属性是role="button"(为屏幕阅读器)和tabindex="0"(为键盘导航),还要记得为EnterSpace添加keypress处理程序,以防您的用户没有鼠标。

const disabledButton = document.querySelector('.disabled-button');
const disabledOutput = document.querySelector('.disabled-output');
const enabledButton = document.querySelector('.enabled-button');
const enabledOutput = document.querySelector('.enabled-output');

function increment(output) {
  const current = Number.parseInt(output.textContent);
  output.textContent = `${current + 1}`;
}

disabledButton.addEventListener('click', () => increment(disabledOutput));
disabledButton.addEventListener('keypress', event => {
  if (['Enter', ' '].includes(event.key)) {
    increment(disabledOutput);
  }
});

enabledButton.addEventListener('click', () => increment(enabledOutput));
enabledButton.addEventListener('keypress', event => {
  if (['Enter', ' '].includes(event.key)) {
    increment(enabledOutput);
  }
});
label {
  display: block;
}

[role="button"] {
  -webkit-appearance: button;
  appearance: button;
  cursor: default;
  font-style: normal;
  -webkit-user-select: none;
  user-select: none;
}
<fieldset disabled>
  <legend>Disabled form elements</legend>

  <label>Input 1<input name="input 1"></label>
  <label>Input 2<input name="input 2"></label>
  
  <button
    class="disabled-button"
    name="disabled-button"
  >
    This is disabled
  </button>

  <i
    class="enabled-button"
    role="button"
    tabindex="0"
  >
    This is enabled
  </i>
</fieldset>

<label>
  Disabled button clicks:
  <output class="disabled-output">0</output>
</label>

<label>
  Enabled button clicks:
  <output class="enabled-output">0</output>
</label>


1
将我的“input”放在“legend”中对我有用。我的HTML编辑器抱怨在“legend”中放置了一堆“不应该”存在的东西,但Chrome和Firefox都可以正常呈现它。 - Jacob Stamm
2
@JacobStamm 根据mdn的说法:“HTML <legend>元素代表其父级<fieldset>内容的标题。”我认为元控件——例如用于切换fieldset禁用状态的复选框;或者微不足道地影响fieldset内容的操作按钮——绝对可以作为所述fieldset的标题。因此,我认为你的文本编辑器给你提供了不合理的建议。话虽如此,上述示例应该明确使用<a>标签来链接“显示更多”。 - Rúnar Berg

2

解决方案1 - 使用带有点击事件的图标

使用图标而不是按钮,并将 click 事件附加到图标上。这样可以绕过禁用的字段集并顺利运行。

<fieldset disabled='disabled'>
  <img src='/images/trash-can.png' ng-click='openModal()'/>
</fieldset>

以及 JavaScript(使用 AngularJS)

$scope.openModal = ()=>{
  // do stuff
};

解决方案2 - 使用带有点击事件的Bootstrap样式的span

Bootstrap可以将一个span样式化为按钮的外观。Span不使用或继承disabled属性。

<fieldset disabled='disabled'>
  <span class="btn btn-default" ng-click='openModal()'>
    Button Text
  </span>
</fieldset>

以及使用AngularJS编写的JavaScript代码

$scope.openModal = ()=>{
  // do stuff
};

0

试试这个:

演示

HTML:

<fieldset id="form">
    <legend>Personalia:</legend>
    Name: <input type="text" /><br />
    Email: <input type="text" /><br />
    Date of birth: <input type="text" />

    <input id="btn1" type="button" value="See More (Enable this!!) " onclick="ButtonClicked1()" />
    Somethingelse: <input type="text" />
    <input type="button" value="View Details " onclick="ButtonClicked2()"/> 
</fieldset>

脚本:

$('#form :input').prop('disabled', true);
$("#btn1").prop('disabled', false);

6
但这不是使用 Angular 的方式,不过,它是有效的。现在的问题可能是如何使它尽可能接近 Angular 的方式。我的意思是,你如何从控制器或指令中选择所有相关元素? - tarekahf
6
这只是一个 jQuery 的“hack”,并不是一个有价值的解决方案。 - artemnih
这是一个可怕的黑客技巧。如果您将要保持启用的输入内容包装在标记中,它仍将有效。不过,我不知道如何定位它。 - Chris Smith
1
这个答案中的代码似乎与此博客上的完全相同:https://exceptionshub.com/how-to-enable-one-button-inside-a-disabled-fieldset.html - steampowered
这在Chrome中不起作用。还有其他可行的解决方案吗? - Hamid
这个答案失去了 fieldset 的重点。如果您需要禁用 fieldset 的不同行为(例如样式),它将无法正常工作。 - Rúnar Berg

0
一种选择是在要禁用的元素周围打开和关闭您的字段集。 (如果有更好的方法就好了):
<fieldset [disabled]="disableForm">
   ....html here that needs to be disabled...
</fieldset>

<button type="button"></button>

<fieldset [disabled]="disabledForm">
   ...more html to disable...
</fieldset>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接