Select2 desplegable pero permitir nuevos valores por usuario?


Quiero tener un menú desplegable con un conjunto de valores, pero también permitir al usuario "seleccionar" un nuevo valor que no aparece allí.

Veo que select2 admite esto si lo está utilizando en modo tokens, pero ¿hay una manera de hacerlo sin tener tokens?

Author: j0k, 2013-01-29

7 answers

Para la versión 4+ check esta respuesta a continuación por Kevin Brown

En Select2 3.5.2 y abajo, puedes usar algo como:

$(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};
    }
  },
});

(tomado de una respuesta en la lista de correo select2, pero no puede encontrar el enlace ahora)

 90
Author: fmpwizard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:26

La excelente respuesta proporcionada por @fmpwizard funciona para Select2 3.5.2 y posteriores, pero no funcionará en 4.0.0.

Desde muy temprano (pero quizás no tan temprano como esta pregunta), Select2 ha soportado el "etiquetado": donde los usuarios pueden agregar su propio valor si se lo permites. Esto se puede habilitar a través de la opción tags, y puede jugar con un ejemplo en la documentación.

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

Por defecto, esto creará una opción que tiene el mismo texto que el término de búsqueda que haya introducido. Puede modificar el objeto que se utiliza si desea marcarlo de una manera especial, o crear el objeto de forma remota una vez que esté seleccionado.

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

Además de servir como una bandera fácil de detectar en el objeto pasado a través del evento select2:select, la propiedad extra también le permite representar la opción ligeramente diferente en el resultado. Así que si usted quería señalar visualmente el hecho de que es una nueva opción poniendo " (nuevo)" junto a él, podrías hacer algo como esto.

$("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;
  }
});
 133
Author: Kevin Brown,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:47:22

Solo por mantener vivo el código, estoy publicando el código de@rrauenza Fiddle de su comentario.

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'}]
});
 14
Author: Michel Ayres,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:54:58

Dado que muchas de estas respuestas no funcionan en 4.0+, si está utilizando ajax, podría hacer que el servidor agregue el nuevo valor como una opción. Así que funcionaría así:

  1. El usuario busca valor (que hace una solicitud ajax al servidor)
  2. Si el valor se encuentra bien, devuelva la opción. Si no solo tiene el servidor anexar esa opción de esta manera: [{"text":" my NEW option)","id":"0"}]
  3. Cuando se envíe el formulario, simplemente verifique si esa opción está en la base de datos y si no la crea antes de guardarla.
 10
Author: Eric,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-07 00:08:50

Improvent on @ fmpwizard respuesta:

//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
 3
Author: Vikash Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-10 12:36:24
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;

En la mayoría de los casos necesitamos comparar valores con registro insensible. Y este código devolverá false, lo que conducirá a la creación de registros duplicados en la base de datos. Además Cuerda.prototipo.localeCompare () no es compatible con el navegador Safary y este código no funcionará en este navegador;

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

Reemplazará mejor a

return this.text.toLowerCase() === term.toLowerCase();
 1
Author: Paul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-02-10 09:53:34

Gracias por la ayuda chicos, he utilizado el siguiente código dentro de Codeigniter I Estoy usando la versión: 3.5.2 de 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]'};
        }
    },
});
 0
Author: Sam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-04 00:43:30