Javascript-форум (https://javascript.ru/forum/)
-   jQuery (https://javascript.ru/forum/jquery/)
-   -   комбобокс для множественного выбора (https://javascript.ru/forum/jquery/44878-komboboks-dlya-mnozhestvennogo-vybora.html)

Sveta 05.02.2014 10:58

комбобокс для множественного выбора
 
Доброе утро) нужно сделать выпадающий список с автозаполнением, пытаюсь использовать комбобокс jquery, он работает: работает автозаполнение, можно выбрать любой пункт. Сложности именно с множественным выбором, выбрать из списка несколько значений я могу, но после выбора первого, на втором и третьем автозаполнение не работает!!! он почему-то продолжает искать автозаполнение по первому выбранному элементу...
function split(val){
		return val.split( /,\s*/ );
	}
	function extractLast(term){
		return split(term).pop();
	}	
	
		$.widget( "custom.combobox", {
			_create: function() {
				this.wrapper = $( "<span>" )
					.addClass( "custom-combobox" )
					.insertAfter( this.element );

				this.element.hide();
				this._createAutocomplete();
				this._createShowAllButton();
			},

			_createAutocomplete: function() {
				var selected = this.element.children( ":selected" ),
					value = selected.val() ? selected.text() : "";

				this.input = $( "<input>" )
					.appendTo( this.wrapper )
					.val( value )
					.attr( "title", "" )
					.addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
					.autocomplete({
						delay: 0,
						minLength: 0,
						source: $.proxy( this, "_source" ),
						
						  // focus select нужны для множественного выбора
						  focus: function(){
							// отменяем вставку значения на получение фокуса
							return false;
						  },
						  select: function(event, ui){
							var terms = split(this.value);
							// удаляем вводимую часть текста и помещаем вместо нее выбранный элемент
							terms.pop();
							
							var  mas_selected_value= ui.item.value.split("'"); //разбиваем выбранный элемент чтобы выделить только id станции
		
							terms.push(mas_selected_value[1]);
														// собираем все элементы в строку, разделяя их запятыми и вставляем 
							// строку обратно в текстовое поле
							terms.push("");
							this.value = terms.join(", ");
							//формируем данные для запроса
							getStId(this.value.substring(0, this.value.length - 2));
							return false;
						  }
					})
					.tooltip({
						tooltipClass: "ui-state-highlight"
					});

				this._on( this.input, {
					autocompleteselect: function( event, ui ) {
						ui.item.option.selected = true;
						this._trigger( "select", event, {
							item: ui.item.option
						});
					},

					autocompletechange: "_removeIfInvalid"
				});
				
			},

			_createShowAllButton: function() {
				var input = this.input,
					wasOpen = false;

				$( "<a>" )
					.attr( "tabIndex", -1 )
					.attr( "title", "Показать весь список" )
					.tooltip()
					.appendTo( this.wrapper )
					.button({
						icons: {
							primary: "ui-icon-triangle-1-s"
						},
						text: false
					})
					.removeClass( "ui-corner-all" )
					.addClass( "custom-combobox-toggle ui-corner-right" )
					.mousedown(function() {
						wasOpen = input.autocomplete( "widget" ).is( ":visible" );
					})
					.click(function() {
						input.focus();

						// Close if already visible
						if ( wasOpen ) {
							return;
						}

						// Pass empty string as value to search for, displaying all results
						input.autocomplete( "search", "" );
					});
			},

			_source: function( request, response ) {
				var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
				response( 
					$.ui.autocomplete.filter(
					this.element.children( "option" ).map(function() {
					var text = $( this ).text();
					if ( this.value && ( !request.term || matcher.test(text) ) )
						return {
							label: text,
							value: text,
							option: this
						};
				})
					
					, extractLast(request.term))
			
				
				);
			},
						
			_removeIfInvalid: function( event, ui ) {

				// Selected an item, nothing to do
				if ( ui.item ) {
					return;
				}

				// Search for a match (case-insensitive)
				var value = this.input.val(),
					valueLowerCase = value.toLowerCase(),
					valid = false;
				this.element.children( "option" ).each(function() {
					if ( $( this ).text().toLowerCase() === valueLowerCase ) {
						this.selected = valid = true;
						return false;
					}
				});

				// Found a match, nothing to do
				if ( valid ) {
					return;
				}

				// Remove invalid value
				this.input
					.val( "" )
					.attr( "title", value + " в списке нет таких элементов" )
					.tooltip( "open" );
				this.element.val( "" );
				this._delay(function() {
					this.input.tooltip( "close" ).attr( "title", "" );
				}, 2500 );
				this.input.data( "ui-autocomplete" ).term = "";
			},

			_destroy: function() {
				this.wrapper.remove();
				this.element.show();
			}
		});
	

	
		$( "#stList" ).combobox();

Вот никак не могу заставить работать...ведь по идее за это отвечает функция extractLast(request.term) подскажите пожалуйста!

рони 05.02.2014 11:24

Sveta,
Цитата:

после ввода трех букв в поле input-text
подсказывает любое последнее слово а не только первое

Sveta 05.02.2014 11:58

я прошла по ссылке - но там эта проблема не решена - начиная со второго элемента варианты не показывает....и пробел у меня ставить не нужно - он сам добавляется.... А стандартный виджет Автозаполнение работает со множественным выбором, я пробовала - он предлагает варианты после каждого выбора....

рони 05.02.2014 12:26

Цитата:

Сообщение от Sveta
я прошла по ссылке - но там эта проблема не решена

а можно узнать какая именно проблема не решена?

Sveta 05.02.2014 12:46

Не предлагает варианты автозаполнения после выбора первого варианта. У меня же список множественного выбора - нужно чтобы и на втором и третьем выборе предлагались варианты из списка.
Например список фруктов: я начинаю вводить "а" - выпадает список и предлагает мне апельсин и ананас, а выбираю апельсин, он вставляется в поле ввода, вставляется запятая и пробел, я ввожу снова букву "а" - а список уже не выпадает!! а нужно чтобы выпадал, обязательно....повторюсь, вроде бы функция extractLast(request.term) должна эту проблему решать...но почему-то не решает..может я ее используя как-то неверно....

рони 05.02.2014 12:59

Цитата:

Сообщение от Sveta
я начинаю вводить "а" - выпадает список и предлагает мне апельсин и ананас, а выбираю апельсин, он вставляется в поле ввода, вставляется запятая и пробел, я ввожу снова букву "а" - а список уже не выпадает!!

выпадает- вариант который я вам показал именно так и делает, разве что лезет с подсказками после третей буквы но всегда подскажет последнее введённое слово

Sveta 05.02.2014 14:19

а я просто посмотрела там последнее сообщение - что у человека не предлагает варианты...но может он ошибся) я не могу понять там в вашем коде - что именно позволяет предлагать варианты после выбора первого элемента? там же как-то надо заставить автозаполнение "не видеть" уже выбранный элемент в текстовом поле...

рони 05.02.2014 14:35

Цитата:

Сообщение от Sveta
я не могу понять там в вашем коде - что именно позволяет предлагать варианты после выбора первого элемента?

проверяем последнее введённое
val = this.value.toLowerCase()
                .split(' ')
                .pop();

если ввели 3 символ
сравниваем это значение с началом слов из базы
data.forEach(function (i) {
            var reg = new RegExp('^'+val, 'i');
            if (reg.test(i)) {

если слово или слова совпали выводим подсказку

Sveta 05.02.2014 15:05

логично))) Спасибо)) попробую в своем коде это как-то реализовать....весь вопрос в том как...у меня должна быть возможность просмотра всего имеющегося списка, это очень удобно реализовано в моем варианте...это в принципе от сюда взято:
http://jqueryui.com/resources/demos/.../combobox.html

