A Pen by Carson McKinstry on CodePen.
Created
July 14, 2017 13:16
-
-
Save CarsonMcKinstry/d55d98a4dc2cdac9635ff3ad74fdc3e4 to your computer and use it in GitHub Desktop.
jwdqmd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <div ng-app="myApp" ng-controller="myController" ng-cloak > | |
| <form autocomplete="off"> | |
| <div class="input" ng-click="setFocus()"> | |
| <ul class="tokens"> | |
| <li arrow-lr class="token" ng-repeat="company in selected | limitTo:screenLimit" ng-click="removeThisCompany(company.id)" ng-keydown="removeFocused(this, $event)" data-tooltip="{{company.name}}" tabindex="-1">{{company.name | myFilter }}</li> | |
| <li arrow-lr ng-if="selected.length > screenLimit" class="leftovers" tabindex="-1"> | |
| {{selected.length - screenLimit}} more... | |
| <ul> | |
| <li class="leftover" ng-repeat="company in selected | startFrom: screenLimit" ng-click="removeThisCompany(company.id)"> | |
| {{company.name}} | |
| </li> | |
| </ul> | |
| </li> | |
| </ul> | |
| <!-- <p ng-repeat="company in selected | startFrom : screenLimit">{{company.name}}</p> --> | |
| <input type="text" ng-model="companyFilter" ng-change="filterCompanies()" id="company-input" placeholder="Enter a company..." ng-keydown="focusSelected($event)"/> | |
| </div> | |
| <ul class="autocomplete-items"> | |
| <li class="autocomplete-item" arrow tabindex="-1" class="autocomplete-item" ng-repeat="company in filteredCompanies | limitTo:5 track by company.id" ng-click="selectThisCompany(company.id)">{{company.name}}</li> | |
| <li class="more" ng-if="more">{{more}} Other companies</li> | |
| </ul> | |
| </form> | |
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function() { | |
| function myController($scope) { | |
| // $('#company-input:first-child').focus(); | |
| $scope.companyFilter = ""; | |
| $scope.screenLimit = 2; | |
| $scope.setFocus = function() { | |
| $('#company-input').focus(); | |
| } | |
| var companies = []; | |
| for(var i = 0; i < 100; i++){ | |
| companies.push( | |
| { | |
| id:i, | |
| name: faker.company.companyName() | |
| } | |
| ); | |
| } | |
| $scope.filterCompanies = function() { | |
| if ($scope.companyFilter.length != "") { | |
| $scope.filteredCompanies = | |
| companies | |
| .filter(sieve) | |
| .sort(function(a, b) { | |
| if (a.name > b.name) { | |
| return 1 | |
| } | |
| if (a.name < b.name) { | |
| return -1 | |
| } | |
| return 0 | |
| }); | |
| var leftOver = $scope.filteredCompanies.length - 5; | |
| if (leftOver > 5) { | |
| $scope.more = leftOver; | |
| } else { | |
| $scope.more = undefined; | |
| } | |
| } else { | |
| $scope.filteredCompanies = []; | |
| $scope.more = undefined; | |
| }; | |
| function sieve(company) { | |
| return _.contains($scope.companyFilter.toLowerCase())(company.name.toLowerCase()); | |
| } | |
| } | |
| $scope.selected = []; | |
| $scope.selectThisCompany = function(id) { | |
| var i = _.findIndex(function(x){return x.id == id})(companies) | |
| $scope.selected.push(companies.splice(i,1)[0]); | |
| $scope.companyFilter = ""; | |
| $scope.filterCompanies(); | |
| $scope.more = undefined; | |
| $('#company-input').focus(); | |
| } | |
| $scope.removeFocused = function(self, e) { | |
| if (e.keyCode === 8 || e.which === 8) { | |
| self.removeThisCompany(self.company.id); | |
| $('#company-input').focus(); | |
| } | |
| } | |
| $scope.removeThisCompany = function(id) { | |
| var i = _.findIndex(function(x){return x.id == id},$scope.selected); | |
| console.log(i); | |
| companies.push($scope.selected.splice(i,1)[0]); | |
| $scope.filterCompanies(); | |
| } | |
| $scope.focusSelected = function(e) { | |
| if (e.which === 40) { | |
| $('.autocomplete-item:first-child').focus(); | |
| } else if (e.which === 37) { | |
| $('.tokens li:last-child').focus(); | |
| } | |
| } | |
| } | |
| function filter() { | |
| return function(input) { | |
| if (input.length > 4) { | |
| return input.slice(0,4) + "..."; | |
| } | |
| } | |
| } | |
| function arrow() { | |
| return function (scope,element,attrs) { | |
| element.bind("keydown keypress", function(event) { | |
| if (event.which === 38 || event.which === 37) { | |
| var prevNode = element[0].previousElementSibling; | |
| var prev = angular.element(prevNode); | |
| prev[0].focus(); | |
| } | |
| else if (event.which === 40 || event.which === 39) { | |
| var target = element.next(); | |
| target[0].focus(); | |
| } | |
| else if (event.which === 13) { | |
| scope.selectThisCompany(scope.company.id); | |
| } | |
| else { | |
| $('#company-input').focus(); | |
| } | |
| }); | |
| } | |
| } | |
| function startFrom() { | |
| return function(input,start) { | |
| return input.slice(start); | |
| } | |
| } | |
| function arrowLr() { | |
| return function (scope,element,attrs) { | |
| element.bind("keydown keypress", function(event) { | |
| if (event.which === 37 || event.which === 38) { | |
| var prevNode = element[0].previousElementSibling; | |
| var prev = angular.element(prevNode); | |
| prev[0].focus(); | |
| } | |
| else if (event.which === 39 || event.which === 40) { | |
| var target = element.next(); | |
| target[0].focus(); | |
| } | |
| else { | |
| $('#company-input').focus(); | |
| } | |
| }); | |
| } | |
| } | |
| angular | |
| .module('myApp', []) | |
| .directive('arrow', arrow) | |
| .directive('arrowLr', arrowLr) | |
| .controller('myController', myController) | |
| .filter('myFilter', filter) | |
| .filter('startFrom', startFrom) | |
| })(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <script src="https://cdnjs.cloudflare.com/ajax/libs/Faker/3.1.0/faker.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.11/angular.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-fp/0.10.4/lodash-fp.js"></script> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $tokenBody: #add8eb; | |
| $tokenBorder: #2b89bd; | |
| $tokenText: #777; | |
| $dark: #444; | |
| %tokenStyle { | |
| background-color: $tokenBody; | |
| border: 2px solid $tokenBorder; | |
| color: $tokenText; | |
| padding: 4px; | |
| border-radius:4px; | |
| margin-right: 4px; | |
| font-size: 14px; | |
| cursor: pointer; | |
| &:focus, &:hover { | |
| outline: 0; | |
| background-color: $tokenBorder; | |
| color: #fff; | |
| } | |
| &:after { | |
| content: '\2715'; | |
| padding-left: 4px; | |
| font-size: 12px; | |
| vertical-align: center; | |
| } | |
| } | |
| body { | |
| font-family: sans-serif; | |
| background-color: #ddd; | |
| } | |
| * { | |
| box-sizing: border-box; | |
| } | |
| form { | |
| background-color: #fff; | |
| input { | |
| border: 0; | |
| padding-left: 6px; | |
| &:focus { | |
| outline: 0; | |
| } | |
| } | |
| input { | |
| font-size: 16px; | |
| } | |
| } | |
| .token { | |
| @extend %tokenStyle; | |
| display: inline; | |
| position: relative; | |
| &:hover:before, &:focus:before { | |
| background-color: $dark; | |
| content:attr(data-tooltip); | |
| position: absolute; | |
| color: white; | |
| left: 20%; | |
| top: 30px; | |
| width: 200px; | |
| padding: 8px 20px; | |
| border-radius: 8px; | |
| } | |
| } | |
| .tokens, .autocomplete-items { | |
| list-style-type: none; | |
| padding-left: 0; | |
| } | |
| .leftovers { | |
| font-size: .75em; | |
| color: $tokenBorder; | |
| display: inline; | |
| position: relative; | |
| > ul { | |
| list-style: none; | |
| padding-left: 0; | |
| display: none; | |
| background-color: #fff; | |
| padding: 8px 10px; | |
| width: 300px; | |
| text-align: right; | |
| box-shadow: 1px 2px 5px rgba(0,0,0,0.125); | |
| li { | |
| @extend %tokenStyle; | |
| margin-right: 0; | |
| margin-bottom: 4px; | |
| } | |
| } | |
| &:focus { | |
| outline: 0; | |
| } | |
| &:focus > ul, &:hover >ul, >ul:hover, >ul:focus { | |
| display: initial; | |
| position: absolute; | |
| top: 14px; | |
| left: 0; | |
| } | |
| } | |
| .autocomplete-items { | |
| margin-top: 0; | |
| } | |
| .autocomplete-item { | |
| padding: 4px 8px; | |
| cursor: pointer; | |
| &:focus, &:hover { | |
| outline: 0; | |
| background-color: $tokenBorder; | |
| color: #fff; | |
| } | |
| } | |
| .more { | |
| padding: 4px 8px; | |
| border-top: 1px solid $tokenText; | |
| color: $tokenText; | |
| cursor: default; | |
| } | |
| .input { | |
| height: 36px; | |
| padding: 4px; | |
| display: flex; | |
| align-items: center; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment