简体   繁体   English

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

[英]Hide virtual keyboard after selecting value on Select2 v3

I'm using select2 v.3.4.5 solely for my project.我仅将 select2 v.3.4.5 用于我的项目。 Currently, when viewing on mobile, the keyboard does not close after it open and value selected, I would like to close it thought.目前,在手机上查看时,打开并选择值后键盘不会关闭,我想关闭它。 I would like open only when user focus on it and type something.我只想在用户专注于它并输入内容时打开。

 $(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>

As this js作为这个js

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

I set input-search box to blur already but keyboard does not close.我已经将输入搜索框设置为模糊,但键盘没有关闭。

How can I do to archive this purpose?我该怎么做才能存档这个目的? Please kindly help.请帮助。 Thanks.谢谢。

PS: Understandably, select2 v4 fixed this bug, yet I could not upgrade my select2 version since my project is solely depend on v3.* PS:可以理解,select2 v4 修复了这个错误,但我无法升级我的 select2 版本,因为我的项目完全依赖 v3。*

Ensuring the search box does not autofocus确保搜索框不会自动对焦

There is no way to do this well in Select2 - whenever you try to call the blur() function on this input, it just refocuses it.在 Select2 中没有办法做到这一点 - 每当您尝试在此输入上调用blur()函数时,它只会重新聚焦它。

However, by listening on the open event, we can replace the search box with our own one, that does not autofocus.但是,通过监听open事件,我们可以用我们自己的搜索框替换搜索框,它不会自动对焦。 Only the currently active search box has the class select2-focused , so we use that to find it, and then create a new search box (with the same select2-input class so it retains the same look and feel), and then re-implement the search feature ourselves, finally inserting that into the DOM, and removing the old search box.只有当前活动的搜索框有select2-focused类,所以我们使用它来查找它,然后创建一个新的搜索框(使用相同的select2-input类,因此它保留相同的外观),然后重新 -自己实现搜索功能,最后将其插入到 DOM 中,并删除旧的搜索框。

Not showing the keyboard after closing the selection popup关闭选择弹出窗口后不显示键盘

Select2 seems to try and implement its own blur() event in a very weird way (see here ). Select2 似乎尝试以一种非常奇怪的方式实现它自己的blur()事件(参见此处)。

So, rather than try and use that, take advantage of CSS selectors.因此,与其尝试使用它,不如利用 CSS 选择器。 The :focus selector in CSS selects anything that has focus. CSS 中的:focus选择器选择任何有焦点的东西。 Since Select2 doesn't actually add any new DOM elements (ie once in the HTML, it becomes standard <div> elements, <input> elements, etc), we can find the one that has focus, and successfully call blur on it.由于 Select2 实际上并没有添加任何新的 DOM 元素(即一旦在 HTML 中,它就会变成标准的<div>元素、 <input>元素等),我们可以找到具有焦点的那个,并成功地对其调用模糊。

Therefore, by calling $(":focus").blur() , we find the DOM element that currently has focus, and we blur it.因此,通过调用$(":focus").blur() ,我们找到当前具有焦点的 DOM 元素,并对其进行模糊处理。

Also, by using select2-close as our event, rather than change , the keyboard won't open even if the user doesn't select an item, but instead clicks outside of it.此外,通过使用select2-close作为我们的事件,而不是change ,即使用户没有选择一个项目,键盘也不会打开,而是在它外面点击。


I have tested it, and it does work for me on an iPad running iOS 11. Here is the final, working code:我已经对其进行了测试,它在运行 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 (ie 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>

I have an alternative work around that I've been using for about a week now.我有一个替代的工作,我已经使用了大约一个星期了。 So far it seems to work well on all android and ios devices I've tried.到目前为止,它似乎在我尝试过的所有 android 和 ios 设备上都运行良好。 I use this on select2 instances that have 'multiple' set to false (ie 'single' type).我在'multiple'设置为false(即'single'类型)的select2实例上使用它。 In this case, I want the user to make a single selection, and the the keyboard should disappear.在这种情况下,我希望用户进行单个选择,并且键盘应该消失。

In short, during the select2-close event you set a flag that indicates that you want to disable any focus event the select2-focusser receives.简而言之,在 select2-close 事件期间,您设置了一个标志,指示您要禁用 select2-focusser 接收的任何焦点事件。 When the focus event is triggered, you check if the flag is set and if so you simply move the focus to another target.当焦点事件被触发时,你检查标志是否被设置,如果是,你只需将焦点移动到另一个目标。 I add the flag as a data property and I reset this flag after a second using a setTimeOut.我将该标志添加为数据属性,并在使用 setTimeOut 一秒后重置该标志。

This works because the select2 close handler is split into 2 parts, and the 'select2-close' event is triggered at the end of part 1 (and before part 2).这是有效的,因为 select2 关闭处理程序被分成 2 部分,并且 'select2-close' 事件在第 1 部分结束时(在第 2 部分之前)被触发。 Part 1 is the 'abstract' close handler, which actually closes the selection dialog, and sets the control's value.第 1 部分是“抽象”关闭处理程序,它实际上关闭选择对话框,并设置控件的值。 Part 2 is the 'single' close handler, which really just causes the select2 to refocus on itself (which is the problem!).第 2 部分是“单个”关闭处理程序,它实际上只是导致 select2 重新聚焦于自身(这就是问题所在!)。

For me, I added a '.focus-bait' class to one of my nav bar buttons, and I use this to divert focus during the focusser's focus event execution.对我来说,我在我的导航栏按钮之一中添加了一个“.focus-bait”类,我用它来在聚焦器的焦点事件执行期间转移焦点。 If you have issues getting this refocus step to work, try a different element (I had a problem getting it to work on a button I had made for the purpose of focusing on. I'm still not sure why, but I didn't investigate more as my nav button solution worked perfectly for my needs).如果您在使此重新聚焦步骤起作用时遇到问题,请尝试不同的元素(我遇到了问题,使其在我为聚焦而制作的按钮上起作用。我仍然不确定为什么,但我没有进行更多调查,因为我的导航按钮解决方案非常适合我的需求)。

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

Here is a full code snippet.这是一个完整的代码片段。 While writing it I noticed that if the select2 container is sourced from a 'select' element, the 'multiple' property does not exist (mine used a 'div'), so I've changed one line of code: .opts.multiple != true (instead of == false ).在编写它时,我注意到如果 select2 容器来自“select”元素,则“multiple”属性不存在(我使用的是“div”),因此我更改了一行代码: .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; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/3.5.4/select2.js"></script> <button type="button" class="focus-bait"> Just the bait! </button> <br> <div> <input id="currentVal" style="height:20px;width:150px"/> </div> <br><br> <select class="select2_focus_ctrl" id="Salutation" style="width:200px;"> <option value="Mrs">Mrs</option> <option value="Mr">Mr</option> <option value="Miss">Miss</option> <option value="Esquire">Esquire</option> <option value="Other Options">Other Options</option> <option value="Just for interest">Interesting longer item</option> </select>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM