Select2, но разрешить новые значения пользователем?

Я хочу иметь выпадающий список с набором значений, но также позволять пользователю «выбирать» новое значение, не указанное в нем.

Я вижу, что select2 поддерживает это, если вы используете его в режиме tokens , но есть ли способ сделать это, не имея токенов?

101
Select2 никогда не работал для меня, по крайней мере createSearchChoice никогда не работал для меня в 4.0.3, и я не хотел, чтобы мои пользователи дождались завершения ajax, чтобы вернуть одно и то же ключевое слово, поэтому мне пришлось развернуть свою собственную библиотеку, я только потому что я думаю, что это может помочь другим, которые все еще запутались, как я, пожалуйста, не голосуйте, если вы не согласны с моим ответом: добавлено автор razzbee, источник

7 ответы

отличный ответ предоставлен @ fmpwizard работает для Select2 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 = $("");

    $result.text(data.text);

    if (data.newOption) {
      $result.append(" (new)");
    }

    return $result;
  }
});
131
добавлено
Это было очень полезно @ Markus1980Wien
добавлено автор abiieez, источник
Я думаю, что я использовал этот фрагмент несколько раз.
добавлено автор Vishal Kumar Sahu, источник
Если вы не используете двойную проверку, вы добавили эту опцию на select2, не добавляя параметры ajax. для select2 ajax
добавлено автор Zohaib Hassan, источник
Демо-скрипт для Select2 v. 4.0.3: jsfiddle.net/f303mh0f/2
добавлено автор Markus1980Wien, источник

Для версии 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, но не может найти ссылку сейчас)

90
добавлено
+1 удивительный, просто комментарий, новый элемент добавляется в список, только если я нажму «enter» ?! Возможно ли, что новое значение приняло, когда поле выбора потеряло фокус (только обычное поле ввода!)
добавлено автор Alireza Fattahi, источник
Добавление selectOnBlur: true выполнит задание, пожалуйста, смотрите: stackoverflow.com/questions/25616520/…
добавлено автор Alireza Fattahi, источник
Как отобразить новое значение, если нет в списке выбора? Если форма предварительно заполнена новым значением, метка пуста. Я все еще хочу отображать значение, даже если оно отсутствует в списке.
добавлено автор teleman, источник
@fmpwizard Почему предпочитаете метод jQuery filter() выше native Array.prototype.filter() ?
добавлено автор Koen, источник
@Koen Я не помню, если бы мне пришлось угадать, потому что я привык использовать jQuery
добавлено автор fmpwizard, источник
Извините за поздний ответ, но большое спасибо за ваше решение! Другой плакат опубликовал ссылку на ваш gist btw, который делает вас вдвойне удивительным! :)
добавлено автор johnjohn, источник
Просто голова для будущих читателей, вероятно, вы хотите использовать теги : [] вместе с createSearchChoice .
добавлено автор Kevin Brown, источник
rrauenza потрясающе, именно то, что я искал
добавлено автор Matthias S, источник
Я нашел рабочую скрипку: jsfiddle.net/pHSdP/2
добавлено автор rrauenza, источник
Не фильтруется ли data ? Почему не просто if (data.length === 0) ?
добавлено автор PahJoker, источник
Попробуйте что-то подобное с несколькими: true. Работает только для первой новой записи. Если он уже есть, он только позволит вам выбрать из списка.
добавлено автор Mark A. Tagliaferro, источник
Скрипка, связанная выше, кажется сломанной.
добавлено автор Himura, источник
Исправлена ​​скрипка: jsfiddle.net/wp2fn397
добавлено автор Mark van Duijker, источник

Просто для того, чтобы сохранить код в живых, я отправляю код @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'}]
});
14
добавлено
Когда я иду на скрипку, я нигде не вижу drop2. Было бы неплохо иметь пример, который на самом деле ... что-то делает?
добавлено автор IcedDante, источник
Я пошел на скрипку, но, похоже, это не работает для меня в Chrome. Можешь подтвердить?
добавлено автор IcedDante, источник
@IcedDante код работает. точка в скрипке - это просто показать, как это должно быть сделано (выбор скрыт в скрипке)
добавлено автор Michel Ayres, источник
Как я могу установить данные из внешнего источника? Я имею в виду, что, если я хочу загружать города выбранной страны, а выбранная страна - это dropodown?
добавлено автор Ali Baig, источник
скрипка не работает
добавлено автор Justin, источник

Поскольку многие из этих ответов не работают в 4.0+, если вы используете ajax, вы могли бы добавить в новое значение новое значение. Таким образом, это будет работать следующим образом:

  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.
10
добавлено

Улучшить ответ @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
3
добавлено
Я использовал это с небольшой модификацией. Я отвечу через секунду, но спасибо.
добавлено автор Sam, источник
var text = 'New York Mills';
var term = 'new york mills';
return text.localeCompare(term)===0;

В большинстве случаев нам нужно сравнивать значения с нечувствительным регистром. И этот код вернет false, что приведет к созданию дубликатов записей в базе данных. Кроме того, String.prototype.localeCompare() не поддерживается браузером Safary, и этот код не будет работать в этом браузере;

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

лучше заменить на

return this.text.toLowerCase() === term.toLowerCase();
1
добавлено

Спасибо за помощь, ребята, я использовал код ниже в Codeigniter. Я использую версию: 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]'};
        }
    },
});
0
добавлено
Верстка сайтов HTML/CSS/JS/PHP
Верстка сайтов HTML/CSS/JS/PHP
3 439 участник(ов)

Правила группы: напишите !rules в чате. Группа Вк: vk.com/web_structure Freelancer: @web_fl Веб Дизайн: @dev_design Маркетолог: @topmarkening Автор: @M_Boroda

CSS — русскоговорящее сообщество
CSS — русскоговорящее сообщество
1 502 участник(ов)

Сообщество любителей CSS Возникли проблемы с CSS? – пиши сюда, обсудим и предложим самое лучшее решение Работа: @css_ru_jobs Правила: https://teletype.in/@css_ru/r1EWtQ2w7 Приходите в наши чаты @javascript_ru и @frontend_ru Флуд: @css_flood

Чат — Типичный Верстальщик
Чат — Типичный Верстальщик
1 080 участник(ов)

Основной канал: @tpverstak Обратная связь: @annblok Все ссылки на соц.сети проекта: http://taplink.cc/tpverstak ПРАВИЛА ЧАТА — https://teletype.in/@annblok/BygPgC3E7

Веб-Технологи: UI/UX, Вёрстка, Фронтенд
Веб-Технологи: UI/UX, Вёрстка, Фронтенд
167 участник(ов)

Всё про веб-дизайн и вёрстку. А также: HTML, CSS, флекс и бутстрапы, шаблонизаторы, препроцессоры, методологии, аглифаеры, улучшаторы и обфускаторы. Обсуждаем темы юзабилити, устраиваем А/В тесты лендингов, и проводим аудит.

DTP :: @DTPublish
DTP :: @DTPublish
147 участник(ов)

Обсуждаемые темы: полиграфия, препресс, верстка, дизайн, иллюстрации, скрипты, плагины. Канал - @DTPublishing

css_jobs
css_jobs
26 участник(ов)

Чат для вопросов по css и html: @css_ru Флуд: @css_flood Канал с вакансиями и резюме: @css_jobs_feed

css_флуд
css_флуд
10 участник(ов)