user21
user21

Reputation: 1351

jQuery change the width of input search box

I would like to change the width of input search box as soon as the cursor was placed in the input box.

However once the user click on any of the body element which is not input box, I would like the width go back to its original length. However it seems that the program also change the width back to its original length even when the cursor was placed in the search box. How do I select body element which is not input box.

<form class="search" action="/search">
   {% if settings.search_option != "everything" %}
     <input type="hidden" name="type" value="product" />
   {% endif %}
   <input type="text" name="q" class="search_box" 
    placeholder="{{ 'general.search.placeholder' | t }}" 
    value="{% if search and search.results.first.price %}{{ search.terms }}
   {% endif %}"/>
</form>

var input = $(this).find('input[name="q"]');

/* Part A: Change the width of the search input box to 600px when cursor was 
   click on the search box. When I comment out part B, 
   then the width will change to 600px. 
   If I does not comment out part B, the width does not change */

input.bind('click', function(){ 
   console.log("width changed");
   $(this ).css({'width' : '600px'});
});

/* Part B: When user click on any body element which is not the input box,
    change the width of the input box back to original length. 
    This code below does not work the way I want. When the cursor was placed 
    in the input box, it also executes this part of code,which is remain at its 
    original length */

$("body:not(.search_box)").bind('click', function(){ 
   $('input:text').css({'width' : 'inherit'}); 
});

/* Part B: I also tried code below, but does not return the result which I want */

$("body *:not(input:text)").bind('click', function(){ 
   $('input:text').css({'width' : 'inherit'}); 
});

/* hide the search result when click on input box and body*/
$('body').bind('click', function(){
   $('.search-results').hide();  
});

Upvotes: 4

Views: 2525

Answers (2)

user6213434
user6213434

Reputation:

You can use animation with focus / blur events https://jsfiddle.net/L84j4ykx/

$('.inp').on('focus', function () {
  $(this).animate({
    width: '400px'
  }, 1000, function () {

    $(this).on('blur', function () {
      $(this).animate({
        width: '200px'
      }, 1000);
    });
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<input class="inp" type="search" name="q">


Edit: To prevent waiting while completing the animation in case of speed change , then you can use stop() before animate() for each event

$('.inp').on('focus', function () {
  $(this).stop().animate({
    width: '400px'
  }, 1000, function () {
  
    $(this).on('blur', function () {
      $(this).stop().animate({
        width: '200px'
      }, 1000);
    });
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input class="inp" type="search" name="q">

Upvotes: 2

Roko C. Buljan
Roko C. Buljan

Reputation: 206506

use focus and blur events:

var input = $('input[name="q"]');

input.on("focus blur", function(evt) {
  $(this).css({width: evt.type=="focus" ? "400px" : "auto" });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input name="q" type="text">

Animate? well... .animate() it than, a bit more difficult cause you need to store the initial size.

var input = $('input[name="q"]');


input.on("focus blur", function(evt) {
  
  if($(this).is("animated")) return;    // Do nothing while animating

  var isFocus = evt.type=="focus";      // Detect event type
  if(isFocus) this.w = $(this).width(); // On focus remember the element initial Width
  $(this).animate({width: isFocus ? 400 : this.w }); // Finally
  
}).on("input", function() {
  
  $(this).trigger("blur");              // Trigger a blur if user selects a dropdown value
  
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span><input name="q" type="text"></span>

CSS only

Logically I would not write the above "nonsense" if it was possible to use CSS transition from an "auto" width to 400px and back...

But if you define a starting CSS width than you can use CSS!

input[name=q]{
  width:180px;     /* NEEDED */
  transition:0.3s; -webkit-transition: 0.3s;
}
input[name=q]:focus{
  width:320px;
}
<input name="q" type="text">

Upvotes: 2

Related Questions