рони 05.02.2014 15:39

Sveta,
может вы это искали http://jqueryui.com/autocomplete/#multiple

Sveta 06.02.2014 13:04

Нет, как раз нужно совместить autocomplete и multiple select! нужно чтобы была возможность просмотра всего выпадающего списка, возможность выбрать из списка, и при этом была возможность самостоятельного ввода с предлагаемыми вариантами...это и решает combobox, единственное- 3-ий день пытаюсь его заставить предлагать варианты на втором и т.д. выборе....не могу в поле ввода отделить уже выбранный вариант, от нового ввода....:cray:

рони 06.02.2014 13:38

Sveta,
11 пост - но я попрежнему в догадках, что вы хотите сделать и что не получается у вас ;)

Sveta 06.02.2014 14:02

я бы картинку показала, но тут загружать нельзя, только ссылкой...дело так обстоит. Есть выпадающий список (тег select а внутри optionds - стандартно все). Вот чисто как в этом примере:
http://jqueryui.com/resources/demos/.../combobox.html
Видите, здесь пользователь может выбрать что-то из списка, а может сам ввести. При вводе ему предлагаются варианты.
А мне нужно то же самое только с возможностью множественного выбора: чтобы пользователь мог сам выбрать несколько вариантов (это получилось сделать), и чтобы он сам мог ввести несколько вариантов (а вот здесь не получается - вводим что-то - нам предлагаются варианты, ставим запятую, вводим еще что-то - а варианты уже не предлагаются (от себя добавлю: не предлагаются потому что сравнивается все что введено в поле, а там введено и первое и начало второго - а таких вариантов в списке нет, а мне нужно чтобы скрипт автозаполнения то что введено до запятой не рассматривал уже...))

