Show/hide textfield base on what is chosen on a dropdown menu

I need a js to show/hide textfield base on what is chosen on a dropdown menu. I did not find one here http://jqueryui.com/demos/ is it something like that on their site? If no, where else the is a reliable one?

The basic approach would be to give those text fields IDs that match the corresponding values of the select options, and show/hide them on change. Since you’re apparently using jQuery, it might look like

CSS

.text-block {
  display: none;
}

HTML

<select name="my-select" id="my-select">
  <option value="foo">Foo</option>
  <option value="bar">Bar</option>
</select>

<div id="foo" class="text-block">Foo text</div>
<div id="bar" class="text-block">Bar text</div>

JS

// Cache the text blocks
var textBlocks = $('.text-block');

$('#my-select').change(function() {  
    textBlocks.hide();
  
  // Show the text block that corresponds to
  // the select value
  textBlocks.filter('#' + this.value).show();
});

fiddle

1 Like

Sorry for confusion. I meant textfield of form not a text.

The same method could be applied to any html element.

1 Like

BTW, you could also do this more generically by wrapping those text areas (or whichever elements) in a container div, where each nth child corresponds to the nth option of the select; this way you don’t have to maintain the matching values/IDs. Like

<select name="my-select" id="my-select">
  <option value="foo">Foo</option>
  <option value="bar">Bar</option>
</select>

<div class="container">
  <textarea>Foo text</textarea>
  <textarea>Bar text</textarea>
</div>
var textareas = $('.container textarea');

$('#my-select').change(function() {  
  textareas.hide();
  textareas.eq(this.selectedIndex).show();
});

However, the explicit way would probably be more reliable (if that’s really an issue) as an unmatched ID would simply not show – the wrong order would lead to the wrong element to be shown, which requires more careful QA.

For start let’s keep it easy and use inline simple js instead of jQuery.
I want if recaptcha is chosen then private and public key fields will be visible. As I see I use a table, so the entire row show be hidden. and the rest of forms should become upper to be immediately under select menu if those fields should be hidden. But it doesn’t work for row. and only the second field will be in/invisible because I added the style on field rather than on tr. (just for testing for first one I used it for tr and for second one I used for field, but only second one works.) How to set it work for row and the rest of form will be upper to avoid two blank rows in form?

<tr class="something1">
   <td class="left">Activate Captcha: </td>
   <td class="right"><select name="activate_captcha" onchange="if (this.value=='recaptcha'){this.form['recaptcha'].style.visibility='visible'}else{this.form['recaptcha'].style.visibility='hidden'};">
   <option value="none">None</option>
   <option value="recaptcha">ReCaptcha</option>
   </select>
</td>
 </tr>
 <tr class="something1" id="recaptcha" style="visibility:hidden;">
   <td class="left">ReCaptcha Public Key: </td>
   <td class="right"><input type="text" size="40" name="pub_key" value="" /></td>
</tr>
 <tr class="something1">
   <td class="left">ReCaptcha Private Key: </td>
   <td class="right"><input type="text" id="recaptcha" style="visibility:hidden;" size="40" name="priv_key" value="" /></td>
</tr>

Apologies, but you did mention jQuery in your OP. ^^ Good on you for preferring vanilla JS, but I’d strongly advise not to use inline JS – it’s not simple, it’s hard to maintain and debug, practically unreusable, and you can’t even get proper syntax highlighting. Same for inline styles, with the additional problem that they can only be overridden with !important rules – or even more inline styles.

Simple: don’t use tables for styling. ;-) Anyway, my first example above would actually even work with table rows. Here’s the same w/o jQuery:

CSS

.hidden {
  display: none;
}

HTML

Activate Captcha:
<select name="captcha-select" id="captcha-select">
  <option value="pub_key">None</option>
  <option value="priv_key">ReCaptcha</option>
</select>

<div id="pub_key" class="hidden">
  ReCaptcha Public Key: <input type="text" name="pub_key">
</div>
<div id="priv_key" class="hidden">
  ReCaptcha Private Key: <input type="text" name="priv_key">
</div>

JS

// Reference to the hidden elements (doesn't change
// when the class list changes), as well as the select
var hidden = document.querySelectorAll('.hidden');
var select = document.querySelector('#captcha-select');

select.addEventListener('change', function() {  
	
  // Hide all elements that were initially hidden
  for (var i in Object.keys(hidden)) {
    hidden[i].classList.add('hidden');
  }
  
  // Show the element that corresponds to
  // the select value
  document
    .querySelector('#' + this.value)
    .classList
    .remove('hidden');
});
2 Likes

Ok. Many thanks for your advice. Then how would be jQuery equivalent to approach this? I apologize for the pain. With your first answer, the row under those two text fields will come up under select menu? You gave example for textarea and for textblock, but how to use it for input textfield? What should I change in your first jQuery for input text field?

Just use the jQuery equivalents to the plain JavaScript commands - although in this case there is almost no difference in the length of the code apart from having to add the jQuery library so using jQuery unless you need it for other scripts in the page is unnecessary.

I am using it:

<form>
 <table>
<tr class="something1">
  <td class="left">Activate Captcha:</td>
  <td class="right">
    <select name="activate_captcha" onchange="$(this.form).find('.recaptcha').css('visibility', this.value=='recaptcha' ? 'visible' : 'hidden');">
      <option value="none">None</option>
      <option value="recaptcha">ReCaptcha</option>
    </select>
  </td>

</tr>
<tr class="something1 recaptcha" style="visibility:hidden;">
  <td class="left">ReCaptcha Public Key:</td>
  <td class="right">
    <input type="text" size="40" name="pub_key" value="" />
  </td>

</tr>
<tr class="something1 recaptcha" style="visibility:hidden;">
  <td class="left">ReCaptcha Private Key:</td>
  <td class="right">
    <input type="text" size="40" name="priv_key" value="" />
  </td>
</tr>
</tr>
<tr class="something1">
  <td class="left">This row should come up under dropdown if rows above are invisible:</td>
  <td class="right">
    <input type="text" value="" />
  </td>
</tr>
</table>
</form>

It works fine, but

  1. if two fields disappears I want to third field comes up immediately under select menu to avoid row gaps
  2. select menu might be already recaptcha from start as it comes from db and already saved. so it must not work only on change but also if select menu is recaptcha already from start.

How to fix these 2 issues?

Stop jumbling the HTML and JavaScript together - you don’t need to support Netscape 4 any more and that JavaScript will no longer run once you install CSP headers to prevent code injection in your pages.

Ok. Thanks for advice. But how to fix 2 issues I said above?

No worries! :-)

As @SamA74 said above, those examples work for any elements (with any children, like inputs etc. – so would simply apply it to the wrapping elements, like the trs in your code). To answer your other questions,

  1. You could do this with CSS, like e.g.
.hidden,
.recaptcha:not(.hidden) ~ .fallback {
  display: none;
}
<div class="recaptcha hidden">Foo</div>
<div class="recaptcha hidden">Bar</div>
<div class="fallback">FallBaz</div>

(Just replace the divs with table rows if you must.)

  1. You could trigger the change event right after it was attached, like (using jQuery again – I’m starting to get confused) ^^
var select = $('#my-select');

select.change(function(event) { /* ... */ });
select.change();

With vanilla JS, you’d first have to create a corresponding event in order to dispatch it, like

var select = document.querySelector('#my-select');
var change = new Event('change');

select.addEventListener('change', function(event) { /* ... */ });
select.dispatchEvent(change);

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.