Click button trigger input to appear with focus











up vote
2
down vote

favorite












I have a hidden search bar that is made visible when you click on a button. When the search bar appears I would like the input to already have focus, so the user can immediately start typing.



I'm using $('#search-input').focus(); to try and achieve this on click but it isn't working.



Here is a JSFiddle. Click on the red box to trigger the search bar.



My Code:






$('#search-btn').on('click', function() {
$(this).toggleClass('active');
$('#search-input').focus();
$('#search-wrapper').toggleClass('visible');

if ($('#region-wrapper').hasClass('visible')) {
$('#region-wrapper').toggleClass('visible');
}

if ($('#region-select').hasClass('active')) {
$('#region-select').toggleClass('active');
}
});

#menu-side {
width: 200px;
float: right;
position: static;
z-index: 10;
margin-right: 15px;
margin-top: 15px;
}

#search-btn {
background: red;
border: none;
font-size: 1.8rem;
cursor: pointer;
outline: 0;
position: relative;
display: block;
width: 40px;
height: 40px;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper {
width: 100%;
position: absolute;
top: 90px;
left: 0;
right: 0;
opacity: 0;
visibility: hidden;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper.visible {
opacity: 1;
visibility: visible !important;
}

#search-inner {
background: #e5e5e5;
padding: 35px 80px;
}

#search-input {
border: none;
background: none;
font-size: 1.8rem;
line-height: 1.8rem;
color: black;
float: left;
width: 90%;
}

#search-submit {
background: none;
border: none;
float: right;
width: 10%;
font-size: 1.8rem;
outline: 0;
transition-duration: 0.3s;
transition-property: all;
cursor: pointer;
max-width: 21px;
margin: 0;
padding: 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
<button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

<div id="search-wrapper">
<div class="container">
<div id="search-inner" class="o-bdr-top">
<form role="search" method="get" id="search-form" class="clearfix" action="">
<button id="search-submit"><i class="fas fa-search float-right"></i></button>
<input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
</form>
</div>
</div>
</div>
</div>












share|improve this question




















  • 1




    Is it necesary to #search-wrapper be hidden? If i remove this property - all seems work fine.
    – Smollet777
    Nov 8 at 11:05








  • 1




    @Smollet777 You catched the point, I removed also my answers (setTimeout based) because that's a dirty fix and nor resolve the problem root nor address to good programming patterns.
    – Mosè Raguzzini
    Nov 8 at 11:19















up vote
2
down vote

favorite












I have a hidden search bar that is made visible when you click on a button. When the search bar appears I would like the input to already have focus, so the user can immediately start typing.



I'm using $('#search-input').focus(); to try and achieve this on click but it isn't working.



Here is a JSFiddle. Click on the red box to trigger the search bar.



My Code:






$('#search-btn').on('click', function() {
$(this).toggleClass('active');
$('#search-input').focus();
$('#search-wrapper').toggleClass('visible');

if ($('#region-wrapper').hasClass('visible')) {
$('#region-wrapper').toggleClass('visible');
}

if ($('#region-select').hasClass('active')) {
$('#region-select').toggleClass('active');
}
});

#menu-side {
width: 200px;
float: right;
position: static;
z-index: 10;
margin-right: 15px;
margin-top: 15px;
}

#search-btn {
background: red;
border: none;
font-size: 1.8rem;
cursor: pointer;
outline: 0;
position: relative;
display: block;
width: 40px;
height: 40px;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper {
width: 100%;
position: absolute;
top: 90px;
left: 0;
right: 0;
opacity: 0;
visibility: hidden;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper.visible {
opacity: 1;
visibility: visible !important;
}

#search-inner {
background: #e5e5e5;
padding: 35px 80px;
}

#search-input {
border: none;
background: none;
font-size: 1.8rem;
line-height: 1.8rem;
color: black;
float: left;
width: 90%;
}

#search-submit {
background: none;
border: none;
float: right;
width: 10%;
font-size: 1.8rem;
outline: 0;
transition-duration: 0.3s;
transition-property: all;
cursor: pointer;
max-width: 21px;
margin: 0;
padding: 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
<button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

<div id="search-wrapper">
<div class="container">
<div id="search-inner" class="o-bdr-top">
<form role="search" method="get" id="search-form" class="clearfix" action="">
<button id="search-submit"><i class="fas fa-search float-right"></i></button>
<input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
</form>
</div>
</div>
</div>
</div>












share|improve this question




















  • 1




    Is it necesary to #search-wrapper be hidden? If i remove this property - all seems work fine.
    – Smollet777
    Nov 8 at 11:05








  • 1




    @Smollet777 You catched the point, I removed also my answers (setTimeout based) because that's a dirty fix and nor resolve the problem root nor address to good programming patterns.
    – Mosè Raguzzini
    Nov 8 at 11:19













up vote
2
down vote

favorite









up vote
2
down vote

favorite











I have a hidden search bar that is made visible when you click on a button. When the search bar appears I would like the input to already have focus, so the user can immediately start typing.



I'm using $('#search-input').focus(); to try and achieve this on click but it isn't working.



Here is a JSFiddle. Click on the red box to trigger the search bar.



My Code:






$('#search-btn').on('click', function() {
$(this).toggleClass('active');
$('#search-input').focus();
$('#search-wrapper').toggleClass('visible');

if ($('#region-wrapper').hasClass('visible')) {
$('#region-wrapper').toggleClass('visible');
}

if ($('#region-select').hasClass('active')) {
$('#region-select').toggleClass('active');
}
});

#menu-side {
width: 200px;
float: right;
position: static;
z-index: 10;
margin-right: 15px;
margin-top: 15px;
}

#search-btn {
background: red;
border: none;
font-size: 1.8rem;
cursor: pointer;
outline: 0;
position: relative;
display: block;
width: 40px;
height: 40px;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper {
width: 100%;
position: absolute;
top: 90px;
left: 0;
right: 0;
opacity: 0;
visibility: hidden;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper.visible {
opacity: 1;
visibility: visible !important;
}

#search-inner {
background: #e5e5e5;
padding: 35px 80px;
}

#search-input {
border: none;
background: none;
font-size: 1.8rem;
line-height: 1.8rem;
color: black;
float: left;
width: 90%;
}

#search-submit {
background: none;
border: none;
float: right;
width: 10%;
font-size: 1.8rem;
outline: 0;
transition-duration: 0.3s;
transition-property: all;
cursor: pointer;
max-width: 21px;
margin: 0;
padding: 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
<button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

<div id="search-wrapper">
<div class="container">
<div id="search-inner" class="o-bdr-top">
<form role="search" method="get" id="search-form" class="clearfix" action="">
<button id="search-submit"><i class="fas fa-search float-right"></i></button>
<input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
</form>
</div>
</div>
</div>
</div>












share|improve this question















I have a hidden search bar that is made visible when you click on a button. When the search bar appears I would like the input to already have focus, so the user can immediately start typing.



I'm using $('#search-input').focus(); to try and achieve this on click but it isn't working.



Here is a JSFiddle. Click on the red box to trigger the search bar.



