Kampfzwerg
2/23/2016 - 2:27 PM

Spinner Input Field with custom controls

Spinner Input Field with custom controls

.e-spinner {
  position: relative;
  @include inline-block;
  margin-bottom: $space;

  input {
    margin-bottom: 0;
  }

  .icon-increase, .icon-decrease {
    position: absolute;
    right: 0;

    color: $white;
    background-color: $primary-color;
    @include transition(background-color 300ms ease);
    font-size: rem-calc(18);
    line-height: 50%;

    width: 2rem;
    height: 50%;

    &:focus {
      outline: none;
    }

    &:hover {
      background-color: lighten($primary-color, 5);
    }
  }

  .icon-increase {
    top: 0;
    border-top-right-radius: 3px;
  }

  .icon-decrease {
    bottom: 0;
    border-bottom-right-radius: 3px;
  }
}
Utils = {
  initSpinner: function ($elems) {
    $elems.each( function () {
        var self = $(this),
            $input = self.find('input'),
            $buttons = self.find('button'),
            min = $input.attr('min') || -9999,
            max = $input.attr('max') || 9999,
            step = $input.attr('step') || 1;

        $buttons.off('click');
        $buttons.click(function (e) {
            e.preventDefault();

            var $button = $(this),
                sign = $button.hasClass('js-increase') ? '+' : '-',
                oldValue = $input.val() || 0,
                newValue;

            // Calculate new value
            newValue = parseInt(oldValue) + parseInt(sign + step);

            // Check if newValue is between min and max
            if (min <= newValue && newValue <= max) {
                $input.val(newValue);
            }
            $input.change();
            $input.addClass('is-filled');
        });
    });
  }
};
$(function(){
  Utils.initSpinner($('.js-spinner'));
})();
<div class="e-spinner js-spinner">
    <input type="number" value="1" min="0" id="number_field">
    <button class="js-increase icon-increase">keyboard_arrow_up</button>
    <button class="js-decrease icon-decrease">keyboard_arrow_down</button>
</div>