рони 06.02.2014 14:08

Sveta,
как происходит ввод множественного выбора -- выбрали 2 слова в селекте-подсказке -- далее что? является окончанием выбора?

рони 06.02.2014 14:11

Цитата:

Сообщение от Sveta
я бы картинку показала, но тут загружать нельзя

почему нельзя? и вот сервис если вам тут неудобно http://savepic.net/

Sveta 06.02.2014 14:29



вроде получилось) вот видите - когда первое вводим - список появляется, когда второе - уже не появляется...должна быть возможность выбора любого количества. Когда выбрали все что хотели, щелкаем куда-нибудь в другое место..
http://savepic.net/4552985.htm
http://savepic.net/4536601.htm

рони 06.02.2014 15:27

Sveta,
:write: так?
<!doctype html>
<html lang="en">
<head>
	<meta charset="utf-8">
	<title>jQuery UI Autocomplete - Combobox</title>
	<link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/sunny/jquery-ui.css">
	<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
	<script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
	<link rel="stylesheet" href="/resources/demos/style.css">
	<style>
	.custom-combobox {
		position: relative;
		display: inline-block;
	}
	.custom-combobox-toggle {
		position: absolute;
		top: 0;
		bottom: 0;
		margin-left: -1px;
		padding: 0;
		/* support: IE7 */
		*height: 1.7em;
		*top: 0.1em;
	}
	.custom-combobox-input {
		margin: 0;
		padding: 0.3em;
        width: 500px;
	}
	</style>
	<script>
	(function( $ ) {
      function split( val ) {
      return val.split( /,\s*/ );

    }

    function extractLast( term ) {

      return split( term ).pop();

    }

		$.widget( "custom.combobox", {
			_create: function() {
				this.wrapper = $( "<span>" )
					.addClass( "custom-combobox" )
					.insertAfter( this.element );

				this.element.hide();
				this._createAutocomplete();
				this._createShowAllButton();
			},

			_createAutocomplete: function() {
				var selected = this.element.children( ":selected" ),
					value = selected.val() ? selected.text() : "";

				this.input = $( "<input>" )
					.appendTo( this.wrapper )
					.val( value )
					.attr( "title", "" )
					.addClass( "custom-combobox-input ui-widget ui-widget-content ui-state-default ui-corner-left" )
					.autocomplete({
						delay: 0,
						minLength: 0,
						source: $.proxy( this, "_source" ),
                        select: function( event, ui ) {
          var terms = split( this.value );
          terms.pop();
          terms.push( ui.item.value );
          terms.push( "" );
          this.value = terms.join( ", " );
          return false;
        }
 					})
					.tooltip({
						tooltipClass: "ui-state-highlight"
					});

				this._on( this.input, {
					autocompleteselect: function( event, ui ) {
						ui.item.option.selected = true;
						this._trigger( "select", event, {
							item: ui.item.option
						});
					},

					autocompletechange: "_removeIfInvalid"
				});
			},

			_createShowAllButton: function() {
				var input = this.input,
					wasOpen = false;

				$( "<a>" )
					.attr( "tabIndex", -1 )
					.attr( "title", "Show All Items" )
					.tooltip()
					.appendTo( this.wrapper )
					.button({
						icons: {
							primary: "ui-icon-triangle-1-s"
						},
						text: false
					})
					.removeClass( "ui-corner-all" )
					.addClass( "custom-combobox-toggle ui-corner-right" )
					.mousedown(function() {
						wasOpen = input.autocomplete( "widget" ).is( ":visible" );
					})
					.click(function() {
						input.focus();

						// Close if already visible
						if ( wasOpen ) {
							return;
						}

						// Pass empty string as value to search for, displaying all results
					   	input.autocomplete( "search", "" );
					});
			},

			_source: function( request, response ) {
                                           				var matcher = new RegExp( $.ui.autocomplete.escapeRegex(extractLast( request.term )), "i" );
				response( this.element.children( "option" ).map(function() {
					var text = $( this ).text();
					if ( this.value && ( !request.term || matcher.test(text) ) )
						return {
							label: text,
							value: text,
							option: this
						};
				}) );
			},

			_removeIfInvalid: function( event, ui ) {

				// Selected an item, nothing to do
				if ( ui.item ) {
					return;
				}

				// Search for a match (case-insensitive)
				var value = this.input.val(),
					valueLowerCase = value.toLowerCase(),
					valid = false;
				this.element.children( "option" ).each(function() {
					if ( $( this ).text().toLowerCase() === valueLowerCase ) {
						this.selected = valid = true;
						return false;
					}
				});

				// Found a match, nothing to do
				if ( valid ) {
					return;
				}

				// Remove invalid value
				this.input
					.val( "" )
					.attr( "title", value + " didn't match any item" )
					.tooltip( "open" );
			     	this.element.val( "" );
				this._delay(function() {
					this.input.tooltip( "close" ).attr( "title", "" );
				}, 2500 );
				this.input.data( "ui-autocomplete" ).term = "";
			},

			_destroy: function() {
				this.wrapper.remove();
				this.element.show();
			}
		});
	})( jQuery );

	$(function() {
		$( "#combobox" ).combobox();
        	$( "#toggle" ).click(function() {
			$( "#combobox" ).toggle();
		});
	});
	</script>
