Виберіть спадне меню Select2, але дозволите нові значення користувачеві?


125

Я хочу мати спадне меню з набором значень, але також дозволити користувачеві "вибрати" нове значення, яке там не вказано.

Я бачу, що select2 підтримує це, якщо ви його використовуєтеtags режимі, але чи є спосіб це зробити без використання тегів?


1
Select2 ніколи не працював для мене, принаймні createSearchChoice ніколи не працював для мене в 4.0.3, і я не хотів, щоб мої користувачі чекали завершення ajax, щоб повернути те саме ключове слово, тому мені довелося розгорнути власну бібліотеку, я лише поділившись цим, бо я думаю, що це може допомогти іншим, хто все ще плутається, як і я, будь ласка, не голосуйте, якщо ви не згодні з моєю відповіддю: github.com/razzbee/tagcomplete
razzbee

Відповіді:


100

Для версії 4+ перевірте цю відповідь нижче Кевін Браун

У Select2 3.5.2 і нижче ви можете використовувати щось на кшталт:

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

(взято з відповіді у списку розсилки select2, але зараз не можна знайти посилання)


4
Вибачте за пізню відповідь, але дуже дякую за ваше рішення! Інший плакат розмістив посилання на вашу суть btw, яка робить вас удвічі приголомшливішими! :)
johnjohn

rrauenza дивним, саме те, що я шукав
Matthias S

4
Додавання selectOnBlur: trueзробить роботу дивіться: stackoverflow.com/questions/25616520 / ...
Реза Фаттаха

1
Лише голова для майбутніх читачів, яку ви, мабуть, хочете використовувати tags: []разом із createSearchChoice.
Кевін Браун

5
Згадана вище скрипка здається зламаною.
Вольфр

175

Відмінний відповідь надається @fmpwizard робіт по вибор2 3.5.2 і нижче, але це не буде працювати в 4.0.0 .

З самого початку (але, можливо, ще не в цьому питанні), Select2 підтримує "тегування": користувачі можуть додавати власні значення, якщо ви дозволите їх. Це можна ввімкнути за допомогою tagsпараметра, і ви можете пограти з прикладом у документації .

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

За замовчуванням це створить параметр, який має той самий текст, що і введений ними пошуковий термін. Ви можете змінити об'єкт, який використовується, якщо ви хочете відзначити його спеціальним чином, або створити об’єкт віддалено, як тільки він буде обраний.

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

Окрім того, що слугує прапором, який легко помітити на об'єкті, переданому через select2:selectподію, додаткова властивість також дозволяє відображати опцію дещо по-іншому. Тож якби ви хотіли візуально сигналізувати про те, що це новий варіант, поставивши поруч " (новий) ", ви могли б зробити щось подібне.

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

Це було дуже корисно @ Markus1980Wien
abiieez

Я думаю, що я використовував цей фрагмент кілька разів.
Саху V Кумар

Якщо не працює подвійна перевірка, ви мали додати цю опцію на select2, а не додати в опції ajax. для select2 ajax
Zohaib

2
Його важкий у версії select2 (4.0.6) таким чином: $ ("select"). Select2 ({теги: true, createTag: function (params) {return {id: params.term, текст: params.term, newOption : true}}, templateResult: функція (data) {var result = data.text; if (data.newOption) {result = result + '(new)';} return return;}}); дякую @Kevin Brown
М. Салах

Це має бути найкращим відгуком. Я деякий час шукав це, і цей варіант відповідає на кожне запитання, яке я бачив у цій темі.
Джастін

14

Просто задля збереження коду в живих, я публікую код @rrauenza Fiddle з його коментаря .

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'}]
});

2
Я перейшов до загадки, але, здається, це не працює для мене в Chrome. Ви можете підтвердити?
IcedDante

@IcedDante код працює. Суть у загадці полягає лише в тому, щоб показати, як це потрібно робити (вибір схований у скрипці)
Мішель Ейрес

4
Коли я переходжу до скрипки, я ніде не бачу випаду select2. Не було б непогано мати приклад, який насправді ... щось робить?
IcedDante

Як я можу встановити дані із зовнішнього джерела? Я маю на увазі, що якщо я хочу завантажити міста вибраної країни, а сама вибрана країна - це дропдоун?
Алі Байг

12

Оскільки багато з цих відповідей не працюють у версії 4.0+, якщо ви використовуєте ajax, сервер міг би додати нове значення як опцію. Так би це працювало так:

  1. Користувач шукає значення (що робить запит ajax на сервер)
  2. Якщо значення знайдено великим, поверніть параметр. Якщо сервер не просто додав такий параметр, як це:[{"text":" my NEW option)","id":"0"}]
  3. Після надсилання форми просто перевірте, чи є ця опція в db, а чи не створити її перед збереженням.


4

Удосконалити відповідь на @fmpwizard:

//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

Я використав це з невеликою модифікацією, я виклав свою відповідь за секунду, але дякую.
Сем


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

У більшості випадків нам потрібно порівняти значення з нечутливим регістром. І цей код поверне помилковий, що призведе до створення дублікатів записів у базі даних. Більше того, String.prototype.localeCompare () не підтримується браузером Safary, і цей код не працюватиме в цьому браузері;

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

краще замінить на

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

1

Дякую за допомогу, хлопці, я використав код нижче в Codeigniter II, використовуючи версію: 3.5.2 від 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]'};
        }
    },
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.