Select2 dropdown but allow new values by user?

Jquery Select2

Jquery Select2 Problem Overview


I want to have a dropdown with a set of values but also allow the user to "select" a new value not listed there.

I see that select2 supports this if you are using it in tags mode, but is there a way to do it without using tags?

Jquery Select2 Solutions


Solution 1 - Jquery Select2

The excellent answer provided by @fmpwizard works for Select2 3.5.2 and below, but it will not work in 4.0.0.

Since very early on (but perhaps not as early as this question), Select2 has supported "tagging": where users can add in their own value if you allow them to. This can be enabled through the tags option, and you can play around with an example in the documentation.

$("select").select2({
  tags: true
});

By default, this will create an option that has the same text as the search term that they have entered. You can modify the object that is used if you are looking to mark it in a special way, or create the object remotely once it is selected.

$("select").select2({
  tags: true,
  createTag: function (params) {
    return {
      id: params.term,
      text: params.term,
      newOption: true
    }
  }
});

In addition to serving as an easy to spot flag on the object passed in through the select2:select event, the extra property also allows you to render the option slightly differently in the result. So if you wanted to visually signal the fact that it is a new option by putting "(new)" next to it, you could do something like this.

$("select").select2({
  tags: true,
  createTag: function (params) {
    return {
      id: params.term,
      text: params.term,
      newOption: true
    }
  },
  templateResult: function (data) {
    var $result = $("<span></span>");

    $result.text(data.text);

    if (data.newOption) {
      $result.append(" <em>(new)</em>");
    }

    return $result;
  }
});

Solution 2 - Jquery Select2

For version 4+ check this answer below by Kevin Brown

In Select2 3.5.2 and below, you can use something like:

$(selector).select2({
  minimumInputLength:1,
  "ajax": {
    data:function (term, page) {
      return { term:term, page:page };
    },
    dataType:"json",
    quietMillis:100,
    results: function (data, page) {
      return {results: data.results};
    },
    "url": url
  },
  id: function(object) {
    return object.text;
  },
  //Allow manually entered text in drop down.
  createSearchChoice:function(term, data) {
    if ( $(data).filter( function() {
      return this.text.localeCompare(term)===0;
    }).length===0) {
      return {id:term, text:term};
    }
  },
});

(taken from an answer on the select2 mailing list, but cannot find the link now)

Solution 3 - Jquery Select2

Just for the sake of keep the code alive, I'm posting @rrauenza Fiddle's code from his comment.

HTML

<input type='hidden' id='tags' style='width:300px'/>

jQuery

$("#tags").select2({
	createSearchChoice:function(term, data) { 
		if ($(data).filter(function() { 
			return this.text.localeCompare(term)===0; 
		}).length===0) 
		{return {id:term, text:term};} 
	},
	multiple: false,
	data: [{id: 0, text: 'story'},{id: 1, text: 'bug'},{id: 2, text: 'task'}]
});

Solution 4 - Jquery Select2

Since many of these answers don't work in 4.0+, if you are using ajax, you could have the server add the new value as an option. So it would work like this:

  1. User searches for value (which makes ajax request to server)
  2. If value found great, return the option. If not just have the server append that option like this: [{"text":" my NEW option)","id":"0"}]
  3. When the form is submitted just check to see if that option is in the db and if not create it before saving.

Solution 5 - Jquery Select2

There is a better solution I think now

simply set tagging to true on the select options ?

tags: true

from https://select2.org/tagging

Solution 6 - Jquery Select2

Improvent on @fmpwizard answer:

//Allow manually entered text in drop down.
createSearchChoice:function(term, data) {
  if ( $(data).filter( function() {
    return term.localeCompare(this.text)===0; //even if the this.text is undefined it works
  }).length===0) {
    return {id:term, text:term};
  }
},

//solution to this error: Uncaught TypeError: Cannot read property 'localeCompare' of undefined

Solution 7 - Jquery Select2

Thanks for the help guys, I used the code below within Codeigniter I I am using version: 3.5.2 of select2.

var results = [];
var location_url = <?php echo json_encode(site_url('job/location')); ?>;
$('.location_select').select2({
   	ajax: {
        url: location_url,
        dataType: 'json',
        quietMillis: 100,
        data: function (term) {
            return {
                term: term
            };
        },
        results: function (data) {
        	results = [];
         	$.each(data, function(index, item){
            	results.push({
              		id: item.location_id,
              		text: item.location_name
            	});
          	});
          	return {
              	results: results
          	};
        }
    },
   	//Allow manually entered text in drop down.
	createSearchChoice:function(term, results) {
	  	if ($(results).filter( function() {
	    	return term.localeCompare(this.text)===0; 
	  	}).length===0) {
	    	return {id:term, text:term + ' [New]'};
	  	}
	},
});

Solution 8 - Jquery Select2

I just stumbled upon this from Kevin Brown. https://stackoverflow.com/a/30019966/112680

All you have to do for v4.0.6 is use tags: true parameter.

Solution 9 - Jquery Select2

var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;

In most cases we need to compare values with insensitive register. And this code will return false, which will lead to the creation of duplicate records in the database. Moreover String.prototype.localeCompare () is not supported by browser Safary and this code will not work in this browser;

return this.text.localeCompare(term)===0;

will better replace to

return this.text.toLowerCase() === term.toLowerCase();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionjohnjohnView Question on Stackoverflow
Solution 1 - Jquery Select2Kevin Brown-SilvaView Answer on Stackoverflow
Solution 2 - Jquery Select2fmpwizardView Answer on Stackoverflow
Solution 3 - Jquery Select2Michel AyresView Answer on Stackoverflow
Solution 4 - Jquery Select2EricView Answer on Stackoverflow
Solution 5 - Jquery Select2Steven MoffatView Answer on Stackoverflow
Solution 6 - Jquery Select2Vikash SinghView Answer on Stackoverflow
Solution 7 - Jquery Select2SomeoneView Answer on Stackoverflow
Solution 8 - Jquery Select2dbinottView Answer on Stackoverflow
Solution 9 - Jquery Select2outdeadView Answer on Stackoverflow