1

So I have a function which is called when input's value changes. It checks if new value is not '' and then it's supposed to slide an input field a little to the left to make room for "clear" button to appear, but I just don't know how to do it.

Here's what I have.

<div class="searchbox">
    <input type="text" ng-model="search" ng-change="filterHeaders()"
           ng-focus="changeSearchValue()" ng-blur="changeSearchValue()" />
    <button id="clearSearch">x</button>
</div>

Please ignore the ng-stuff, but I left it here, so there are no questions how the function is called. It's called from angular.

$('#clearSearch').hide();
searchButton = function() {
    if($('.searchbox input').val() !== '') {
        if($('#clearSearch:hidden')) {
            $('.searchbox input').stop().animate(
                {marginRight: 20},
                {queue: false, duration: 500}
            );
            $('#clearSearch').stop().fadeIn(500);
        }
    }
};

But, of course, it doesn't work as I want it to. It first jumps to the left, giving room for the button to appear, as it would without any animation, and only after begins to slide 20px more to the left.

I understand, that marginRight is not the way to achieve this, but I have no other idea. What do you think?

tldr: I want to slide input to the left to make room for a button to fade in. Simultaneously.

Here is a fiddle of the problem.

Yotam Omer
  • 15,310
  • 11
  • 62
  • 65
Ivan Chepurin
  • 131
  • 1
  • 2
  • 10

4 Answers4

2

All you need to do is make the clear button absolutly positioned so it doesn't disturb the other elements: (Working jsFiddle)

.searchbox {
    float: right;
    position:relative;
}

.searchbox button{
    position: absolute;
    top:0; right:0;
}

Also, I would add an "animating" class or something to tell if the input is currently animating.. What currently happens is that when typing fast the .stop() function is called every time which causes a short "break" on each keypress. Another jsFiddle to illustrate this.

Yotam Omer
  • 15,310
  • 11
  • 62
  • 65
0

If I understand correctly, what you want to do is run your second animation like so:

http://jsfiddle.net/rktpw89p/3/

$('#clearSearch').hide();
$('.searchbox input').keyup(function() {
    if($('.searchbox input').val() !== '') {
        if($('#clearSearch:hidden')) {
            $('.searchbox input').stop().animate({
                marginRight: 20
            }, 500, function() {

                alert('first animation complete!');
                $('#clearSearch').stop().fadeIn(500);

            });

        }
    }
});

it's waiting for the first one to complete.

jdu
  • 581
  • 2
  • 3
  • Not really. My question says "Simultaneously". And still, in your example input still jumps to the left when button fades in, so it's animation is actually pointless in the first place – Ivan Chepurin Jul 15 '15 at 18:01
0

You don't want to change the position of the input, just decrease its width, so animate the width property instead of any margins.

Here's a running example where the animation starts after two seconds.

$(function() {
  $('#clearSearch').hide();
  setTimeout(function() {
    animate();
  }, 2000);
});

function animate() {
  var input = $('.searchbox input');
  var newWidth = input.width() - 20;
  input.stop().animate({
    width: newWidth
  }, {
    queue: false, 
    duration: 500
  });
  $('#clearSearch').stop().fadeIn(500);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="searchbox">
    <input type="text" />
    <button id="clearSearch">x</button>
</div>
Dave
  • 10,748
  • 3
  • 43
  • 54
0

use absolute positining like so :

.searchbox {
   right:0;
   position: absolute;
}
#clearSearch {
   right:0;
   top:0;
   position: absolute;
}

That way, the search box does not jump to the left when the button gets rendered because absolute positioning does not affect the positioning of other DOM elements like described here

here is a working jsfiddle:

http://jsfiddle.net/rktpw89p/5/

Community
  • 1
  • 1
muchwow
  • 715
  • 7
  • 22