My Code:






$('#search-btn').on('click', function() {
$(this).toggleClass('active');
$('#search-input').focus();
$('#search-wrapper').toggleClass('visible');

if ($('#region-wrapper').hasClass('visible')) {
$('#region-wrapper').toggleClass('visible');
}

if ($('#region-select').hasClass('active')) {
$('#region-select').toggleClass('active');
}
});

#menu-side {
width: 200px;
float: right;
position: static;
z-index: 10;
margin-right: 15px;
margin-top: 15px;
}

#search-btn {
background: red;
border: none;
font-size: 1.8rem;
cursor: pointer;
outline: 0;
position: relative;
display: block;
width: 40px;
height: 40px;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper {
width: 100%;
position: absolute;
top: 90px;
left: 0;
right: 0;
opacity: 0;
visibility: hidden;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper.visible {
opacity: 1;
visibility: visible !important;
}

#search-inner {
background: #e5e5e5;
padding: 35px 80px;
}

#search-input {
border: none;
background: none;
font-size: 1.8rem;
line-height: 1.8rem;
color: black;
float: left;
width: 90%;
}

#search-submit {
background: none;
border: none;
float: right;
width: 10%;
font-size: 1.8rem;
outline: 0;
transition-duration: 0.3s;
transition-property: all;
cursor: pointer;
max-width: 21px;
margin: 0;
padding: 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
<button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

<div id="search-wrapper">
<div class="container">
<div id="search-inner" class="o-bdr-top">
<form role="search" method="get" id="search-form" class="clearfix" action="">
<button id="search-submit"><i class="fas fa-search float-right"></i></button>
<input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
</form>
</div>
</div>
</div>
</div>








$('#search-btn').on('click', function() {
$(this).toggleClass('active');
$('#search-input').focus();
$('#search-wrapper').toggleClass('visible');

if ($('#region-wrapper').hasClass('visible')) {
$('#region-wrapper').toggleClass('visible');
}

if ($('#region-select').hasClass('active')) {
$('#region-select').toggleClass('active');
}
});

#menu-side {
width: 200px;
float: right;
position: static;
z-index: 10;
margin-right: 15px;
margin-top: 15px;
}

#search-btn {
background: red;
border: none;
font-size: 1.8rem;
cursor: pointer;
outline: 0;
position: relative;
display: block;
width: 40px;
height: 40px;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper {
width: 100%;
position: absolute;
top: 90px;
left: 0;
right: 0;
opacity: 0;
visibility: hidden;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper.visible {
opacity: 1;
visibility: visible !important;
}

#search-inner {
background: #e5e5e5;
padding: 35px 80px;
}

#search-input {
border: none;
background: none;
font-size: 1.8rem;
line-height: 1.8rem;
color: black;
float: left;
width: 90%;
}

#search-submit {
background: none;
border: none;
float: right;
width: 10%;
font-size: 1.8rem;
outline: 0;
transition-duration: 0.3s;
transition-property: all;
cursor: pointer;
max-width: 21px;
margin: 0;
padding: 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
<button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

<div id="search-wrapper">
<div class="container">
<div id="search-inner" class="o-bdr-top">
<form role="search" method="get" id="search-form" class="clearfix" action="">
<button id="search-submit"><i class="fas fa-search float-right"></i></button>
<input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
</form>
</div>
</div>
</div>
</div>





$('#search-btn').on('click', function() {
$(this).toggleClass('active');
$('#search-input').focus();
$('#search-wrapper').toggleClass('visible');

if ($('#region-wrapper').hasClass('visible')) {
$('#region-wrapper').toggleClass('visible');
}

if ($('#region-select').hasClass('active')) {
$('#region-select').toggleClass('active');
}
});

#menu-side {
width: 200px;
float: right;
position: static;
z-index: 10;
margin-right: 15px;
margin-top: 15px;
}

#search-btn {
background: red;
border: none;
font-size: 1.8rem;
cursor: pointer;
outline: 0;
position: relative;
display: block;
width: 40px;
height: 40px;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper {
width: 100%;
position: absolute;
top: 90px;
left: 0;
right: 0;
opacity: 0;
visibility: hidden;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper.visible {
opacity: 1;
visibility: visible !important;
}

#search-inner {
background: #e5e5e5;
padding: 35px 80px;
}

#search-input {
border: none;
background: none;
font-size: 1.8rem;
line-height: 1.8rem;
color: black;
float: left;
width: 90%;
}

#search-submit {
background: none;
border: none;
float: right;
width: 10%;
font-size: 1.8rem;
outline: 0;
transition-duration: 0.3s;
transition-property: all;
cursor: pointer;
max-width: 21px;
margin: 0;
padding: 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
<button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

<div id="search-wrapper">
<div class="container">
<div id="search-inner" class="o-bdr-top">
<form role="search" method="get" id="search-form" class="clearfix" action="">
<button id="search-submit"><i class="fas fa-search float-right"></i></button>
<input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
</form>
</div>
</div>
</div>
</div>






javascript jquery html






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 8 at 11:06









Zakaria Acharki

54.3k134266




54.3k134266










asked Nov 8 at 10:58









probablybest

68711132




68711132








  • 1




    Is it necesary to #search-wrapper be hidden? If i remove this property - all seems work fine.
    – Smollet777
    Nov 8 at 11:05








  • 1




    @Smollet777 You catched the point, I removed also my answers (setTimeout based) because that's a dirty fix and nor resolve the problem root nor address to good programming patterns.
    – Mosè Raguzzini
    Nov 8 at 11:19














  • 1




    Is it necesary to #search-wrapper be hidden? If i remove this property - all seems work fine.
    – Smollet777
    Nov 8 at 11:05








  • 1




    @Smollet777 You catched the point, I removed also my answers (setTimeout based) because that's a dirty fix and nor resolve the problem root nor address to good programming patterns.
    – Mosè Raguzzini
    Nov 8 at 11:19








1




1




Is it necesary to #search-wrapper be hidden? If i remove this property - all seems work fine.
– Smollet777
Nov 8 at 11:05






Is it necesary to #search-wrapper be hidden? If i remove this property - all seems work fine.
– Smollet777
Nov 8 at 11:05






1




1




@Smollet777 You catched the point, I removed also my answers (setTimeout based) because that's a dirty fix and nor resolve the problem root nor address to good programming patterns.
– Mosè Raguzzini
Nov 8 at 11:19




@Smollet777 You catched the point, I removed also my answers (setTimeout based) because that's a dirty fix and nor resolve the problem root nor address to good programming patterns.
– Mosè Raguzzini
Nov 8 at 11:19












3 Answers
3






active

oldest

votes

















up vote
1
down vote













The problem resides on input being hidden initially and browsers prevent operation such as focus on hidden elements.
Common pratice, instead of using display: none, is to take the component off screen (IE: Fixed position with negative left and opacity === 0 or visibility hidden).



Using setTimeout (which in this case in undeterministic) is a bad pratice and should be avoided.






