Hide Labels and Inputs with Jquery

Solution for Hide Labels and Inputs with Jquery
is Given Below:

Good afternoon,

I have the following code:

$(document).ready(function() {
  var mod = $('#modality').val();
  if (mod == "On Site") {
    $('#l_clinic').attr("hidden", false);
    $('#clinic').attr("hidden", false);
    $('#l_phone').attr("hidden", true);
    $('#phone').attr("hidden", true);
    $('#l_link').attr("hidden", true);
    $('#link').attr("hidden", true);
  }
  if (mod == "Telephonic") {
    $('#l_clinic').attr("hidden", true);
    $('#clinic').attr("hidden", true);
    $('#l_phone').attr("hidden", false);
    $('#phone').attr("hidden", false);
    $('#l_link').attr("hidden", true);
    $('#link').attr("hidden", true);
  }
  if (mod == "Videochat") {
    $('#l_clinic').attr("hidden", true);
    $('#clinic').attr("hidden", true);
    $('#l_phone').attr("hidden", true);
    $('#phone').attr("hidden", true);
    $('#l_link').attr("hidden", false);
    $('#link').attr("hidden", false);
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label style="font-weight: bold;">Modality:</label>
<input type="text" name="" id="modality" class="form-control">

<label id="l_clinic" style="font-weight: bold;">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control">
<label id="l_phone" style="font-weight: bold;">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control">
<label id="l_link" style="font-weight: bold;">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control">

I need to hide and show some of the labels and inputs depending on the value of the modality input, but it doesn’t work

Please help!!

As written, your code retrieves the value of the #modality <input> on document-ready, as the <input> has no default-value, and the user has not – yet – had opportunity to enter a value into the <input>, the value doesn’t match any of the listed matches.

As there is no else clause in your code nothing can happen.

Instead, assuming you wish the hiding/showing to occur following the user’s entry into that <input> element, you should enclose the functionality in an event-handler, as follows:

$(document).ready(function() {
  // we use the on() method to bind the anonymous (arrow) function
  // as the event-handler for the 'input' event, which handles
  // paste, keyup, keydown...
  $('#modality').on('input', () => {
    var mod = $('#modality').val();

    if (mod == "On Site") {
      $('#l_clinic').attr("hidden", false);
      $('#clinic').attr("hidden", false);
      $('#l_phone').attr("hidden", true);
      $('#phone').attr("hidden", true);
      $('#l_link').attr("hidden", true);
      $('#link').attr("hidden", true);
      // using else-if in order to group the
      // various conditions together (rather than
      // having multiple independent 'if'
      // statements that (theoretically) may
      // all be executed:
    } else if (mod == "Telephonic") {
      $('#l_clinic').attr("hidden", true);
      $('#clinic').attr("hidden", true);
      $('#l_phone').attr("hidden", false);
      $('#phone').attr("hidden", false);
      $('#l_link').attr("hidden", true);
      $('#link').attr("hidden", true);
    } else if (mod == "Videochat") {
      $('#l_clinic').attr("hidden", true);
      $('#clinic').attr("hidden", true);
      $('#l_phone').attr("hidden", true);
      $('#phone').attr("hidden", true);
      $('#l_link').attr("hidden", false);
      $('#link').attr("hidden", false);
    }
  });
});
*,
 ::before,
 ::after {
  box-sizing: border-box;
  font-size: 1rem;
  line-height: 1.4;
  margin: 0;
  padding: 0;
}


/* to style all <label> elements, rather than using
   the in-line style attribute: */
label {
  font-weight: bold;
}


/* forcing each <label> element to a new line: */
label::before {
  content: '';
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<!-- added the "for" attribute, filling the attribute-value equal to the
     id of the input-element to which the label relates: -->
<label for="modality">Modality:</label>
<input type="text" name="" id="modality" class="form-control">

<label id="l_clinic" for="clinic">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control">

<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control">

<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control">

JS Fiddle demo.

Of course, it’s worth observing that should someone clear the text from the #modality input, this doesn’t reset the visibility of the other elements (although if the user subsequently enters a value that matches the id of another element that element will be shown).

With that in mind it may be a benefit to allow the visibility of elements to reset to all being visible should the <input> be emptied:

$(document).ready(function() {
  $('#modality').on('input', () => {
    var mod = $('#modality').val();

    if (mod == "On Site") {
      $('#l_clinic').attr("hidden", false);
      $('#clinic').attr("hidden", false);
      $('#l_phone').attr("hidden", true);
      $('#phone').attr("hidden", true);
      $('#l_link').attr("hidden", true);
      $('#link').attr("hidden", true);
    } else if (mod == "Telephonic") {
      $('#l_clinic').attr("hidden", true);
      $('#clinic').attr("hidden", true);
      $('#l_phone').attr("hidden", false);
      $('#phone').attr("hidden", false);
      $('#l_link').attr("hidden", true);
      $('#link').attr("hidden", true);
    } else if (mod == "Videochat") {
      $('#l_clinic').attr("hidden", true);
      $('#clinic').attr("hidden", true);
      $('#l_phone').attr("hidden", true);
      $('#phone').attr("hidden", true);
      $('#l_link').attr("hidden", false);
      $('#link').attr("hidden", false);
    // here we add a further else-if clause,
    // which matches an empty-string:
    } else if (mod == "") {
      $('#l_clinic').attr("hidden", false);
      $('#clinic').attr("hidden", false);
      $('#l_phone').attr("hidden", false);
      $('#phone').attr("hidden", false);
      $('#l_link').attr("hidden", false);
      $('#link').attr("hidden", false);
    }
  });
});
*,
 ::before,
 ::after {
  box-sizing: border-box;
  font-size: 1rem;
  line-height: 1.4;
  margin: 0;
  padding: 0;
}

label {
  font-weight: bold;
}

label::before {
  content: '';
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="modality">Modality:</label>
<input type="text" name="" id="modality" class="form-control">

<label id="l_clinic" for="clinic">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control">

<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control">

<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control">

JS Fiddle demo.

But there is a whole lot of repetition in that posted code, and the maxim of “DRY” (“Don’t Repeat Yourself”) code is that we shouldn’t do that, since it helps reduce the potential for errors. So, instead we can access the elements and update them all using a simple switch/assessment:

$(document).ready(function() {
  $('#modality').on('input', () => {
    const mod = $('#modality').val(),
      // here we select the relevant <input> elements via
      // their id:
      group = $('#clinic, #phone, #link');

    // we iterate over the <input> elements using the prop() method
    // (most, if not all, jQuery methods interally iterate over the
    // collection they're working on) to update the 'hidden' property;
    // the arguments passed to the function are:
    // _i: the index of the current element in the collection, and
    // current: the current property-value of the property we're
    // updating:
    group.prop('hidden', function(_i, current) {

      // here we retrieve the attribute-value of the custom
      // data-mode attribute, and use the
      // String.prototype.startsWith() method to obtain a Boolean
      // result indicating whether the data-mode attribute-value of
      // the current element starts with the String stored in the
      // 'mod' variable; we then use the NOT operator to invert that
      // result because passing a Boolean true to the 'hidden' property
      // will hide the element, whereas we want to show the element
      // whose data-mode attribute-value begins with the entered string:
      const evaluation = !$(this).data('mode').startsWith(mod);

      // here we retrieve the <label> elements associated with (their
      // for attribute, or htmlFor property) the relevant <input> and
      // we update them in a similar way to the <input> elements (though
      // we pass a single argument rather than using a callback function):
      $(this.labels).prop('hidden', evaluation);

      // and here we return the evaluation true (to hide an element) or
      // false (to show an element):
      return evaluation;
    });
  });
});
*,
::before,
::after {
  box-sizing: border-box;
  font-size: 1rem;
  line-height: 1.4;
  margin: 0;
  padding: 0;
}

label {
  font-weight: bold;
}

label::before {
  content: '';
  display: block;
}
<label for="modality">Modality:</label>
<input type="text" name="" id="modality" class="form-control">

<label id="l_clinic" for="clinic">Clinic:</label>
<!-- I've added a custom data-* attribute - here 'data-mode' - to define
     the string that the user should type to show this specific <input>,
     this is absolutely configurable to your own needs/preferences: -->
<input type="text" name="" id="clinic" class="form-control" data-mode="clinic">

<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control" data-mode="phone">

<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control" data-mode="link ">

JS Fiddle demo.

It’s worth noting, though, that any solution that requires a user to type a specific string &ndash even if case-matching isn’t strict – means that any given user may become frustrated; therefore I’d suggest improving the UI through the use of either a <select> or a radio-<input>.

First, the <select>:

$(document).ready(function() {
  $('#modality').on('change', () => {
    const mod = $('#modality').val(),
      group = $('#clinic, #phone, #link');

    group.prop('hidden', function(_i, current) {

      const evaluation = !$(this).data('mode').startsWith(mod);

      $(this.labels).prop('hidden', evaluation);

      return evaluation;
    });

  });
});
*,
::before,
::after {
  box-sizing: border-box;
  font-size: 1rem;
  line-height: 1.4;
  margin: 0;
  padding: 0;
}

label {
  font-weight: bold;
}

label::before {
  content: '';
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label for="modality">Modality:</label>
<select id="modality">
  <!-- we set the disabled property to prevent the user from
       re-selecting the 'please select' option, and we set
       the 'selected' property in order to ensure that this
       option is visible on page-load: -->
  <option value="-1" disabled selected>Please select:</option>
  <option value="clinic">Clinic</option>
  <option value="phone">Telephone</option>
  <option value="link">Videochat</option>
</select>

<label id="l_clinic" for="clinic">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control" data-mode="clinic">

<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control" data-mode="phone">

<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control" data-mode="link ">

And, finally, using radio <input> elements:

$(document).ready(function() {
    // here we select all <input> elements with a type equal to "radio" and
  // a name equal to "modality", and we then use the on() method with the
  // anonymous function (not an arrow function, as we need use 'this' within
  // the function body) as the handler for the 'change' event, since the
  // radio <input> takes only that one type of input-related event:
  $('input[type="radio"][name="modality"]').on('change', function() {
    const mod = $(this).val(),
      group = $('#clinic, #phone, #link');

    group.prop('hidden', function(_i, current) {

      const evaluation = !$(this).data('mode').startsWith(mod);

      $(this.labels).prop('hidden', evaluation);

      return evaluation;
    });

  });
});
*,
::before,
::after {
  box-sizing: border-box;
  font-size: 1rem;
  line-height: 1.4;
  margin: 0;
  padding: 0;
}

legend,
label {
  font-weight: bold;
}

label::before {
  content: '';
  display: block;
}

/* selecting those <label> elements inside of a
   <fieldset> element, and using the 'initial'
   property-value for the 'display' property to
   revert them to their native/unstyled form: */
fieldset label::before {
  display: initial;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<fieldset>
  <legend>Modality:</legend>

  <label>
    <span>Clinic</span>
    <input type="radio" name="modality" value="clinic">
  </label>

  <label>
    <span>Telephone</span>
    <input type="radio" name="modality" value="phone">
  </label>

  <label>
    <span>Videochat</span>
    <input type="radio" name="modality" value="link">
  </label>
</fieldset>

<label id="l_clinic" for="clinic">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control" data-mode="clinic">

<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control" data-mode="phone">

<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control" data-mode="link ">

It’s worth noting that this is all quite possible without jQuery, in native JavaScript:

// we trigger the JavaScript to run once the window receives the DOMContentLoaded event,
// implying that the elements exist on the page (but not necessarily that all <img> elements
// have finished loading); we use an anonymous Arrow function to wrap the JavaScript:
window.addEventListener('DOMContentLoaded', () => {

    // here we use document.querySelectorAll() to find all elements that are
  // <input> elements, with a type of "radio" and a name-attribute equal to
  // "modality":
  document.querySelectorAll('input[type=radio][name=modality]')
    // we use NodeList.prototype.forEach() to iterate over those elements:
    .forEach(
        // and use an Arrow function to bind an anonymous event-handling (arrow)
      // function to handle the 'change' event:
      (el) => {
        el.addEventListener('change', (e) => {

                    // we retrieve the changed <input> via the EventObject's
          // 'target' property, which retrieves the element that
          // fired the event to which we're currently reacting:
          const changed = e.target,
                    // we retrieve the value from that <input> element:
                  value = changed.value,
                // and we then select the <input> elements upon which
                // we wish to act, using a simple CSS selector which
                // selects all <input> elements which do not have
                // a name attribute equal to "modality":
                    group = document.querySelectorAll('input:not([name="modality"])');

                        // we again use NodeList.prototype.forEach() to iterate over the
            // group of elements, using an Arrow function:
            group.forEach(
                // the first argument of the arrow function is a reference to
              // the current Node of the NodeList over which we're iterating:
                (input) => {
                // here we do as before, retrieve the value, assess whether
                // the current element's data-mode attribute is exactly equal
                // to the value we retrieved earlier, and then invert that
                // Boolean:
                const evaluation = !(input.dataset.mode === value);

                                // We again use NodeList.prototype.forEach() to iterate
                // over the NodeList of <label> elements held in the
                // <input> element's 'labels' property, and update their
                // hidden property to match the earlier evaluation:
                input.labels.forEach(
                    (label) => label.hidden = evaluation
                )
                
                // and then, finally, we update the hidden property of
                // the current <input>:
                input.hidden = evaluation;
            });
        });
      });
});
*,
::before,
::after {
  box-sizing: border-box;
  font-size: 1rem;
  line-height: 1.4;
  margin: 0;
  padding: 0;
}

legend,
label {
  font-weight: bold;
}

label::before {
  content: '';
  display: block;
}

fieldset label::before {
  display: initial;
}
<fieldset>
  <legend>Modality:</legend>

  <label>
    <span>Clinic</span>
    <input type="radio" name="modality" value="clinic">
  </label>

  <label>
    <span>Telephone</span>
    <input type="radio" name="modality" value="phone">
  </label>

  <label>
    <span>Videochat</span>
    <input type="radio" name="modality" value="link">
  </label>
</fieldset>

<label id="l_clinic" for="clinic">Clinic:</label>
<input type="text" name="" id="clinic" class="form-control" data-mode="clinic">

<label id="l_phone" for="phone">Phone Number:</label>
<input type="text" name="" id="phone" class="form-control" data-mode="phone">

<label id="l_link" for="link">Videochat Link:</label>
<input type="text" name="" id="link" class="form-control" data-mode="link ">

JS Fiddle demo.