How to enable one button inside a disabled fieldset
Asked Answered
C

4

39

I want to disable all the elements inside Fieldset but enable few buttons inside it. Demo:

<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>
Copywriter answered 22/8, 2014 at 11:43 Comment(2)
You want to enable only buttons in fieldset??Armillda
Depending on situations you can use non-input elements like anchor, span etc and style that as your button.Dulsea
V
0

Try this:

DEMO

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>

SCRIPT:

$('#form :input').prop('disabled', true);
$("#btn1").prop('disabled', false);
Vie answered 22/8, 2014 at 13:35 Comment(6)
But this is not using angular way. However, it works. So probably the question now is how to make it as close as possible to angular. I mean, how you can select all related elements from a controller or directive?Kero
This a jQuery hack, not a valuable solutionZombie
Here's a horrible hack. If you wrap the input you want to remain enabled in the tags it will still work. No idea how you'd position it though.Belfast
The code in this answer seems to exist exactly the same on this blog: exceptionshub.com/…Freestanding
This doesn't work in chrome. any other viable solutions?Kerriekerrigan
This answer looses the point of the fieldset. It won’t work if you need some different behavior for disabled fieldset (for example for styling).Mei
B
12

I have 3 solutions for you:

Solution 1: <details> and <summary>

In your example you should probably use the <details> and <summary> elements:

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>

Solution 2: Put your button inside the <legend>

If your are not disclosing a more detailed information, but you want to, say, toggle the disabling of the fieldset, then you can put the toggle button in the <legend> element

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>

Solution 3: Use a “fake” button

If your use-case is something entirely different, you can use aria-roles to “fake” a button role="button" (see ARIA button role). Remember to add the necessary accessibility features to make this button clickable for users without display screens or mouse. The important attributes are role="button" (for screen readers) and tabindex="0" (for keyboard navigation), also remember to add a handler for keypress for Enter and Space in case your user doesn’t have a mouse.

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>
Balbur answered 14/3, 2019 at 5:41 Comment(2)
Putting my input inside the legend worked for me. My HTML editor complained about putting a bunch of stuff in a legend that "shouldn't" be there, but Chrome and Firefox both render it just fine.Jeannettejeannie
@JacobStamm According to mdn: “The HTML <legend> element represents a caption for the content of its parent <fieldset>.” I think meta controls—such as a checkbox to toggle the fieldset’s disabled state; or action buttons that marginally affect the fieldset’s content—do definitely pass as a caption for the said fieldset. So I think your text editor is giving you an unsound advice. That being said the above example should definitely rather use an <a> tag for a link to “show more”.Mei
F
2

Solution 1 - use icons with click event

Use icons instead of buttons and attaching the click event to the icons. This bypasses the disabled fieldset and works like a charm.

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

and the javascript (using angularjs)

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

Solution 2 - use a Bootstrap-styled span with click event

Bootstrap can style a span to look exactly like a button. Spans do not use, or inherit, the disabled attribute.

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

and the javascript (using angularjs)

$scope.openModal = ()=>{
  // do stuff
};
Freestanding answered 12/12, 2019 at 17:21 Comment(0)
V
0

Try this:

DEMO

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>

SCRIPT:

$('#form :input').prop('disabled', true);
$("#btn1").prop('disabled', false);
Vie answered 22/8, 2014 at 13:35 Comment(6)
But this is not using angular way. However, it works. So probably the question now is how to make it as close as possible to angular. I mean, how you can select all related elements from a controller or directive?Kero
This a jQuery hack, not a valuable solutionZombie
Here's a horrible hack. If you wrap the input you want to remain enabled in the tags it will still work. No idea how you'd position it though.Belfast
The code in this answer seems to exist exactly the same on this blog: exceptionshub.com/…Freestanding
This doesn't work in chrome. any other viable solutions?Kerriekerrigan
This answer looses the point of the fieldset. It won’t work if you need some different behavior for disabled fieldset (for example for styling).Mei
S
0

One option: open and close your fieldset around the elements you want to disable. (It would be nice if there was a better way):

<fieldset [disabled]="disableForm">
   ....html here that needs to be disabled...
</fieldset>

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

<fieldset [disabled]="disabledForm">
   ...more html to disable...
</fieldset>
Suctorial answered 12/6, 2023 at 18:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.