I have a form that has two radio buttons and a textarea. The textarea is disabled initially. When the user selects the 'Custom Message' radio button, the disabled property is removed and the textarea bees editable.
Now if the user selects the 'Dummy Message' radio button, the textarea should bee disabled again.
So far I have this code,
document.getElementById('customMessageRadioButton').addEventListener('change', function() {
if (document.getElementById('customMessageRadioButton').checked) {
document.getElementById('customMessageTextArea').removeAttribute("disabled");
document.getElementById('customMessageTextArea').focus();
}
if (!document.getElementById('customMessageRadioButton').checked) {
document.getElementById('customMessageTextArea').setAttribute("disabled", "true");
}
});
<input name="group1" id="dummy" type="radio" />Dummy Message
<input name="group1" id="customMessageRadioButton" type="radio" />Custom Message
<textarea disabled id="customMessageTextArea"></textarea>
I have a form that has two radio buttons and a textarea. The textarea is disabled initially. When the user selects the 'Custom Message' radio button, the disabled property is removed and the textarea bees editable.
Now if the user selects the 'Dummy Message' radio button, the textarea should bee disabled again.
So far I have this code,
document.getElementById('customMessageRadioButton').addEventListener('change', function() {
if (document.getElementById('customMessageRadioButton').checked) {
document.getElementById('customMessageTextArea').removeAttribute("disabled");
document.getElementById('customMessageTextArea').focus();
}
if (!document.getElementById('customMessageRadioButton').checked) {
document.getElementById('customMessageTextArea').setAttribute("disabled", "true");
}
});
<input name="group1" id="dummy" type="radio" />Dummy Message
<input name="group1" id="customMessageRadioButton" type="radio" />Custom Message
<textarea disabled id="customMessageTextArea"></textarea>
The issue I am facing here is in this case - when I select the 'Custom Message' radio button first and then I go back and choose the 'Dummy Message' radio button, the textarea is not getting disabled.
Here is my JS Bin
P.S. I cannot use jQuery. Have to use only vanilla Javascript.
Share Improve this question edited Jun 7, 2018 at 0:40 Barmar 782k56 gold badges546 silver badges660 bronze badges asked Jun 7, 2018 at 0:38 Kemat RochiKemat Rochi 9523 gold badges23 silver badges37 bronze badges 4- Possible duplicate of javascript remove "disabled" attribute to html input – Francesco Commented Jun 7, 2018 at 0:42
-
A change event isn't fired when a checkbox loses its
checked
status – Patrick Evans Commented Jun 7, 2018 at 0:43 - @PatrickEvans It seems to be fired in my snippet. – Barmar Commented Jun 7, 2018 at 0:44
- @Barmar not when I just tested it. Going back to the dummy one after checking the custom checkbox leaves the textarea still enabled – Patrick Evans Commented Jun 7, 2018 at 0:45
3 Answers
Reset to default 8Updated code based on your requirements, to make code simpler, I've used a flag to toggle the state of textarea.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
<script src="https://code.jquery./jquery-1.12.4.js"></script>
</head>
<body>
<input name="group1" id="dummy" type="radio" onclick="toggleRadio(false)"/>Dummy Message
<input name="group1" id="customMessageRadioButton" onclick="toggleRadio(true)" type="radio" />Custom Message
<textarea disabled id="customMessageTextArea"></textarea>
<script>
function toggleRadio(flag){
if(!flag) {
document.getElementById('customMessageTextArea').setAttribute("disabled", "true");
} else {
document.getElementById('customMessageTextArea').removeAttribute("disabled");
document.getElementById('customMessageTextArea').focus();
}
}
</script>
</body>
</html>
Here's the updated jsbin : http://jsbin./gadupoheke/1/edit?html,console,output
Solution
See the Control section if you don't want to read everything.
Layout
If using more than one form control...
...wrap everything in a
<form>
tag and give it an #id....separate form controls into groups and wrap them into
<fieldset>
tags....give the
<fieldset>
s and form controls #ids.
Access
For plete control of a <form>
...
...reference
<form>
tag with Document Object .forms propertyDot notation and #id of form
var formObj = document.forms.**FormID**
Or bracket notation and index of zero for first form
var formObj = document.forms[0]
Next, collect all of the
<form>
tag's form controls using the .elements property:var fields = formObj.elements
Having done that, you may use HTMLFormControlsCollection to reference any form control like a HTMLCollection by referencing the elements property and #id of the form control:
var set = fields.**fieldsetID** var sel = fields.**selectID** var btn3 = fields[2] // third form control
Control
An element's attributes are initially set by hard coding them in HTML:
<fieldset disabled>
Or programmatically by JS methods like setAttribute()
fieldsetObj.setAttribute('disabled', true)
Once an attribute is established, it should be referenced as a property if you want to change it:
fieldsetObj.disabled = false;
Event Handling
Delegate Events by registering events to the <form>
tag.
formObj.addEventListener('change', function)
Events that are the most applicable are:
change, input, click, focus, blur, submit, reset
When all events are delegated to the <form>
tag, the Event Object property Event.currentTarget will always refer to it. The element that was actually clicked, changed, received user input, gained focus, etc. is the origin of the event and can be referenced as Event.target.
Once an event occurs, an event chain will enter the capture phase:
e.currentTarget ===> e.target
<form> ============> <input>
Then the target phase:
e.target changed
<input checked>
Last is the bubbling phase any other elements thereafter will be triggered by event if arranged to do so by its own default behavior, by being registered, or arranged to do so (ex. if x is this, then y is that):
e.target =============> e.currentTarget
<input checked> ======> <form>
Tags
Many (but not all) form controls have special behavior that facilitates the operation of a <form>
and its form controls:
<fieldset>
: apply the [disabled] attribute to it and all of the form controls nested within will be enabled/disabled as well.<input type="radio">
: apply the [name] attribute to a group of [radios] and they will be mutually exclusive when [checked] (i.e. only one may be checked)Form controls with a [name] attribute will have their
value
sent to a server when the<form>
submits.<label>
: apply [for] attribute and set its value to another form control's #id will sync said<label>
and form control together. If a click event happens on said<label>
, then the associated form control will behave as if it was clicked as well.
Not all of the inherit traits listed above are used in the Demo but are mentioned because the possibility is there if needed.
Demo
Details mented in Demo
// Reference the form tag
var main = document.forms.main;
// Collect all of #main form controls
var m = main.elements;
// Reference the radio group
var g0 = m.grp0;
// Register change event on #main
main.addEventListener('change', action);
// Define callback passing the Event Object
function action(e) {
// if the changed element's [name] is "grp0"...
if (e.target.name === "grp0") {
// ...if "grp0" value is "on"...
if (g0.value === 'on') {
//...find the #set0 and enable it
m.set0.disabled = false;
} else {
//...otherwise disable #set0
m.set0.disabled = true;
}
//...otherwise if it isn't then ignore it.
} else {
return false;
}
}
/* for future exansion of form#main add if else condition between
|| if and else conditions
*/
<form id='main'>
<fieldset id='ctrl'>
<label>Group 1 On
<input name="grp0" value="on" type="radio" checked/>
Off
<input name="grp0" value="off" type="radio" />
</label>
</fieldset>
<fieldset id='set0'>
<legend>Group 1</legend>
<textarea id="txt"></textarea>
</fieldset>
</form>
const focusHandler = (e, status) => {
if(status) {
e?.target?.classList?.remove("text-grey");
e?.target?.classList?.add("text-black");
}else{
e?.target?.classList?.remove("text-black");
e?.target?.classList?.add("text-grey");
}
}
<Input className="text-grey" onChange={(e) => handleInputValue(e, "firstName")} onBlur={(e) => focusHandler(e, false)} onFocus={(e) => focusHandler(e, true)} placeholder="Enter your first name" />
you can use the above code for handling the toggle of the color code.