在Select2 v3上选择值后隐藏虚拟键盘

时间:2018-08-23 03:04:00

标签: javascript jquery-select2-3

我仅将select2 v.3.4.5用于我的项目。目前,在移动设备上查看时,打开并选择了值后键盘没有关闭,我想将其关闭。我只想在用户关注并输入内容时打开它。

$(document).ready(function() {
  $('#Salutation,#Gender').select2()
    .on('change select-open', function(e) {
      setTimeout(function() {
        $('.select2-input').blur();
      }, 500);
    });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.min.js"></script>


<div class="container">
  <div class="row">
    <div class="col-xs-4 col-xs-offset-4">
      <h3>Application Form</h3>
      <form class="form" action="/action_page.php">
        <div class="form-group">
          <label for="GivenName">Given Name:</label>
          <input class="form-control" type="text" id="GivenName">
        </div>
        <div class="form-group">
          <label for="Surname">Surname:</label>
          <input class="form-control" type="text" id="Surname">
        </div>
        <div class="form-group">
          <label for="Salutation">Salutation:</label>
          <select class="" name="" id="Salutation">
            <option value="Mrs">Mrs</option>
            <option value="Mr">Mr</option>
            <option value="Miss">Miss</option>
          </select>
        </div>
        <div class="form-group">
          <label for="Gender">Gender:</label>
          <select class="" name="" id="Gender">
            <option value="Female">Female</option>
            <option value="Male">Male</option>
            <option value="Transgender">Transgender</option>
          </select>
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
    </div>
  </div>
</div>

此js

    $('#Salutation,#Gender').select2()
    .on('change select2-open',function(e){
        setTimeout(function(){
            $('.select2-input').blur();
        }, 500);
    });

我将输入搜索框设置为已经模糊,但键盘没有关闭。

我该如何存档此目的?请帮助。谢谢。

PS:可以理解,select2 v4修复了该错误,但是由于我的项目仅依赖于v3,所以我无法升级select2版本。*

2 个答案:

答案 0 :(得分:2)

确保搜索框不会自动对焦

在Select2中无法做到这一点-每当您尝试在此输入上调用blur()函数时,它只会重新调整其焦点。

但是,通过监听open事件,我们可以将搜索框替换为我们自己的搜索框,该框不会自动对焦。只有当前活动的搜索框具有类select2-focused,因此我们使用它来查找它,然后创建一个新的搜索框(具有相同的select2-input类,从而保留相同的外观),然后自己重​​新实现搜索功能,最后将其插入DOM中,并删除旧的搜索框。

关闭选择弹出窗口后不显示键盘

Select2似乎试图以一种非常怪异的方式实现自己的blur()事件(请参见here)。

因此,不要尝试使用它,而要利用CSS选择器。 CSS中的:focus选择器会选择所有具有焦点的内容。由于Select2实际上并未添加任何新的DOM元素(即,在HTML中一次添加,因此成为标准的<div>元素,<input>元素等),我们可以找到具有焦点的元素,并成功调用在上面模糊。

因此,通过调用$(":focus").blur(),我们找到当前具有焦点的DOM元素,然后对其进行模糊处理。

另外,通过使用select2-close作为事件,而不是change,即使用户没有选择项目,而是在其外部单击,键盘也不会打开。


我已经对其进行了测试,并且它在运行iOS 11的iPad上确实可以正常工作。这是最终的工作代码:

$(document).ready(function() {

	$("#Salutation,#Gender").select2().on("select2-open",()=>{
		let oldSearchBox = $(".select2-focused")[0]; //Get the current search box
		let parent = oldSearchBox.parentNode; //The parent of the search box (i.e. the element that holds it)

		let search = document.createElement("input"); //Create a new input box
		search.classList.add("select2-input"); //Make it look like the old one
		search.addEventListener("keyup", ()=>{ //Whenever someone releases a key, filter the results
			let results = parent.parentNode.getElementsByClassName("select2-result"); //Get all of the select box options
			let query = search.value.toLowerCase(); //Get what the user has typed (in lower case so search is case-insensitive)
			for (let result of results) { //Loop through all of the select box options
				let resultText = result.children[0].childNodes[1].nodeValue.toLowerCase(); //Get the text for that option (also in lower case)
				result.style.display =  (resultText.indexOf(query)==-1) ? "none" : "block"; //If the result text contains the search, it is displayed, otherwise it is hidden
			}
		})
		
		parent.appendChild(search); //Add the new search box to the page
		oldSearchBox.remove(); //Remove the old one
	});
  
  $("#Salutation,#Gender").select2().on("select2-close",()=>{
  	setTimeout(()=>{
			$(":focus").blur();
    }, 50);
  });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.4.5/select2.min.js"></script>


<div class="container">
  <div class="row">
    <div class="col-xs-4 col-xs-offset-4">
      <h3>Application Form</h3>
      <form class="form" action="/action_page.php">
        <div class="form-group">
          <label for="GivenName">Given Name:</label>
          <input class="form-control" type="text" id="GivenName">
        </div>
        <div class="form-group">
          <label for="Surname">Surname:</label>
          <input class="form-control" type="text" id="Surname">
        </div>
        <div class="form-group">
          <label for="Salutation">Salutation:</label>
          <select class="" name="" id="Salutation">
            <option value="Mrs">Mrs</option>
            <option value="Mr">Mr</option>
            <option value="Miss">Miss</option>
          </select>
        </div>
        <div class="form-group">
          <label for="Gender">Gender:</label>
          <select class="" name="" id="Gender">
            <option value="Female">Female</option>
            <option value="Male">Male</option>
            <option value="Transgender">Transgender</option>
          </select>
        </div>
        <button type="submit" class="btn btn-default">Submit</button>
      </form>
    </div>
  </div>
</div>

答案 1 :(得分:0)

我已经使用了大约一周的替代工作。到目前为止,它似乎在我尝试过的所有android和ios设备上都能正常运行。我在将'multiple'设置为false(即'single'类型)的select2实例上使用此方法。在这种情况下,我希望用户进行单个选择,并且键盘应该消失。

简而言之,在select2-close事件期间,您设置一个标志,指示您要禁用select2-focusser接收到的任何焦点事件。触发焦点事件时,您可以检查标志是否已设置,如果已设置,则只需将焦点移到另一个目标即可。我将标志添加为数据属性,并使用setTimeOut一秒钟后重置此标志。

之所以起作用,是因为select2 close处理程序分为两部分,并且在第1部分的末尾(第2部分之前)触发了“ select2-close”事件。第1部分是“抽象”关闭处理程序,该处理程序实际上关闭选择对话框,并设置控件的值。第2部分是“单个”关闭处理程序,它实际上只是导致select2重新专注于自身(这是问题所在!)。

对我来说,我向导航栏按钮之一添加了“ .focus-bait”类,并在执行焦点事件的焦点事件期间使用它来转移焦点。如果您在使重新调整步骤起作用时遇到问题,请尝试其他元素(在将其用于为专注于按钮而制作的按钮上,我遇到了问题。我仍然不确定为什么,但是我没有我的导航按钮解决方案可以很好地满足我的需求,因此请进行更多调查。

$('body').on('focus','.select2-focusser', function(e) { 
    let isDisabled = $(this).parent().first().data("disable-focus");
    if (isDisabled) {
        console.log('Focusser: focus event aborted');
       $('.focus-bait').focus();
    }   
});

//select2_focus_ctrl is a class that I add to any select2 container
//that I wish to use this focus logic e.g. add it to #Salutation,#Gender
$('body').on('select2-close','select2_focus_ctrl', function(e) {
    console.log('Focusser: disabling focus event');
    if ($(this).data('select2').opts.multiple != true) {
        $(this).prev().data("disable-focus",true);
        setTimeout(function() { 
            console.log('Focusser: enabling focusser');
            $(this).prev().data("disable-focus",false);
        }, 1000);               
    }
});

这是完整的代码段。在编写它时,我注意到,如果select2容器是从'select'元素获取的,则'multiple'属性不存在(我使用了'div'),因此我更改了一行代码:{{1} }(而不是.opts.multiple != true)。

== false
$(document).ready(function() {

$('#Salutation').select2(

);

    
$('body').on('focus','.select2-focusser', function(e) { 
    let isDisabled = $(this).parent().first().data("disable-focus");
    if (isDisabled) {
        console.log('Focusser: focus event aborted');
       $('.focus-bait').focus(); 
    }   
});

$('body').on('select2-close','.select2_focus_ctrl', function(e) {
    console.log('Focusser: disabling focus event');
    if ($(this).data('select2').opts.multiple != true) {
        $(this).prev().data("disable-focus",true);
        setTimeout(function() { 
            console.log('Focusser: enabling focusser');
            $(this).prev().data("disable-focus",false);
    	}, 1000);
    }
});


$('body').on('change','#Salutation', function(e) {
      let theVal = $('#Salutation').select2("val");
      $('#currentVal').val(theVal);
});
      
});
body {
  background: #dddddd;
  padding: 20px;
  font-family: Helvetica;
}

button {
  background: #0084ff;
  border: none;
  border-radius: 5px;
  padding: 8px 14px;
  font-size: 15px;
  color: #fff;
  cursor: pointer;
}

button:focus {
  background: #fff;
  color: red;
}