</head>
<body>

<div class="ui-widget">
	<label>Your preferred programming language: </label><br>
	<select id="combobox" multiple="multiple">
		<option value="">Select one...</option>
		<option value="ActionScript">ActionScript</option>
		<option value="AppleScript">AppleScript</option>
		<option value="Asp">Asp</option>
		<option value="BASIC">BASIC</option>
		<option value="C">C</option>
		<option value="C++">C++</option>
		<option value="Clojure">Clojure</option>
		<option value="COBOL">COBOL</option>
		<option value="ColdFusion">ColdFusion</option>
		<option value="Erlang">Erlang</option>
		<option value="Fortran">Fortran</option>
		<option value="Groovy">Groovy</option>
		<option value="Haskell">Haskell</option>
		<option value="Java">Java</option>
		<option value="JavaScript">JavaScript</option>
		<option value="Lisp">Lisp</option>
		<option value="Perl">Perl</option>
		<option value="PHP">PHP</option>
		<option value="Python">Python</option>
		<option value="Ruby">Ruby</option>
		<option value="Scala">Scala</option>
		<option value="Scheme">Scheme</option>
	</select>
</div>
<button id="toggle">Show underlying select</button>
</body>
</html>

Sveta 06.02.2014 15:42

ДАА!!!! Рони!!! Вы меня спасли!!!! Спасибо огромное!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!:dance:

рони 06.02.2014 16:15

Sveta,:dance:


Часовой пояс GMT +3, время: 20:57.