HTML select form with option to enter custom value
Asked Answered
C

7

159

I would like to have an input field that users can enter custom text value or choose from drop down. A regular <select> only offers drop down options.

How can I make a <select> accept custom value? For instance: Ford?

<select>
  <option value="volvo">Volvo</option>
  <option value="saab">Saab</option>
  <option value="mercedes">Mercedes</option>
  <option value="audi">Audi</option>
</select>
Criswell answered 13/4, 2011 at 13:56 Comment(2)
You could use javascript to dynamically add an option to the select but then using this information would become a real pain.Roundabout
I did not add that option for custom values on my website finnmglas.com/contact however someone contacted me with a custom value. That is so weirdFeverwort
G
365

HTML5 has a built-in combo box. You create a text input and a datalist. Then you add a list attribute to the input, with a value of the id of the datalist.

Update: As of March 2019 all major browsers (now including Safari 12.1 and iOS Safari 12.3) support datalist to the level needed for this functionality. See caniuse for detailed browser support.

It looks like this:

<input type="text" list="cars" />
<datalist id="cars">
  <option>Volvo</option>
  <option>Saab</option>
  <option>Mercedes</option>
  <option>Audi</option>
</datalist>
Gainsborough answered 22/2, 2014 at 18:6 Comment(8)
It works for me well. In many cases we don't need to support old browsers. I only added "down arrow" image on the background of input field to give users a hint it's expandable. Code (you need an actual image file): <input type="text" list="cars" style="background:url('images/arrow_down.png') no-repeat right center">Decoupage
I just tested in recent versions of IE, Firefox and Chrome with all working fine. I think this is a great simple solution to this common problem for many cases.Sauter
I really wanted to use this but I needed to set a default value. The user only sees the default in the drop down vs. all the options (because they are filtered out). They would need to know to clear the input field before seeing all the options.Disqualify
In Chrome this worked great with a short list. But once I added nearly 40 options, Chrome would no longer display the full list on the screen. Also if I added a value to the option tag <option value=""></option> Chrome displayed that value to the left, and then the other data to the right. Really bizarre.Bacteria
Found a page worth linking to this page. https://mcmap.net/q/152212/-html-datalist-shows-extra-options-separated-by-horizontal-line/2943403Perfect
The major cons of this method is, if I already selected Volvo then it won't display other options until we clear the whole text. This is not the case while using <select>. All options are always visible in <select>.File
Is there a way to make the dropdown menu appear with 1 click instead of 2?Schrick
Agreed with Srk95. It's a shame it doesn't show the full list after an option is selected. Not sure who thought this was a good idea. Awful design.Pollypollyanna
P
28

Alen Saqe's latest JSFiddle didn't toggle for me on Firefox, so I thought I would provide a simple html/javascript workaround that will function nicely within forms (regarding submission) until the day that the datalist tag is accepted by all browsers/devices. For more details and see it in action, go to: http://jsfiddle.net/6nq7w/4/ Note: Do not allow any spaces between toggling siblings!

<!DOCTYPE html>
<html>
<script>
function toggleField(hideObj,showObj){
  hideObj.disabled=true;        
  hideObj.style.display='none';
  showObj.disabled=false;   
  showObj.style.display='inline';
  showObj.focus();
}
</script>
<body>
<form name="BrowserSurvey" action="#">
Browser: <select name="browser" 
          onchange="if(this.options[this.selectedIndex].value=='customOption'){
              toggleField(this,this.nextSibling);
              this.selectedIndex='0';
          }">
            <option></option>
            <option value="customOption">[type a custom value]</option>
            <option>Chrome</option>
            <option>Firefox</option>
            <option>Internet Explorer</option>
            <option>Opera</option>
            <option>Safari</option>
        </select><input name="browser" style="display:none;" disabled="disabled" 
            onblur="if(this.value==''){toggleField(this,this.previousSibling);}">
<input type="submit" value="Submit">
</form>
</body>
</html>

Perfect answered 28/5, 2014 at 3:23 Comment(5)
I would like to go throught that fidle again! Witch version of Firefox was not supported there! I tested it with some version i dont remember! Kudos!Burroughs
I dont' know which version of FF I was on. I just had a look on FF34.0 and I am getting functionality now, so no worries. However, the default toggling option "Other" can be cleared away. When I remove "Other" by editing the value, the dropmenu doesn't offer an intuitive value to select (to access the editing feature). I think this comes down to personal preference. Because the dropmenu arrow is still present when the field is editable, users may not realize the field is editable. Not having a dig at you; just some feedback. My snippet also considers field naming inside of a <form>.Perfect
The end result of this ingenious but indecipherable (to me) script+html is to attach the selected option value, or entered text, to a GET of the same page as a query string. Does anyone know how to convert the action to a POST, so I can grab the value in a php file and do something with it there?Willem
I composed this script with the specific intention for it to behave in accordance with html form submissions. Are you using the post method as an attribute in the form tag? @Willem if you create a 3v4l.org link of your isolated snippet, I can take a quick look and possibly advise.Perfect
Boy do I feel dumb. I forgot to put a method in the form tag. It worked as posted with this very slight modification: <form name="BrowserSurvey" method="post" action="/gotThis.php"> ...Beautiful script, mickmackusa. Thanks for your followup hint!Willem
B
16