share|improve this answer





















  • Why did you think setTimeout() is a bad practice for this case? instead of using display: none where you see this role?
    – Zakaria Acharki
    Nov 8 at 11:20








  • 1




    @ZakariaAcharki simply because we cannot be sure of client’s internet speed / computing power. The delay may not be enough.
    – Smollet777
    Nov 8 at 11:28








  • 1




    Your solution based on the change of display: none to opacity or visibility is hidden when the author already using opacity: 0;visibility: hidden; !!! could you give us a working fiddle instead?
    – Zakaria Acharki
    Nov 8 at 11:32












  • Sorry my fault, also visibility prevent focus, so the offscreen hack work without change of visibility.
    – Antonio Buelli
    Nov 8 at 11:53






  • 2




    @ZakariaAcharki toggleClass does not take always the same time. In fact jquery provides promises to work with when dealing with those methods. Also setTimeout does not guarantee the real time execution delay
    – Antonio Buelli
    Nov 8 at 11:56


















up vote
1
down vote














(From the official documentation) Take care to only use .focus() on elements that are visible.




You need just to wait for the toggle fired by toggleClass() to end so the #search-input input will be visible then you could perform the focus to the input.



Since toggleClass() method has no complete callback you could use setTimeout() for this like:



setTimeout(function() {
$('#search-input').focus();
}, 100);





$('#search-input').focus();

$('#search-btn').on('click', function() {
$(this).toggleClass('active');
$('#search-wrapper').toggleClass('visible');

if ($('#region-wrapper').hasClass('visible')) {
$('#region-wrapper').toggleClass('visible');
}

if ($('#region-select').hasClass('active')) {
$('#region-select').toggleClass('active');
}
setTimeout(function() {
$('#search-input').focus();
}, 100);
});

#menu-side {
width: 200px;
float: right;
position: static;
z-index: 10;
margin-right: 15px;
margin-top: 15px;
}

#search-btn {
background: red;
border: none;
font-size: 1.8rem;
cursor: pointer;
outline: 0;
position: relative;
display: block;
width: 40px;
height: 40px;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper {
width: 100%;
position: absolute;
top: 90px;
left: 0;
right: 0;
opacity: 0;
visibility: hidden;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper.visible {
opacity: 1;
visibility: visible !important;
}

#search-inner {
background: #e5e5e5;
padding: 35px 80px;
}

#search-input {
border: none;
background: none;
font-size: 1.8rem;
line-height: 1.8rem;
color: black;
float: left;
width: 90%;
}

#search-submit {
background: none;
border: none;
float: right;
width: 10%;
font-size: 1.8rem;
outline: 0;
transition-duration: 0.3s;
transition-property: all;
cursor: pointer;
max-width: 21px;
margin: 0;
padding: 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
<button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

<div id="search-wrapper">
<div class="container">
<div id="search-inner" class="o-bdr-top">
<form role="search" method="get" id="search-form" class="clearfix" action="">
<button id="search-submit"><i class="fas fa-search float-right"></i></button>
<input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
</form>
</div>
</div>
</div>
</div>








share|improve this answer



















  • 1




    as in another comment below another answer both toggleClass and setTimeout haven't real timing you can rely on. Working with off screen elements or jquery promises ($("#myId").toggleClass('fadeOut',600).promise().done(...mymethod) is so much cleaner and solid
    – Mosè Raguzzini
    Nov 8 at 12:00










  • @MosèRaguzzini thanks for your intervention, .promise() require jQuery-UI I don't want to suggest it here, you could post a working answer that will be cool.
    – Zakaria Acharki
    Nov 8 at 12:07


















up vote
-1
down vote













I suggest the use of display instead of visibility/opacity and toggling the classes, you could use simply display: none by default then toggle the display using the jQuery toggle() method then the focus will work:






$('#search-input').focus();

$('#search-btn').on('click', function() {
$(this).toggleClass('active');
$('#search-wrapper').toggle();
$('#search-input').focus();

if ($('#region-wrapper').hasClass('visible')) {
$('#region-wrapper').toggleClass('visible');
}

if ($('#region-select').hasClass('active')) {
$('#region-select').toggleClass('active');
}
$('#search-input').toggleClass('active').focus();
});

#menu-side {
width: 200px;
float: right;
position: static;
z-index: 10;
margin-right: 15px;
margin-top: 15px;
}

#search-btn {
background: red;
border: none;
font-size: 1.8rem;
cursor: pointer;
outline: 0;
position: relative;
display: block;
width: 40px;
height: 40px;
transition-duration: 0.3s;
transition-property: all;
}

#search-wrapper {
width: 100%;
position: absolute;
top: 90px;
left: 0;
right: 0;
display: none;
transition-duration: 0.3s;
transition-property: all;
}

#search-inner {
background: #e5e5e5;
padding: 35px 80px;
}

#search-input {
border: none;
background: none;
font-size: 1.8rem;
line-height: 1.8rem;
color: black;
float: left;
width: 90%;
}

#search-submit {
background: none;
border: none;
float: right;
width: 10%;
font-size: 1.8rem;
outline: 0;
transition-duration: 0.3s;
transition-property: all;
cursor: pointer;
max-width: 21px;
margin: 0;
padding: 0;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="menu-side" class="clearfix">
<button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

<div id="search-wrapper">
<div class="container">
<div id="search-inner" class="o-bdr-top">
<form role="search" method="get" id="search-form" class="clearfix" action="">
<button id="search-submit"><i class="fas fa-search float-right"></i></button>
<input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
</form>
</div>
</div>
</div>
</div>








