angular.module('plunker', ['jqSearchBox']).

controller('MainCtrl', function($scope) {
    $scope.search = {
        query: ''
    };
});
<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <script data-require="jquery@*" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
    <script data-require="angular.js@1.0.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js" data-semver="1.0.8"></script>
    <link rel="stylesheet" href="jquery.searchBox.css" />
    <link rel="stylesheet" href="app.css" />
    <script src="searchBox.js"></script>
    <script src="searchBoxDirective.js"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <div search-box ng-model="search.query" placeholder="Type in to search..."></div>
    <p>Text to search: {{ search.query }}</p>
    <p><input ng-model="search.query" /></p>
  </body>

</html>
.search-box {
    display: inline-block;
    position: relative;
    background: white;
    margin-bottom: 10px;
}
.search-box input {
    border: none;
    outline: 0;
    border-radius: 15px;
    box-shadow: 1px 1px 12px -1px #eee inset;
    background: white;
    padding: 8px 22px 6px 10px;
    margin: 0;
    box-sizing: border-box;
    font-size: 12px;
    line-height: 12px;
    color: #999;
}
.search-box span {
    display: inline-block;
    position: absolute;
    z-index: 2;
    right: 7px;
    top: 7px;
    width: 16px;
    height: 16px;
    color: #ccc;
}
.search-box span::before {
    content: "";
    display: block;
    position: absolute;
    float: left;
    z-index: 2;
    -webkit-transform: rotate(40deg);
    transform: rotate(45deg);
    width: 3px;
    height: 7px;
    margin: 7px 0 0 5px;
    background: #ccc;
}
.search-box span::after {
    content: "";
    display: block;
    float: right;
    z-index: 3;
    border: 1px solid #ccc;
    border-radius: 50%;
    width: 9px;
    height: 9px;
    box-sizing: border-box;
}
(function($, undefined) {

    var template = '<div class="search-box"><input type="text" /><span></span></div>',
        dataAttributeName = 'search-box',
        arrSlice = Array.prototype.slice;

    function SearchBox(element, options) {
        this.$el = element;
        element.html('').append(template);

        var $input = this.$input = element.find('input'),
            me = this;

        if (options.placeholder) {
            $input.attr('placeholder', options.placeholder);
        }

        if (typeof options.onchange === 'function') {
            this.$change = options.onchange;
        }
        
        $input.on('keyup change', function(event) {
            me.$change && me.$change(event, me.$input.val());
        });
    }

    SearchBox.prototype = {
        constructor: SearchBox,
        $change: false,
        $input: null,
        $el: null,

        setValue: function(value) {
            this.$input.val(value);
        },

        getValue: function() {
            return this.$input.val();
        }
    };

    $.fn.searchBox = function(options) {
        var args = arrSlice.call(arguments),
            returnValue;

        this.each(function() {
            var $this = $(this),
                data = $this.data(dataAttributeName);

            if (!data) {
                options = typeof options === 'object' && options || {};
                data = new SearchBox($this, options);
                $this.data(dataAttributeName, data);
            }

            if (typeof options === 'string' && typeof data[options] === 'function') {
                args.shift();
                returnValue = data[options].apply(data, args);
            }
        });

        return returnValue !== undefined ? returnValue : this;
    };

})(jQuery);
angular.module('jqSearchBox', []).

directive('searchBox', function() {
    return {
        restrict: 'A',
        require: '?ngModel',

        link: function($scope, $element, $attrs, ngModel) {
            if (!ngModel) return;

            $element.searchBox({
                placeholder: $attrs.placeholder || '',
                onchange: function(e, value) {
                    if (ngModel.$viewValue !== value) {
                        $scope.$apply(function() {
                            ngModel.$setViewValue(value);
                        });
                    }
                }
            });

            ngModel.$render = function() {
                $element.searchBox('setValue', ngModel.$viewValue || '');
            };
        }
    };
});
* {
    margin: 0;
    padding: 0;
    font-size: 1em;
}

body {
    font-size: 13px;
    font-family: sans-serif;
    padding: 10px;
}