0

I have the following HTML form with 5 fields, in which one is a drop down list with two option (ward and room) and 4 other input text fields. I am trying to achieve that if I select ward from list, then room no and room name should be disabled. And if select Room from list then ward no and wardname should be disabled. Can I have a few bits of advice on how to achieve this?

$("select").change(function() {
  if ($(this).val() == ward) {
    $(".abc").attr("disabled", "disabled");
    $(".abc1").attr("disabled", "disabled");
  } else {
    $(".roomno").attr("disabled", "disabled");
    $(".roomname").attr("disabled", "disabled");
  }
}).trigger("change");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

<body>
  <form method="post" action="">
    <label>Sub Department :</label>
    <select id="type">
          <option value="ward">Ward</option>
          <option value="room">Room</option>
           </select>
    <label> Ward No<input type  = "text" name "abc" id = "abc">
    <label> Ward Name <input type  = "text" name "abc1" id = "abc1">
    <label> Room No<input type  = "text" name "roomno" id = "roomno">
    <label> Room Name <input type  = "text" name "roomname" id = "roomnam">
    </form>
    </body>
    </html>
DarkBee
  • 16,592
  • 6
  • 46
  • 58
Moon
  • 63
  • 5
  • What problem are you having? It seems like a simple `if/else` in the event listener for the dropdown. Please post what you tried and we'll help you fix it. – Barmar Aug 01 '23 at 06:12
  • @Barmar check my javasscript code now, select valueis coming from mysql database table – Moon Aug 01 '23 at 06:24
  • You're never enabling the other inputs. You need to use `.removeAttr('disabled')` on the ones that should be enabled. – Barmar Aug 01 '23 at 06:26
  • @Barmar it will be on the basis of selection, if ward selected then first two will be enables, otherwise last two. can u edit my code , i need it for my study project – Moon Aug 01 '23 at 06:31

4 Answers4

1

When you disable one set of inputs you have to enable the other set.

Other problems:

  • You have to put ward in quotes to make it a string.
  • You have to use # to select by ID. . is for classes.
  • You had no <option> in your <select>
  • You were missing all the </label>
  • You were missing = after all the name.

$("select").change(function() {
  if ($(this).val() == 'ward') {
    $("#abc, #abc1").removeAttr("disabled");
    $("#roomno, #roomname").attr("disabled", "disabled");
  } else {
    $("#abc, #abc1").attr("disabled", "disabled");
    $("#roomno, #roomname").removeAttr("disabled");
  }
}).trigger("change");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

<body>
  <form method="post" action="">
    <label>Sub Department :</label>
    <select name="wardroom" id="wardroom">
      <option value="ward">Ward</option>
      <option value="room">Room</option>
    </select>
    <br>
    <label> Ward No<input type  = "text" name="abc" id = "abc"></label>
    <label> Ward Name <input type  = "text" name="abc1" id = "abc1"></label>
    <br>
    <label> Room No<input type  = "text" name="roomno" id = "roomno"></label>
    <label> Room Name <input type  = "text" name="roomname" id = "roomname"></label>
  </form>
</body>

</html>
Martlark
  • 14,208
  • 13
  • 83
  • 99
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

$("select").change(function() {
  if ($(this).val() == 'ward') {
    $("#abc, #abc1").removeAttr("disabled");
    $("#roomno, #roomname").attr("disabled", "disabled");
  } else {
    $("#abc, #abc1").attr("disabled", "disabled");
    $("#roomno, #roomname").removeAttr("disabled");
  }
}).trigger("change");
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>

<body>
  <form method="post" action="">
    <label>Sub Department :</label>
    <select name="wardroom" id="wardroom">
      <option value="ward">Ward</option>
      <option value="room">Room</option>
    </select>
    <br>
    <label> Ward No<input type  = "text" name="abc" id = "abc"></label>
    <label> Ward Name <input type  = "text" name="abc1" id = "abc1"></label>
    <br>
    <label> Room No<input type  = "text" name="roomno" id = "roomno"></label>
    <label> Room Name <input type  = "text" name="roomname" id = "roomnam"></label>
  </form>
</body>

</html>
  • As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 04 '23 at 00:08
0

There are a few options to implement this, I'll offer both jQuery and (plain) JavaScript options:

// selecting the relevant element via its id, using a CSS selector, and
// using the on() method to bind the anonymous function as the event-
// handler of the 'change' event fired on the identified element:
$('#type').on('change', function() {
  // getting the currently selected value (as a string), using
  // String.prototype.trim() to remove leading and trailing white-space,
  // and then converting to lower-case text for comparison:
  let value = $(this).val().trim().toLowerCase();

  // selecing all <label> elements, and iterating over that collection
  // using each():
  $('label').each(function() {
    // $(this) is the current <label> of each iteration:
    $(this)
      // from the <label> we find the nested <input>:
      .find('input')
      // we use the prop() method to update the 'disabled' property:
      .prop('disabled',
        // and here we convert the text of the current <label> ($(this))
        // to lower-case, and use String.prototype.includes() to
        // return a Boolean; this is true if the value (the string
        // we're looking for) is included, and false if not; because
        // we're setting the disabled/"inactive" state, we invert
        // that Boolean to appropriately disable/enable the <input>:
        !$(this).text().toLowerCase().includes(value)
      );
  });
// firing the 'change' event after the event-listener is bound so
// that the <input> elements are in the correct state on page-load:
}).change();
label {
  display: flex;
  gap: 1rem;
  inline-size: 30%;
  justify-content: end;
  padding-block: 0.25rem;
}

input {
  border: 2px solid var(--stateIndicator);
  inline-size: 10rem;
  padding-block: 0.25rem;
  padding-inline: 0.5rem;
  transition: border-color 250ms;
}

input:enabled {
  --stateIndicator: palegreen;
}

input:disabled {
  --stateIndicator: salmon;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" action="">
  <label>Sub Department :</label>
  <select id="type">
    <option value="ward">Ward</option>
    <option value="room">Room</option>
  </select>
  <label> Ward No<input type="text" name="abc" id="abc"></label>
  <label> Ward Name <input type="text" name="abc1" id="abc1"></label>
  <label> Room No<input type="text" name="roomno" id="roomno"></label>
  <label> Room Name <input type="text" name="roomname" id="roomname"></label>
</form>

JS Fiddle.

In plain JavaScript the above would be:

// we're using this element in two places in this example, so 
// it makes sense to cache it in a variable:
let selectElement = document.querySelector('#type');

  selectElement
  // binding the anonymous function of the
  // EventTarget.addEventListener() method:
  .addEventListener('change', (evt) => {
    // using destructuring assignment to retrieve
    // the currentTarget property, and rename it
    // to the variable 'el':
    let {
      currentTarget: el
    } = evt,
    // retrieving the selected value of the
    // element, again: trimming away white-space
    // from beginning and end, and converting
    // to lower-case:
    {
      form
    } = el,
    value = el.value.trim().toLowerCase();

    // using Element.querySelectorAll() to find all
    // matching elements contained within the <form>
    // element that contains the <select>:
    form.querySelectorAll('label')
      // iterating over the NodeList returned:
      .forEach(
        (label) => {
          // this is because while jQuery guards against the
          // consequence of a selector returning null,
          // JavaScript doesn't; so here we first retrieve
          // the <input>:
          let input = label.querySelector('input');

          // and here we test for its existence (because obviously
          // the <label> prior to the <select> has no <input> element):
          if (input) {
            // here we do exactly as we did in jQuery, we update
            // the disabled property of the <input> element depending
            // on the presence or absence of the 'value' in the
            // <label> element's text:
            label.querySelector('input').disabled = !label.textContent.toLowerCase().includes(value)
          }
        })
  });
  
// firing the 'change' event after the event-listener is bound, using
// EventTarget.dispatchEvent, in order that the <input> elements are
// in the correct state on page-load:
  selectElement.dispatchEvent(new Event('change'));
label {
  display: flex;
  gap: 1rem;
  inline-size: 30%;
  justify-content: end;
  padding-block: 0.25rem;
}

input {
  border: 2px solid var(--stateIndicator);
  inline-size: 10rem;
  padding-block: 0.25rem;
  padding-inline: 0.5rem;
  transition: border-color 250ms;
}

input:enabled {
  --stateIndicator: palegreen;
}

input:disabled {
  --stateIndicator: salmon;
}
<form method="post" action="">
  <label>Sub Department :</label>
  <select id="type">
    <option value="ward">Ward</option>
    <option value="room">Room</option>
  </select>
  <label> Ward No<input type="text" name="abc" id="abc"></label>
  <label> Ward Name <input type="text" name="abc1" id="abc1"></label>
  <label> Room No<input type="text" name="roomno" id="roomno"></label>
  <label> Room Name <input type="text" name="roomname" id="roomname"></label>
</form>

JS Fiddle demo.

The problems with the original code are below:

$("select").change(function() {
  // ward - without quotes - is interpreted as a
  // variable, not as a String; therefore it
  // needs to be quoted:
  if ($(this).val() == ward) {
    // while this is perfectly okay, I personally
    // prefer to minimise my code and reduce the
    // amount of typing I have to both undertake
    // and remember to update/change; also, I'd
    // personally use prop() rather than attr()
    // though that's not a "problem," just a
    // preference:
    $(".abc").attr("disabled", "disabled");
    $(".abc1").attr("disabled", "disabled");
  } else {
    $(".roomno").attr("disabled", "disabled");
    $(".roomname").attr("disabled", "disabled");
  }
}).trigger("change");

<form method="post" action="">
  <!-- there's no association between the label and
       the element to which it's related, ideally
       there'd be a 'for="type"' attribute and value:
  -->
  <label>Sub Department :</label>
  <select id="type">
    <!-- because there's no <option> set to be
         selected the initial page-state is
         determined by the browser rather than
         the app/site; which is fine but may
         cause issues:
    -->
    <option value="ward">Ward</option>
    <option value="room">Room</option>
  </select>
  <!-- <option> elements don't need to have a closing
       tag (if they're immediately followed by another
       <option> or <optgroup>, and I don't think anything
       else should be a sibling), but it looks messy?
       Further, though, the lack of an "=" sign between
       the "name" and the "abc" value, means that you
       create an element whose name attribute-value is
       empty (therefore useless), and - in Firefox at
       least - a quoted-attribute "abc" which also has
       an empty attribute-value; though this may be platform-
       specific:
  -->
  <label> Ward No<input type  = "text" name "abc" id = "abc">
  <label> Ward Name <input type  = "text" name "abc1" id = "abc1">
  <label> Room No<input type  = "text" name "roomno" id = "roomno">
  <label> Room Name <input type  = "text" name "roomname" id = "roomnam">
</form>

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
0

I will encourage you to use the <fieldset> for structuring your form fields. It has some build-in features that are useful. The attribute disabled can be used for enabling/disabling parts of the form. If a fieldset is disabled the values of the form fields/input elements inside the fieldset are not submitted with the form. So, you don't post stuff that is not in use. The disabled attribute does not hide the form fields, but you can hide the fieldset with a simple CSS selector.

As a side note, in forms it is often not necessary with IDs for input elements. Use the name attribute instead.

document.forms.form01.wardroom.addEventListener('change', e => {
  let val = e.target.value;
  let form = e.target.form;
  //disable all fieldsets
  [...form.elements]
    .filter(elm => elm.type == 'fieldset')
    .forEach(elm => elm.disabled = true);
  // enable the selected fieldset
  form.elements[val].disabled = false;
});
fieldset {
  border: none;
}

fieldset:disabled {
  display: none;
}
<form name="form01" method="post" action="">
  <label>Sub Department :</label>
  <select name="wardroom">
    <option value="ward">Ward</option>
    <option value="room">Room</option>
  </select>
  <fieldset name="ward">
    <label> Ward No <input type="text" name="wardno"></label>
    <label> Ward Name <input type="text" name="wardname"></label>
  </fieldset>
  <fieldset name="room" disabled>
    <label> Room No <input type="text" name="roomno"></label>
    <label> Room Name <input type="text" name="roomname"></label>
  </fieldset>
</form>
chrwahl
  • 8,675
  • 2
  • 20
  • 30