share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














     

    draft saved


    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53206346%2fclick-button-trigger-input-to-appear-with-focus%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote













    The problem resides on input being hidden initially and browsers prevent operation such as focus on hidden elements.
    Common pratice, instead of using display: none, is to take the component off screen (IE: Fixed position with negative left and opacity === 0 or visibility hidden).



    Using setTimeout (which in this case in undeterministic) is a bad pratice and should be avoided.






    share|improve this answer





















    • Why did you think setTimeout() is a bad practice for this case? instead of using display: none where you see this role?
      – Zakaria Acharki
      Nov 8 at 11:20








    • 1




      @ZakariaAcharki simply because we cannot be sure of client’s internet speed / computing power. The delay may not be enough.
      – Smollet777
      Nov 8 at 11:28








    • 1




      Your solution based on the change of display: none to opacity or visibility is hidden when the author already using opacity: 0;visibility: hidden; !!! could you give us a working fiddle instead?
      – Zakaria Acharki
      Nov 8 at 11:32












    • Sorry my fault, also visibility prevent focus, so the offscreen hack work without change of visibility.
      – Antonio Buelli
      Nov 8 at 11:53






    • 2




      @ZakariaAcharki toggleClass does not take always the same time. In fact jquery provides promises to work with when dealing with those methods. Also setTimeout does not guarantee the real time execution delay
      – Antonio Buelli
      Nov 8 at 11:56















    up vote
    1
    down vote













    The problem resides on input being hidden initially and browsers prevent operation such as focus on hidden elements.
    Common pratice, instead of using display: none, is to take the component off screen (IE: Fixed position with negative left and opacity === 0 or visibility hidden).



    Using setTimeout (which in this case in undeterministic) is a bad pratice and should be avoided.






    share|improve this answer





















    • Why did you think setTimeout() is a bad practice for this case? instead of using display: none where you see this role?
      – Zakaria Acharki
      Nov 8 at 11:20








    • 1




      @ZakariaAcharki simply because we cannot be sure of client’s internet speed / computing power. The delay may not be enough.
      – Smollet777
      Nov 8 at 11:28








    • 1




      Your solution based on the change of display: none to opacity or visibility is hidden when the author already using opacity: 0;visibility: hidden; !!! could you give us a working fiddle instead?
      – Zakaria Acharki
      Nov 8 at 11:32












    • Sorry my fault, also visibility prevent focus, so the offscreen hack work without change of visibility.
      – Antonio Buelli
      Nov 8 at 11:53






    • 2




      @ZakariaAcharki toggleClass does not take always the same time. In fact jquery provides promises to work with when dealing with those methods. Also setTimeout does not guarantee the real time execution delay
      – Antonio Buelli
      Nov 8 at 11:56













    up vote
    1
    down vote










    up vote
    1
    down vote









    The problem resides on input being hidden initially and browsers prevent operation such as focus on hidden elements.
    Common pratice, instead of using display: none, is to take the component off screen (IE: Fixed position with negative left and opacity === 0 or visibility hidden).



    Using setTimeout (which in this case in undeterministic) is a bad pratice and should be avoided.






    share|improve this answer












    The problem resides on input being hidden initially and browsers prevent operation such as focus on hidden elements.
    Common pratice, instead of using display: none, is to take the component off screen (IE: Fixed position with negative left and opacity === 0 or visibility hidden).



    Using setTimeout (which in this case in undeterministic) is a bad pratice and should be avoided.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 8 at 11:15









    Antonio Buelli

    292




    292












    • Why did you think setTimeout() is a bad practice for this case? instead of using display: none where you see this role?
      – Zakaria Acharki
      Nov 8 at 11:20








    • 1




      @ZakariaAcharki simply because we cannot be sure of client’s internet speed / computing power. The delay may not be enough.
      – Smollet777
      Nov 8 at 11:28








    • 1




      Your solution based on the change of display: none to opacity or visibility is hidden when the author already using opacity: 0;visibility: hidden; !!! could you give us a working fiddle instead?
      – Zakaria Acharki
      Nov 8 at 11:32












    • Sorry my fault, also visibility prevent focus, so the offscreen hack work without change of visibility.
      – Antonio Buelli
      Nov 8 at 11:53






    • 2




      @ZakariaAcharki toggleClass does not take always the same time. In fact jquery provides promises to work with when dealing with those methods. Also setTimeout does not guarantee the real time execution delay
      – Antonio Buelli
      Nov 8 at 11:56


















    • Why did you think setTimeout() is a bad practice for this case? instead of using display: none where you see this role?
      – Zakaria Acharki
      Nov 8 at 11:20








    • 1




      @ZakariaAcharki simply because we cannot be sure of client’s internet speed / computing power. The delay may not be enough.
      – Smollet777
      Nov 8 at 11:28








    • 1




      Your solution based on the change of display: none to opacity or visibility is hidden when the author already using opacity: 0;visibility: hidden; !!! could you give us a working fiddle instead?
      – Zakaria Acharki
      Nov 8 at 11:32












    • Sorry my fault, also visibility prevent focus, so the offscreen hack work without change of visibility.
      – Antonio Buelli
      Nov 8 at 11:53






    • 2




      @ZakariaAcharki toggleClass does not take always the same time. In fact jquery provides promises to work with when dealing with those methods. Also setTimeout does not guarantee the real time execution delay
      – Antonio Buelli
      Nov 8 at 11:56
















    Why did you think setTimeout() is a bad practice for this case? instead of using display: none where you see this role?
    – Zakaria Acharki
    Nov 8 at 11:20






    Why did you think setTimeout() is a bad practice for this case? instead of using display: none where you see this role?
    – Zakaria Acharki
    Nov 8 at 11:20






    1




    1




    @ZakariaAcharki simply because we cannot be sure of client’s internet speed / computing power. The delay may not be enough.
    – Smollet777
    Nov 8 at 11:28






    @ZakariaAcharki simply because we cannot be sure of client’s internet speed / computing power. The delay may not be enough.
    – Smollet777
    Nov 8 at 11:28






    1




    1




    Your solution based on the change of display: none to opacity or visibility is hidden when the author already using opacity: 0;visibility: hidden; !!! could you give us a working fiddle instead?
    – Zakaria Acharki
    Nov 8 at 11:32






    Your solution based on the change of display: none to opacity or visibility is hidden when the author already using opacity: 0;visibility: hidden; !!! could you give us a working fiddle instead?
    – Zakaria Acharki
    Nov 8 at 11:32














    Sorry my fault, also visibility prevent focus, so the offscreen hack work without change of visibility.
    – Antonio Buelli
    Nov 8 at 11:53




    Sorry my fault, also visibility prevent focus, so the offscreen hack work without change of visibility.
    – Antonio Buelli
    Nov 8 at 11:53




    2




    2




    @ZakariaAcharki toggleClass does not take always the same time. In fact jquery provides promises to work with when dealing with those methods. Also setTimeout does not guarantee the real time execution delay
    – Antonio Buelli
    Nov 8 at 11:56




    @ZakariaAcharki toggleClass does not take always the same time. In fact jquery provides promises to work with when dealing with those methods. Also setTimeout does not guarantee the real time execution delay
    – Antonio Buelli
    Nov 8 at 11:56












    up vote
    1
    down vote














    (From the official documentation) Take care to only use .focus() on elements that are visible.




    You need just to wait for the toggle fired by toggleClass() to end so the #search-input input will be visible then you could perform the focus to the input.



    Since toggleClass() method has no complete callback you could use setTimeout() for this like:



    setTimeout(function() {
    $('#search-input').focus();
    }, 100);





    $('#search-input').focus();

    $('#search-btn').on('click', function() {
    $(this).toggleClass('active');
    $('#search-wrapper').toggleClass('visible');

    if ($('#region-wrapper').hasClass('visible')) {
    $('#region-wrapper').toggleClass('visible');
    }

    if ($('#region-select').hasClass('active')) {
    $('#region-select').toggleClass('active');
    }
    setTimeout(function() {
    $('#search-input').focus();
    }, 100);
    });

    #menu-side {
    width: 200px;
    float: right;
    position: static;
    z-index: 10;
    margin-right: 15px;
    margin-top: 15px;
    }

    #search-btn {
    background: red;
    border: none;
    font-size: 1.8rem;
    cursor: pointer;
    outline: 0;
    position: relative;
    display: block;
    width: 40px;
    height: 40px;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper {
    width: 100%;
    position: absolute;
    top: 90px;
    left: 0;
    right: 0;
    opacity: 0;
    visibility: hidden;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper.visible {
    opacity: 1;
    visibility: visible !important;
    }

    #search-inner {
    background: #e5e5e5;
    padding: 35px 80px;
    }

    #search-input {
    border: none;
    background: none;
    font-size: 1.8rem;
    line-height: 1.8rem;
    color: black;
    float: left;
    width: 90%;
    }

    #search-submit {
    background: none;
    border: none;
    float: right;
    width: 10%;
    font-size: 1.8rem;
    outline: 0;
    transition-duration: 0.3s;
    transition-property: all;
    cursor: pointer;
    max-width: 21px;
    margin: 0;
    padding: 0;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="menu-side" class="clearfix">
    <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

    <div id="search-wrapper">
    <div class="container">
    <div id="search-inner" class="o-bdr-top">
    <form role="search" method="get" id="search-form" class="clearfix" action="">
    <button id="search-submit"><i class="fas fa-search float-right"></i></button>
    <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
    </form>
    </div>
    </div>
    </div>
    </div>








    share|improve this answer



















    • 1




      as in another comment below another answer both toggleClass and setTimeout haven't real timing you can rely on. Working with off screen elements or jquery promises ($("#myId").toggleClass('fadeOut',600).promise().done(...mymethod) is so much cleaner and solid
      – Mosè Raguzzini
      Nov 8 at 12:00










    • @MosèRaguzzini thanks for your intervention, .promise() require jQuery-UI I don't want to suggest it here, you could post a working answer that will be cool.
      – Zakaria Acharki
      Nov 8 at 12:07















    up vote
    1
    down vote














    (From the official documentation) Take care to only use .focus() on elements that are visible.




    You need just to wait for the toggle fired by toggleClass() to end so the #search-input input will be visible then you could perform the focus to the input.



    Since toggleClass() method has no complete callback you could use setTimeout() for this like:



    setTimeout(function() {
    $('#search-input').focus();
    }, 100);





    $('#search-input').focus();

    $('#search-btn').on('click', function() {
    $(this).toggleClass('active');
    $('#search-wrapper').toggleClass('visible');

    if ($('#region-wrapper').hasClass('visible')) {
    $('#region-wrapper').toggleClass('visible');
    }

    if ($('#region-select').hasClass('active')) {
    $('#region-select').toggleClass('active');
    }
    setTimeout(function() {
    $('#search-input').focus();
    }, 100);
    });

    #menu-side {
    width: 200px;
    float: right;
    position: static;
    z-index: 10;
    margin-right: 15px;
    margin-top: 15px;
    }

    #search-btn {
    background: red;
    border: none;
    font-size: 1.8rem;
    cursor: pointer;
    outline: 0;
    position: relative;
    display: block;
    width: 40px;
    height: 40px;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper {
    width: 100%;
    position: absolute;
    top: 90px;
    left: 0;
    right: 0;
    opacity: 0;
    visibility: hidden;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper.visible {
    opacity: 1;
    visibility: visible !important;
    }

    #search-inner {
    background: #e5e5e5;
    padding: 35px 80px;
    }

    #search-input {
    border: none;
    background: none;
    font-size: 1.8rem;
    line-height: 1.8rem;
    color: black;
    float: left;
    width: 90%;
    }

    #search-submit {
    background: none;
    border: none;
    float: right;
    width: 10%;
    font-size: 1.8rem;
    outline: 0;
    transition-duration: 0.3s;
    transition-property: all;
    cursor: pointer;
    max-width: 21px;
    margin: 0;
    padding: 0;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="menu-side" class="clearfix">
    <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

    <div id="search-wrapper">
    <div class="container">
    <div id="search-inner" class="o-bdr-top">
    <form role="search" method="get" id="search-form" class="clearfix" action="">
    <button id="search-submit"><i class="fas fa-search float-right"></i></button>
    <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
    </form>
    </div>
    </div>
    </div>
    </div>








    share|improve this answer



















    • 1




      as in another comment below another answer both toggleClass and setTimeout haven't real timing you can rely on. Working with off screen elements or jquery promises ($("#myId").toggleClass('fadeOut',600).promise().done(...mymethod) is so much cleaner and solid
      – Mosè Raguzzini
      Nov 8 at 12:00










    • @MosèRaguzzini thanks for your intervention, .promise() require jQuery-UI I don't want to suggest it here, you could post a working answer that will be cool.
      – Zakaria Acharki
      Nov 8 at 12:07













    up vote
    1
    down vote










    up vote
    1
    down vote










    (From the official documentation) Take care to only use .focus() on elements that are visible.




    You need just to wait for the toggle fired by toggleClass() to end so the #search-input input will be visible then you could perform the focus to the input.



    Since toggleClass() method has no complete callback you could use setTimeout() for this like:



    setTimeout(function() {
    $('#search-input').focus();
    }, 100);





    $('#search-input').focus();

    $('#search-btn').on('click', function() {
    $(this).toggleClass('active');
    $('#search-wrapper').toggleClass('visible');

    if ($('#region-wrapper').hasClass('visible')) {
    $('#region-wrapper').toggleClass('visible');
    }

    if ($('#region-select').hasClass('active')) {
    $('#region-select').toggleClass('active');
    }
    setTimeout(function() {
    $('#search-input').focus();
    }, 100);
    });

    #menu-side {
    width: 200px;
    float: right;
    position: static;
    z-index: 10;
    margin-right: 15px;
    margin-top: 15px;
    }

    #search-btn {
    background: red;
    border: none;
    font-size: 1.8rem;
    cursor: pointer;
    outline: 0;
    position: relative;
    display: block;
    width: 40px;
    height: 40px;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper {
    width: 100%;
    position: absolute;
    top: 90px;
    left: 0;
    right: 0;
    opacity: 0;
    visibility: hidden;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper.visible {
    opacity: 1;
    visibility: visible !important;
    }

    #search-inner {
    background: #e5e5e5;
    padding: 35px 80px;
    }

    #search-input {
    border: none;
    background: none;
    font-size: 1.8rem;
    line-height: 1.8rem;
    color: black;
    float: left;
    width: 90%;
    }

    #search-submit {
    background: none;
    border: none;
    float: right;
    width: 10%;
    font-size: 1.8rem;
    outline: 0;
    transition-duration: 0.3s;
    transition-property: all;
    cursor: pointer;
    max-width: 21px;
    margin: 0;
    padding: 0;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="menu-side" class="clearfix">
    <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

    <div id="search-wrapper">
    <div class="container">
    <div id="search-inner" class="o-bdr-top">
    <form role="search" method="get" id="search-form" class="clearfix" action="">
    <button id="search-submit"><i class="fas fa-search float-right"></i></button>
    <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
    </form>
    </div>
    </div>
    </div>
    </div>








    share|improve this answer















    (From the official documentation) Take care to only use .focus() on elements that are visible.




    You need just to wait for the toggle fired by toggleClass() to end so the #search-input input will be visible then you could perform the focus to the input.



    Since toggleClass() method has no complete callback you could use setTimeout() for this like:



    setTimeout(function() {
    $('#search-input').focus();
    }, 100);





    $('#search-input').focus();

    $('#search-btn').on('click', function() {
    $(this).toggleClass('active');
    $('#search-wrapper').toggleClass('visible');

    if ($('#region-wrapper').hasClass('visible')) {
    $('#region-wrapper').toggleClass('visible');
    }

    if ($('#region-select').hasClass('active')) {
    $('#region-select').toggleClass('active');
    }
    setTimeout(function() {
    $('#search-input').focus();
    }, 100);
    });

    #menu-side {
    width: 200px;
    float: right;
    position: static;
    z-index: 10;
    margin-right: 15px;
    margin-top: 15px;
    }

    #search-btn {
    background: red;
    border: none;
    font-size: 1.8rem;
    cursor: pointer;
    outline: 0;
    position: relative;
    display: block;
    width: 40px;
    height: 40px;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper {
    width: 100%;
    position: absolute;
    top: 90px;
    left: 0;
    right: 0;
    opacity: 0;
    visibility: hidden;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper.visible {
    opacity: 1;
    visibility: visible !important;
    }

    #search-inner {
    background: #e5e5e5;
    padding: 35px 80px;
    }

    #search-input {
    border: none;
    background: none;
    font-size: 1.8rem;
    line-height: 1.8rem;
    color: black;
    float: left;
    width: 90%;
    }

    #search-submit {
    background: none;
    border: none;
    float: right;
    width: 10%;
    font-size: 1.8rem;
    outline: 0;
    transition-duration: 0.3s;
    transition-property: all;
    cursor: pointer;
    max-width: 21px;
    margin: 0;
    padding: 0;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="menu-side" class="clearfix">
    <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

    <div id="search-wrapper">
    <div class="container">
    <div id="search-inner" class="o-bdr-top">
    <form role="search" method="get" id="search-form" class="clearfix" action="">
    <button id="search-submit"><i class="fas fa-search float-right"></i></button>
    <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
    </form>
    </div>
    </div>
    </div>
    </div>








    $('#search-input').focus();

    $('#search-btn').on('click', function() {
    $(this).toggleClass('active');
    $('#search-wrapper').toggleClass('visible');

    if ($('#region-wrapper').hasClass('visible')) {
    $('#region-wrapper').toggleClass('visible');
    }

    if ($('#region-select').hasClass('active')) {
    $('#region-select').toggleClass('active');
    }
    setTimeout(function() {
    $('#search-input').focus();
    }, 100);
    });

    #menu-side {
    width: 200px;
    float: right;
    position: static;
    z-index: 10;
    margin-right: 15px;
    margin-top: 15px;
    }

    #search-btn {
    background: red;
    border: none;
    font-size: 1.8rem;
    cursor: pointer;
    outline: 0;
    position: relative;
    display: block;
    width: 40px;
    height: 40px;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper {
    width: 100%;
    position: absolute;
    top: 90px;
    left: 0;
    right: 0;
    opacity: 0;
    visibility: hidden;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper.visible {
    opacity: 1;
    visibility: visible !important;
    }

    #search-inner {
    background: #e5e5e5;
    padding: 35px 80px;
    }

    #search-input {
    border: none;
    background: none;
    font-size: 1.8rem;
    line-height: 1.8rem;
    color: black;
    float: left;
    width: 90%;
    }

    #search-submit {
    background: none;
    border: none;
    float: right;
    width: 10%;
    font-size: 1.8rem;
    outline: 0;
    transition-duration: 0.3s;
    transition-property: all;
    cursor: pointer;
    max-width: 21px;
    margin: 0;
    padding: 0;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="menu-side" class="clearfix">
    <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

    <div id="search-wrapper">
    <div class="container">
    <div id="search-inner" class="o-bdr-top">
    <form role="search" method="get" id="search-form" class="clearfix" action="">
    <button id="search-submit"><i class="fas fa-search float-right"></i></button>
    <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
    </form>
    </div>
    </div>
    </div>
    </div>





    $('#search-input').focus();

    $('#search-btn').on('click', function() {
    $(this).toggleClass('active');
    $('#search-wrapper').toggleClass('visible');

    if ($('#region-wrapper').hasClass('visible')) {
    $('#region-wrapper').toggleClass('visible');
    }

    if ($('#region-select').hasClass('active')) {
    $('#region-select').toggleClass('active');
    }
    setTimeout(function() {
    $('#search-input').focus();
    }, 100);
    });

    #menu-side {
    width: 200px;
    float: right;
    position: static;
    z-index: 10;
    margin-right: 15px;
    margin-top: 15px;
    }

    #search-btn {
    background: red;
    border: none;
    font-size: 1.8rem;
    cursor: pointer;
    outline: 0;
    position: relative;
    display: block;
    width: 40px;
    height: 40px;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper {
    width: 100%;
    position: absolute;
    top: 90px;
    left: 0;
    right: 0;
    opacity: 0;
    visibility: hidden;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper.visible {
    opacity: 1;
    visibility: visible !important;
    }

    #search-inner {
    background: #e5e5e5;
    padding: 35px 80px;
    }

    #search-input {
    border: none;
    background: none;
    font-size: 1.8rem;
    line-height: 1.8rem;
    color: black;
    float: left;
    width: 90%;
    }

    #search-submit {
    background: none;
    border: none;
    float: right;
    width: 10%;
    font-size: 1.8rem;
    outline: 0;
    transition-duration: 0.3s;
    transition-property: all;
    cursor: pointer;
    max-width: 21px;
    margin: 0;
    padding: 0;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="menu-side" class="clearfix">
    <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

    <div id="search-wrapper">
    <div class="container">
    <div id="search-inner" class="o-bdr-top">
    <form role="search" method="get" id="search-form" class="clearfix" action="">
    <button id="search-submit"><i class="fas fa-search float-right"></i></button>
    <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
    </form>
    </div>
    </div>
    </div>
    </div>






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 8 at 11:52

























    answered Nov 8 at 11:05









    Zakaria Acharki

    54.3k134266




    54.3k134266








    • 1




      as in another comment below another answer both toggleClass and setTimeout haven't real timing you can rely on. Working with off screen elements or jquery promises ($("#myId").toggleClass('fadeOut',600).promise().done(...mymethod) is so much cleaner and solid
      – Mosè Raguzzini
      Nov 8 at 12:00










    • @MosèRaguzzini thanks for your intervention, .promise() require jQuery-UI I don't want to suggest it here, you could post a working answer that will be cool.
      – Zakaria Acharki
      Nov 8 at 12:07














    • 1




      as in another comment below another answer both toggleClass and setTimeout haven't real timing you can rely on. Working with off screen elements or jquery promises ($("#myId").toggleClass('fadeOut',600).promise().done(...mymethod) is so much cleaner and solid
      – Mosè Raguzzini
      Nov 8 at 12:00










    • @MosèRaguzzini thanks for your intervention, .promise() require jQuery-UI I don't want to suggest it here, you could post a working answer that will be cool.
      – Zakaria Acharki
      Nov 8 at 12:07








    1




    1




    as in another comment below another answer both toggleClass and setTimeout haven't real timing you can rely on. Working with off screen elements or jquery promises ($("#myId").toggleClass('fadeOut',600).promise().done(...mymethod) is so much cleaner and solid
    – Mosè Raguzzini
    Nov 8 at 12:00




    as in another comment below another answer both toggleClass and setTimeout haven't real timing you can rely on. Working with off screen elements or jquery promises ($("#myId").toggleClass('fadeOut',600).promise().done(...mymethod) is so much cleaner and solid
    – Mosè Raguzzini
    Nov 8 at 12:00












    @MosèRaguzzini thanks for your intervention, .promise() require jQuery-UI I don't want to suggest it here, you could post a working answer that will be cool.
    – Zakaria Acharki
    Nov 8 at 12:07




    @MosèRaguzzini thanks for your intervention, .promise() require jQuery-UI I don't want to suggest it here, you could post a working answer that will be cool.
    – Zakaria Acharki
    Nov 8 at 12:07










    up vote
    -1
    down vote













    I suggest the use of display instead of visibility/opacity and toggling the classes, you could use simply display: none by default then toggle the display using the jQuery toggle() method then the focus will work:






    $('#search-input').focus();

    $('#search-btn').on('click', function() {
    $(this).toggleClass('active');
    $('#search-wrapper').toggle();
    $('#search-input').focus();

    if ($('#region-wrapper').hasClass('visible')) {
    $('#region-wrapper').toggleClass('visible');
    }

    if ($('#region-select').hasClass('active')) {
    $('#region-select').toggleClass('active');
    }
    $('#search-input').toggleClass('active').focus();
    });

    #menu-side {
    width: 200px;
    float: right;
    position: static;
    z-index: 10;
    margin-right: 15px;
    margin-top: 15px;
    }

    #search-btn {
    background: red;
    border: none;
    font-size: 1.8rem;
    cursor: pointer;
    outline: 0;
    position: relative;
    display: block;
    width: 40px;
    height: 40px;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-wrapper {
    width: 100%;
    position: absolute;
    top: 90px;
    left: 0;
    right: 0;
    display: none;
    transition-duration: 0.3s;
    transition-property: all;
    }

    #search-inner {
    background: #e5e5e5;
    padding: 35px 80px;
    }

    #search-input {
    border: none;
    background: none;
    font-size: 1.8rem;
    line-height: 1.8rem;
    color: black;
    float: left;
    width: 90%;
    }

    #search-submit {
    background: none;
    border: none;
    float: right;
    width: 10%;
    font-size: 1.8rem;
    outline: 0;
    transition-duration: 0.3s;
    transition-property: all;
    cursor: pointer;
    max-width: 21px;
    margin: 0;
    padding: 0;
    }

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="menu-side" class="clearfix">
    <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

    <div id="search-wrapper">
    <div class="container">
    <div id="search-inner" class="o-bdr-top">
    <form role="search" method="get" id="search-form" class="clearfix" action="">
    <button id="search-submit"><i class="fas fa-search float-right"></i></button>
    <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
    </form>
    </div>
    </div>
    </div>
    </div>








    share|improve this answer

























      up vote
      -1
      down vote













      I suggest the use of display instead of visibility/opacity and toggling the classes, you could use simply display: none by default then toggle the display using the jQuery toggle() method then the focus will work:






      $('#search-input').focus();

      $('#search-btn').on('click', function() {
      $(this).toggleClass('active');
      $('#search-wrapper').toggle();
      $('#search-input').focus();

      if ($('#region-wrapper').hasClass('visible')) {
      $('#region-wrapper').toggleClass('visible');
      }

      if ($('#region-select').hasClass('active')) {
      $('#region-select').toggleClass('active');
      }
      $('#search-input').toggleClass('active').focus();
      });

      #menu-side {
      width: 200px;
      float: right;
      position: static;
      z-index: 10;
      margin-right: 15px;
      margin-top: 15px;
      }

      #search-btn {
      background: red;
      border: none;
      font-size: 1.8rem;
      cursor: pointer;
      outline: 0;
      position: relative;
      display: block;
      width: 40px;
      height: 40px;
      transition-duration: 0.3s;
      transition-property: all;
      }

      #search-wrapper {
      width: 100%;
      position: absolute;
      top: 90px;
      left: 0;
      right: 0;
      display: none;
      transition-duration: 0.3s;
      transition-property: all;
      }

      #search-inner {
      background: #e5e5e5;
      padding: 35px 80px;
      }

      #search-input {
      border: none;
      background: none;
      font-size: 1.8rem;
      line-height: 1.8rem;
      color: black;
      float: left;
      width: 90%;
      }

      #search-submit {
      background: none;
      border: none;
      float: right;
      width: 10%;
      font-size: 1.8rem;
      outline: 0;
      transition-duration: 0.3s;
      transition-property: all;
      cursor: pointer;
      max-width: 21px;
      margin: 0;
      padding: 0;
      }

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
      <div id="menu-side" class="clearfix">
      <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

      <div id="search-wrapper">
      <div class="container">
      <div id="search-inner" class="o-bdr-top">
      <form role="search" method="get" id="search-form" class="clearfix" action="">
      <button id="search-submit"><i class="fas fa-search float-right"></i></button>
      <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
      </form>
      </div>
      </div>
      </div>
      </div>








      share|improve this answer























        up vote
        -1
        down vote










        up vote
        -1
        down vote









        I suggest the use of display instead of visibility/opacity and toggling the classes, you could use simply display: none by default then toggle the display using the jQuery toggle() method then the focus will work:






        $('#search-input').focus();

        $('#search-btn').on('click', function() {
        $(this).toggleClass('active');
        $('#search-wrapper').toggle();
        $('#search-input').focus();

        if ($('#region-wrapper').hasClass('visible')) {
        $('#region-wrapper').toggleClass('visible');
        }

        if ($('#region-select').hasClass('active')) {
        $('#region-select').toggleClass('active');
        }
        $('#search-input').toggleClass('active').focus();
        });

        #menu-side {
        width: 200px;
        float: right;
        position: static;
        z-index: 10;
        margin-right: 15px;
        margin-top: 15px;
        }

        #search-btn {
        background: red;
        border: none;
        font-size: 1.8rem;
        cursor: pointer;
        outline: 0;
        position: relative;
        display: block;
        width: 40px;
        height: 40px;
        transition-duration: 0.3s;
        transition-property: all;
        }

        #search-wrapper {
        width: 100%;
        position: absolute;
        top: 90px;
        left: 0;
        right: 0;
        display: none;
        transition-duration: 0.3s;
        transition-property: all;
        }

        #search-inner {
        background: #e5e5e5;
        padding: 35px 80px;
        }

        #search-input {
        border: none;
        background: none;
        font-size: 1.8rem;
        line-height: 1.8rem;
        color: black;
        float: left;
        width: 90%;
        }

        #search-submit {
        background: none;
        border: none;
        float: right;
        width: 10%;
        font-size: 1.8rem;
        outline: 0;
        transition-duration: 0.3s;
        transition-property: all;
        cursor: pointer;
        max-width: 21px;
        margin: 0;
        padding: 0;
        }

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <div id="menu-side" class="clearfix">
        <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

        <div id="search-wrapper">
        <div class="container">
        <div id="search-inner" class="o-bdr-top">
        <form role="search" method="get" id="search-form" class="clearfix" action="">
        <button id="search-submit"><i class="fas fa-search float-right"></i></button>
        <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
        </form>
        </div>
        </div>
        </div>
        </div>








        share|improve this answer












        I suggest the use of display instead of visibility/opacity and toggling the classes, you could use simply display: none by default then toggle the display using the jQuery toggle() method then the focus will work:






        $('#search-input').focus();

        $('#search-btn').on('click', function() {
        $(this).toggleClass('active');
        $('#search-wrapper').toggle();
        $('#search-input').focus();

        if ($('#region-wrapper').hasClass('visible')) {
        $('#region-wrapper').toggleClass('visible');
        }

        if ($('#region-select').hasClass('active')) {
        $('#region-select').toggleClass('active');
        }
        $('#search-input').toggleClass('active').focus();
        });

        #menu-side {
        width: 200px;
        float: right;
        position: static;
        z-index: 10;
        margin-right: 15px;
        margin-top: 15px;
        }

        #search-btn {
        background: red;
        border: none;
        font-size: 1.8rem;
        cursor: pointer;
        outline: 0;
        position: relative;
        display: block;
        width: 40px;
        height: 40px;
        transition-duration: 0.3s;
        transition-property: all;
        }

        #search-wrapper {
        width: 100%;
        position: absolute;
        top: 90px;
        left: 0;
        right: 0;
        display: none;
        transition-duration: 0.3s;
        transition-property: all;
        }

        #search-inner {
        background: #e5e5e5;
        padding: 35px 80px;
        }

        #search-input {
        border: none;
        background: none;
        font-size: 1.8rem;
        line-height: 1.8rem;
        color: black;
        float: left;
        width: 90%;
        }

        #search-submit {
        background: none;
        border: none;
        float: right;
        width: 10%;
        font-size: 1.8rem;
        outline: 0;
        transition-duration: 0.3s;
        transition-property: all;
        cursor: pointer;
        max-width: 21px;
        margin: 0;
        padding: 0;
        }

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <div id="menu-side" class="clearfix">
        <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

        <div id="search-wrapper">
        <div class="container">
        <div id="search-inner" class="o-bdr-top">
        <form role="search" method="get" id="search-form" class="clearfix" action="">
        <button id="search-submit"><i class="fas fa-search float-right"></i></button>
        <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
        </form>
        </div>
        </div>
        </div>
        </div>








        $('#search-input').focus();

        $('#search-btn').on('click', function() {
        $(this).toggleClass('active');
        $('#search-wrapper').toggle();
        $('#search-input').focus();

        if ($('#region-wrapper').hasClass('visible')) {
        $('#region-wrapper').toggleClass('visible');
        }

        if ($('#region-select').hasClass('active')) {
        $('#region-select').toggleClass('active');
        }
        $('#search-input').toggleClass('active').focus();
        });

        #menu-side {
        width: 200px;
        float: right;
        position: static;
        z-index: 10;
        margin-right: 15px;
        margin-top: 15px;
        }

        #search-btn {
        background: red;
        border: none;
        font-size: 1.8rem;
        cursor: pointer;
        outline: 0;
        position: relative;
        display: block;
        width: 40px;
        height: 40px;
        transition-duration: 0.3s;
        transition-property: all;
        }

        #search-wrapper {
        width: 100%;
        position: absolute;
        top: 90px;
        left: 0;
        right: 0;
        display: none;
        transition-duration: 0.3s;
        transition-property: all;
        }

        #search-inner {
        background: #e5e5e5;
        padding: 35px 80px;
        }

        #search-input {
        border: none;
        background: none;
        font-size: 1.8rem;
        line-height: 1.8rem;
        color: black;
        float: left;
        width: 90%;
        }

        #search-submit {
        background: none;
        border: none;
        float: right;
        width: 10%;
        font-size: 1.8rem;
        outline: 0;
        transition-duration: 0.3s;
        transition-property: all;
        cursor: pointer;
        max-width: 21px;
        margin: 0;
        padding: 0;
        }

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <div id="menu-side" class="clearfix">
        <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

        <div id="search-wrapper">
        <div class="container">
        <div id="search-inner" class="o-bdr-top">
        <form role="search" method="get" id="search-form" class="clearfix" action="">
        <button id="search-submit"><i class="fas fa-search float-right"></i></button>
        <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
        </form>
        </div>
        </div>
        </div>
        </div>





        $('#search-input').focus();

        $('#search-btn').on('click', function() {
        $(this).toggleClass('active');
        $('#search-wrapper').toggle();
        $('#search-input').focus();

        if ($('#region-wrapper').hasClass('visible')) {
        $('#region-wrapper').toggleClass('visible');
        }

        if ($('#region-select').hasClass('active')) {
        $('#region-select').toggleClass('active');
        }
        $('#search-input').toggleClass('active').focus();
        });

        #menu-side {
        width: 200px;
        float: right;
        position: static;
        z-index: 10;
        margin-right: 15px;
        margin-top: 15px;
        }

        #search-btn {
        background: red;
        border: none;
        font-size: 1.8rem;
        cursor: pointer;
        outline: 0;
        position: relative;
        display: block;
        width: 40px;
        height: 40px;
        transition-duration: 0.3s;
        transition-property: all;
        }

        #search-wrapper {
        width: 100%;
        position: absolute;
        top: 90px;
        left: 0;
        right: 0;
        display: none;
        transition-duration: 0.3s;
        transition-property: all;
        }

        #search-inner {
        background: #e5e5e5;
        padding: 35px 80px;
        }

        #search-input {
        border: none;
        background: none;
        font-size: 1.8rem;
        line-height: 1.8rem;
        color: black;
        float: left;
        width: 90%;
        }

        #search-submit {
        background: none;
        border: none;
        float: right;
        width: 10%;
        font-size: 1.8rem;
        outline: 0;
        transition-duration: 0.3s;
        transition-property: all;
        cursor: pointer;
        max-width: 21px;
        margin: 0;
        padding: 0;
        }

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <div id="menu-side" class="clearfix">
        <button id="search-btn" class="float-right js-overlay"><i class="fas fa-search float-right"></i></button>

        <div id="search-wrapper">
        <div class="container">
        <div id="search-inner" class="o-bdr-top">
        <form role="search" method="get" id="search-form" class="clearfix" action="">
        <button id="search-submit"><i class="fas fa-search float-right"></i></button>
        <input type="search" id="search-input" placeholder="What are you looking for?" name="s" class="float-left" />
        </form>
        </div>
        </div>
        </div>
        </div>






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 8 at 11:50









        Zakaria Acharki

        54.3k134266




        54.3k134266






























             

            draft saved


            draft discarded



















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53206346%2fclick-button-trigger-input-to-appear-with-focus%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Guess what letter conforming each word

            Port of Spain

            Run scheduled task as local user group (not BUILTIN)