select2_box
Github

	function select2_box() {
		return _class('html')->select2_box('input_name', ['k1' => 'key1', 'k2' => 'key2']);
	}
	function select2_box($name, $values = [], $selected = '', $extra = []) {
		$css   = [];
		$style = [];
		if (is_array($name)) {
			$extra = (array)$extra + $name;
		} else {
			$extra['name'] = $name;
		}
		$extra['force_id'] = $extra['force_id'] ?: __FUNCTION__.'_'.++$this->_ids[__FUNCTION__];
		// put default js options here
		$js_options = (array)$extra['js_options'] + [
			'width'       => 'element',
			'placeholder' => @$extra['placeholder'] ?: @$extra['desc'],
		];
		// ajax
		$js_functions = [];
		if( @$extra[ 'ajax_func' ] ) {
			foreach( (array)$extra[ 'ajax_func' ] as $key => $value ) {
				$js_options[ 'ajax' ][ $key ] = '%__'. $key .'__%';
				$js_functions[ '"%__'. $key .'__%"' ] = $value;
			}
		}
		if( @$extra[ 'ajax' ] ) {
			$js_options += [
				'maximumSelectionSize' => 10,
				'minimumInputLength'   => 1,
				'minimumInputLength'   => 1,
				'initSelection'        => '%__initSelection__%',
			];
			$js_options[ 'ajax' ] = $extra[ 'ajax' ];
			$js_options[ 'ajax' ] += [
				// 'dataType'           => 'json',
				// 'quietMillis'        => 500,
				// 'cache'              => true,
				'data'               => '%__data__%',
				'results'            => '%__results__%',
			];
			$js_functions += [
				'"%__data__%"'    => 'function( term, page, context ) { return { q: term, page: page }; }',
				'"%__results__%"' => 'function( data, page, query ) { return { results: data.items, more: data.more || false  }; }',
				'"%__initSelection__%"' => 'function( element, callback ) {
					var $this = $(element);
					var id = $this.val();
					if( id !== "" ) {
						$.ajax("'. $js_options[ 'ajax' ][ 'url' ] .'" + "&q=" + id, {
							dataType: "json"
						}).done(function(data) { callback(data.items[0] || null); });
					}
				}',
			];
		}
		asset('jq-select2');
		// prepare js options
		$_js_options = json_encode( $js_options );
		$js_functions && $_js_options = str_replace( array_keys( $js_functions ), array_values( $js_functions ), $_js_options  );
		jquery('$("#'.addslashes($extra['force_id']).'").select2('. $_js_options .');');
		$func = $extra['multiple'] ? 'multi_select' : 'select_box';
		if( $extra[ 'ajax' ] ) {
			$func = 'input';
			$extra[ 'id' ] = $extra['force_id'];
			$extra[ 'value' ] = @$extra['selected'] ?: @$extra['value'] ?: '';
			$css[] = $this->CLASS_INPUT;
		}
		$css[]   = 'no-chosen';
			$extra[ 'class' ] && $css[] = $extra[ 'class' ];
		// $style[] = 'padding:0.3em';
			$extra[ 'style' ] && $style[] = $extra[ 'style' ];
		$extra[ 'class' ] = implode( ' ', $css   );
		$extra[ 'style' ] = implode( ';', $style );
		return $this->$func($extra, $values, $selected);
	}