jQuery Solution!

Demo: http://jsfiddle.net/69wP6/2/

Another Demo Below(updated!)

I needed something similar in a case when i had some fixed Options and i wanted one other option to be editable! In this case i made a hidden input that would overlap the select option and would be editable and used jQuery to make it all work seamlessly.

I am sharing the fiddle with all of you!

HTML

<div id="billdesc">
    <select id="test">
      <option class="non" value="option1">Option1</option>
      <option class="non" value="option2">Option2</option>
      <option class="editable" value="other">Other</option>
    </select>
    <input class="editOption" style="display:none;"></input>
</div>

CSS

body{
    background: blue;
}
#billdesc{
    padding-top: 50px;
}
#test{
    width: 100%;
    height: 30px;
}
option {
    height: 30px;
    line-height: 30px;
}

.editOption{
    width: 90%;
    height: 24px;
    position: relative;
    top: -30px

}

jQuery

var initialText = $('.editable').val();
$('.editOption').val(initialText);

$('#test').change(function(){
var selected = $('option:selected', this).attr('class');
var optionText = $('.editable').text();

if(selected == "editable"){
  $('.editOption').show();


  $('.editOption').keyup(function(){
      var editText = $('.editOption').val();
      $('.editable').val(editText);
      $('.editable').html(editText);
  });

}else{
  $('.editOption').hide();
}
});

Edit : Added some simple touches design wise, so people can clearly see where the input ends!

JS Fiddle : http://jsfiddle.net/69wP6/4/

Burroughs answered 23/5, 2014 at 13:15 Comment(0)
P
16

If the datalist option doesn't fulfill your requirements, take a look to the Select2 library and the "Dynamic option creation"

$(".js-example-tags").select2({
  tags: true
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>


<select class="form-control js-example-tags">
  <option selected="selected">orange</option>
  <option>white</option>
  <option>purple</option>
</select>
Polo answered 13/7, 2018 at 12:52 Comment(0)
C
10

You can't really. You'll have to have both the drop down, and the text box, and have them pick or fill in the form. Without javascript you could create a separate radio button set where they choose dropdown or text input, but this seems messy to me. With some javascript you could toggle disable one or the other depending on which one they choose, for instance, have an 'other' option in the dropdown that triggers the text field.

Cookery answered 13/4, 2011 at 14:6 Comment(0)
P
2

Using one of the above solutions ( @mickmackusa ), I made a working prototype in React 16.8+ using Hooks.

https://codesandbox.io/s/heuristic-dewdney-0h2y2

I hope it helps someone.

Prognostication answered 5/9, 2019 at 3:21 Comment(3)
I am honored. I just checked my records and this was the 12th post that I made here on Stack Overflow -- feels like a million years ago.Perfect
I just had a play with your demo link and it looks like you have lost the effect to indefinitely toggle between the two types of fields.Perfect
this answer is too reliant on the off-site link. Please edit your answer to include the actual code.Perfect
M
2

This is the same solution as @mickmackusa but written using jquery:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="BrowserSurvey" action="#">
  Browser: <select name="browser" onchange="if($(this).val()=='customOption'){$(this).hide().prop('disabled',true);$('input[name=browser]').show().prop('disabled', false).focus();$(this).val(null);}">
    <option></option>
    <option value="customOption">[type a custom value]</option>
    <option>Chrome</option>
    <option>Firefox</option>
    <option>Internet Explorer</option>
    <option>Opera</option>
    <option>Safari</option></select><input name="browser" style="display:none;" disabled="disabled" onblur="if($(this).val()==''){$(this).hide().prop('disabled',true);$('select[name=browser]').show().prop('disabled', false).focus();}">
  <input type="submit" value="Submit">
</form>

Maybe a more readable version:

function toggle($toBeHidden, $toBeShown) {
  $toBeHidden.hide().prop('disabled', true);
  $toBeShown.show().prop('disabled', false).focus();
}

function showOptions(inputName) {
  var $select = $(`select[name=${inputName}]`);
  toggle($(`input[name=${inputName}]`), $select);
  $select.val(null);
}


function showCustomInput(inputName) {
  toggle($(`select[name=${inputName}]`), $(`input[name=${inputName}]`));
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form name="BrowserSurvey" action="#">
Browser: <select name="browser" onchange="if($(this).val()=='customOption')showCustomInput('browser')">
    <option></option>
    <option value="customOption">[type a custom value]</option>
    <option>Chrome</option>
    <option>Firefox</option>
    <option>Internet Explorer</option>
    <option>Opera</option>
    <option>Safari</option></select><input name="browser" style="display:none;" disabled="disabled" onblur="if($(this).val()=='')showOptions('browser')">
<input type="submit" value="Submit">
</form>
Mackey answered 9/8, 2022 at 9:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.