├── example ├── css │ ├── angucomplete-alt.css │ └── structure.css ├── js │ ├── libs │ │ ├── angucomplete-alt.js │ │ ├── json3.min.js │ │ └── es5-shim.min.js │ └── app.js ├── img │ ├── alanp.jpg │ ├── annie.jpg │ └── daryl.jpeg ├── fonts │ └── bariol │ │ ├── bariol_bold-webfont.eot │ │ ├── bariol_bold-webfont.ttf │ │ ├── bariol_bold-webfont.woff │ │ ├── bariol_regular-webfont.eot │ │ ├── bariol_regular-webfont.ttf │ │ ├── bariol_regular-webfont.woff │ │ ├── bariol.css │ │ └── bariol_bold-demo.html ├── README.md ├── countries.json └── index.html ├── .bowerrc ├── .gitignore ├── .editorconfig ├── bower.json ├── CONTRIBUTING.md ├── package.json ├── .jshintrc ├── LICENSE ├── angucomplete-alt.css ├── Gruntfile.js ├── test └── karma.conf.js ├── CONTRIBUTORS.md ├── dist └── angucomplete-alt.min.js ├── README.md └── angucomplete-alt.js /example/css/angucomplete-alt.css: -------------------------------------------------------------------------------- 1 | ../../angucomplete-alt.css -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /example/js/libs/angucomplete-alt.js: -------------------------------------------------------------------------------- 1 | ../../../angucomplete-alt.js -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | bower_components 3 | .*.swp 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /example/img/alanp.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghiden/angucomplete-alt/HEAD/example/img/alanp.jpg -------------------------------------------------------------------------------- /example/img/annie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghiden/angucomplete-alt/HEAD/example/img/annie.jpg -------------------------------------------------------------------------------- /example/img/daryl.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghiden/angucomplete-alt/HEAD/example/img/daryl.jpeg -------------------------------------------------------------------------------- /example/fonts/bariol/bariol_bold-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghiden/angucomplete-alt/HEAD/example/fonts/bariol/bariol_bold-webfont.eot -------------------------------------------------------------------------------- /example/fonts/bariol/bariol_bold-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghiden/angucomplete-alt/HEAD/example/fonts/bariol/bariol_bold-webfont.ttf -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | angucomplete-alt 2 | ============ 3 | 4 | AngularJS Autocomplete Directive 5 | 6 | ```bash 7 | python -m SimpleHTTPServer 8 | ``` 9 | -------------------------------------------------------------------------------- /example/fonts/bariol/bariol_bold-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghiden/angucomplete-alt/HEAD/example/fonts/bariol/bariol_bold-webfont.woff -------------------------------------------------------------------------------- /example/fonts/bariol/bariol_regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghiden/angucomplete-alt/HEAD/example/fonts/bariol/bariol_regular-webfont.eot -------------------------------------------------------------------------------- /example/fonts/bariol/bariol_regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghiden/angucomplete-alt/HEAD/example/fonts/bariol/bariol_regular-webfont.ttf -------------------------------------------------------------------------------- /example/fonts/bariol/bariol_regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghiden/angucomplete-alt/HEAD/example/fonts/bariol/bariol_regular-webfont.woff -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | end_of_line = lf 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angucomplete-alt", 3 | "version": "3.0.0", 4 | "homepage": "http://ghiden.github.io/angucomplete-alt/", 5 | "authors": [ 6 | "Hidenari Nozaki " 7 | ], 8 | "description": "Autocomplete directive for AngularJS", 9 | "keywords": [ 10 | "autocomplete", 11 | "typeahead", 12 | "angularjs" 13 | ], 14 | "license": "MIT", 15 | "main": [ 16 | "./angucomplete-alt.js", 17 | "./angucomplete-alt.css" 18 | ], 19 | "ignore": [ 20 | "example", 21 | "bower_components", 22 | "node_modules", 23 | "**/.*", 24 | "test", 25 | "tests" 26 | ], 27 | "dependencies": { 28 | "angular": ">=1.6.0" 29 | }, 30 | "devDependencies": { 31 | "angular-mocks": ">=1.6.0", 32 | "jquery": "~2.1.0" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## How to Contribute to angucomplete-alt 2 | 3 | * Before sending a PR for a feature or bug fix, be sure to run tests by running 4 | 5 | ```bash 6 | grunt # no arguments, just grunt 7 | ``` 8 | 9 | (If you don't have grunt installed, you'll need to run ``npm install -g grunt-cli`` to install grunt. 10 | You'll also want to run ``bower install && npm install``.) 11 | 12 | * If PR is not trivial, please add tests. 13 | 14 | * All pull requests should be made to the `master` branch. 15 | 16 | * No tabs please. Indent with 2 spaces. 17 | 18 | * Do not generate minified version. 19 | 20 | * Do not update package.json and bower.json unless you have a strong reason to do it. 21 | 22 | ### How to run examples: 23 | 24 | ```bash 25 | cd example 26 | python -m SimpleHTTPServer 27 | ``` 28 | 29 | Open your browser and access http://localhost:8000 30 | 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "angucomplete-alt", 3 | "version": "3.0.0", 4 | "description": "Awesome Autocompleteness for AngularJS", 5 | "author": "ghiden", 6 | "email": "hidenari@gmail.com", 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/ghiden/angucomplete-alt.git" 10 | }, 11 | "engines": { 12 | "node": ">= 0.8.4" 13 | }, 14 | "license": "MIT", 15 | "main": "./angucomplete-alt.js", 16 | "dependencies": {}, 17 | "devDependencies": { 18 | "grunt": "~0.4.1", 19 | "grunt-contrib-uglify": "~0.5.1", 20 | "grunt-contrib-jshint": "~0.6.4", 21 | "grunt-contrib-watch": "~0.5.3", 22 | "grunt-karma": "~0.12.2", 23 | "karma": "^0.13.0", 24 | "karma-phantomjs-launcher": "^1.0.0", 25 | "karma-jasmine": "~0.3.3", 26 | "jasmine-core": "~2.4.1", 27 | "phantomjs-prebuilt": ">1.9.0", 28 | "grunt-conventional-changelog": "~1.0.0", 29 | "load-grunt-tasks": "~0.2.0" 30 | } 31 | } 32 | 33 | -------------------------------------------------------------------------------- /example/fonts/bariol/bariol.css: -------------------------------------------------------------------------------- 1 | /* Generated by Font Squirrel (http://www.fontsquirrel.com) on January 12, 2014 */ 2 | 3 | 4 | 5 | @font-face { 6 | font-family: 'bariol_regularregular'; 7 | src: url('bariol_regular-webfont.eot'); 8 | src: url('bariol_regular-webfont.eot?#iefix') format('embedded-opentype'), 9 | url('bariol_regular-webfont.woff') format('woff'), 10 | url('bariol_regular-webfont.ttf') format('truetype'), 11 | url('bariol_regular-webfont.svg#bariol_regularregular') format('svg'); 12 | font-weight: normal; 13 | font-style: normal; 14 | 15 | } 16 | 17 | 18 | @font-face { 19 | font-family: 'bariol_boldbold'; 20 | src: url('bariol_bold-webfont.eot'); 21 | src: url('bariol_bold-webfont.eot?#iefix') format('embedded-opentype'), 22 | url('bariol_bold-webfont.woff') format('woff'), 23 | url('bariol_bold-webfont.ttf') format('truetype'), 24 | url('bariol_bold-webfont.svg#bariol_boldbold') format('svg'); 25 | font-weight: normal; 26 | font-style: normal; 27 | 28 | } -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": false, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 2, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "strict": true, 18 | "trailing": true, 19 | "smarttabs": true, 20 | "white": false, 21 | "globals": { 22 | "define": false, 23 | "angular": false, 24 | "_": false, 25 | "_V_": false, 26 | "afterEach": false, 27 | "beforeEach": false, 28 | "confirm": false, 29 | "context": false, 30 | "describe": false, 31 | "expect": false, 32 | "it": false, 33 | "inject": false, 34 | "jasmine": false, 35 | "JSHINT": false, 36 | "mostRecentAjaxRequest": false, 37 | "qq": false, 38 | "runs": false, 39 | "spyOn": false, 40 | "spyOnEvent": false, 41 | "waitsFor": false, 42 | "xdescribe": false, 43 | "$": false, 44 | "dump": false 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License 2 | 3 | Copyright (c) 2014 Hidenari Nozaki and contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /angucomplete-alt.css: -------------------------------------------------------------------------------- 1 | .angucomplete-holder { 2 | position: relative; 3 | } 4 | 5 | .angucomplete-dropdown { 6 | border-color: #ececec; 7 | border-width: 1px; 8 | border-style: solid; 9 | border-radius: 2px; 10 | width: 250px; 11 | padding: 6px; 12 | cursor: pointer; 13 | z-index: 9999; 14 | position: absolute; 15 | /*top: 32px; 16 | left: 0px; 17 | */ 18 | margin-top: -6px; 19 | background-color: #ffffff; 20 | } 21 | 22 | .angucomplete-searching { 23 | color: #acacac; 24 | font-size: 14px; 25 | } 26 | 27 | .angucomplete-description { 28 | font-size: 14px; 29 | } 30 | 31 | .angucomplete-row { 32 | padding: 5px; 33 | color: #000000; 34 | margin-bottom: 4px; 35 | clear: both; 36 | } 37 | 38 | .angucomplete-selected-row { 39 | background-color: lightblue; 40 | color: #ffffff; 41 | } 42 | 43 | .angucomplete-image-holder { 44 | padding-top: 2px; 45 | float: left; 46 | margin-right: 10px; 47 | margin-left: 5px; 48 | } 49 | 50 | .angucomplete-image { 51 | height: 34px; 52 | width: 34px; 53 | border-radius: 50%; 54 | border-color: #ececec; 55 | border-style: solid; 56 | border-width: 1px; 57 | } 58 | 59 | .angucomplete-image-default { 60 | /* Add your own default image here 61 | background-image: url('/assets/default.png'); 62 | */ 63 | background-position: center; 64 | background-size: contain; 65 | height: 34px; 66 | width: 34px; 67 | } 68 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function (grunt) { 2 | 'use strict'; 3 | 4 | var initConfig; 5 | 6 | // Loading external tasks 7 | require('load-grunt-tasks')(grunt); 8 | 9 | // Project configuration. 10 | initConfig = { 11 | bower: 'bower_components', 12 | pkg: grunt.file.readJSON('package.json'), 13 | watch: { 14 | test: { 15 | // Lint & run unit tests in Karma 16 | // Just running `$ grunt watch` will only lint your code; to run tests 17 | // on watch, use `$ grunt watch:karma` to start a Karma server first 18 | tasks: ['jshint', 'karma:unit:run'] 19 | } 20 | }, 21 | karma: { 22 | options: { 23 | configFile: 'test/karma.conf.js', 24 | browsers: ['PhantomJS'] 25 | }, 26 | unit: { 27 | singleRun: true 28 | }, 29 | watch: { 30 | autoWatch: true 31 | }, 32 | server: { 33 | background: true 34 | } 35 | }, 36 | jshint: { 37 | all:[ 38 | 'gruntFile.js', 39 | 'angucomplete-alt.js', 40 | 'test/**/*.spec.js' 41 | ], 42 | options: { 43 | jshintrc: '.jshintrc' 44 | } 45 | }, 46 | changelog: { 47 | options: { 48 | dest: 'CHANGELOG.md' 49 | } 50 | }, 51 | uglify: { 52 | options: { 53 | preserveComments: 'some' 54 | }, 55 | build: { 56 | files: { 57 | 'dist/angucomplete-alt.min.js': ['angucomplete-alt.js'] 58 | } 59 | } 60 | } 61 | }; 62 | 63 | // Register tasks 64 | grunt.registerTask('default', ['jshint', 'karma:unit']); 65 | grunt.registerTask('watch', ['jshint', 'karma:watch']); 66 | grunt.registerTask('build', ['jshint', 'uglify:build']); 67 | 68 | grunt.initConfig(initConfig); 69 | }; 70 | 71 | 72 | -------------------------------------------------------------------------------- /test/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | module.exports = function(config) { 3 | config.set({ 4 | 5 | // base path, that will be used to resolve files and exclude 6 | basePath: '..', 7 | 8 | // frameworks to use 9 | frameworks: ['jasmine'], 10 | 11 | // list of files / patterns to load in the browser 12 | files: [ 13 | // Dependencies 14 | 'bower_components/sizzle/dist/sizzle.js', 15 | 'bower_components/jquery/dist/jquery.js', 16 | 'bower_components/angular/angular.js', 17 | 'bower_components/angular-mocks/angular-mocks.js', 18 | 19 | // Source Code 20 | 'angucomplete-alt.js', 21 | 22 | // Test Specs 23 | 'test/*.spec.js' 24 | ], 25 | 26 | // list of files to exclude 27 | exclude: [ 28 | ], 29 | 30 | // test results reporter to use 31 | // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage' 32 | reporters: ['progress'], 33 | 34 | // web server port 35 | port: 9876, 36 | 37 | // enable / disable colors in the output (reporters and logs) 38 | colors: true, 39 | 40 | // level of logging 41 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG 42 | logLevel: config.LOG_INFO, 43 | 44 | // enable / disable watching file and executing tests whenever any file changes 45 | autoWatch: false, 46 | 47 | // Start these browsers, currently available: 48 | // - Chrome 49 | // - ChromeCanary 50 | // - Firefox 51 | // - Opera 52 | // - Safari (only Mac) 53 | // - PhantomJS 54 | // - IE (only Windows) 55 | browsers: ['Chrome'], 56 | 57 | // If browser does not capture in given timeout [ms], kill it 58 | captureTimeout: 60000, 59 | 60 | // Continuous Integration mode 61 | // if true, it capture browsers, run tests and exit 62 | singleRun: false 63 | 64 | }); 65 | }; 66 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # angucomplete-alt contributors (sorted alphabeticaly) 2 | 3 | --- 4 | 5 | ### [@alexbeletsky: Alexander Beletsky](https://github.com/alexbeletsky) 6 | 7 | * Publish to NPM #111, #121 8 | 9 | ### [@alindber: Andy Lindberg](https://github.com/alindber) 10 | 11 | * Required support #23 12 | * Auto match #29 13 | 14 | ### [@andretw: Andre Lee](https://github.com/andretw) 15 | 16 | * Bug fix #109 17 | 18 | ### [@annmirosh](https://github.com/annmirosh) 19 | 20 | * Fix input event for mobile device #232 #178 21 | 22 | ### [@antony: Antony Jones](https://github.com/antony) 23 | 24 | * Allow the user to set an initial value OBJECT instead of just a string #173 25 | * Documentation update #180 26 | 27 | ### [@artvlasov](https://github.com/artvlasov) 28 | 29 | * Implemented changeInput event listener to set input value #260 30 | 31 | ### [@baloo2401](https://github.com/baloo2401) 32 | 33 | * display-searching and display-no-result #129 34 | 35 | ### [@boshen](https://github.com/Boshen) 36 | 37 | * Collaborator and excellent developer 38 | * Add autocapitalize="off" autocorrect="off" autocomplete="off" #15 39 | 40 | ### [@davidgeary: David Geary](https://github.com/davidgeary) 41 | 42 | * Missing 'type' field on input element when not specified #167 43 | 44 | ### [@elkami12](https://github.com/elkami12) 45 | 46 | * Fix for issue #426 (Not found" when an external request is cancelled) #427 47 | 48 | ### [@federicojasson: Federico Jasson](https://github.com/federicojasson) 49 | 50 | * Fix auto-match #245 #246 51 | 52 | ### [@ferfabricio: Fernando Fabricio dos Santos](https://github.com/ferfabricio) 53 | 54 | * Update README #439 55 | 56 | ### [@fkeusch](https://github.com/fkeusch) 57 | 58 | * Add tabindex #311 #57 59 | 60 | ### [@Freezystem: Nico](https://github.com/Freezystem) 61 | 62 | * Add focus-first #92 #242 63 | 64 | ### [@ggillyb: Gilly Barr](https://github.com/ggillyb) 65 | 66 | * stop displaying 'searching' message on error #336 67 | 68 | ### [@glaggia-larus: Gianmarco Laggia](https://github.com/glaggia-larus) 69 | 70 | * Pass textSearching and textNoResult with @ #357 71 | 72 | ### [@handiwijoyo: Handi Wijoyo](https://github.com/handiwijoyo) 73 | 74 | * Add css to bower.json main #68 75 | 76 | ### [@iamgurdip](https://github.com/iamgurdip) 77 | 78 | * Escape regular expression #123 79 | 80 | ### [@JaZo: Jasper Zonneveld](https://github.com/JaZo) 81 | 82 | * Pass textSearching and textNoResult with @ #335 83 | * Show text-searching on focus or when input becomes empty with minlength=0 #378 84 | * Normalize return object before we check the status #421 85 | 86 | ### [@jesusr: Jesús R Peinado](https://github.com/jesusr) 87 | 88 | * Adding parseInput function parameter #294 89 | 90 | ### [@jbuquet: Javier Buquet](https://github.com/jbuquet) 91 | 92 | * Add custom API handler #128 93 | 94 | ### [@jermspeaks: Jeremy Wong](https://github.com/jermspeaks) 95 | 96 | * Support withCredentials for $http #113 97 | 98 | ### [@JohannesFerner: Johannes Ferner](https://github.com/JohannesFerner) 99 | 100 | * Add an example on clearInput event #225 #252 101 | 102 | ### [@johanye: Hang Ye](https://github.com/johanye) 103 | 104 | * Make localData accessible to local search function #343 105 | 106 | ### [@Leocrest](https://github.com/Leocrest) 107 | 108 | * Clear input #61 109 | 110 | ### [@loren138](https://github.com/loren138) 111 | 112 | * Update the package file and contribution instructions #372 113 | * Pass data variable to select function #373 114 | 115 | ### [@mcnocopo: Pachito Marco Calabrese](https://github.com/mcnocopo) 116 | 117 | * Add input name and a not-empty class #124 118 | 119 | ### [@mmBs](https://github.com/mmBs) 120 | 121 | * Add type attribute #96 122 | 123 | ### [@mrdevin: David Hartman](https://github.com/mrdevin) 124 | 125 | * Set the form field to valid when the initialValue is added #59 126 | 127 | ### [@nekcih](https://github.com/nekcih) 128 | 129 | * New callback handler, response translator, better template code format, and css fix #6 130 | * Fixed support for IE8 #13 131 | 132 | ### [@nhim175: Thinh Pham](https://github.com/nhim175) 133 | 134 | * Adding support for IMEs #430 135 | 136 | ### [@peterjkirby: Peter Kirby](https://github.com/peterjkirby) 137 | 138 | * Bug fix #97 139 | 140 | ### [@postama: Adam Postma](https://github.com/postama) 141 | 142 | * Change to use promises instead of success/catch. #442 143 | 144 | ### [@sdbondi: Stan Bondi](https://github.com/sdbondi) 145 | 146 | * Custom template #74 147 | 148 | ### [@SpaceK33z: Kees Kluskens](https://github.com/SpaceK33z) 149 | 150 | * Bug fix #62 151 | 152 | ### [@termleech](https://github.com/termleech) 153 | 154 | * Add maxlength #136 155 | 156 | ### [@thetrevdev: Trevor](https://github.com/thetrevdev) 157 | 158 | * Move strict directive #324 159 | 160 | ### [@tomgutz: Tomas Gutierrez](https://github.com/tomgutz) 161 | 162 | * Added delete keystroke together with backspace #4 163 | 164 | ### [@tuduong2](https://github.com/tuduong2) 165 | 166 | * Encode search parameter #119 167 | 168 | ### [@urecio](https://github.com/urecio) 169 | 170 | * Added input changed callback #12 171 | 172 | ### [@vhuerta: Victor Huerta Hernández](https://github.com/vhuerta) 173 | 174 | * Custom strings for "searching" and "no results" #22 175 | 176 | ### [@YasuhiroYoshida: Yasuhiro Yoshida](https://github.com/YasuhiroYoshida) 177 | 178 | * Fix pressing enter without selecting an item results in "No results found" message #31 179 | * Implement 'update input field' #42 180 | 181 | 182 | -------------------------------------------------------------------------------- /example/js/libs/json3.min.js: -------------------------------------------------------------------------------- 1 | /*! JSON v3.2.6 | http://bestiejs.github.io/json3 | Copyright 2012-2013, Kit Cambridge | http://kit.mit-license.org */ 2 | ;(function(){var n=null; 3 | (function(G){function m(a){if(m[a]!==s)return m[a];var c;if("bug-string-char-index"==a)c="a"!="a"[0];else if("json"==a)c=m("json-stringify")&&m("json-parse");else{var e;if("json-stringify"==a){c=o.stringify;var b="function"==typeof c&&l;if(b){(e=function(){return 1}).toJSON=e;try{b="0"===c(0)&&"0"===c(new Number)&&'""'==c(new String)&&c(p)===s&&c(s)===s&&c()===s&&"1"===c(e)&&"[1]"==c([e])&&"[null]"==c([s])&&"null"==c(n)&&"[null,null,null]"==c([s,p,n])&&'{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'==c({a:[e, 4 | !0,!1,n,"\x00\u0008\n\u000c\r\t"]})&&"1"===c(n,e)&&"[\n 1,\n 2\n]"==c([1,2],n,1)&&'"-271821-04-20T00:00:00.000Z"'==c(new Date(-864E13))&&'"+275760-09-13T00:00:00.000Z"'==c(new Date(864E13))&&'"-000001-01-01T00:00:00.000Z"'==c(new Date(-621987552E5))&&'"1969-12-31T23:59:59.999Z"'==c(new Date(-1))}catch(f){b=!1}}c=b}if("json-parse"==a){c=o.parse;if("function"==typeof c)try{if(0===c("0")&&!c(!1)){e=c('{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}');var j=5==e.a.length&&1===e.a[0];if(j){try{j=!c('"\t"')}catch(d){}if(j)try{j= 5 | 1!==c("01")}catch(h){}if(j)try{j=1!==c("1.")}catch(k){}}}}catch(N){j=!1}c=j}}return m[a]=!!c}var p={}.toString,q,x,s,H=typeof define==="function"&&define.amd,y="object"==typeof JSON&&JSON,o="object"==typeof exports&&exports&&!exports.nodeType&&exports;o&&y?(o.stringify=y.stringify,o.parse=y.parse):o=G.JSON=y||{};var l=new Date(-3509827334573292);try{l=-109252==l.getUTCFullYear()&&0===l.getUTCMonth()&&1===l.getUTCDate()&&10==l.getUTCHours()&&37==l.getUTCMinutes()&&6==l.getUTCSeconds()&&708==l.getUTCMilliseconds()}catch(O){}if(!m("json")){var t= 6 | m("bug-string-char-index");if(!l)var u=Math.floor,I=[0,31,59,90,120,151,181,212,243,273,304,334],z=function(a,c){return I[c]+365*(a-1970)+u((a-1969+(c=+(c>1)))/4)-u((a-1901+c)/100)+u((a-1601+c)/400)};if(!(q={}.hasOwnProperty))q=function(a){var c={},e;if((c.__proto__=n,c.__proto__={toString:1},c).toString!=p)q=function(a){var c=this.__proto__,a=a in(this.__proto__=n,this);this.__proto__=c;return a};else{e=c.constructor;q=function(a){var c=(this.constructor||e).prototype;return a in this&&!(a in c&& 7 | this[a]===c[a])}}c=n;return q.call(this,a)};var J={"boolean":1,number:1,string:1,undefined:1};x=function(a,c){var e=0,b,f,j;(b=function(){this.valueOf=0}).prototype.valueOf=0;f=new b;for(j in f)q.call(f,j)&&e++;b=f=n;if(e)x=e==2?function(a,c){var e={},b=p.call(a)=="[object Function]",f;for(f in a)!(b&&f=="prototype")&&!q.call(e,f)&&(e[f]=1)&&q.call(a,f)&&c(f)}:function(a,c){var e=p.call(a)=="[object Function]",b,f;for(b in a)!(e&&b=="prototype")&&q.call(a,b)&&!(f=b==="constructor")&&c(b);(f||q.call(a, 8 | b="constructor"))&&c(b)};else{f=["valueOf","toString","toLocaleString","propertyIsEnumerable","isPrototypeOf","hasOwnProperty","constructor"];x=function(a,c){var e=p.call(a)=="[object Function]",b,g;if(g=!e)if(g=typeof a.constructor!="function"){g=typeof a.hasOwnProperty;g=g=="object"?!!a.hasOwnProperty:!J[g]}g=g?a.hasOwnProperty:q;for(b in a)!(e&&b=="prototype")&&g.call(a,b)&&c(b);for(e=f.length;b=f[--e];g.call(a,b)&&c(b));}}return x(a,c)};if(!m("json-stringify")){var K={92:"\\\\",34:'\\"',8:"\\b", 9 | 12:"\\f",10:"\\n",13:"\\r",9:"\\t"},v=function(a,c){return("000000"+(c||0)).slice(-a)},D=function(a){var c='"',b=0,g=a.length,f=g>10&&t,j;for(f&&(j=a.split(""));b-1/0&&h<1/0){if(z){l=u(h/864E5);for(k=u(l/365.2425)+1970-1;z(k+1,0)<=l;k++);for(i=u((l-z(k,0))/30.42);z(k,i+1)<=l;i++);l=1+l-z(k,i);m=(h%864E5+864E5)%864E5;o=u(m/36E5)%24;r=u(m/6E4)%60;t=u(m/1E3)%60;m=m%1E3}else{k=h.getUTCFullYear();i=h.getUTCMonth();l=h.getUTCDate();o=h.getUTCHours();r=h.getUTCMinutes();t=h.getUTCSeconds();m=h.getUTCMilliseconds()}h=(k<=0||k>=1E4?(k<0?"-":"+")+v(6,k<0?-k:k):v(4,k))+"-"+v(2,i+1)+"-"+v(2,l)+"T"+v(2,o)+":"+v(2,r)+":"+v(2,t)+"."+v(3,m)+"Z"}else h= 11 | n;else if(typeof h.toJSON=="function"&&(k!="[object Number]"&&k!="[object String]"&&k!="[object Array]"||q.call(h,"toJSON")))h=h.toJSON(a)}b&&(h=b.call(c,a,h));if(h===n)return"null";k=p.call(h);if(k=="[object Boolean]")return""+h;if(k=="[object Number]")return h>-1/0&&h<1/0?""+h:"null";if(k=="[object String]")return D(""+h);if(typeof h=="object"){for(a=d.length;a--;)if(d[a]===h)throw TypeError();d.push(h);w=[];c=j;j=j+f;if(k=="[object Array]"){i=0;for(a=h.length;i0){g="";for(b>10&&(b=10);g.length=48&&d<=57||d>=97&&d<=102||d>=65&&d<=70||i()}e=e+L("0x"+a.slice(g,b));break;default:i()}}else{if(d==34)break;d=a.charCodeAt(b);for(g=b;d>=32&&d!=92&&d!=34;)d=a.charCodeAt(++b); 15 | e=e+a.slice(g,b)}}if(a.charCodeAt(b)==34){b++;return e}i();default:g=b;if(d==45){j=true;d=a.charCodeAt(++b)}if(d>=48&&d<=57){for(d==48&&(d=a.charCodeAt(b+1),d>=48&&d<=57)&&i();b=48&&d<=57);b++);if(a.charCodeAt(b)==46){for(f=++b;f=48&&d<=57);f++);f==b&&i();b=f}d=a.charCodeAt(b);if(d==101||d==69){d=a.charCodeAt(++b);(d==43||d==45)&&b++;for(f=b;f=48&&d<=57);f++);f==b&&i();b=f}return+a.slice(g,b)}j&&i();if(a.slice(b,b+4)=="true"){b= 16 | b+4;return true}if(a.slice(b,b+5)=="false"){b=b+5;return false}if(a.slice(b,b+4)=="null"){b=b+4;return n}i()}}return"$"},C=function(a){var c,b;a=="$"&&i();if(typeof a=="string"){if((t?a.charAt(0):a[0])=="@")return a.slice(1);if(a=="["){for(c=[];;b||(b=true)){a=r();if(a=="]")break;if(b)if(a==","){a=r();a=="]"&&i()}else i();a==","&&i();c.push(C(a))}return c}if(a=="{"){for(c={};;b||(b=true)){a=r();if(a=="}")break;if(b)if(a==","){a=r();a=="}"&&i()}else i();(a==","||typeof a!="string"||(t?a.charAt(0): 17 | a[0])!="@"||r()!=":")&&i();c[a.slice(1)]=C(r())}return c}i()}return a},F=function(a,b,e){e=E(a,b,e);e===s?delete a[b]:a[b]=e},E=function(a,b,e){var g=a[b],f;if(typeof g=="object"&&g)if(p.call(g)=="[object Array]")for(f=g.length;f--;)F(g,f,e);else x(g,function(a){F(g,a,e)});return e.call(a,b,g)};o.parse=function(a,c){var e,g;b=0;A=""+a;e=C(r());r()!="$"&&i();b=A=n;return c&&p.call(c)=="[object Function]"?E((g={},g[""]=e,g),"",c):e}}}H&&define(function(){return o})})(this); 18 | }()); -------------------------------------------------------------------------------- /dist/angucomplete-alt.min.js: -------------------------------------------------------------------------------- 1 | /*! Copyright (c) 2014 Hidenari Nozaki and contributors | Licensed under the MIT license */ 2 | !function(a,b){"use strict";"undefined"!=typeof module&&module.exports?module.exports=b(require("angular")):"function"==typeof define&&define.amd?define(["angular"],b):b(a.angular)}(window,function(a){"use strict";a.module("angucomplete-alt",[]).directive("angucompleteAlt",["$q","$parse","$http","$sce","$timeout","$templateCache","$interpolate",function(a,b,c,d,e,f,g){function h(b,f,g,h){function w(a,c){a&&("object"==typeof a?(b.searchStr=C(a),z({originalObject:a})):"string"==typeof a&&a.length>0?b.searchStr=a:console&&console.error&&console.error("Tried to set "+(c?"initial":"")+" value of angucomplete to",a,"which is an invalid value"),F(!0))}function x(a){na=null,b.hideResults(a),document.body.removeEventListener("click",x)}function y(a){return a.which?a.which:a.keyCode}function z(a){"function"==typeof b.selectedObject?b.selectedObject(a,b.selectedObjectData):b.selectedObject=a,F(a?!0:!1)}function A(a){return function(c){return b[a]?b[a](c):c}}function B(a){z({originalObject:a}),b.clearSelected&&(b.searchStr=null),U()}function C(a){return b.titleField.split(",").map(function(b){return D(a,b)}).join(" ")}function D(a,b){var c,d;if(b){c=b.split("."),d=a;for(var e=0;e'+f[0]+""):a,d.trustAsHtml(e)}function F(a){b.notEmpty=a,ia=b.searchStr,b.fieldRequired&&h&&b.inputName&&h[b.inputName].$setValidity(ha,a)}function G(a){var c=y(a);if(c!==l&&c!==j)if(c===k||c===n)a.preventDefault();else if(c===i)a.preventDefault(),!b.showDropdown&&b.searchStr&&b.searchStr.length>=fa&&(V(),b.searching=!0,Y(b.searchStr));else if(c===m)U(),b.$apply(function(){ea.val(b.searchStr)});else{if(0===fa&&!b.searchStr)return;b.searchStr&&""!==b.searchStr?b.searchStr.length>=fa&&(V(),ga&&e.cancel(ga),b.searching=!0,ga=e(function(){Y(b.searchStr)},b.pause)):b.showDropdown=!1,ia&&ia!==b.searchStr&&!b.clearSelected&&b.$apply(function(){z()})}}function H(a){!b.overrideSuggestions||b.selectedObject&&b.selectedObject.originalObject===b.searchStr||(a&&a.preventDefault(),e.cancel(ga),R(),B(b.searchStr))}function I(a){var b=getComputedStyle(a);return a.offsetHeight+parseInt(b.marginTop,10)+parseInt(b.marginBottom,10)}function J(){return la.getBoundingClientRect().top+parseInt(getComputedStyle(la).maxHeight,10)}function K(){return f[0].querySelectorAll(".angucomplete-row")[b.currentIndex]}function L(){return K().getBoundingClientRect().top-(la.getBoundingClientRect().top+parseInt(getComputedStyle(la).paddingTop,10))}function M(a){la.scrollTop=la.scrollTop+a}function N(){var a=b.results[b.currentIndex];b.matchClass?ea.val(C(a.originalObject)):ea.val(a.title)}function O(a){var c=y(a),d=null,e=null;c===n&&b.results?(b.currentIndex>=0&&b.currentIndex=1?(b.$apply(function(){b.currentIndex--,N()}),ma&&(e=L(),e<0&&M(e-1))):0===b.currentIndex&&b.$apply(function(){b.currentIndex=-1,ea.val(b.searchStr)})):c===o?b.results&&b.results.length>0&&b.showDropdown?b.currentIndex===-1&&b.overrideSuggestions?H():(b.currentIndex===-1&&(b.currentIndex=0),b.selectResult(b.results[b.currentIndex]),b.$digest()):b.searchStr&&b.searchStr.length>0&&H():c===m&&a.preventDefault()}function P(a){return function(c,d,e,f){d||e||f||!c.data||(c=c.data),b.searching=!1,Z(D(aa(c),b.remoteUrlDataField),a)}}function Q(a,c,d,e){b.searching=ka,c||d||e||(c=a.status),0!==c&&c!==-1&&(b.remoteUrlErrorCallback?b.remoteUrlErrorCallback(a,c,d,e):console&&console.error&&console.error("http error"))}function R(){ja&&ja.resolve()}function S(d){var e={},f=b.remoteUrl+encodeURIComponent(d);b.remoteUrlRequestFormatter&&(e={params:b.remoteUrlRequestFormatter(d)},f=b.remoteUrl),b.remoteUrlRequestWithCredentials&&(e.withCredentials=!0),R(),ja=a.defer(),e.timeout=ja.promise,ka=!0,c.get(f,e).then(P(d)).catch(Q).finally(function(){ka=!1})}function T(c){R(),ja=a.defer(),b.remoteApiHandler(c,ja.promise).then(P(c)).catch(Q)}function U(){b.showDropdown=!1,b.results=[],la&&(la.scrollTop=0)}function V(){b.showDropdown=ca,b.currentIndex=b.focusFirst?0:-1,b.results=[]}function W(a){var c,d,e,f,g=b.searchFields.split(","),h=[];for("undefined"!=typeof b.parseInput()&&(a=b.parseInput()(a)),c=0;c=0;d&&(h[h.length]=b.localData[c])}return h}function X(a,c,d){if(!d)return!1;for(var e in c)if(c[e].toLowerCase()===d.toLowerCase())return b.selectResult(a),!0;return!1}function Y(a){!a||a.length0)for(b.results=[],d=0;d=0)?na=null:(_=e(function(){U(),b.$apply(function(){b.searchStr&&b.searchStr.length>0&&ea.val(b.searchStr)})},s),R(),b.focusOut&&b.focusOut(),b.overrideSuggestions&&b.searchStr&&b.searchStr.length>0&&b.currentIndex===-1&&H())},b.resetHideResults=function(){_&&e.cancel(_)},b.hoverRow=function(a){b.currentIndex=a},b.selectResult=function(a){b.matchClass&&(a.title=C(a.originalObject),a.description=D(a.originalObject,b.descriptionField)),b.clearSelected?b.searchStr=null:b.searchStr=a.title,z(a),U()},b.inputChangeHandler=function(a){return a.length
{{ result.title }}
{{result.description}}
'),{restrict:"EA",require:"^?form",scope:{selectedObject:"=",selectedObjectData:"=",disableInput:"=",initialValue:"=",localData:"=",localSearch:"&",remoteUrlRequestFormatter:"=",remoteUrlRequestWithCredentials:"@",remoteUrlResponseFormatter:"=",remoteUrlErrorCallback:"=",remoteApiHandler:"=",id:"@",type:"@",placeholder:"@",textSearching:"@",textNoResults:"@",remoteUrl:"@",remoteUrlDataField:"@",titleField:"@",descriptionField:"@",imageField:"@",inputClass:"@",pause:"@",searchFields:"@",minlength:"@",matchClass:"@",clearSelected:"@",overrideSuggestions:"@",fieldRequired:"=",fieldRequiredClass:"@",inputChanged:"=",autoMatch:"@",focusOut:"&",focusIn:"&",fieldTabindex:"@",inputName:"@",focusFirst:"@",parseInput:"&"},templateUrl:function(a,b){return b.templateUrl||w},compile:function(a){var b=g.startSymbol(),c=g.endSymbol();if("{{"!==b||"}}"!==c){var d=a.html().replace(/\{\{/g,b).replace(/\}\}/g,c);a.html(d)}return h}}}])}); -------------------------------------------------------------------------------- /example/countries.json: -------------------------------------------------------------------------------- 1 | {"data": 2 | [ 3 | {"name": "Afghanistan", "code": "AF"}, 4 | {"name": "Aland Islands", "code": "AX"}, 5 | {"name": "Albania", "code": "AL"}, 6 | {"name": "Algeria", "code": "DZ"}, 7 | {"name": "American Samoa", "code": "AS"}, 8 | {"name": "AndorrA", "code": "AD"}, 9 | {"name": "Angola", "code": "AO"}, 10 | {"name": "Anguilla", "code": "AI"}, 11 | {"name": "Antarctica", "code": "AQ"}, 12 | {"name": "Antigua and Barbuda", "code": "AG"}, 13 | {"name": "Argentina", "code": "AR"}, 14 | {"name": "Armenia", "code": "AM"}, 15 | {"name": "Aruba", "code": "AW"}, 16 | {"name": "Australia", "code": "AU"}, 17 | {"name": "Austria", "code": "AT"}, 18 | {"name": "Azerbaijan", "code": "AZ"}, 19 | {"name": "Bahamas", "code": "BS"}, 20 | {"name": "Bahrain", "code": "BH"}, 21 | {"name": "Bangladesh", "code": "BD"}, 22 | {"name": "Barbados", "code": "BB"}, 23 | {"name": "Belarus", "code": "BY"}, 24 | {"name": "Belgium", "code": "BE"}, 25 | {"name": "Belize", "code": "BZ"}, 26 | {"name": "Benin", "code": "BJ"}, 27 | {"name": "Bermuda", "code": "BM"}, 28 | {"name": "Bhutan", "code": "BT"}, 29 | {"name": "Bolivia", "code": "BO"}, 30 | {"name": "Bosnia and Herzegovina", "code": "BA"}, 31 | {"name": "Botswana", "code": "BW"}, 32 | {"name": "Bouvet Island", "code": "BV"}, 33 | {"name": "Brazil", "code": "BR"}, 34 | {"name": "British Indian Ocean Territory", "code": "IO"}, 35 | {"name": "Brunei Darussalam", "code": "BN"}, 36 | {"name": "Bulgaria", "code": "BG"}, 37 | {"name": "Burkina Faso", "code": "BF"}, 38 | {"name": "Burundi", "code": "BI"}, 39 | {"name": "Cambodia", "code": "KH"}, 40 | {"name": "Cameroon", "code": "CM"}, 41 | {"name": "Canada", "code": "CA"}, 42 | {"name": "Cape Verde", "code": "CV"}, 43 | {"name": "Cayman Islands", "code": "KY"}, 44 | {"name": "Central African Republic", "code": "CF"}, 45 | {"name": "Chad", "code": "TD"}, 46 | {"name": "Chile", "code": "CL"}, 47 | {"name": "China", "code": "CN"}, 48 | {"name": "Christmas Island", "code": "CX"}, 49 | {"name": "Cocos (Keeling) Islands", "code": "CC"}, 50 | {"name": "Colombia", "code": "CO"}, 51 | {"name": "Comoros", "code": "KM"}, 52 | {"name": "Congo", "code": "CG"}, 53 | {"name": "Congo, The Democratic Republic of the", "code": "CD"}, 54 | {"name": "Cook Islands", "code": "CK"}, 55 | {"name": "Costa Rica", "code": "CR"}, 56 | {"name": "Cote D\"Ivoire", "code": "CI"}, 57 | {"name": "Croatia", "code": "HR"}, 58 | {"name": "Cuba", "code": "CU"}, 59 | {"name": "Cyprus", "code": "CY"}, 60 | {"name": "Czech Republic", "code": "CZ"}, 61 | {"name": "Denmark", "code": "DK"}, 62 | {"name": "Djibouti", "code": "DJ"}, 63 | {"name": "Dominica", "code": "DM"}, 64 | {"name": "Dominican Republic", "code": "DO"}, 65 | {"name": "Ecuador", "code": "EC"}, 66 | {"name": "Egypt", "code": "EG"}, 67 | {"name": "El Salvador", "code": "SV"}, 68 | {"name": "Equatorial Guinea", "code": "GQ"}, 69 | {"name": "Eritrea", "code": "ER"}, 70 | {"name": "Estonia", "code": "EE"}, 71 | {"name": "Ethiopia", "code": "ET"}, 72 | {"name": "Falkland Islands (Malvinas)", "code": "FK"}, 73 | {"name": "Faroe Islands", "code": "FO"}, 74 | {"name": "Fiji", "code": "FJ"}, 75 | {"name": "Finland", "code": "FI"}, 76 | {"name": "France", "code": "FR"}, 77 | {"name": "French Guiana", "code": "GF"}, 78 | {"name": "French Polynesia", "code": "PF"}, 79 | {"name": "French Southern Territories", "code": "TF"}, 80 | {"name": "Gabon", "code": "GA"}, 81 | {"name": "Gambia", "code": "GM"}, 82 | {"name": "Georgia", "code": "GE"}, 83 | {"name": "Germany", "code": "DE"}, 84 | {"name": "Ghana", "code": "GH"}, 85 | {"name": "Gibraltar", "code": "GI"}, 86 | {"name": "Greece", "code": "GR"}, 87 | {"name": "Greenland", "code": "GL"}, 88 | {"name": "Grenada", "code": "GD"}, 89 | {"name": "Guadeloupe", "code": "GP"}, 90 | {"name": "Guam", "code": "GU"}, 91 | {"name": "Guatemala", "code": "GT"}, 92 | {"name": "Guernsey", "code": "GG"}, 93 | {"name": "Guinea", "code": "GN"}, 94 | {"name": "Guinea-Bissau", "code": "GW"}, 95 | {"name": "Guyana", "code": "GY"}, 96 | {"name": "Haiti", "code": "HT"}, 97 | {"name": "Heard Island and Mcdonald Islands", "code": "HM"}, 98 | {"name": "Holy See (Vatican City State)", "code": "VA"}, 99 | {"name": "Honduras", "code": "HN"}, 100 | {"name": "Hong Kong", "code": "HK"}, 101 | {"name": "Hungary", "code": "HU"}, 102 | {"name": "Iceland", "code": "IS"}, 103 | {"name": "India", "code": "IN"}, 104 | {"name": "Indonesia", "code": "ID"}, 105 | {"name": "Iran, Islamic Republic Of", "code": "IR"}, 106 | {"name": "Iraq", "code": "IQ"}, 107 | {"name": "Ireland", "code": "IE"}, 108 | {"name": "Isle of Man", "code": "IM"}, 109 | {"name": "Israel", "code": "IL"}, 110 | {"name": "Italy", "code": "IT"}, 111 | {"name": "Jamaica", "code": "JM"}, 112 | {"name": "Japan", "code": "JP"}, 113 | {"name": "Jersey", "code": "JE"}, 114 | {"name": "Jordan", "code": "JO"}, 115 | {"name": "Kazakhstan", "code": "KZ"}, 116 | {"name": "Kenya", "code": "KE"}, 117 | {"name": "Kiribati", "code": "KI"}, 118 | {"name": "Korea, Democratic People\"S Republic of", "code": "KP"}, 119 | {"name": "Korea, Republic of", "code": "KR"}, 120 | {"name": "Kuwait", "code": "KW"}, 121 | {"name": "Kyrgyzstan", "code": "KG"}, 122 | {"name": "Lao People\"S Democratic Republic", "code": "LA"}, 123 | {"name": "Latvia", "code": "LV"}, 124 | {"name": "Lebanon", "code": "LB"}, 125 | {"name": "Lesotho", "code": "LS"}, 126 | {"name": "Liberia", "code": "LR"}, 127 | {"name": "Libyan Arab Jamahiriya", "code": "LY"}, 128 | {"name": "Liechtenstein", "code": "LI"}, 129 | {"name": "Lithuania", "code": "LT"}, 130 | {"name": "Luxembourg", "code": "LU"}, 131 | {"name": "Macao", "code": "MO"}, 132 | {"name": "Macedonia, The Former Yugoslav Republic of", "code": "MK"}, 133 | {"name": "Madagascar", "code": "MG"}, 134 | {"name": "Malawi", "code": "MW"}, 135 | {"name": "Malaysia", "code": "MY"}, 136 | {"name": "Maldives", "code": "MV"}, 137 | {"name": "Mali", "code": "ML"}, 138 | {"name": "Malta", "code": "MT"}, 139 | {"name": "Marshall Islands", "code": "MH"}, 140 | {"name": "Martinique", "code": "MQ"}, 141 | {"name": "Mauritania", "code": "MR"}, 142 | {"name": "Mauritius", "code": "MU"}, 143 | {"name": "Mayotte", "code": "YT"}, 144 | {"name": "Mexico", "code": "MX"}, 145 | {"name": "Micronesia, Federated States of", "code": "FM"}, 146 | {"name": "Moldova, Republic of", "code": "MD"}, 147 | {"name": "Monaco", "code": "MC"}, 148 | {"name": "Mongolia", "code": "MN"}, 149 | {"name": "Montserrat", "code": "MS"}, 150 | {"name": "Morocco", "code": "MA"}, 151 | {"name": "Mozambique", "code": "MZ"}, 152 | {"name": "Myanmar", "code": "MM"}, 153 | {"name": "Namibia", "code": "NA"}, 154 | {"name": "Nauru", "code": "NR"}, 155 | {"name": "Nepal", "code": "NP"}, 156 | {"name": "Netherlands", "code": "NL"}, 157 | {"name": "Netherlands Antilles", "code": "AN"}, 158 | {"name": "New Caledonia", "code": "NC"}, 159 | {"name": "New Zealand", "code": "NZ"}, 160 | {"name": "Nicaragua", "code": "NI"}, 161 | {"name": "Niger", "code": "NE"}, 162 | {"name": "Nigeria", "code": "NG"}, 163 | {"name": "Niue", "code": "NU"}, 164 | {"name": "Norfolk Island", "code": "NF"}, 165 | {"name": "Northern Mariana Islands", "code": "MP"}, 166 | {"name": "Norway", "code": "NO"}, 167 | {"name": "Oman", "code": "OM"}, 168 | {"name": "Pakistan", "code": "PK"}, 169 | {"name": "Palau", "code": "PW"}, 170 | {"name": "Palestinian Territory, Occupied", "code": "PS"}, 171 | {"name": "Panama", "code": "PA"}, 172 | {"name": "Papua New Guinea", "code": "PG"}, 173 | {"name": "Paraguay", "code": "PY"}, 174 | {"name": "Peru", "code": "PE"}, 175 | {"name": "Philippines", "code": "PH"}, 176 | {"name": "Pitcairn", "code": "PN"}, 177 | {"name": "Poland", "code": "PL"}, 178 | {"name": "Portugal", "code": "PT"}, 179 | {"name": "Puerto Rico", "code": "PR"}, 180 | {"name": "Qatar", "code": "QA"}, 181 | {"name": "Reunion", "code": "RE"}, 182 | {"name": "Romania", "code": "RO"}, 183 | {"name": "Russian Federation", "code": "RU"}, 184 | {"name": "RWANDA", "code": "RW"}, 185 | {"name": "Saint Helena", "code": "SH"}, 186 | {"name": "Saint Kitts and Nevis", "code": "KN"}, 187 | {"name": "Saint Lucia", "code": "LC"}, 188 | {"name": "Saint Pierre and Miquelon", "code": "PM"}, 189 | {"name": "Saint Vincent and the Grenadines", "code": "VC"}, 190 | {"name": "Samoa", "code": "WS"}, 191 | {"name": "San Marino", "code": "SM"}, 192 | {"name": "Sao Tome and Principe", "code": "ST"}, 193 | {"name": "Saudi Arabia", "code": "SA"}, 194 | {"name": "Senegal", "code": "SN"}, 195 | {"name": "Serbia and Montenegro", "code": "CS"}, 196 | {"name": "Seychelles", "code": "SC"}, 197 | {"name": "Sierra Leone", "code": "SL"}, 198 | {"name": "Singapore", "code": "SG"}, 199 | {"name": "Slovakia", "code": "SK"}, 200 | {"name": "Slovenia", "code": "SI"}, 201 | {"name": "Solomon Islands", "code": "SB"}, 202 | {"name": "Somalia", "code": "SO"}, 203 | {"name": "South Africa", "code": "ZA"}, 204 | {"name": "South Georgia and the South Sandwich Islands", "code": "GS"}, 205 | {"name": "Spain", "code": "ES"}, 206 | {"name": "Sri Lanka", "code": "LK"}, 207 | {"name": "Sudan", "code": "SD"}, 208 | {"name": "Suriname", "code": "SR"}, 209 | {"name": "Svalbard and Jan Mayen", "code": "SJ"}, 210 | {"name": "Swaziland", "code": "SZ"}, 211 | {"name": "Sweden", "code": "SE"}, 212 | {"name": "Switzerland", "code": "CH"}, 213 | {"name": "Syrian Arab Republic", "code": "SY"}, 214 | {"name": "Taiwan, Province of China", "code": "TW"}, 215 | {"name": "Tajikistan", "code": "TJ"}, 216 | {"name": "Tanzania, United Republic of", "code": "TZ"}, 217 | {"name": "Thailand", "code": "TH"}, 218 | {"name": "Timor-Leste", "code": "TL"}, 219 | {"name": "Togo", "code": "TG"}, 220 | {"name": "Tokelau", "code": "TK"}, 221 | {"name": "Tonga", "code": "TO"}, 222 | {"name": "Trinidad and Tobago", "code": "TT"}, 223 | {"name": "Tunisia", "code": "TN"}, 224 | {"name": "Turkey", "code": "TR"}, 225 | {"name": "Turkmenistan", "code": "TM"}, 226 | {"name": "Turks and Caicos Islands", "code": "TC"}, 227 | {"name": "Tuvalu", "code": "TV"}, 228 | {"name": "Uganda", "code": "UG"}, 229 | {"name": "Ukraine", "code": "UA"}, 230 | {"name": "United Arab Emirates", "code": "AE"}, 231 | {"name": "United Kingdom", "code": "GB"}, 232 | {"name": "United States", "code": "US"}, 233 | {"name": "United States Minor Outlying Islands", "code": "UM"}, 234 | {"name": "Uruguay", "code": "UY"}, 235 | {"name": "Uzbekistan", "code": "UZ"}, 236 | {"name": "Vanuatu", "code": "VU"}, 237 | {"name": "Venezuela", "code": "VE"}, 238 | {"name": "Vietnam", "code": "VN"}, 239 | {"name": "Virgin Islands, British", "code": "VG"}, 240 | {"name": "Virgin Islands, U.S.", "code": "VI"}, 241 | {"name": "Wallis and Futuna", "code": "WF"}, 242 | {"name": "Western Sahara", "code": "EH"}, 243 | {"name": "Yemen", "code": "YE"}, 244 | {"name": "Zambia", "code": "ZM"}, 245 | {"name": "Zimbabwe", "code": "ZW"} 246 | ] 247 | } 248 | -------------------------------------------------------------------------------- /example/js/libs/es5-shim.min.js: -------------------------------------------------------------------------------- 1 | (function(definition){if(typeof define=="function"){define(definition)}else if(typeof YUI=="function"){YUI.add("es5",definition)}else{definition()}})(function(){function Empty(){}if(!Function.prototype.bind){Function.prototype.bind=function bind(that){var target=this;if(typeof target!="function"){throw new TypeError("Function.prototype.bind called on incompatible "+target)}var args=_Array_slice_.call(arguments,1);var bound=function(){if(this instanceof bound){var result=target.apply(this,args.concat(_Array_slice_.call(arguments)));if(Object(result)===result){return result}return this}else{return target.apply(that,args.concat(_Array_slice_.call(arguments)))}};if(target.prototype){Empty.prototype=target.prototype;bound.prototype=new Empty;Empty.prototype=null}return bound}}var call=Function.prototype.call;var prototypeOfArray=Array.prototype;var prototypeOfObject=Object.prototype;var _Array_slice_=prototypeOfArray.slice;var _toString=call.bind(prototypeOfObject.toString);var owns=call.bind(prototypeOfObject.hasOwnProperty);var defineGetter;var defineSetter;var lookupGetter;var lookupSetter;var supportsAccessors;if(supportsAccessors=owns(prototypeOfObject,"__defineGetter__")){defineGetter=call.bind(prototypeOfObject.__defineGetter__);defineSetter=call.bind(prototypeOfObject.__defineSetter__);lookupGetter=call.bind(prototypeOfObject.__lookupGetter__);lookupSetter=call.bind(prototypeOfObject.__lookupSetter__)}if([1,2].splice(0).length!=2){var array_splice=Array.prototype.splice;if(function(){function makeArray(l){var a=[];while(l--){a.unshift(l)}return a}var array=[],lengthBefore;array.splice.bind(array,0,0).apply(null,makeArray(20));array.splice.bind(array,0,0).apply(null,makeArray(26));lengthBefore=array.length;array.splice(5,0,"XXX");if(lengthBefore+1==array.length){return true}}()){Array.prototype.splice=function(start,deleteCount){if(!arguments.length){return[]}else{return array_splice.apply(this,[start===void 0?0:start,deleteCount===void 0?this.length-start:deleteCount].concat(_Array_slice_.call(arguments,2)))}}}else{Array.prototype.splice=function(start,deleteCount){var result,args=_Array_slice_.call(arguments,2),addElementsCount=args.length;if(!arguments.length){return[]}if(start===void 0){start=0}if(deleteCount===void 0){deleteCount=this.length-start}if(addElementsCount>0){if(deleteCount<=0){if(start==this.length){this.push.apply(this,args);return[]}if(start==0){this.unshift.apply(this,args);return[]}}result=_Array_slice_.call(this,start,start+deleteCount);args.push.apply(args,_Array_slice_.call(this,start+deleteCount,this.length));args.unshift.apply(args,_Array_slice_.call(this,0,start));args.unshift(0,this.length);array_splice.apply(this,args);return result}return array_splice.call(this,start,deleteCount)}}}if([].unshift(0)!=1){var array_unshift=Array.prototype.unshift;Array.prototype.unshift=function(){array_unshift.apply(this,arguments);return this.length}}if(!Array.isArray){Array.isArray=function isArray(obj){return _toString(obj)=="[object Array]"}}var boxedString=Object("a"),splitString=boxedString[0]!="a"||!(0 in boxedString);if(!Array.prototype.forEach){Array.prototype.forEach=function forEach(fun){var object=toObject(this),self=splitString&&_toString(this)=="[object String]"?this.split(""):object,thisp=arguments[1],i=-1,length=self.length>>>0;if(_toString(fun)!="[object Function]"){throw new TypeError}while(++i>>0,result=Array(length),thisp=arguments[1];if(_toString(fun)!="[object Function]"){throw new TypeError(fun+" is not a function")}for(var i=0;i>>0,result=[],value,thisp=arguments[1];if(_toString(fun)!="[object Function]"){throw new TypeError(fun+" is not a function")}for(var i=0;i>>0,thisp=arguments[1];if(_toString(fun)!="[object Function]"){throw new TypeError(fun+" is not a function")}for(var i=0;i>>0,thisp=arguments[1];if(_toString(fun)!="[object Function]"){throw new TypeError(fun+" is not a function")}for(var i=0;i>>0;if(_toString(fun)!="[object Function]"){throw new TypeError(fun+" is not a function")}if(!length&&arguments.length==1){throw new TypeError("reduce of empty array with no initial value")}var i=0;var result;if(arguments.length>=2){result=arguments[1]}else{do{if(i in self){result=self[i++];break}if(++i>=length){throw new TypeError("reduce of empty array with no initial value")}}while(true)}for(;i>>0;if(_toString(fun)!="[object Function]"){throw new TypeError(fun+" is not a function")}if(!length&&arguments.length==1){throw new TypeError("reduceRight of empty array with no initial value")}var result,i=length-1;if(arguments.length>=2){result=arguments[1]}else{do{if(i in self){result=self[i--];break}if(--i<0){throw new TypeError("reduceRight of empty array with no initial value")}}while(true)}do{if(i in this){result=fun.call(void 0,result,self[i],i,object)}}while(i--);return result}}if(!Array.prototype.indexOf||[0,1].indexOf(1,2)!=-1){Array.prototype.indexOf=function indexOf(sought){var self=splitString&&_toString(this)=="[object String]"?this.split(""):toObject(this),length=self.length>>>0;if(!length){return-1}var i=0;if(arguments.length>1){i=toInteger(arguments[1])}i=i>=0?i:Math.max(0,length+i);for(;i>>0;if(!length){return-1}var i=length-1;if(arguments.length>1){i=Math.min(i,toInteger(arguments[1]))}i=i>=0?i:length-Math.abs(i);for(;i>=0;i--){if(i in self&&sought===self[i]){return i}}return-1}}if(!Object.keys){var hasDontEnumBug=true,dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=dontEnums.length;for(var key in{toString:null}){hasDontEnumBug=false}Object.keys=function keys(object){if(typeof object!="object"&&typeof object!="function"||object===null){throw new TypeError("Object.keys called on a non-object")}var keys=[];for(var name in object){if(owns(object,name)){keys.push(name)}}if(hasDontEnumBug){for(var i=0,ii=dontEnumsLength;i9999?"+":"")+("00000"+Math.abs(year)).slice(0<=year&&year<=9999?-4:-6);length=result.length;while(length--){value=result[length];if(value<10){result[length]="0"+value}}return year+"-"+result.slice(0,2).join("-")+"T"+result.slice(2).join(":")+"."+("000"+this.getUTCMilliseconds()).slice(-3)+"Z"}}var dateToJSONIsSupported=false;try{dateToJSONIsSupported=Date.prototype.toJSON&&new Date(NaN).toJSON()===null&&new Date(negativeDate).toJSON().indexOf(negativeYearString)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return true}})}catch(e){}if(!dateToJSONIsSupported){Date.prototype.toJSON=function toJSON(key){var o=Object(this),tv=toPrimitive(o),toISO;if(typeof tv==="number"&&!isFinite(tv)){return null}toISO=o.toISOString;if(typeof toISO!="function"){throw new TypeError("toISOString property is not callable")}return toISO.call(o)}}if(!Date.parse||"Date.parse is buggy"){Date=function(NativeDate){function Date(Y,M,D,h,m,s,ms){var length=arguments.length;if(this instanceof NativeDate){var date=length==1&&String(Y)===Y?new NativeDate(Date.parse(Y)):length>=7?new NativeDate(Y,M,D,h,m,s,ms):length>=6?new NativeDate(Y,M,D,h,m,s):length>=5?new NativeDate(Y,M,D,h,m):length>=4?new NativeDate(Y,M,D,h):length>=3?new NativeDate(Y,M,D):length>=2?new NativeDate(Y,M):length>=1?new NativeDate(Y):new NativeDate;date.constructor=Date;return date}return NativeDate.apply(this,arguments)}var isoDateExpression=new RegExp("^"+"(\\d{4}|[+-]\\d{6})"+"(?:-(\\d{2})"+"(?:-(\\d{2})"+"(?:"+"T(\\d{2})"+":(\\d{2})"+"(?:"+":(\\d{2})"+"(?:(\\.\\d{1,}))?"+")?"+"("+"Z|"+"(?:"+"([-+])"+"(\\d{2})"+":(\\d{2})"+")"+")?)?)?)?"+"$");var months=[0,31,59,90,120,151,181,212,243,273,304,334,365];function dayFromMonth(year,month){var t=month>1?1:0;return months[month]+Math.floor((year-1969+t)/4)-Math.floor((year-1901+t)/100)+Math.floor((year-1601+t)/400)+365*(year-1970)}for(var key in NativeDate){Date[key]=NativeDate[key]}Date.now=NativeDate.now;Date.UTC=NativeDate.UTC;Date.prototype=NativeDate.prototype;Date.prototype.constructor=Date;Date.parse=function parse(string){var match=isoDateExpression.exec(string);if(match){var year=Number(match[1]),month=Number(match[2]||1)-1,day=Number(match[3]||1)-1,hour=Number(match[4]||0),minute=Number(match[5]||0),second=Number(match[6]||0),millisecond=Math.floor(Number(match[7]||0)*1e3),offset=!match[4]||match[8]?0:Number(new NativeDate(1970,0)),signOffset=match[9]==="-"?1:-1,hourOffset=Number(match[10]||0),minuteOffset=Number(match[11]||0),result;if(hour<(minute>0||second>0||millisecond>0?24:25)&&minute<60&&second<60&&millisecond<1e3&&month>-1&&month<12&&hourOffset<24&&minuteOffset<60&&day>-1&&day=0){c+=data[i];data[i]=Math.floor(c/n);c=c%n*base}}function toString(){var i=size;var s="";while(--i>=0){if(s!==""||i===0||data[i]!==0){var t=String(data[i]);if(s===""){s=t}else{s+="0000000".slice(0,7-t.length)+t}}}return s}function pow(x,n,acc){return n===0?acc:n%2===1?pow(x,n-1,acc*x):pow(x*x,n/2,acc)}function log(x){var n=0;while(x>=4096){n+=12;x/=4096}while(x>=2){n+=1;x/=2}return n}Number.prototype.toFixed=function(fractionDigits){var f,x,s,m,e,z,j,k;f=Number(fractionDigits);f=f!==f?0:Math.floor(f);if(f<0||f>20){throw new RangeError("Number.toFixed called with invalid number of decimals")}x=Number(this);if(x!==x){return"NaN"}if(x<=-1e21||x>=1e21){return String(x)}s="";if(x<0){s="-";x=-x}m="0";if(x>1e-21){e=log(x*pow(2,69,1))-69;z=e<0?x*pow(2,-e,1):x/pow(2,e,1);z*=4503599627370496;e=52-e;if(e>0){multiply(0,z);j=f;while(j>=7){multiply(1e7,0);j-=7}multiply(pow(10,j,1),0);j=e-1;while(j>=23){divide(1<<23);j-=23}divide(1<0){k=m.length;if(k<=f){m=s+"0.0000000000000000000".slice(0,f-k+2)+m}else{m=s+m.slice(0,k-f)+"."+m.slice(k-f)}}else{m=s+m}return m}})()}if("0".split(void 0,0).length){var string_split=String.prototype.split;String.prototype.split=function(separator,limit){if(separator===void 0&&limit===0)return[];return string_split.apply(this,arguments)}}if("".substr&&"0b".substr(-1)!=="b"){var string_substr=String.prototype.substr;String.prototype.substr=function(start,length){return string_substr.call(this,start<0?(start=this.length+start)<0?0:start:start,length)}}var ws=" \n \f\r \xa0\u1680\u180e\u2000\u2001\u2002\u2003"+"\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028"+"\u2029\ufeff";if(!String.prototype.trim||ws.trim()){ws="["+ws+"]";var trimBeginRegexp=new RegExp("^"+ws+ws+"*"),trimEndRegexp=new RegExp(ws+ws+"*$");String.prototype.trim=function trim(){if(this===undefined||this===null){throw new TypeError("can't convert "+this+" to object")}return String(this).replace(trimBeginRegexp,"").replace(trimEndRegexp,"")}}function toInteger(n){n=+n;if(n!==n){n=0}else if(n!==0&&n!==1/0&&n!==-(1/0)){n=(n>0||-1)*Math.floor(Math.abs(n))}return n}function isPrimitive(input){var type=typeof input;return input===null||type==="undefined"||type==="boolean"||type==="number"||type==="string"}function toPrimitive(input){var val,valueOf,toString;if(isPrimitive(input)){return input}valueOf=input.valueOf;if(typeof valueOf==="function"){val=valueOf.call(input);if(isPrimitive(val)){return val}}toString=input.toString;if(typeof toString==="function"){val=toString.call(input);if(isPrimitive(val)){return val}}throw new TypeError}var toObject=function(o){if(o==null){throw new TypeError("can't convert "+o+" to object")}return Object(o)}}); 2 | /* 3 | //@ sourceMappingURL=es5-shim.map 4 | */ -------------------------------------------------------------------------------- /example/js/app.js: -------------------------------------------------------------------------------- 1 | var app = angular.module('app', ["ngTouch", "angucomplete-alt"]); 2 | 3 | app.controller('MainController', ['$scope', '$http', '$rootScope', 4 | function MainController($scope, $http, $rootScope) { 5 | $scope.remoteUrlRequestFn = function(str) { 6 | return {q: str}; 7 | }; 8 | 9 | $scope.countrySelected = function(selected) { 10 | if (selected) { 11 | window.alert('You have selected ' + selected.title); 12 | } else { 13 | console.log('cleared'); 14 | } 15 | }; 16 | 17 | $scope.localSearch = function(str, people) { 18 | var matches = []; 19 | people.forEach(function(person) { 20 | var fullName = person.firstName + ' ' + person.surname; 21 | if ((person.firstName.toLowerCase().indexOf(str.toString().toLowerCase()) >= 0) || 22 | (person.surname.toLowerCase().indexOf(str.toString().toLowerCase()) >= 0) || 23 | (fullName.toLowerCase().indexOf(str.toString().toLowerCase()) >= 0)) { 24 | matches.push(person); 25 | } 26 | }); 27 | return matches; 28 | }; 29 | 30 | $scope.people = [ 31 | {firstName: "Daryl", surname: "Rowland", twitter: "@darylrowland", pic: "img/daryl.jpeg"}, 32 | {firstName: "Alan", surname: "Partridge", twitter: "@alangpartridge", pic: "img/alanp.jpg"}, 33 | {firstName: "Annie", surname: "Rowland", twitter: "@anklesannie", pic: "img/annie.jpg"} 34 | ]; 35 | 36 | $scope.countries = [ 37 | {name: 'Afghanistan', code: 'AF'}, 38 | {name: 'Aland Islands', code: 'AX'}, 39 | {name: 'Albania', code: 'AL'}, 40 | {name: 'Algeria', code: 'DZ'}, 41 | {name: 'American Samoa', code: 'AS'}, 42 | {name: 'AndorrA', code: 'AD'}, 43 | {name: 'Angola', code: 'AO'}, 44 | {name: 'Anguilla', code: 'AI'}, 45 | {name: 'Antarctica', code: 'AQ'}, 46 | {name: 'Antigua and Barbuda', code: 'AG'}, 47 | {name: 'Argentina', code: 'AR'}, 48 | {name: 'Armenia', code: 'AM'}, 49 | {name: 'Aruba', code: 'AW'}, 50 | {name: 'Australia', code: 'AU'}, 51 | {name: 'Austria', code: 'AT'}, 52 | {name: 'Azerbaijan', code: 'AZ'}, 53 | {name: 'Bahamas', code: 'BS'}, 54 | {name: 'Bahrain', code: 'BH'}, 55 | {name: 'Bangladesh', code: 'BD'}, 56 | {name: 'Barbados', code: 'BB'}, 57 | {name: 'Belarus', code: 'BY'}, 58 | {name: 'Belgium', code: 'BE'}, 59 | {name: 'Belize', code: 'BZ'}, 60 | {name: 'Benin', code: 'BJ'}, 61 | {name: 'Bermuda', code: 'BM'}, 62 | {name: 'Bhutan', code: 'BT'}, 63 | {name: 'Bolivia', code: 'BO'}, 64 | {name: 'Bosnia and Herzegovina', code: 'BA'}, 65 | {name: 'Botswana', code: 'BW'}, 66 | {name: 'Bouvet Island', code: 'BV'}, 67 | {name: 'Brazil', code: 'BR'}, 68 | {name: 'British Indian Ocean Territory', code: 'IO'}, 69 | {name: 'Brunei Darussalam', code: 'BN'}, 70 | {name: 'Bulgaria', code: 'BG'}, 71 | {name: 'Burkina Faso', code: 'BF'}, 72 | {name: 'Burundi', code: 'BI'}, 73 | {name: 'Cambodia', code: 'KH'}, 74 | {name: 'Cameroon', code: 'CM'}, 75 | {name: 'Canada', code: 'CA'}, 76 | {name: 'Cape Verde', code: 'CV'}, 77 | {name: 'Cayman Islands', code: 'KY'}, 78 | {name: 'Central African Republic', code: 'CF'}, 79 | {name: 'Chad', code: 'TD'}, 80 | {name: 'Chile', code: 'CL'}, 81 | {name: 'China', code: 'CN'}, 82 | {name: 'Christmas Island', code: 'CX'}, 83 | {name: 'Cocos (Keeling) Islands', code: 'CC'}, 84 | {name: 'Colombia', code: 'CO'}, 85 | {name: 'Comoros', code: 'KM'}, 86 | {name: 'Congo', code: 'CG'}, 87 | {name: 'Congo, The Democratic Republic of the', code: 'CD'}, 88 | {name: 'Cook Islands', code: 'CK'}, 89 | {name: 'Costa Rica', code: 'CR'}, 90 | {name: 'Cote D\'Ivoire', code: 'CI'}, 91 | {name: 'Croatia', code: 'HR'}, 92 | {name: 'Cuba', code: 'CU'}, 93 | {name: 'Cyprus', code: 'CY'}, 94 | {name: 'Czech Republic', code: 'CZ'}, 95 | {name: 'Denmark', code: 'DK'}, 96 | {name: 'Djibouti', code: 'DJ'}, 97 | {name: 'Dominica', code: 'DM'}, 98 | {name: 'Dominican Republic', code: 'DO'}, 99 | {name: 'Ecuador', code: 'EC'}, 100 | {name: 'Egypt', code: 'EG'}, 101 | {name: 'El Salvador', code: 'SV'}, 102 | {name: 'Equatorial Guinea', code: 'GQ'}, 103 | {name: 'Eritrea', code: 'ER'}, 104 | {name: 'Estonia', code: 'EE'}, 105 | {name: 'Ethiopia', code: 'ET'}, 106 | {name: 'Falkland Islands (Malvinas)', code: 'FK'}, 107 | {name: 'Faroe Islands', code: 'FO'}, 108 | {name: 'Fiji', code: 'FJ'}, 109 | {name: 'Finland', code: 'FI'}, 110 | {name: 'France', code: 'FR'}, 111 | {name: 'French Guiana', code: 'GF'}, 112 | {name: 'French Polynesia', code: 'PF'}, 113 | {name: 'French Southern Territories', code: 'TF'}, 114 | {name: 'Gabon', code: 'GA'}, 115 | {name: 'Gambia', code: 'GM'}, 116 | {name: 'Georgia', code: 'GE'}, 117 | {name: 'Germany', code: 'DE'}, 118 | {name: 'Ghana', code: 'GH'}, 119 | {name: 'Gibraltar', code: 'GI'}, 120 | {name: 'Greece', code: 'GR'}, 121 | {name: 'Greenland', code: 'GL'}, 122 | {name: 'Grenada', code: 'GD'}, 123 | {name: 'Guadeloupe', code: 'GP'}, 124 | {name: 'Guam', code: 'GU'}, 125 | {name: 'Guatemala', code: 'GT'}, 126 | {name: 'Guernsey', code: 'GG'}, 127 | {name: 'Guinea', code: 'GN'}, 128 | {name: 'Guinea-Bissau', code: 'GW'}, 129 | {name: 'Guyana', code: 'GY'}, 130 | {name: 'Haiti', code: 'HT'}, 131 | {name: 'Heard Island and Mcdonald Islands', code: 'HM'}, 132 | {name: 'Holy See (Vatican City State)', code: 'VA'}, 133 | {name: 'Honduras', code: 'HN'}, 134 | {name: 'Hong Kong', code: 'HK'}, 135 | {name: 'Hungary', code: 'HU'}, 136 | {name: 'Iceland', code: 'IS'}, 137 | {name: 'India', code: 'IN'}, 138 | {name: 'Indonesia', code: 'ID'}, 139 | {name: 'Iran, Islamic Republic Of', code: 'IR'}, 140 | {name: 'Iraq', code: 'IQ'}, 141 | {name: 'Ireland', code: 'IE'}, 142 | {name: 'Isle of Man', code: 'IM'}, 143 | {name: 'Israel', code: 'IL'}, 144 | {name: 'Italy', code: 'IT'}, 145 | {name: 'Jamaica', code: 'JM'}, 146 | {name: 'Japan', code: 'JP'}, 147 | {name: 'Jersey', code: 'JE'}, 148 | {name: 'Jordan', code: 'JO'}, 149 | {name: 'Kazakhstan', code: 'KZ'}, 150 | {name: 'Kenya', code: 'KE'}, 151 | {name: 'Kiribati', code: 'KI'}, 152 | {name: 'Korea, Democratic People\'S Republic of', code: 'KP'}, 153 | {name: 'Korea, Republic of', code: 'KR'}, 154 | {name: 'Kuwait', code: 'KW'}, 155 | {name: 'Kyrgyzstan', code: 'KG'}, 156 | {name: 'Lao People\'S Democratic Republic', code: 'LA'}, 157 | {name: 'Latvia', code: 'LV'}, 158 | {name: 'Lebanon', code: 'LB'}, 159 | {name: 'Lesotho', code: 'LS'}, 160 | {name: 'Liberia', code: 'LR'}, 161 | {name: 'Libyan Arab Jamahiriya', code: 'LY'}, 162 | {name: 'Liechtenstein', code: 'LI'}, 163 | {name: 'Lithuania', code: 'LT'}, 164 | {name: 'Luxembourg', code: 'LU'}, 165 | {name: 'Macao', code: 'MO'}, 166 | {name: 'Macedonia, The Former Yugoslav Republic of', code: 'MK'}, 167 | {name: 'Madagascar', code: 'MG'}, 168 | {name: 'Malawi', code: 'MW'}, 169 | {name: 'Malaysia', code: 'MY'}, 170 | {name: 'Maldives', code: 'MV'}, 171 | {name: 'Mali', code: 'ML'}, 172 | {name: 'Malta', code: 'MT'}, 173 | {name: 'Marshall Islands', code: 'MH'}, 174 | {name: 'Martinique', code: 'MQ'}, 175 | {name: 'Mauritania', code: 'MR'}, 176 | {name: 'Mauritius', code: 'MU'}, 177 | {name: 'Mayotte', code: 'YT'}, 178 | {name: 'Mexico', code: 'MX'}, 179 | {name: 'Micronesia, Federated States of', code: 'FM'}, 180 | {name: 'Moldova, Republic of', code: 'MD'}, 181 | {name: 'Monaco', code: 'MC'}, 182 | {name: 'Mongolia', code: 'MN'}, 183 | {name: 'Montserrat', code: 'MS'}, 184 | {name: 'Morocco', code: 'MA'}, 185 | {name: 'Mozambique', code: 'MZ'}, 186 | {name: 'Myanmar', code: 'MM'}, 187 | {name: 'Namibia', code: 'NA'}, 188 | {name: 'Nauru', code: 'NR'}, 189 | {name: 'Nepal', code: 'NP'}, 190 | {name: 'Netherlands', code: 'NL'}, 191 | {name: 'Netherlands Antilles', code: 'AN'}, 192 | {name: 'New Caledonia', code: 'NC'}, 193 | {name: 'New Zealand', code: 'NZ'}, 194 | {name: 'Nicaragua', code: 'NI'}, 195 | {name: 'Niger', code: 'NE'}, 196 | {name: 'Nigeria', code: 'NG'}, 197 | {name: 'Niue', code: 'NU'}, 198 | {name: 'Norfolk Island', code: 'NF'}, 199 | {name: 'Northern Mariana Islands', code: 'MP'}, 200 | {name: 'Norway', code: 'NO'}, 201 | {name: 'Oman', code: 'OM'}, 202 | {name: 'Pakistan', code: 'PK'}, 203 | {name: 'Palau', code: 'PW'}, 204 | {name: 'Palestinian Territory, Occupied', code: 'PS'}, 205 | {name: 'Panama', code: 'PA'}, 206 | {name: 'Papua New Guinea', code: 'PG'}, 207 | {name: 'Paraguay', code: 'PY'}, 208 | {name: 'Peru', code: 'PE'}, 209 | {name: 'Philippines', code: 'PH'}, 210 | {name: 'Pitcairn', code: 'PN'}, 211 | {name: 'Poland', code: 'PL'}, 212 | {name: 'Portugal', code: 'PT'}, 213 | {name: 'Puerto Rico', code: 'PR'}, 214 | {name: 'Qatar', code: 'QA'}, 215 | {name: 'Reunion', code: 'RE'}, 216 | {name: 'Romania', code: 'RO'}, 217 | {name: 'Russian Federation', code: 'RU'}, 218 | {name: 'RWANDA', code: 'RW'}, 219 | {name: 'Saint Helena', code: 'SH'}, 220 | {name: 'Saint Kitts and Nevis', code: 'KN'}, 221 | {name: 'Saint Lucia', code: 'LC'}, 222 | {name: 'Saint Pierre and Miquelon', code: 'PM'}, 223 | {name: 'Saint Vincent and the Grenadines', code: 'VC'}, 224 | {name: 'Samoa', code: 'WS'}, 225 | {name: 'San Marino', code: 'SM'}, 226 | {name: 'Sao Tome and Principe', code: 'ST'}, 227 | {name: 'Saudi Arabia', code: 'SA'}, 228 | {name: 'Senegal', code: 'SN'}, 229 | {name: 'Serbia and Montenegro', code: 'CS'}, 230 | {name: 'Seychelles', code: 'SC'}, 231 | {name: 'Sierra Leone', code: 'SL'}, 232 | {name: 'Singapore', code: 'SG'}, 233 | {name: 'Slovakia', code: 'SK'}, 234 | {name: 'Slovenia', code: 'SI'}, 235 | {name: 'Solomon Islands', code: 'SB'}, 236 | {name: 'Somalia', code: 'SO'}, 237 | {name: 'South Africa', code: 'ZA'}, 238 | {name: 'South Georgia and the South Sandwich Islands', code: 'GS'}, 239 | {name: 'Spain', code: 'ES'}, 240 | {name: 'Sri Lanka', code: 'LK'}, 241 | {name: 'Sudan', code: 'SD'}, 242 | {name: 'Suriname', code: 'SR'}, 243 | {name: 'Svalbard and Jan Mayen', code: 'SJ'}, 244 | {name: 'Swaziland', code: 'SZ'}, 245 | {name: 'Sweden', code: 'SE'}, 246 | {name: 'Switzerland', code: 'CH'}, 247 | {name: 'Syrian Arab Republic', code: 'SY'}, 248 | {name: 'Taiwan, Province of China', code: 'TW'}, 249 | {name: 'Tajikistan', code: 'TJ'}, 250 | {name: 'Tanzania, United Republic of', code: 'TZ'}, 251 | {name: 'Thailand', code: 'TH'}, 252 | {name: 'Timor-Leste', code: 'TL'}, 253 | {name: 'Togo', code: 'TG'}, 254 | {name: 'Tokelau', code: 'TK'}, 255 | {name: 'Tonga', code: 'TO'}, 256 | {name: 'Trinidad and Tobago', code: 'TT'}, 257 | {name: 'Tunisia', code: 'TN'}, 258 | {name: 'Turkey', code: 'TR'}, 259 | {name: 'Turkmenistan', code: 'TM'}, 260 | {name: 'Turks and Caicos Islands', code: 'TC'}, 261 | {name: 'Tuvalu', code: 'TV'}, 262 | {name: 'Uganda', code: 'UG'}, 263 | {name: 'Ukraine', code: 'UA'}, 264 | {name: 'United Arab Emirates', code: 'AE'}, 265 | {name: 'United Kingdom', code: 'GB'}, 266 | {name: 'United States', code: 'US'}, 267 | {name: 'United States Minor Outlying Islands', code: 'UM'}, 268 | {name: 'Uruguay', code: 'UY'}, 269 | {name: 'Uzbekistan', code: 'UZ'}, 270 | {name: 'Vanuatu', code: 'VU'}, 271 | {name: 'Venezuela', code: 'VE'}, 272 | {name: 'Vietnam', code: 'VN'}, 273 | {name: 'Virgin Islands, British', code: 'VG'}, 274 | {name: 'Virgin Islands, U.S.', code: 'VI'}, 275 | {name: 'Wallis and Futuna', code: 'WF'}, 276 | {name: 'Western Sahara', code: 'EH'}, 277 | {name: 'Yemen', code: 'YE'}, 278 | {name: 'Zambia', code: 'ZM'}, 279 | {name: 'Zimbabwe', code: 'ZW'} 280 | ]; 281 | 282 | $scope.countrySelected9 = {name: 'Zimbabwe', code: 'ZW'}; 283 | $scope.countrySelectedFn9 = function(selected) { 284 | if (selected) { 285 | $scope.countrySelected9 = selected.originalObject; 286 | } else { 287 | $scope.countrySelected9 = null; 288 | } 289 | } 290 | 291 | $scope.selectedCountry16 = {name: 'Russia'}; 292 | 293 | $scope.inputChanged = function(str) { 294 | $scope.console10 = str; 295 | } 296 | 297 | $scope.focusState = 'None'; 298 | $scope.focusIn = function() { 299 | var focusInputElem = document.getElementById('ex12_value'); 300 | $scope.focusState = 'In'; 301 | focusInputElem.classList.remove('small-input'); 302 | } 303 | $scope.focusOut = function() { 304 | var focusInputElem = document.getElementById('ex12_value'); 305 | $scope.focusState = 'Out'; 306 | focusInputElem.classList.add('small-input'); 307 | } 308 | 309 | /*** 310 | * Send a broadcast to the directive in order to clear itself 311 | * if an id parameter is given only this ancucomplete is cleared 312 | * @param id 313 | */ 314 | $scope.clearInput = function (id) { 315 | if (id) { 316 | $scope.$broadcast('angucomplete-alt:clearInput', id); 317 | } 318 | else{ 319 | $scope.$broadcast('angucomplete-alt:clearInput'); 320 | } 321 | } 322 | 323 | /*** 324 | * Send a broadcast to the directive in order to change itself 325 | * if an id parameter is given only this ancucomplete is changed 326 | * @param id 327 | */ 328 | $scope.changeInput = function (id) { 329 | if (id) { 330 | var pos = Math.floor(Math.random() * ($scope.countries.length - 1)); 331 | $scope.$broadcast('angucomplete-alt:changeInput', id, $scope.countries[pos]); 332 | } 333 | } 334 | 335 | $scope.disableInput = true; 336 | 337 | $scope.requireExample8a = true; 338 | $scope.requireExample8b = true; 339 | } 340 | ]); 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | angucomplete-alt 2 | ============ 3 | 4 | This is a fork of Daryl Rowland's angucomplete (https://github.com/darylrowland/angucomplete) with a bit of tweaks such as: 5 | 6 | * change long attribute names to hyphenated ones 7 | * coding style similar to angular standard 8 | * refactored in general 9 | * jshint 10 | * more test coverage 11 | 12 | To see a demo go here: https://ghiden.github.io/angucomplete-alt 13 | 14 | ###Key Features 15 | * Show just a title, a title and a description or a title, description and image in your autocomplete list 16 | * Deliberately minimally styled so you can customise it to your heart's content! 17 | * Reads JSON data and allows you to specify which fields to use for display 18 | * Simple setup - e.g. to pull data from a server, just set the url parameter 19 | 20 | ### Extra Features 21 | * Request format function: if you need to tweak data before you send to your search API, you can set your own format function. Search query goes through your function and gets sent to your API. 22 | * Response format function: if you need to tweak response from the server before it gets processed by the directive, you can set your own format function. Raw HTTP response goes through your function. Thanks to @nekcih for proposing this feature. 23 | * Clear on selection: when you select an item, input field is cleared. 24 | * Blur event handling, thanks to @leejsinclair 25 | * Override suggestions 26 | * You can either bind an object or callback function 27 | * bind an object: it works as one-way-data-binding. It gets set when a selection is made. 28 | * callback function: when a selection is made by user, this callback is called with the selected object. When the selection is deselected, the callback is called with undefined. Thanks to @nekcih for proposing this feature. 29 | * Required support: It is a bit different from ng-required which becomes valid when there is any character in input field. This required becomes valid when a selection is made. Class name is "autocomplete-required" and customizable. Thanks to @alindber for the initial idea. 30 | * Custom texts for "Searching..." and "No results found", thanks to @vhuerta for this idea. 31 | * Be able to set initial value. This becomes handy if you use this directive for updating existing model. 32 | * Be able to set a error callback for ajax request 33 | * Add a callback for tracking input changes. Thanks to @urecio for the initial idea. 34 | * Auto match 35 | * Add callbacks for tracking focus in/out. 36 | * Enable/disable input field 37 | * Show scrollbar. See [example #1](https://ghiden.github.io/angucomplete-alt/#example1) 38 | * Clear input by sending $broadcast from parent scope. Thanks to @Leocrest for #61. 39 | * Override template with your own. When you use this feature, test throughly as it might break other features. Thanks to @sdbondi for #74. 40 | * Show all items. 41 | * Custom remote API handler which allows you to fully control how to communicate with your remote API. Thanks to @jbuquet 42 | * Custom search function for handling local data 43 | 44 | ### Angular 1.2 45 | 46 | From v2.0.0, I have dropped the support for angular 1.2. 47 | Please use [angucomplete-ie8](https://github.com/ghiden/angucomplete-ie8) which still supports 1.2. 48 | 49 | ### Getting Started 50 | Download the package, and include the dist/angucomplete-alt.min.js file in your page. 51 | 52 | ```bash 53 | bower install angucomplete-alt --save 54 | ``` 55 | 56 | Or 57 | 58 | ```bash 59 | npm install angucomplete-alt --save 60 | ``` 61 | 62 | Then add the angucomplete-alt module to your Angular App file, e.g. 63 | 64 | ```js 65 | var app = angular.module('app', ["angucomplete-alt"]); 66 | ``` 67 | 68 | ### Using local data 69 | 70 | ```html 71 | 80 | ``` 81 | 82 | ### Using local data with custom search function 83 | 84 | ```html 85 | 97 | ``` 98 | 99 | Local search function takes a string and returns an array of matched items. 100 | ```javascript 101 | // Here is a naive implementation for matching first name, last name, or full name 102 | $scope.localSearch = function(str) { 103 | var matches = []; 104 | $scope.people.forEach(function(person) { 105 | var fullName = person.firstName + ' ' + person.surname; 106 | if ((person.firstName.toLowerCase().indexOf(str.toString().toLowerCase()) >= 0) || 107 | (person.surname.toLowerCase().indexOf(str.toString().toLowerCase()) >= 0) || 108 | (fullName.toLowerCase().indexOf(str.toString().toLowerCase()) >= 0)) { 109 | matches.push(person); 110 | } 111 | }); 112 | return matches; 113 | }; 114 | ``` 115 | [Example](https://ghiden.github.io/angucomplete-alt/#example2) 116 | 117 | ### Using remote API 118 | 119 | ```html 120 | 130 | ``` 131 | 132 | It expects the returned results from remote API to have a root object. In the above example, 'results' is an array of search results. 133 | 134 | ### Description of attributes 135 | | Attribute | Description | Required | Binding | Example | 136 | | :------------- |:-------------| :-----:| :-----:| :-----| 137 | | id | A unique ID for the field. [example](https://ghiden.github.io/angucomplete-alt/#example1) | Yes | @ | members | 138 | | placeholder | Placeholder text for the search field. [example](https://ghiden.github.io/angucomplete-alt/#example1) | No | @ | Search members | 139 | | maxlength | Maxlength attribute for the search field. [example](https://ghiden.github.io/angucomplete-alt/#example1) | No | attribute | 25 | 140 | | pause | The time to wait (in milliseconds) before searching when the user enters new characters. [example](https://ghiden.github.io/angucomplete-alt/#example1) | No | @ | 400 | 141 | | selected-object | Either an object in your scope or callback function. If you set an object, it will be passed to the directive with '=' sign but it is actually one-way-bound data. So, setting it from your scope has no effect on input string. If you set a callback, it gets called when selection is made. To get attributes of the input from which the assignment was made, use this.$parent.$index within your function. [example](https://ghiden.github.io/angucomplete-alt/#example1) | Yes | = | selectedObject or objectSelectedCallback | 142 | | selected-object-data | A second parameter which will be passed to selected-object. Only works when using selected-object. | No | = | row | 143 | | remote-url | The remote URL to hit to query for results in JSON. angucomplete will automatically append the search string on the end of this, so it must be a GET request. [example](https://ghiden.github.io/angucomplete-alt/#example5) | No | @ | http://myserver.com/api/users/find?searchstr= | 144 | | remote-url-data-field | The name of the field in the JSON object returned back that holds the Array of objects to be used for the autocomplete list. [example](https://ghiden.github.io/angucomplete-alt/#example5) | No | @ | results | 145 | | title-field | The name of the field in the JSON objects returned back that should be used for displaying the title in the autocomplete list. Note, if you want to combine fields together, you can comma separate them here (e.g. for a first and last name combined). If you want to access nested field, use dot to connect attributes (e.g. name.first). [example](https://ghiden.github.io/angucomplete-alt/#example1) | Yes | @ | firstName,lastName | 146 | | description-field | The name of the field in the JSON objects returned back that should be used for displaying the description in the autocomplete list. [example](https://ghiden.github.io/angucomplete-alt/#example6) | No | @ | twitterUsername | 147 | | image-field | The name of the field in the JSON objects returned back that should be used for displaying an image in the autocomplete list. [example](https://ghiden.github.io/angucomplete-alt/#example2) | No | @ | pic | 148 | | minlength | The minimum length of string required before searching. [example](https://ghiden.github.io/angucomplete-alt/#example1). If set to 0, it shows all items. It works both local and remote but is intended to use with local data. If used with remote API, it needs to return all items when query parameter is empty string. | No | @ | 3 | 149 | | input-name | Name for input field. This is required when you use field-required. | No | @ | | 150 | | input-class | The classes to use for styling the input box. [example](https://ghiden.github.io/angucomplete-alt/#example1) | No | @ | form-control | 151 | | match-class | If it is assigned, matching part of title is highlighted with given class style. [example](https://ghiden.github.io/angucomplete-alt/#example6) | No | @ | highlight | 152 | | local-data | The local data variable to use from your controller. Should be an array of objects. [example](https://ghiden.github.io/angucomplete-alt/#example1) | No | = | countriesList | 153 | | local-search | A function that search local data. It should take a input string and an array of items as arguments and returns an array of matched items. [example](https://ghiden.github.io/angucomplete-alt/#example2) | No | & | localSearch | 154 | | search-fields | The fields from your local data to search on (comma separate them). Each field can contain dots for accessing nested attribute. [example](https://ghiden.github.io/angucomplete-alt/#example1) | No | @ | title,description | 155 | | remote-url-request-formatter | A function that takes a query string and returns parameter(s) for GET. It should take the query string as argument and returns a key-value object. [example](https://ghiden.github.io/angucomplete-alt/#example5) | No | = | Suppose if you need to send a query keyword and a timestamp to search API, you can write a function like this in the parent scope. $scope.dataFormatFn = function(str) { return {q: str, timestamp: +new Date()}; } | 156 | | remote-url-request-with-credentials | A boolean that accepts parameters with credentials. | No | @ | true or false | 157 | | remote-url-response-formatter | A function on the scope that will modify raw response from remote API before it is rendered in the drop-down. Useful for adding data that may not be available from the API. The specified function must return the object in the format that angucomplete understands. | No | = | addImageUrlToObject | 158 | | remote-url-error-callback | A callback funciton to handle error response from $http.get | No | = | httpErrorCallbackFn | 159 | | remote-api-handler | This gives a way to fully delegate handling of remote search API. This function takes user input string and timeout promise, and it needs to return a promise. For example, if your search API is based on POST, you can use this function to create your own http handler. See example below | No | = | | 160 | | clear-selected | To clear out input field upon selecting an item, set this attribute to true. [example](https://ghiden.github.io/angucomplete-alt/#example3) | No | @ | true | 161 | | override-suggestions | To override suggestions and set the value in input field to selectedObject. [example](https://ghiden.github.io/angucomplete-alt/#example4) | No | true | 162 | | field-required | Set field to be required. Requirement for this to work is that this directive needs to be in a form and you need to provide input-name. Default class name is "autocomplete-required". [example](https://ghiden.github.io/angucomplete-alt/#example8). | No | = | a variable holding true/false | 163 | | field-required-class | Set custom class name for required. | No | @ | "match" | 164 | | text-searching | Custom string to show when search is in progress. Set this to 'false' prevents text to show up. | No | @ | "Searching for items..." | 165 | | text-no-results | Custom string to show when there is no match. Set this to 'false' prevents text to show up. | No | @ | "Not found" | 166 | | initial-value | Initial value for component. If string, the internal model is set to the string value, if an object, the title-field attribute is used to parse the correct title for the view, and the internal model is set to the object. [example](https://ghiden.github.io/angucomplete-alt/#example9) | No | = | myInitialValue (object/string) | 167 | | input-changed | A callback function that is called when input field is changed. To get attributes of the input from which the assignment was made, use this.$parent.$index within your function. [example](https://ghiden.github.io/angucomplete-alt/#example10) | No | = | inputChangedFn | 168 | | auto-match | Allows for auto selecting an item if the search text matches a search results attributes exactly. [example](https://ghiden.github.io/angucomplete-alt/#example11) | No | @ | true | 169 | | focus-in | A function or expression to be called when input field gets focused. [example](https://ghiden.github.io/angucomplete-alt/#example12) | No | & | focusIn() | 170 | | focus-out | A function or expression to be called when input field lose focus. [example](https://ghiden.github.io/angucomplete-alt/#example12) | No | & | focusOut() | 171 | | disable-input | A model to control disable/enable of input field. [example page](https://ghiden.github.io/angucomplete-alt/#example13) | No | = | disableInput | 172 | | template-url | Customize the markup of the autocomplete template. [example page](https://ghiden.github.io/angucomplete-alt/#example14) | No | attribute | "/my-custom-template.html" | 173 | | focus-first | Automatically select the first match from the result list. | No | @ | true | 174 | | parse-input | A function or expression to parse input string before comparing into search process. | No | & | parseInput() | 175 | | field-tabindex | Setting the tabindex attribute on the input field. | No | @ | field-tabindex="25" | 176 | 177 | 178 | ### Scrollbar 179 | 180 | To show scrollbar, you need to set the following css style to angucomplete-dropdown class, and then the directive automatically picks it up. 181 | ```css 182 | .angucomplete-dropdown { 183 | ... 184 | overflow-y: auto; 185 | max-height: 200px; // your preference 186 | ... 187 | } 188 | ``` 189 | See [example #1](https://ghiden.github.io/angucomplete-alt/#example1) 190 | 191 | ### Clear Input 192 | 193 | To clear all angucomplete-alt input fields, send this message 194 | ```js 195 | $scope.$broadcast('angucomplete-alt:clearInput'); 196 | ``` 197 | 198 | To clear an angucomplete-alt input field, send this message with id of the directive. For example, the id of the directive is 'autocomplete-1'. 199 | ```js 200 | $scope.$broadcast('angucomplete-alt:clearInput', 'autocomplete-1'); 201 | ``` 202 | 203 | ### Change Input 204 | 205 | To set an angucomplete-alt input field, send this message with id of the directive and desired value. 206 | One can pass a simple string or an object as an argument, the same rules applied as for ```initial-value``` parameter. 207 | For example, the id of the directive is 'autocomplete-1'. 208 | ```js 209 | $scope.$broadcast('angucomplete-alt:changeInput', 'autocomplete-1', 'Hello!'); 210 | ``` 211 | 212 | ### Remote API Handler 213 | 214 | This is an example calling search API with POST. 215 | Pass this searchAPI function to the directive as remote-api-handler. 216 | 217 | ```js 218 | $scope.searchAPI = function(userInputString, timeoutPromise) { 219 | return $http.post('/yourownapi/', {q: userInputString}, {timeout: timeoutPromise}); 220 | } 221 | ``` 222 | When you use remote-api-handler, these attributes are ignored: 223 | ``` 224 | remote-url 225 | remote-url-request-formatter 226 | remote-url-request-with-credentials 227 | ``` 228 | 229 | ### Callback behaviour 230 | 231 | Callbacks ```selected-object``` and ```input-changed``` are called with the following method signature: 232 | 233 | ``` 234 | function ($item) { 235 | 236 | $item.title // or description, or image - from your angucomplete attribute configuration 237 | $item.originalObject // the actual object which was selected 238 | this.$parent // the control which caused the change, contains useful things like $index for use in ng-repeat. 239 | 240 | } 241 | ``` 242 | 243 | ### Examples 244 | 245 | To run examples, cd into 'examples' directory and run static http server of your choice: 246 | 247 | ```bash 248 | cd examples 249 | python -m SimpleHTTPServer 250 | ``` 251 | 252 | ### Contributors 253 | 254 | Here is the list of [contributors](CONTRIBUTORS.md). 255 | Here is how to [contribute](CONTRIBUTING.md). 256 | Of course the easiest contribution is to give it a star! 257 | -------------------------------------------------------------------------------- /example/css/structure.css: -------------------------------------------------------------------------------- 1 | html { 2 | height: 100%; 3 | } 4 | 5 | body { 6 | font-family: "bariol_regularregular", Arial; 7 | letter-spacing: 0.01em; 8 | font-size: 1em; 9 | padding: 40px; 10 | text-rendering: optimizeLegibility; 11 | background-color: #ffffff; 12 | margin: 0px; 13 | height: 100%; 14 | } 15 | 16 | input, button, textarea { 17 | -webkit-appearance: none; 18 | } 19 | 20 | .white-bg { 21 | background: #ffffff; 22 | min-height: 100%; 23 | } 24 | 25 | a { 26 | color: #5BCDD5; 27 | text-decoration: none; 28 | } 29 | 30 | a:hover { 31 | color: #F98200; 32 | } 33 | 34 | .centered-heading { 35 | font-family: "bariol_regularregular", Arial; 36 | font-size: 5em; 37 | text-align: center; 38 | } 39 | 40 | h1, h2, h3, h4, h5, h6 { 41 | font-family: "bariol_regularregular", Arial; 42 | line-height: 1em; 43 | margin-bottom: 10px; 44 | margin-top: 10px; 45 | } 46 | 47 | h1 { 48 | font-size: 4em; 49 | } 50 | 51 | h3 { 52 | margin-top: 1px; 53 | margin-bottom: 1px; 54 | } 55 | 56 | p { 57 | margin-top: 0px; 58 | margin-bottom: 0px; 59 | } 60 | 61 | .container { 62 | width: 90%; 63 | margin-left: auto; 64 | margin-right: auto; 65 | } 66 | 67 | 68 | /* Top Menu */ 69 | .top-bar { 70 | padding: 10px; 71 | position: fixed; 72 | top: 0; 73 | left: 0; 74 | height: 30px; 75 | color: #ffffff; 76 | width: 100%; 77 | background-color: #363636; 78 | z-index: 100001; 79 | } 80 | 81 | .top-bar-inner { 82 | height: 10px; 83 | margin: 10px; 84 | } 85 | 86 | .top-bar-brand { 87 | position: absolute; 88 | top: 15px; 89 | } 90 | 91 | .top-bar-logo { 92 | height: 30px; 93 | } 94 | 95 | .top-bar-links { 96 | display: none; 97 | } 98 | 99 | .top-bar-mobile-link-menu { 100 | float: right; 101 | font-size: 1.8em; 102 | margin-right: 10px; 103 | margin-top: 10px; 104 | color: #FF4157; 105 | 106 | } 107 | 108 | h1 { 109 | font-size: 36px; 110 | } 111 | 112 | @media screen and (min-width: 500px) { 113 | h1 { 114 | font-size: 50px; 115 | } 116 | 117 | .top-bar-mobile-link-menu { 118 | display: none; 119 | } 120 | 121 | .top-bar-links { 122 | display: block; 123 | position: absolute; 124 | top: 0px; 125 | left: 150px; 126 | } 127 | 128 | .top-bar-links ul { 129 | list-style: none; 130 | } 131 | 132 | .top-bar-links li { 133 | list-style: none; 134 | float: left; 135 | margin-right: 20px; 136 | font-family: "bariol_regularregular"; 137 | font-size: 16px; 138 | font-weight: 800; 139 | letter-spacing: -0.02em; 140 | } 141 | 142 | .top-bar-link-active a { 143 | color: #60CDD4; 144 | } 145 | 146 | .top-bar-links a { 147 | color: #ffffff; 148 | } 149 | 150 | .top-bar-links a:hover { 151 | color: #F98200; 152 | } 153 | 154 | .top-bar-link-active:after { 155 | display: block; 156 | position: relative; 157 | top: 8px; 158 | height: 6px; 159 | width: 100%; 160 | background-color: #F98200; 161 | content: ""; 162 | } 163 | } 164 | 165 | /* Rows and columns */ 166 | .row { 167 | margin-top: 10px; 168 | display: block; 169 | } 170 | 171 | .text-centered { 172 | text-align: center; 173 | } 174 | 175 | .col-3, col-6 { 176 | margin-bottom: 10px; 177 | } 178 | 179 | .jumbotron { 180 | padding-top: 40px; 181 | text-align: center; 182 | } 183 | 184 | .jumbotron-red { 185 | background-color: #FF5C5B; 186 | color: #ffffff; 187 | padding: 30px; 188 | text-align: left; 189 | } 190 | 191 | @media screen and (min-width: 500px) { 192 | .col-3 { 193 | float: left; 194 | width: 31%; 195 | margin-left: 1%; 196 | margin-right: 1%; 197 | } 198 | 199 | .col-6 { 200 | float: left; 201 | width: 48%; 202 | margin-left: 1%; 203 | margin-right: 1%; 204 | } 205 | 206 | .col-12 { 207 | float: left; 208 | width: 98%; 209 | margin-left: 1%; 210 | margin-right: 1%; 211 | } 212 | } 213 | 214 | /* Buttons */ 215 | .btn { 216 | border-style: none; 217 | font-size: 14px; 218 | margin: 14px; 219 | margin-left: 4px; 220 | margin-right: 4px; 221 | border-radius: 2px; 222 | padding: 10px; 223 | cursor: pointer; 224 | min-width: 100px; 225 | } 226 | 227 | .btn-slim { 228 | min-width: 50px; 229 | } 230 | 231 | .btn-large { 232 | font-size: 22px; 233 | } 234 | 235 | .btn:focus { 236 | border-style: none; 237 | outline-style: none; 238 | } 239 | 240 | .btn-blue { 241 | background-color: #60CDD4; 242 | color: #ffffff; 243 | } 244 | 245 | .btn-blue:hover { 246 | background-color: #1D94B0; 247 | color: #ffffff; 248 | } 249 | 250 | .btn-orange { 251 | background-color: #FFA300; 252 | color: #ffffff; 253 | } 254 | 255 | .dropdown-description { 256 | display: none; 257 | } 258 | 259 | .criteria-table-cell { 260 | color: #ffffff; 261 | padding: 4px; 262 | display: block; 263 | text-align: center; 264 | border-radius: 4px; 265 | } 266 | 267 | @media screen and (min-width: 400px) { 268 | .dropdown-description { 269 | display: block; 270 | position: absolute; 271 | right: 70px; 272 | top: 15px; 273 | max-width: 200px; 274 | background-color: #000000; 275 | color: #ffffff; 276 | border-radius: 4px; 277 | padding: 6px; 278 | padding-left: 10px; 279 | padding-right: 10px; 280 | opacity: 0.8; 281 | } 282 | } 283 | 284 | .dropdown { 285 | width: 53px; 286 | position: absolute; 287 | right: 4px; 288 | top: 50px; 289 | z-index: 100; 290 | padding: 0px; 291 | text-align: left; 292 | text-align: center; 293 | border-bottom-left-radius: 2px; 294 | border-bottom-right-radius: 2px; 295 | text-align: center; 296 | } 297 | 298 | .dropdown-icon { 299 | margin-bottom: 0px; 300 | padding: 5px; 301 | cursor: pointer; 302 | padding-top: 10px; 303 | padding-bottom: 10px; 304 | } 305 | 306 | .dropdown-icon:hover { 307 | background-color: #fb8200; 308 | } 309 | 310 | .dropdown-orange { 311 | background-color: #FFA300; 312 | color: #ffffff; 313 | } 314 | 315 | .btn-orange:hover { 316 | background-color: #F78200; 317 | color: #ffffff; 318 | } 319 | 320 | .padded-row { 321 | margin-top: 10px; 322 | } 323 | 324 | .large-padded-row { 325 | margin-top: 20px; 326 | } 327 | 328 | .very-large-padded-row { 329 | margin-top: 40px; 330 | } 331 | 332 | .full-screen-cancel:hover { 333 | color: #363636; 334 | cursor: pointer; 335 | } 336 | 337 | .grey-background { 338 | background-color: #888888; 339 | } 340 | 341 | .big-card-controls { 342 | position: absolute; 343 | bottom: 15px; 344 | left: 15px; 345 | font-size: 16px; 346 | color: #ACACAC; 347 | } 348 | 349 | .comment-details { 350 | color: #e0e0e0; 351 | font-size: 11px; 352 | } 353 | 354 | .comment-details a { 355 | color: #e0e0e0; 356 | } 357 | 358 | .comment-details a:hover { 359 | color: #F98200; 360 | } 361 | 362 | .icon-spaced-right { 363 | margin-right: 2px; 364 | } 365 | 366 | .ng-cloak { 367 | display: none; 368 | } 369 | 370 | .card { 371 | position: relative; 372 | margin-top: 20px; 373 | border-radius: 4px; 374 | padding: 20px; 375 | background: #FFFFFF; 376 | /*-moz-box-shadow: 0px 0px 4px 0px #D8D8D8; 377 | -webkit-box-shadow: 0px 0px 4px 0px #D8D8D8; 378 | box-shadow: 0px 0px 4px 0px #D8D8D8;*/ 379 | border-style: none; 380 | border-style: solid; 381 | border-color: #D8D8D8; 382 | border-width: 1px; 383 | height: 140px; 384 | overflow: auto; 385 | cursor: pointer; 386 | max-width: 220px; 387 | margin-bottom: 10px; 388 | } 389 | 390 | .card.ng-show { 391 | opacity: 0; 392 | display: block !important; 393 | transition: opacity 1s; 394 | } 395 | 396 | .card-full-width { 397 | max-width: 1000px; 398 | } 399 | 400 | .card.ng-show-active { 401 | opacity: 1; 402 | } 403 | 404 | .circle-image { 405 | position: absolute; 406 | left: 10px; 407 | border-radius: 50%; 408 | height: 70px; 409 | width: 70px; 410 | border-style: solid; 411 | border-width: 1px; 412 | border-color: #E1E1E1; 413 | } 414 | 415 | .card-content-float { 416 | position: absolute; 417 | left: 90px; 418 | right: 10px; 419 | } 420 | 421 | .card-content { 422 | 423 | } 424 | 425 | .card-heading { 426 | font-size: 22px; 427 | font-weight: 800; 428 | white-space: nowrap; 429 | overflow: hidden; 430 | text-overflow: ellipsis; 431 | } 432 | 433 | .card-small-text { 434 | font-size: 13px; 435 | white-space: nowrap; 436 | overflow: hidden; 437 | text-overflow: ellipsis; 438 | } 439 | 440 | .tags { 441 | white-space: nowrap; 442 | overflow: hidden; 443 | text-overflow: ellipsis; 444 | margin-top: 4px; 445 | } 446 | 447 | .tag { 448 | padding-bottom: 1px; 449 | font-size: 10px; 450 | color: #A4A4A4; 451 | padding: 2px; 452 | border-bottom-style: solid; 453 | border-bottom-width: 0px; 454 | background-color: #ECECEC; 455 | margin-right: 5px; 456 | border-radius: 6px; 457 | padding-left: 4px; 458 | padding-right: 4px; 459 | } 460 | 461 | .search-box { 462 | position: relative; 463 | border-style: solid; 464 | border-color: #F2F2F2; 465 | border-width: 2px; 466 | border-radius: 4px; 467 | padding: 6px; 468 | background-color: #ffffff; 469 | margin-top: 10px; 470 | } 471 | 472 | .search-box-entry { 473 | padding-left: 10px; 474 | } 475 | 476 | .search-box-entry-input { 477 | width: 80%; 478 | border-style: none; 479 | font-size: 18px; 480 | } 481 | 482 | .search-box-icon { 483 | position: absolute; 484 | right: 10px; 485 | top: 10px; 486 | } 487 | 488 | .search-box-entry-input:focus { 489 | outline: 0; 490 | } 491 | 492 | .lead { 493 | font-size: 22px; 494 | } 495 | 496 | .centered { 497 | text-align: center; 498 | } 499 | 500 | .login-page { 501 | background: #5B5B5C; 502 | } 503 | 504 | .login-form { 505 | width: 220px; 506 | margin-right: auto; 507 | margin-left: auto; 508 | background: #ffffff; 509 | padding: 20px; 510 | border-radius: 10px; 511 | } 512 | 513 | .form-control { 514 | outline: 0; 515 | border-color: #ECECEC; 516 | border-style: solid; 517 | border-width: 1px; 518 | width: 95%; 519 | background-color: #ffffff; 520 | padding: 6px; 521 | border-radius: 2px; 522 | margin-bottom: 5px; 523 | font-size: 14px; 524 | } 525 | 526 | .form-control-small { 527 | -webkit-transition: width .5s ease-in-out; 528 | -moz-transition: width .5s ease-in-out; 529 | -o-transition: width .5s ease-in-out; 530 | -ms-transition: width .5s ease-in-out; 531 | transition: width .5s ease-in-out; 532 | width: 72%; 533 | } 534 | 535 | .form-control:-webkit-autofill { 536 | background-color: #fff !important; 537 | } 538 | 539 | input:-webkit-autofill { 540 | -webkit-box-shadow: 0 0 0px 1000px white inset; 541 | } 542 | 543 | .error-handler-title { 544 | font-size: 50px; 545 | color: #ffffff; 546 | } 547 | 548 | .error-handler-text { 549 | font-size: 22px; 550 | color: #ffffff; 551 | } 552 | 553 | .icon-spaced { 554 | margin-left: 5px; 555 | } 556 | 557 | .form-control-fill { 558 | width: 96%; 559 | } 560 | 561 | .profile-circle { 562 | position: relative; 563 | top: 10px; 564 | width: 30px; 565 | height: 30px; 566 | display: left; 567 | margin-right: 10px; 568 | border-radius: 50%; 569 | border-color: #363636; 570 | border-width: 1px; 571 | border-style: solid; 572 | } 573 | 574 | .criterion { 575 | font-size: 14px; 576 | display: inline; 577 | margin-left: 2px; 578 | width: 300px; 579 | height: 150px; 580 | position: relative; 581 | } 582 | 583 | .criterion-rating { 584 | padding: 2px; 585 | background-color: #acacac; 586 | border-radius: 0px; 587 | color: #ffffff; 588 | margin-left: 3px; 589 | font-size: 12px; 590 | margin-top: -3px; 591 | padding-left: 5px; 592 | padding-right: 5px; 593 | cursor: pointer; 594 | display: inline; 595 | } 596 | 597 | .criterion-rating-dropdown { 598 | padding: 2px; 599 | border-radius: 0px; 600 | color: #ACACAC; 601 | margin-left: 0px; 602 | font-size: 12px; 603 | margin-top: -3px; 604 | padding-left: 5px; 605 | padding-right: 5px; 606 | cursor: pointer; 607 | display: block; 608 | } 609 | 610 | .criterion-rating-dropdown:hover { 611 | color: #383736; 612 | } 613 | 614 | .criterion-rating-green { 615 | background-color: #5BC25B; 616 | } 617 | 618 | .criterion-rating-red { 619 | background-color: #EA3D35; 620 | } 621 | 622 | .criterion-rating-orange { 623 | background-color: #F88707; 624 | } 625 | 626 | .criterion-dropdown { 627 | width: 60px; 628 | text-align: left; 629 | top: 60px; 630 | left: 100px; 631 | padding: 2px; 632 | background-color: #e0e0e0; 633 | z-index: 9999; 634 | position: relative; 635 | } 636 | 637 | .inline { 638 | display: inline; 639 | } 640 | 641 | .criterion-menu { 642 | display: inline; 643 | } 644 | 645 | input[type="checkbox"] { 646 | -webkit-appearance: checkbox; 647 | padding-bottom: 10px; 648 | cursor: pointer; 649 | } 650 | 651 | .reveal-section { 652 | margin-left: 5px; 653 | margin-right: 5px; 654 | border-radius: 6px; 655 | background-color: #363636; 656 | padding: 10px; 657 | padding-left: 20px; 658 | padding-right: 20px; 659 | color: #ffffff; 660 | } 661 | 662 | .tab-section { 663 | height: 36px; 664 | border-bottom-style: solid; 665 | border-bottom-width: 1px; 666 | border-bottom-color: #E0E0E0; 667 | } 668 | 669 | .tab { 670 | list-style-position: inside; 671 | margin-left: 0px; 672 | list-style-type: none; 673 | padding-left: 5px; 674 | } 675 | 676 | .tab li { 677 | list-style: none; 678 | text-indent: 0px; 679 | margin-left: 10px; 680 | float: left; 681 | border: 1px solid #E0E0E0; 682 | border-bottom-width: 0; 683 | margin-right: 10px; 684 | padding: 8px; 685 | padding-left: 10px; 686 | padding-right: 10px; 687 | border-top-left-radius: 3px; 688 | border-top-right-radius: 3px; 689 | } 690 | 691 | .active-tab { 692 | padding-top: 0px; 693 | font-family: bariol_boldbold; 694 | margin-top: -5px; 695 | color: #000000; 696 | height: 21px; 697 | padding-top: 12px !important; 698 | } 699 | 700 | .active-tab a { 701 | color: #000000; 702 | height: 25px; 703 | padding-top: 13px; 704 | } 705 | 706 | .col-right-align { 707 | text-align: right; 708 | } 709 | 710 | .top-right-float { 711 | position: absolute; 712 | top: 0px; 713 | right: 0px; 714 | } 715 | 716 | .idea-board-settings { 717 | position: absolute; 718 | top: 100px; 719 | right: 0px; 720 | } 721 | 722 | .relative { 723 | position: relative; 724 | } 725 | 726 | .heading-with-icons { 727 | padding-right: 80px; 728 | } 729 | 730 | [contenteditable]:focus { 731 | outline: 0px solid transparent; 732 | } 733 | 734 | .placeholder-colour { 735 | color: #e0e0e0; 736 | } 737 | 738 | .card.ng-show { 739 | -webkit-transition:all linear 0.5s; 740 | transition:all linear 0.5s; 741 | line-height:20px; 742 | opacity:0.2; 743 | padding:10px; 744 | border:1px solid black; 745 | background:black; 746 | } 747 | 748 | .opaque-cover { 749 | position: relative; 750 | top: 0; 751 | left: 0; 752 | opacity: 0.5; 753 | background-color: #000000; 754 | z-index: 9999; 755 | height: 100%; 756 | width: 100%; 757 | } 758 | 759 | .bold-span { 760 | font-family: "bariol_boldbold"; 761 | margin-left: 5px; 762 | } 763 | 764 | .bold-span a { 765 | color: #000000; 766 | } 767 | 768 | .pointer { 769 | cursor: pointer; 770 | } 771 | 772 | .full-screen-card { 773 | background-color: #ffffff; 774 | z-index: 9999; 775 | position: absolute; 776 | left: 0; 777 | top: 50; 778 | width: 100%; 779 | height: 100%; 780 | } 781 | 782 | .card-centered { 783 | width: 60%; 784 | height: 170px; 785 | margin-left: auto; 786 | margin-right: auto; 787 | font-size: 18px; 788 | margin: auto; 789 | padding: 20px; 790 | overflow: auto; 791 | margin-top: 20px; 792 | 793 | } 794 | 795 | .carousel { 796 | position: fixed; 797 | height: 50px; 798 | top: 0; 799 | bottom: 0; 800 | margin-top: auto; 801 | margin-bottom: auto; 802 | font-size: 30px; 803 | cursor: pointer; 804 | color: #E0E0E0; 805 | } 806 | 807 | .left-carousel { 808 | left: 20px; 809 | } 810 | 811 | .right-carousel { 812 | right: 20px; 813 | } 814 | 815 | .right-carousel:hover, .left-carousel:hover { 816 | color: #363636; 817 | } 818 | 819 | .btn-input { 820 | min-width: 95%; 821 | margin-left: auto; 822 | margin-right: auto; 823 | } 824 | 825 | .big-comment-section { 826 | margin-top: 20px; 827 | text-align: left; 828 | width: 70%; 829 | margin-left: auto; 830 | margin-right: auto; 831 | } 832 | 833 | .big-idea { 834 | text-align: center; 835 | } 836 | 837 | .comment { 838 | position: relative; 839 | left: 42px; 840 | top: -28px; 841 | width: 80%; 842 | } 843 | 844 | .comment-holder { 845 | margin-top: -15px; 846 | } 847 | 848 | .comment-entry { 849 | margin-bottom: 10px; 850 | } 851 | 852 | @media screen and (min-width: 680px) { 853 | .comment { 854 | width: 90%; 855 | } 856 | 857 | .btn-input { 858 | position: relative; 859 | left: -3px; 860 | top: -1px; 861 | height: 31px; 862 | padding-top: 6px; 863 | min-width: 30px; 864 | } 865 | 866 | .card-centered { 867 | width: 400px; 868 | height: 250px; 869 | margin-left: auto; 870 | margin-right: auto; 871 | max-width: 800px; 872 | font-size: 30px; 873 | margin: auto; 874 | left: 0; 875 | top: 0; 876 | bottom: 0; 877 | right: 0; 878 | padding: 50px; 879 | margin-top: 40px; 880 | } 881 | 882 | .carousel { 883 | position: fixed; 884 | height: 100px; 885 | top: 0; 886 | bottom: 0; 887 | margin-top: auto; 888 | margin-bottom: auto; 889 | font-size: 100px; 890 | cursor: pointer; 891 | color: #E0E0E0; 892 | } 893 | 894 | .left-carousel { 895 | left: 40px; 896 | } 897 | 898 | .right-carousel { 899 | right: 40px; 900 | } 901 | 902 | .big-comment-section { 903 | margin-top: 20px; 904 | text-align: left; 905 | width: 600px; 906 | margin-left: auto; 907 | margin-right: auto; 908 | } 909 | 910 | .form-control-small { 911 | width: 80%; 912 | } 913 | 914 | .login-form { 915 | width: 500px; 916 | } 917 | } 918 | 919 | .postit { 920 | text-align:center; 921 | width: 275px; 922 | margin: 25px; 923 | min-height:175px; 924 | max-height:175px; 925 | padding-top:35px; 926 | position:relative; 927 | border:1px solid #E8E8E8; 928 | border-top:60px solid #fdfd86; 929 | font-family:'Reenie Beanie'; 930 | font-size:22px; 931 | border-bottom-right-radius: 60px 5px; 932 | display:inline-block; 933 | background: rgb(255,255,136); /* Old browsers */ 934 | background: -moz-linear-gradient(-45deg, rgba(255,255,136,1) 77%, rgba(255,255,214,1) 100%); /* FF3.6+ */ 935 | background: -webkit-gradient(linear, left top, right bottom, color-stop(77%,rgba(255,255,136,1)), color-stop(100%,rgba(255,255,214,1))); /* Chrome,Safari4+ */ 936 | background: -webkit-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* Chrome10+,Safari5.1+ */ 937 | background: -o-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* Opera 11.10+ */ 938 | background: -ms-linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* IE10+ */ 939 | background: linear-gradient(-45deg, rgba(255,255,136,1) 77%,rgba(255,255,214,1) 100%); /* W3C */ 940 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffff88', endColorstr='#ffff88',GradientType=0 ); /* IE6-9 fallback on horizontal gradient */ 941 | } 942 | 943 | .postit:after { 944 | content: ""; 945 | position:absolute; 946 | z-index:-1; 947 | right:-0px; bottom:20px; 948 | width:200px; 949 | height: 25px; 950 | background: rgba(0, 0, 0, 0.2); 951 | box-shadow:2px 15px 5px rgba(0, 0, 0, 0.40); 952 | -moz-transform: matrix(-1, -0.1, 0, 1, 0, 0); 953 | -webkit-transform: matrix(-1, -0.1, 0, 1, 0, 0); 954 | -o-transform: matrix(-1, -0.1, 0, 1, 0, 0); 955 | -ms-transform: matrix(-1, -0.1, 0, 1, 0, 0); 956 | transform: matrix(-1, -0.1, 0, 1, 0, 0); 957 | } 958 | 959 | .top-bar-location { 960 | background-color: rgba(0,0,0,0.1); 961 | position: fixed; 962 | top: 50px; 963 | height: 20px; 964 | width: 100%; 965 | left: 0px; 966 | z-index: 9999; 967 | padding: 1px; 968 | padding-left: 22px; 969 | padding-right: 22px; 970 | font-size: 14px; 971 | color: #000000; 972 | } 973 | 974 | .close-card { 975 | position: fixed; 976 | right: 31px; 977 | top: 65px; 978 | background-color: #e0e0e0; 979 | border-radius: 50%; 980 | width: 30px; 981 | height: 30px; 982 | z-index: 9999; 983 | color: #ACACAC; 984 | font-size: 20px; 985 | cursor: pointer; 986 | text-align: center; 987 | font-family: bariol_boldbold; 988 | } 989 | 990 | .close-card:hover { 991 | color: #000000; 992 | } 993 | 994 | table, th, td 995 | { 996 | font-size: 14px; 997 | border: 1px solid #E0E0E0; 998 | border-collapse: collapse; 999 | 1000 | } 1001 | 1002 | th { 1003 | background-color: #e6e9e8; 1004 | padding: 5px; 1005 | text-align: left; 1006 | 1007 | } 1008 | 1009 | td { 1010 | padding: 5px; 1011 | } 1012 | 1013 | .highlight { 1014 | color: #ff0000; 1015 | } 1016 | 1017 | form input.ng-invalid-autocomplete-required { 1018 | border-color: red; 1019 | } 1020 | 1021 | .valid-status { 1022 | display: inline-block; 1023 | margin-left: 10px; 1024 | } 1025 | 1026 | .valid-status.valid { 1027 | color: green; 1028 | } 1029 | 1030 | .valid-status.invalid { 1031 | color: red; 1032 | } 1033 | 1034 | .console { 1035 | margin-left: 30px; 1036 | font-family: Monaco; 1037 | font-size: 12px; 1038 | color: #ccc; 1039 | } 1040 | 1041 | .small-input { 1042 | width: 30%; 1043 | } 1044 | 1045 | input:disabled { 1046 | background-color: #ddd; 1047 | } 1048 | 1049 | a.page-anchor { 1050 | color: black; 1051 | text-decoration: none; 1052 | } 1053 | 1054 | a.page-anchor:hover { 1055 | color: black; 1056 | } 1057 | 1058 | ul { 1059 | list-style: none; 1060 | } 1061 | 1062 | #ex1_dropdown { 1063 | overflow-y: auto; 1064 | max-height: 150px; 1065 | } 1066 | 1067 | pre { 1068 | width: 600px; 1069 | overflow-x: auto; 1070 | font-family: courier; 1071 | font-size: .8em; 1072 | display: block; 1073 | line-height: 1; 1074 | padding: 10px 15px; 1075 | background-color: #000; 1076 | color: #fff; 1077 | } 1078 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Angucomplete Alt: Autocomplete Directive for AngularJS 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 19 | 20 | Fork me on GitHub 21 | 22 |
23 | 24 |

Angucomplete Alt

25 |

Awesome Autocompleteness for AngularJS

26 |

27 | A minimal looking autocomplete directive originally developed by Daryl Rowland as Angucomplete, and I added a few tweaks to it and renamed it to angucomplete-alt. 28 |

29 | 30 | 50 | 51 |
52 | 53 |

Example 1 - Countries of the World

54 |
55 |
 56 | <div angucomplete-alt id="ex1"
 57 |   placeholder="Search countries"
 58 |   maxlength="50"
 59 |   pause="100"
 60 |   selected-object="selectedCountry"
 61 |   local-data="countries"
 62 |   search-fields="name"
 63 |   title-field="name"
 64 |   minlength="1"
 65 |   input-class="form-control form-control-small"
 66 |   match-class="highlight"></div>
 67 | 
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | You selected {{selectedCountry.originalObject.name}} which has a country code of {{selectedCountry.originalObject.code}} 76 |
77 |
78 | 79 |
80 | 81 |
82 | 83 |

Example 2 - Custom Search

84 |
85 |
 86 | <div angucomplete-alt id="ex2"
 87 |   placeholder="Search people"
 88 |   pause="300"
 89 |   selected-object="selectedPerson"
 90 |   local-data="people"
 91 |   local-search="localSearch"
 92 |   title-field="firstName,surname"
 93 |   description-field="twitter"
 94 |   image-field="pic"
 95 |   minlength="1"
 96 |   input-class="form-control form-control-small"
 97 |   match-class="highlight">
 98 | </div>
 99 | 
100 |
101 |
102 | // search function to match full text
103 | $scope.localSearch = function(str, people) {
104 |   var matches = [];
105 |   people.forEach(function(person) {
106 |     var fullName = person.firstName + ' ' + person.surname;
107 |     if ((person.firstName.toLowerCase().indexOf(str.toString().toLowerCase()) >= 0) ||
108 |         (person.surname.toLowerCase().indexOf(str.toString().toLowerCase()) >= 0) ||
109 |         (fullName.toLowerCase().indexOf(str.toString().toLowerCase()) >= 0)) {
110 |       matches.push(person);
111 |     }
112 |   });
113 |   return matches;
114 | };
115 | 
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | You selected {{selectedPerson.originalObject.firstName}} {{selectedPerson.originalObject.surname}} 124 |
125 |
126 | 127 |
128 | 129 |
130 | 131 |

Example 3 - Clear Result on Selection

132 |
133 |
134 | <div angucomplete-alt id="ex3"
135 |   placeholder="Search countries"
136 |   pause="100"
137 |   selected-object="selectedCountry3"
138 |   local-data="countries"
139 |   search-fields="name"
140 |   title-field="name"
141 |   minlength="1"
142 |   input-class="form-control form-control-small"
143 |   match-class="highlight"
144 |   clear-selected="true">
145 | </div>
146 | 
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 | You selected {{selectedCountry3.originalObject.name}} which has a country code of {{selectedCountry3.originalObject.code}} 155 |
156 |
157 | 158 |
159 | 160 |
161 | 162 |

Example 4 - Override Suggestion with Clear Results

163 |
164 |
165 | <div angucomplete-alt
166 |   id="ex4"
167 |   placeholder="Search countries"
168 |   pause="100"
169 |   selected-object="selectedCountry4"
170 |   local-data="countries"
171 |   search-fields="name"
172 |   title-field="name"
173 |   minlength="1"
174 |   input-class="form-control form-control-small"
175 |   match-class="highlight"
176 |   override-suggestions="true"
177 |   clear-selected="true">
178 | </div>
179 | 
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 | You selected {{selectedCountry4.originalObject}} 188 |
189 |
190 | 191 |
192 | 193 |
194 | 195 |

Example 5 - Using GitHub Search API

196 |
197 |
198 | <div angucomplete-alt
199 |   id="ex5"
200 |   placeholder="Search projects"
201 |   pause="500"
202 |   selected-object="selectedProject"
203 |   remote-url="https://api.github.com/search/repositories"
204 |   remote-url-request-formatter="remoteUrlRequestFn"
205 |   remote-url-data-field="items"
206 |   title-field="name"
207 |   description-field="description"
208 |   minlength="2"
209 |   input-class="form-control form-control-small"
210 |   match-class="highlight">
211 | </div>
212 | 
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 | Repository: {{selectedProject.originalObject.git_url}} 221 |
222 |
223 | 224 |
225 | 226 |
227 | 228 |

Example 6 - Show Matches in Both Name and Description

229 |
230 |
231 | <div angucomplete-alt
232 |   id="ex6"
233 |   placeholder="Search countries"
234 |   pause="100"
235 |   selected-object="selectedCountry6"
236 |   local-data="countries"
237 |   search-fields="name,code"
238 |   title-field="name"
239 |   description-field="code"
240 |   minlength="1"
241 |   input-class="form-control form-control-small"
242 |   match-class="highlight">
243 | </div>
244 | 
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 | You selected {{selectedCountry6.title}} which has a country code of {{selectedCountry6.description}} 253 |
254 |
255 | 256 |
257 | 258 |
259 | 260 |

Example 7 - Callback

261 |
262 |
263 | <div angucomplete-alt
264 |   id="ex7"
265 |   placeholder="Search countries"
266 |   pause="100"
267 |   selected-object="countrySelected"
268 |   local-data="countries"
269 |   search-fields="name"
270 |   title-field="name"
271 |   minlength="1"
272 |   input-class="form-control form-control-small"
273 |   match-class="highlight">
274 | </div>
275 | 
276 |
277 |
278 |
279 |
280 |
281 | 282 |
283 | 284 |
285 | 286 |
287 | <form name="form">
288 |   <h3><a name="example8" class="page-anchor">Example 8 - Required</a><span ng-show="form.$valid" class="valid-status valid">[VALID]</span><span class="valid-status invalid" ng-show="form.$invalid">[INVALID]</span></h3>
289 |   <div class="padded-row">
290 |     <span>Choose two countries</span>
291 |     <div angucomplete-alt
292 |       id="ex8a"
293 |       placeholder="Search countries"
294 |       pause="100"
295 |       selected-object="countrySelected8a"
296 |       local-data="countries"
297 |       search-fields="name"
298 |       title-field="name"
299 |       minlength="1"
300 |       input-class="form-control form-control-small"
301 |       match-class="highlight"
302 |       field-required="true"
303 |       input-name="country8a">
304 |     </div>
305 | 
306 |     <div angucomplete-alt
307 |       id="ex8b"
308 |       placeholder="Search countries"
309 |       pause="100"
310 |       selected-object="countrySelected8b"
311 |       local-data="countries"
312 |       search-fields="name"
313 |       title-field="name"
314 |       minlength="1"
315 |       input-class="form-control form-control-small"
316 |       match-class="highlight"
317 |       field-required="true"
318 |       input-name="country8b">
319 |     </div>
320 |   </div>
321 | </form>
322 | 
323 |
324 |

Example 8 - Required[VALID][INVALID]

325 |
326 | Choose two countries 327 |
328 |
329 | 330 |
331 |
332 |
333 |
334 | 335 |
336 | 337 |
338 | 339 |

Example 9 - Initial Value

340 |
341 |
342 | <div angucomplete-alt
343 |   id="ex9"
344 |   placeholder="Search countries"
345 |   pause="100"
346 |   selected-object="countrySelectedFn9"
347 |   local-data="countries"
348 |   search-fields="name"
349 |   title-field="name"
350 |   minlength="1"
351 |   input-class="form-control form-control-small"
352 |   match-class="highlight"
353 |   initial-value="countrySelected9">
354 | </div>
355 | 
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 | You selected {{countrySelected9.name}} 364 |
365 |
366 | 367 |
368 | 369 |
370 | 371 |

Example 10 - Track Input Changescurrent input field value: {{ console10 }}

372 |
373 |
374 | <div angucomplete-alt
375 |   id="ex10"
376 |   placeholder="Search countries"
377 |   pause="100"
378 |   selected-object="countrySelected10"
379 |   local-data="countries"
380 |   search-fields="name"
381 |   title-field="name"
382 |   minlength="1"
383 |   input-class="form-control form-control-small"
384 |   match-class="highlight"
385 |   input-changed="inputChanged">
386 | </div>
387 | 
388 |
389 |
390 |
391 |
392 | 393 |
394 | 395 |
396 | 397 |

Example 11 - Auto Match

398 |
399 |
400 | <div angucomplete-alt
401 |   id="ex11"
402 |   placeholder="Search countries"
403 |   pause="100"
404 |   selected-object="countrySelected11"
405 |   local-data="countries"
406 |   search-fields="name"
407 |   title-field="name"
408 |   minlength="2"
409 |   input-class="form-control form-control-small"
410 |   match-class="highlight"
411 |   auto-match="true">
412 | </div>
413 | 
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 | You selected {{countrySelected11.originalObject.name}} which has a country code of {{countrySelected11.originalObject.code}} 422 |
423 |
424 | 425 |
426 | 427 |
428 | 429 |

Example 12 - Track Input Focusinput field focus state: {{ focusState }}

430 |
431 |
432 | <div angucomplete-alt
433 |   id="ex12"
434 |   placeholder="Search countries"
435 |   pause="100"
436 |   selected-object="countrySelected12"
437 |   local-data="countries"
438 |   search-fields="name"
439 |   title-field="name"
440 |   minlength="1"
441 |   input-class="form-control form-control-small small-input"
442 |   match-class="highlight"
443 |   focus-in="focusIn()"
444 |   focus-out="focusOut()">
445 | </div>
446 | 
447 |
448 |
449 |
450 |
451 | 452 |
453 | 454 |
455 | 456 |

Example 13 - Disable/Enable Inputdisable

457 |
458 |
459 | <div angucomplete-alt
460 |   id="ex13"
461 |   placeholder="Search countries"
462 |   pause="100"
463 |   selected-object="countrySelected13"
464 |   local-data="countries"
465 |   search-fields="name"
466 |   title-field="name"
467 |   minlength="1"
468 |   input-class="form-control form-control-small"
469 |   match-class="highlight"
470 |   disable-input="disableInput">
471 | </div>
472 | 
473 |
474 |
475 |
476 |
477 |
478 |
479 |
480 | You selected {{countrySelected13.originalObject.name}} which has a country code of {{countrySelected13.originalObject.code}} 481 |
482 |
483 | 484 |
485 | 486 |
487 | 488 |

Example 14 - Custom template

489 |
490 | 524 |
525 |
526 | 527 |
528 |
529 | <div angucomplete-alt
530 |   id="ex14"
531 |   placeholder="Search countries"
532 |   pause="100"
533 |   selected-object="countrySelected14"
534 |   local-data="countries"
535 |   search-fields="name"
536 |   title-field="name"
537 |   minlength="1"
538 |   input-class="form-control form-control-small"
539 |   match-class="highlight"
540 |   template-url="/my-custom-template.html">
541 | </div>
542 | 
543 |
544 |
545 |
556 |
557 | 558 |
559 |
560 | 561 | You selected {{countrySelected14.originalObject.name}} which has a country code of {{countrySelected14.originalObject.code}} 562 | 563 | 564 | You selected a custom country {{countrySelected14.originalObject.name}} 565 | 566 |
567 |
568 |
569 | 570 |
571 |

Example 15 - Clear Input on Button Click

572 |
573 |
574 | <div angucomplete-alt id="ex15"
575 |   placeholder="Search countries"
576 |   maxlength="50"
577 |   pause="100"
578 |   selected-object="selectedCountry15"
579 |   local-data="countries"
580 |   search-fields="name"
581 |   title-field="name"
582 |   minlength="1"
583 |   input-class="form-control form-control-small"
584 |   match-class="highlight">
585 | </div>
586 | 
587 |
588 |
589 |
600 |
601 |
602 | 603 |
604 | 605 | 606 | 607 |
608 | 609 |
610 |
611 | You selected {{selectedCountry15.originalObject.name}} which has a country code of {{selectedCountry15.originalObject.code}} 612 |
613 |
614 |
615 | 616 |
617 |

Example 16 - Change Input on Button Click

618 |
619 |
620 | <div angucomplete-alt id="ex16"
621 |    placeholder="Search countries"
622 |    maxlength="50"
623 |    pause="100"
624 |    selected-object="selectedCountry16"
625 |    initial-value="selectedCountry16"
626 |    local-data="countries"
627 |    search-fields="name"
628 |    title-field="name"
629 |    minlength="1"
630 |    input-class="form-control form-control-small"
631 |    match-class="highlight">
632 | </div>
633 | 
634 |
635 |
636 |
648 |
649 |
650 | 651 |
652 | 653 | 654 |
655 | 656 |
657 |
658 | You selected {{selectedCountry16.originalObject.name}} which has a country code of {{selectedCountry16.originalObject.code}} 659 |
660 |
661 |
662 | 663 |
664 |
Originally developed by Daryl Rowland (@darylrowland)
665 |
Forked and developed by Hidenari Nozaki (@ghiden)
666 |
667 | 668 | 669 | 670 | 671 | 672 |
673 | 674 | 675 | -------------------------------------------------------------------------------- /angucomplete-alt.js: -------------------------------------------------------------------------------- 1 | /* 2 | * angucomplete-alt 3 | * Autocomplete directive for AngularJS 4 | * This is a fork of Daryl Rowland's angucomplete with some extra features. 5 | * By Hidenari Nozaki 6 | */ 7 | 8 | /*! Copyright (c) 2014 Hidenari Nozaki and contributors | Licensed under the MIT license */ 9 | 10 | (function (root, factory) { 11 | 'use strict'; 12 | if (typeof module !== 'undefined' && module.exports) { 13 | // CommonJS 14 | module.exports = factory(require('angular')); 15 | } else if (typeof define === 'function' && define.amd) { 16 | // AMD 17 | define(['angular'], factory); 18 | } else { 19 | // Global Variables 20 | factory(root.angular); 21 | } 22 | }(window, function (angular) { 23 | 'use strict'; 24 | 25 | angular.module('angucomplete-alt', []).directive('angucompleteAlt', ['$q', '$parse', '$http', '$sce', '$timeout', '$templateCache', '$interpolate', function ($q, $parse, $http, $sce, $timeout, $templateCache, $interpolate) { 26 | // keyboard events 27 | var KEY_DW = 40; 28 | var KEY_RT = 39; 29 | var KEY_UP = 38; 30 | var KEY_LF = 37; 31 | var KEY_ES = 27; 32 | var KEY_EN = 13; 33 | var KEY_TAB = 9; 34 | 35 | var MIN_LENGTH = 3; 36 | var MAX_LENGTH = 524288; // the default max length per the html maxlength attribute 37 | var PAUSE = 500; 38 | var BLUR_TIMEOUT = 200; 39 | 40 | // string constants 41 | var REQUIRED_CLASS = 'autocomplete-required'; 42 | var TEXT_SEARCHING = 'Searching...'; 43 | var TEXT_NORESULTS = 'No results found'; 44 | var TEMPLATE_URL = '/angucomplete-alt/index.html'; 45 | 46 | // Set the default template for this directive 47 | $templateCache.put(TEMPLATE_URL, 48 | '
' + 49 | ' ' + 50 | '
' + 51 | '
' + 52 | '
' + 53 | '
' + 54 | '
' + 55 | ' ' + 56 | '
' + 57 | '
' + 58 | '
' + 59 | '
{{ result.title }}
' + 60 | '
' + 61 | '
{{result.description}}
' + 62 | '
' + 63 | '
' + 64 | '
' 65 | ); 66 | 67 | function link(scope, elem, attrs, ctrl) { 68 | var inputField = elem.find('input'); 69 | var minlength = MIN_LENGTH; 70 | var searchTimer = null; 71 | var hideTimer; 72 | var requiredClassName = REQUIRED_CLASS; 73 | var responseFormatter; 74 | var validState = null; 75 | var httpCanceller = null; 76 | var httpCallInProgress = false; 77 | var dd = elem[0].querySelector('.angucomplete-dropdown'); 78 | var isScrollOn = false; 79 | var mousedownOn = null; 80 | var unbindInitialValue; 81 | var displaySearching; 82 | var displayNoResults; 83 | 84 | elem.on('mousedown', function(event) { 85 | if (event.target.id) { 86 | mousedownOn = event.target.id; 87 | if (mousedownOn === scope.id + '_dropdown') { 88 | document.body.addEventListener('click', clickoutHandlerForDropdown); 89 | } 90 | } 91 | else { 92 | mousedownOn = event.target.className; 93 | } 94 | }); 95 | 96 | scope.currentIndex = scope.focusFirst ? 0 : null; 97 | scope.searching = false; 98 | unbindInitialValue = scope.$watch('initialValue', function(newval) { 99 | if (newval) { 100 | // remove scope listener 101 | unbindInitialValue(); 102 | // change input 103 | handleInputChange(newval, true); 104 | } 105 | }); 106 | 107 | scope.$watch('fieldRequired', function(newval, oldval) { 108 | if (newval !== oldval) { 109 | if (!newval) { 110 | ctrl[scope.inputName].$setValidity(requiredClassName, true); 111 | } 112 | else if (!validState || scope.currentIndex === -1) { 113 | handleRequired(false); 114 | } 115 | else { 116 | handleRequired(true); 117 | } 118 | } 119 | }); 120 | 121 | scope.$on('angucomplete-alt:clearInput', function (event, elementId) { 122 | if (!elementId || elementId === scope.id) { 123 | scope.searchStr = null; 124 | callOrAssign(); 125 | handleRequired(false); 126 | clearResults(); 127 | } 128 | }); 129 | 130 | scope.$on('angucomplete-alt:changeInput', function (event, elementId, newval) { 131 | if (!!elementId && elementId === scope.id) { 132 | handleInputChange(newval); 133 | } 134 | }); 135 | 136 | function handleInputChange(newval, initial) { 137 | if (newval) { 138 | if (typeof newval === 'object') { 139 | scope.searchStr = extractTitle(newval); 140 | callOrAssign({originalObject: newval}); 141 | } else if (typeof newval === 'string' && newval.length > 0) { 142 | scope.searchStr = newval; 143 | } else { 144 | if (console && console.error) { 145 | console.error('Tried to set ' + (!!initial ? 'initial' : '') + ' value of angucomplete to', newval, 'which is an invalid value'); 146 | } 147 | } 148 | 149 | handleRequired(true); 150 | } 151 | } 152 | 153 | // #194 dropdown list not consistent in collapsing (bug). 154 | function clickoutHandlerForDropdown(event) { 155 | mousedownOn = null; 156 | scope.hideResults(event); 157 | document.body.removeEventListener('click', clickoutHandlerForDropdown); 158 | } 159 | 160 | // for IE8 quirkiness about event.which 161 | function ie8EventNormalizer(event) { 162 | return event.which ? event.which : event.keyCode; 163 | } 164 | 165 | function callOrAssign(value) { 166 | if (typeof scope.selectedObject === 'function') { 167 | scope.selectedObject(value, scope.selectedObjectData); 168 | } 169 | else { 170 | scope.selectedObject = value; 171 | } 172 | 173 | if (value) { 174 | handleRequired(true); 175 | } 176 | else { 177 | handleRequired(false); 178 | } 179 | } 180 | 181 | function callFunctionOrIdentity(fn) { 182 | return function(data) { 183 | return scope[fn] ? scope[fn](data) : data; 184 | }; 185 | } 186 | 187 | function setInputString(str) { 188 | callOrAssign({originalObject: str}); 189 | 190 | if (scope.clearSelected) { 191 | scope.searchStr = null; 192 | } 193 | clearResults(); 194 | } 195 | 196 | function extractTitle(data) { 197 | // split title fields and run extractValue for each and join with ' ' 198 | return scope.titleField.split(',') 199 | .map(function(field) { 200 | return extractValue(data, field); 201 | }) 202 | .join(' '); 203 | } 204 | 205 | function extractValue(obj, key) { 206 | var keys, result; 207 | if (key) { 208 | keys= key.split('.'); 209 | result = obj; 210 | for (var i = 0; i < keys.length; i++) { 211 | result = result[keys[i]]; 212 | } 213 | } 214 | else { 215 | result = obj; 216 | } 217 | return result; 218 | } 219 | 220 | function findMatchString(target, str) { 221 | var result, matches, re; 222 | // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions 223 | // Escape user input to be treated as a literal string within a regular expression 224 | re = new RegExp(str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'i'); 225 | if (!target) { return; } 226 | if (!target.match || !target.replace) { target = target.toString(); } 227 | matches = target.match(re); 228 | if (matches) { 229 | result = target.replace(re, 230 | ''+ matches[0] +''); 231 | } 232 | else { 233 | result = target; 234 | } 235 | return $sce.trustAsHtml(result); 236 | } 237 | 238 | function handleRequired(valid) { 239 | scope.notEmpty = valid; 240 | validState = scope.searchStr; 241 | if (scope.fieldRequired && ctrl && scope.inputName) { 242 | ctrl[scope.inputName].$setValidity(requiredClassName, valid); 243 | } 244 | } 245 | 246 | function keyupHandler(event) { 247 | var which = ie8EventNormalizer(event); 248 | if (which === KEY_LF || which === KEY_RT) { 249 | // do nothing 250 | return; 251 | } 252 | 253 | if (which === KEY_UP || which === KEY_EN) { 254 | event.preventDefault(); 255 | } 256 | else if (which === KEY_DW) { 257 | event.preventDefault(); 258 | if (!scope.showDropdown && scope.searchStr && scope.searchStr.length >= minlength) { 259 | initResults(); 260 | scope.searching = true; 261 | searchTimerComplete(scope.searchStr); 262 | } 263 | } 264 | else if (which === KEY_ES) { 265 | clearResults(); 266 | scope.$apply(function() { 267 | inputField.val(scope.searchStr); 268 | }); 269 | } 270 | else { 271 | if (minlength === 0 && !scope.searchStr) { 272 | return; 273 | } 274 | 275 | if (!scope.searchStr || scope.searchStr === '') { 276 | scope.showDropdown = false; 277 | } else if (scope.searchStr.length >= minlength) { 278 | initResults(); 279 | 280 | if (searchTimer) { 281 | $timeout.cancel(searchTimer); 282 | } 283 | 284 | scope.searching = true; 285 | 286 | searchTimer = $timeout(function() { 287 | searchTimerComplete(scope.searchStr); 288 | }, scope.pause); 289 | } 290 | 291 | if (validState && validState !== scope.searchStr && !scope.clearSelected) { 292 | scope.$apply(function() { 293 | callOrAssign(); 294 | }); 295 | } 296 | } 297 | } 298 | 299 | function handleOverrideSuggestions(event) { 300 | if (scope.overrideSuggestions && 301 | !(scope.selectedObject && scope.selectedObject.originalObject === scope.searchStr)) { 302 | if (event) { 303 | event.preventDefault(); 304 | } 305 | 306 | // cancel search timer 307 | $timeout.cancel(searchTimer); 308 | // cancel http request 309 | cancelHttpRequest(); 310 | 311 | setInputString(scope.searchStr); 312 | } 313 | } 314 | 315 | function dropdownRowOffsetHeight(row) { 316 | var css = getComputedStyle(row); 317 | return row.offsetHeight + 318 | parseInt(css.marginTop, 10) + parseInt(css.marginBottom, 10); 319 | } 320 | 321 | function dropdownHeight() { 322 | return dd.getBoundingClientRect().top + 323 | parseInt(getComputedStyle(dd).maxHeight, 10); 324 | } 325 | 326 | function dropdownRow() { 327 | return elem[0].querySelectorAll('.angucomplete-row')[scope.currentIndex]; 328 | } 329 | 330 | function dropdownRowTop() { 331 | return dropdownRow().getBoundingClientRect().top - 332 | (dd.getBoundingClientRect().top + 333 | parseInt(getComputedStyle(dd).paddingTop, 10)); 334 | } 335 | 336 | function dropdownScrollTopTo(offset) { 337 | dd.scrollTop = dd.scrollTop + offset; 338 | } 339 | 340 | function updateInputField(){ 341 | var current = scope.results[scope.currentIndex]; 342 | if (scope.matchClass) { 343 | inputField.val(extractTitle(current.originalObject)); 344 | } 345 | else { 346 | inputField.val(current.title); 347 | } 348 | } 349 | 350 | function keydownHandler(event) { 351 | var which = ie8EventNormalizer(event); 352 | var row = null; 353 | var rowTop = null; 354 | 355 | if (which === KEY_EN && scope.results) { 356 | if (scope.currentIndex >= 0 && scope.currentIndex < scope.results.length) { 357 | event.preventDefault(); 358 | scope.selectResult(scope.results[scope.currentIndex]); 359 | } else { 360 | handleOverrideSuggestions(event); 361 | clearResults(); 362 | } 363 | scope.$apply(); 364 | } else if (which === KEY_DW && scope.results) { 365 | event.preventDefault(); 366 | if ((scope.currentIndex + 1) < scope.results.length && scope.showDropdown) { 367 | scope.$apply(function() { 368 | scope.currentIndex ++; 369 | updateInputField(); 370 | }); 371 | 372 | if (isScrollOn) { 373 | row = dropdownRow(); 374 | if (dropdownHeight() < row.getBoundingClientRect().bottom) { 375 | dropdownScrollTopTo(dropdownRowOffsetHeight(row)); 376 | } 377 | } 378 | } 379 | } else if (which === KEY_UP && scope.results) { 380 | event.preventDefault(); 381 | if (scope.currentIndex >= 1) { 382 | scope.$apply(function() { 383 | scope.currentIndex --; 384 | updateInputField(); 385 | }); 386 | 387 | if (isScrollOn) { 388 | rowTop = dropdownRowTop(); 389 | if (rowTop < 0) { 390 | dropdownScrollTopTo(rowTop - 1); 391 | } 392 | } 393 | } 394 | else if (scope.currentIndex === 0) { 395 | scope.$apply(function() { 396 | scope.currentIndex = -1; 397 | inputField.val(scope.searchStr); 398 | }); 399 | } 400 | } else if (which === KEY_TAB) { 401 | if (scope.results && scope.results.length > 0 && scope.showDropdown) { 402 | if (scope.currentIndex === -1 && scope.overrideSuggestions) { 403 | // intentionally not sending event so that it does not 404 | // prevent default tab behavior 405 | handleOverrideSuggestions(); 406 | } 407 | else { 408 | if (scope.currentIndex === -1) { 409 | scope.currentIndex = 0; 410 | } 411 | scope.selectResult(scope.results[scope.currentIndex]); 412 | scope.$digest(); 413 | } 414 | } 415 | else { 416 | // no results 417 | // intentionally not sending event so that it does not 418 | // prevent default tab behavior 419 | if (scope.searchStr && scope.searchStr.length > 0) { 420 | handleOverrideSuggestions(); 421 | } 422 | } 423 | } else if (which === KEY_ES) { 424 | // This is very specific to IE10/11 #272 425 | // without this, IE clears the input text 426 | event.preventDefault(); 427 | } 428 | } 429 | 430 | function httpSuccessCallbackGen(str) { 431 | return function(responseData, status, headers, config) { 432 | // normalize return obejct from promise 433 | if (!status && !headers && !config && responseData.data) { 434 | responseData = responseData.data; 435 | } 436 | scope.searching = false; 437 | processResults( 438 | extractValue(responseFormatter(responseData), scope.remoteUrlDataField), 439 | str); 440 | }; 441 | } 442 | 443 | function httpErrorCallback(errorRes, status, headers, config) { 444 | scope.searching = httpCallInProgress; 445 | 446 | // normalize return obejct from promise 447 | if (!status && !headers && !config) { 448 | status = errorRes.status; 449 | } 450 | 451 | // cancelled/aborted 452 | if (status === 0 || status === -1) { return; } 453 | if (scope.remoteUrlErrorCallback) { 454 | scope.remoteUrlErrorCallback(errorRes, status, headers, config); 455 | } 456 | else { 457 | if (console && console.error) { 458 | console.error('http error'); 459 | } 460 | } 461 | } 462 | 463 | function cancelHttpRequest() { 464 | if (httpCanceller) { 465 | httpCanceller.resolve(); 466 | } 467 | } 468 | 469 | function getRemoteResults(str) { 470 | var params = {}, 471 | url = scope.remoteUrl + encodeURIComponent(str); 472 | if (scope.remoteUrlRequestFormatter) { 473 | params = {params: scope.remoteUrlRequestFormatter(str)}; 474 | url = scope.remoteUrl; 475 | } 476 | if (!!scope.remoteUrlRequestWithCredentials) { 477 | params.withCredentials = true; 478 | } 479 | cancelHttpRequest(); 480 | httpCanceller = $q.defer(); 481 | params.timeout = httpCanceller.promise; 482 | httpCallInProgress = true; 483 | $http.get(url, params) 484 | .then(httpSuccessCallbackGen(str)) 485 | .catch(httpErrorCallback) 486 | .finally(function(){httpCallInProgress=false;}); 487 | } 488 | 489 | function getRemoteResultsWithCustomHandler(str) { 490 | cancelHttpRequest(); 491 | 492 | httpCanceller = $q.defer(); 493 | 494 | scope.remoteApiHandler(str, httpCanceller.promise) 495 | .then(httpSuccessCallbackGen(str)) 496 | .catch(httpErrorCallback); 497 | 498 | /* IE8 compatible 499 | scope.remoteApiHandler(str, httpCanceller.promise) 500 | ['then'](httpSuccessCallbackGen(str)) 501 | ['catch'](httpErrorCallback); 502 | */ 503 | } 504 | 505 | function clearResults() { 506 | scope.showDropdown = false; 507 | scope.results = []; 508 | if (dd) { 509 | dd.scrollTop = 0; 510 | } 511 | } 512 | 513 | function initResults() { 514 | scope.showDropdown = displaySearching; 515 | scope.currentIndex = scope.focusFirst ? 0 : -1; 516 | scope.results = []; 517 | } 518 | 519 | function getLocalResults(str) { 520 | var i, match, s, value, 521 | searchFields = scope.searchFields.split(','), 522 | matches = []; 523 | if (typeof scope.parseInput() !== 'undefined') { 524 | str = scope.parseInput()(str); 525 | } 526 | for (i = 0; i < scope.localData.length; i++) { 527 | match = false; 528 | 529 | for (s = 0; s < searchFields.length; s++) { 530 | value = extractValue(scope.localData[i], searchFields[s]) || ''; 531 | match = match || (value.toString().toLowerCase().indexOf(str.toString().toLowerCase()) >= 0); 532 | } 533 | 534 | if (match) { 535 | matches[matches.length] = scope.localData[i]; 536 | } 537 | } 538 | return matches; 539 | } 540 | 541 | function checkExactMatch(result, obj, str){ 542 | if (!str) { return false; } 543 | for(var key in obj){ 544 | if(obj[key].toLowerCase() === str.toLowerCase()){ 545 | scope.selectResult(result); 546 | return true; 547 | } 548 | } 549 | return false; 550 | } 551 | 552 | function searchTimerComplete(str) { 553 | // Begin the search 554 | if (!str || str.length < minlength) { 555 | return; 556 | } 557 | if (scope.localData) { 558 | scope.$apply(function() { 559 | var matches; 560 | if (typeof scope.localSearch() !== 'undefined') { 561 | matches = scope.localSearch()(str, scope.localData); 562 | } else { 563 | matches = getLocalResults(str); 564 | } 565 | scope.searching = false; 566 | processResults(matches, str); 567 | }); 568 | } 569 | else if (scope.remoteApiHandler) { 570 | getRemoteResultsWithCustomHandler(str); 571 | } else { 572 | getRemoteResults(str); 573 | } 574 | } 575 | 576 | function processResults(responseData, str) { 577 | var i, description, image, text, formattedText, formattedDesc; 578 | 579 | if (responseData && responseData.length > 0) { 580 | scope.results = []; 581 | 582 | for (i = 0; i < responseData.length; i++) { 583 | if (scope.titleField && scope.titleField !== '') { 584 | text = formattedText = extractTitle(responseData[i]); 585 | } 586 | 587 | description = ''; 588 | if (scope.descriptionField) { 589 | description = formattedDesc = extractValue(responseData[i], scope.descriptionField); 590 | } 591 | 592 | image = ''; 593 | if (scope.imageField) { 594 | image = extractValue(responseData[i], scope.imageField); 595 | } 596 | 597 | if (scope.matchClass) { 598 | formattedText = findMatchString(text, str); 599 | formattedDesc = findMatchString(description, str); 600 | } 601 | 602 | scope.results[scope.results.length] = { 603 | title: formattedText, 604 | description: formattedDesc, 605 | image: image, 606 | originalObject: responseData[i] 607 | }; 608 | } 609 | 610 | } else { 611 | scope.results = []; 612 | } 613 | 614 | if (scope.autoMatch && scope.results.length === 1 && 615 | checkExactMatch(scope.results[0], 616 | {title: text, desc: description || ''}, scope.searchStr)) { 617 | scope.showDropdown = false; 618 | } else if (scope.results.length === 0 && !displayNoResults) { 619 | scope.showDropdown = false; 620 | } else { 621 | scope.showDropdown = true; 622 | } 623 | } 624 | 625 | function showAll() { 626 | if (scope.localData) { 627 | scope.searching = false; 628 | processResults(scope.localData, ''); 629 | } 630 | else if (scope.remoteApiHandler) { 631 | scope.searching = true; 632 | getRemoteResultsWithCustomHandler(''); 633 | } 634 | else { 635 | scope.searching = true; 636 | getRemoteResults(''); 637 | } 638 | } 639 | 640 | scope.onFocusHandler = function() { 641 | if (scope.focusIn) { 642 | scope.focusIn(); 643 | } 644 | if (minlength === 0 && (!scope.searchStr || scope.searchStr.length === 0)) { 645 | scope.currentIndex = scope.focusFirst ? 0 : scope.currentIndex; 646 | scope.showDropdown = true; 647 | showAll(); 648 | } 649 | }; 650 | 651 | scope.hideResults = function() { 652 | if (mousedownOn && 653 | (mousedownOn === scope.id + '_dropdown' || 654 | mousedownOn.indexOf('angucomplete') >= 0)) { 655 | mousedownOn = null; 656 | } 657 | else { 658 | hideTimer = $timeout(function() { 659 | clearResults(); 660 | scope.$apply(function() { 661 | if (scope.searchStr && scope.searchStr.length > 0) { 662 | inputField.val(scope.searchStr); 663 | } 664 | }); 665 | }, BLUR_TIMEOUT); 666 | cancelHttpRequest(); 667 | 668 | if (scope.focusOut) { 669 | scope.focusOut(); 670 | } 671 | 672 | if (scope.overrideSuggestions) { 673 | if (scope.searchStr && scope.searchStr.length > 0 && scope.currentIndex === -1) { 674 | handleOverrideSuggestions(); 675 | } 676 | } 677 | } 678 | }; 679 | 680 | scope.resetHideResults = function() { 681 | if (hideTimer) { 682 | $timeout.cancel(hideTimer); 683 | } 684 | }; 685 | 686 | scope.hoverRow = function(index) { 687 | scope.currentIndex = index; 688 | }; 689 | 690 | scope.selectResult = function(result) { 691 | // Restore original values 692 | if (scope.matchClass) { 693 | result.title = extractTitle(result.originalObject); 694 | result.description = extractValue(result.originalObject, scope.descriptionField); 695 | } 696 | 697 | if (scope.clearSelected) { 698 | scope.searchStr = null; 699 | } 700 | else { 701 | scope.searchStr = result.title; 702 | } 703 | callOrAssign(result); 704 | clearResults(); 705 | }; 706 | 707 | scope.inputChangeHandler = function(str) { 708 | if (str.length < minlength) { 709 | cancelHttpRequest(); 710 | clearResults(); 711 | } 712 | else if (str.length === 0 && minlength === 0) { 713 | showAll(); 714 | } 715 | 716 | if (scope.inputChanged) { 717 | str = scope.inputChanged(str); 718 | } 719 | return str; 720 | }; 721 | 722 | // check required 723 | if (scope.fieldRequiredClass && scope.fieldRequiredClass !== '') { 724 | requiredClassName = scope.fieldRequiredClass; 725 | } 726 | 727 | // check min length 728 | if (scope.minlength && scope.minlength !== '') { 729 | minlength = parseInt(scope.minlength, 10); 730 | } 731 | 732 | // check pause time 733 | if (!scope.pause) { 734 | scope.pause = PAUSE; 735 | } 736 | 737 | // check clearSelected 738 | if (!scope.clearSelected) { 739 | scope.clearSelected = false; 740 | } 741 | 742 | // check override suggestions 743 | if (!scope.overrideSuggestions) { 744 | scope.overrideSuggestions = false; 745 | } 746 | 747 | // check required field 748 | if (scope.fieldRequired && ctrl) { 749 | // check initial value, if given, set validitity to true 750 | if (scope.initialValue) { 751 | handleRequired(true); 752 | } 753 | else { 754 | handleRequired(false); 755 | } 756 | } 757 | 758 | scope.inputType = attrs.type ? attrs.type : 'text'; 759 | 760 | // set strings for "Searching..." and "No results" 761 | scope.textSearching = attrs.textSearching ? attrs.textSearching : TEXT_SEARCHING; 762 | scope.textNoResults = attrs.textNoResults ? attrs.textNoResults : TEXT_NORESULTS; 763 | displaySearching = scope.textSearching === 'false' ? false : true; 764 | displayNoResults = scope.textNoResults === 'false' ? false : true; 765 | 766 | // set max length (default to maxlength deault from html 767 | scope.maxlength = attrs.maxlength ? attrs.maxlength : MAX_LENGTH; 768 | 769 | // register events 770 | inputField.on('keydown', keydownHandler); 771 | inputField.on('keyup compositionend', keyupHandler); 772 | 773 | // set response formatter 774 | responseFormatter = callFunctionOrIdentity('remoteUrlResponseFormatter'); 775 | 776 | // set isScrollOn 777 | $timeout(function() { 778 | var css = getComputedStyle(dd); 779 | isScrollOn = css.maxHeight && css.overflowY === 'auto'; 780 | }); 781 | } 782 | 783 | return { 784 | restrict: 'EA', 785 | require: '^?form', 786 | scope: { 787 | selectedObject: '=', 788 | selectedObjectData: '=', 789 | disableInput: '=', 790 | initialValue: '=', 791 | localData: '=', 792 | localSearch: '&', 793 | remoteUrlRequestFormatter: '=', 794 | remoteUrlRequestWithCredentials: '@', 795 | remoteUrlResponseFormatter: '=', 796 | remoteUrlErrorCallback: '=', 797 | remoteApiHandler: '=', 798 | id: '@', 799 | type: '@', 800 | placeholder: '@', 801 | textSearching: '@', 802 | textNoResults: '@', 803 | remoteUrl: '@', 804 | remoteUrlDataField: '@', 805 | titleField: '@', 806 | descriptionField: '@', 807 | imageField: '@', 808 | inputClass: '@', 809 | pause: '@', 810 | searchFields: '@', 811 | minlength: '@', 812 | matchClass: '@', 813 | clearSelected: '@', 814 | overrideSuggestions: '@', 815 | fieldRequired: '=', 816 | fieldRequiredClass: '@', 817 | inputChanged: '=', 818 | autoMatch: '@', 819 | focusOut: '&', 820 | focusIn: '&', 821 | fieldTabindex: '@', 822 | inputName: '@', 823 | focusFirst: '@', 824 | parseInput: '&' 825 | }, 826 | templateUrl: function(element, attrs) { 827 | return attrs.templateUrl || TEMPLATE_URL; 828 | }, 829 | compile: function(tElement) { 830 | var startSym = $interpolate.startSymbol(); 831 | var endSym = $interpolate.endSymbol(); 832 | if (!(startSym === '{{' && endSym === '}}')) { 833 | var interpolatedHtml = tElement.html() 834 | .replace(/\{\{/g, startSym) 835 | .replace(/\}\}/g, endSym); 836 | tElement.html(interpolatedHtml); 837 | } 838 | return link; 839 | } 840 | }; 841 | }]); 842 | 843 | })); 844 | -------------------------------------------------------------------------------- /example/fonts/bariol/bariol_bold-demo.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 17 | 18 | Bariol Bold Bold Specimen 19 | 20 | 21 | 26 | 27 | 28 | 29 |
30 | 32 | 39 | 40 |
41 | 42 | 43 |
44 | 45 |
46 |
47 |
AaBb
48 |
49 |
50 | 51 |
52 |
A​B​C​D​E​F​G​H​I​J​K​L​M​N​O​P​Q​R​S​T​U​V​W​X​Y​Z​a​b​c​d​e​f​g​h​i​j​k​l​m​n​o​p​q​r​s​t​u​v​w​x​y​z​1​2​3​4​5​6​7​8​9​0​&​.​,​?​!​@​(​)​#​$​%​*​+​-​=​:​;
53 |
54 |
55 |
56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 |
10abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
11abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
12abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
13abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
14abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
16abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
18abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
20abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
24abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
30abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
36abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
48abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
60abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
72abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
90abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
73 | 74 |
75 | 76 |
77 | 78 | 79 | 80 |
81 | 82 | 83 |
84 |
◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼◼body
body
body
body
85 |
86 | bodyBariol Bold Bold 87 |
88 |
89 | bodyArial 90 |
91 |
92 | bodyVerdana 93 |
94 |
95 | bodyGeorgia 96 |
97 | 98 | 99 | 100 |
101 | 102 | 103 |
104 | 105 |
106 |

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

107 | 108 |
109 |
110 |

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

111 | 112 |
113 |
114 |

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

115 | 116 |
117 |
118 |

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

119 | 120 |
121 |
122 | 123 |
124 |
125 |
126 |

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

127 | 128 |
129 |
130 |

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

131 | 132 |
133 |
134 |

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

135 | 136 |
137 | 138 |
139 | 140 |
141 | 142 |
143 |
144 |

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

145 |
146 |
147 |

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

148 |
149 | 150 |
151 | 152 |
153 | 154 |
155 |
156 |

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

157 |
158 |
159 | 160 |
161 | 162 | 163 | 164 |
165 |
166 |

10.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

167 | 168 |
169 |
170 |

11.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

171 | 172 |
173 |
174 |

12.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

175 | 176 |
177 |
178 |

13.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

179 | 180 |
181 |
182 | 183 |
184 | 185 |
186 |
187 |

14.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

188 | 189 |
190 |
191 |

16.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

192 | 193 |
194 |
195 |

18.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

196 | 197 |
198 |
199 | 200 |
201 | 202 |
203 |
204 |

20.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

205 |
206 |
207 |

24.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

208 |
209 | 210 |
211 | 212 |
213 | 214 |
215 |
216 |

30.Aenean lacinia bibendum nulla sed consectetur. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Nullam id dolor id nibh ultricies vehicula ut id elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nulla vitae elit libero, a pharetra augue.

217 |
218 |
219 | 220 |
221 | 222 | 223 | 224 | 225 |
226 | 227 |
228 | 229 |
230 | 231 |
232 |

Lorem Ipsum Dolor

233 |

Etiam porta sem malesuada magna mollis euismod

234 | 235 | 236 |
237 |
238 |
239 |
240 |

Donec sed odio dui. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus.

241 | 242 | 243 |

Pellentesque ornare sem

244 | 245 |

Maecenas sed diam eget risus varius blandit sit amet non magna. Maecenas faucibus mollis interdum. Donec ullamcorper nulla non metus auctor fringilla. Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam id dolor id nibh ultricies vehicula ut id elit.

246 | 247 |

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus.

248 | 249 |

Nulla vitae elit libero, a pharetra augue. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Aenean lacinia bibendum nulla sed consectetur.

250 | 251 |

Nullam quis risus eget urna mollis ornare vel eu leo. Nullam quis risus eget urna mollis ornare vel eu leo. Maecenas sed diam eget risus varius blandit sit amet non magna. Donec ullamcorper nulla non metus auctor fringilla.

252 | 253 |

Cras mattis consectetur

254 | 255 |

Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Aenean lacinia bibendum nulla sed consectetur. Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Cras mattis consectetur purus sit amet fermentum.

256 | 257 |

Nullam id dolor id nibh ultricies vehicula ut id elit. Nullam quis risus eget urna mollis ornare vel eu leo. Cras mattis consectetur purus sit amet fermentum.

258 |
259 | 260 | 277 |
278 | 279 |
280 | 281 | 282 | 283 | 284 | 285 | 286 |
287 |
288 |
289 | 290 |

Language Support

291 |

The subset of Bariol Bold Bold in this kit supports the following languages:
292 | 293 | Albanian, Basque, Breton, Chamorro, Danish, Dutch, English, Faroese, Finnish, French, Frisian, Galician, German, Icelandic, Italian, Malagasy, Norwegian, Portuguese, Spanish, Swedish

294 |

Glyph Chart

295 |

The subset of Bariol Bold Bold in this kit includes all the glyphs listed below. Unicode entities are included above each glyph to help you insert individual characters into your layout.

296 |
297 | 298 |

&#13;

299 |

&#32;

300 |

&#33;

!
301 |

&#34;

"
302 |

&#35;

#
303 |

&#36;

$
304 |

&#37;

%
305 |

&#38;

&
306 |

&#39;

'
307 |

&#40;

(
308 |

&#41;

)
309 |

&#42;

*
310 |

&#43;

+
311 |

&#44;

,
312 |

&#45;

-
313 |

&#46;

.
314 |

&#47;

/
315 |

&#48;

0
316 |

&#49;

1
317 |

&#50;

2
318 |

&#51;

3
319 |

&#52;

4
320 |

&#53;

5
321 |

&#54;

6
322 |

&#55;

7
323 |

&#56;

8
324 |

&#57;

9
325 |

&#58;

:
326 |

&#59;

;
327 |

&#60;

<
328 |

&#61;

=
329 |

&#62;

>
330 |

&#63;

?
331 |

&#64;

@
332 |

&#65;

A
333 |

&#66;

B
334 |

&#67;

C
335 |

&#68;

D
336 |

&#69;

E
337 |

&#70;

F
338 |

&#71;

G
339 |

&#72;

H
340 |

&#73;

I
341 |

&#74;

J
342 |

&#75;

K
343 |

&#76;

L
344 |

&#77;

M
345 |

&#78;

N
346 |

&#79;

O
347 |

&#80;

P
348 |

&#81;

Q
349 |

&#82;

R
350 |

&#83;

S
351 |

&#84;

T
352 |

&#85;

U
353 |

&#86;

V
354 |

&#87;

W
355 |

&#88;

X
356 |

&#89;

Y
357 |

&#90;

Z
358 |

&#91;

[
359 |

&#92;

\
360 |

&#93;

]
361 |

&#94;

^
362 |

&#95;

_
363 |

&#96;

`
364 |

&#97;

a
365 |

&#98;

b
366 |

&#99;

c
367 |

&#100;

d
368 |

&#101;

e
369 |

&#102;

f
370 |

&#103;

g
371 |

&#104;

h
372 |

&#105;

i
373 |

&#106;

j
374 |

&#107;

k
375 |

&#108;

l
376 |

&#109;

m
377 |

&#110;

n
378 |

&#111;

o
379 |

&#112;

p
380 |

&#113;

q
381 |

&#114;

r
382 |

&#115;

s
383 |

&#116;

t
384 |

&#117;

u
385 |

&#118;

v
386 |

&#119;

w
387 |

&#120;

x
388 |

&#121;

y
389 |

&#122;

z
390 |

&#123;

{
391 |

&#124;

|
392 |

&#125;

}
393 |

&#126;

~
394 |

&#160;

 
395 |

&#161;

¡
396 |

&#162;

¢
397 |

&#163;

£
398 |

&#164;

¤
399 |

&#165;

¥
400 |

&#166;

¦
401 |

&#167;

§
402 |

&#168;

¨
403 |

&#169;

©
404 |

&#170;

ª
405 |

&#171;

«
406 |

&#172;

¬
407 |

&#173;

­
408 |

&#174;

®
409 |

&#175;

¯
410 |

&#176;

°
411 |

&#177;

±
412 |

&#178;

²
413 |

&#179;

³
414 |

&#180;

´
415 |

&#181;

µ
416 |

&#182;

417 |

&#183;

·
418 |

&#184;

¸
419 |

&#185;

¹
420 |

&#186;

º
421 |

&#187;

»
422 |

&#188;

¼
423 |

&#189;

½
424 |

&#190;

¾
425 |

&#191;

¿
426 |

&#192;

À
427 |

&#193;

Á
428 |

&#194;

Â
429 |

&#195;

Ã
430 |

&#196;

Ä
431 |

&#197;

Å
432 |

&#198;

Æ
433 |

&#199;

Ç
434 |

&#200;

È
435 |

&#201;

É
436 |

&#202;

Ê
437 |

&#203;

Ë
438 |

&#204;

Ì
439 |

&#205;

Í
440 |

&#206;

Î
441 |

&#207;

Ï
442 |

&#208;

Ð
443 |

&#209;

Ñ
444 |

&#210;

Ò
445 |

&#211;

Ó
446 |

&#212;

Ô
447 |

&#213;

Õ
448 |

&#214;

Ö
449 |

&#215;

×
450 |

&#216;

Ø
451 |

&#217;

Ù
452 |

&#218;

Ú
453 |

&#219;

Û
454 |

&#220;

Ü
455 |

&#221;

Ý
456 |

&#222;

Þ
457 |

&#223;

ß
458 |

&#224;

à
459 |

&#225;

á
460 |

&#226;

â
461 |

&#227;

ã
462 |

&#228;

ä
463 |

&#229;

å
464 |

&#230;

æ
465 |

&#231;

ç
466 |

&#232;

è
467 |

&#233;

é
468 |

&#234;

ê
469 |

&#235;

ë
470 |

&#236;

ì
471 |

&#237;

í
472 |

&#238;

î
473 |

&#239;

ï
474 |

&#240;

ð
475 |

&#241;

ñ
476 |

&#242;

ò
477 |

&#243;

ó
478 |

&#244;

ô
479 |

&#245;

õ
480 |

&#246;

ö
481 |

&#247;

÷
482 |

&#248;

ø
483 |

&#249;

ù
484 |

&#250;

ú
485 |

&#251;

û
486 |

&#252;

ü
487 |

&#253;

ý
488 |

&#254;

þ
489 |

&#255;

ÿ
490 |

&#338;

Œ
491 |

&#339;

œ
492 |

&#376;

Ÿ
493 |

&#710;

ˆ
494 |

&#732;

˜
495 |

&#8192;

 
496 |

&#8193;

497 |

&#8194;

498 |

&#8195;

499 |

&#8196;

500 |

&#8197;

501 |

&#8198;

502 |

&#8199;

503 |

&#8200;

504 |

&#8201;

505 |

&#8202;

506 |

&#8208;

507 |

&#8209;

508 |

&#8210;

509 |

&#8211;

510 |

&#8212;

511 |

&#8216;

512 |

&#8217;

513 |

&#8218;

514 |

&#8220;

515 |

&#8221;

516 |

&#8222;

517 |

&#8226;

518 |

&#8230;

519 |

&#8239;

520 |

&#8249;

521 |

&#8250;

522 |

&#8287;

523 |

&#8364;

524 |

&#8482;

525 |

&#9724;

526 |

&#64257;

527 |

&#64258;

528 |

&#64259;

529 |

&#64260;

530 |
531 |
532 | 533 | 534 |
535 |
536 | 537 | 538 |
539 | 540 |
541 | 542 |
543 |
544 |
545 |

Installing Webfonts

546 | 547 |

Webfonts are supported by all major browser platforms but not all in the same way. There are currently four different font formats that must be included in order to target all browsers. This includes TTF, WOFF, EOT and SVG.

548 | 549 |

1. Upload your webfonts

550 |

You must upload your webfont kit to your website. They should be in or near the same directory as your CSS files.

551 | 552 |

2. Include the webfont stylesheet

553 |

A special CSS @font-face declaration helps the various browsers select the appropriate font it needs without causing you a bunch of headaches. Learn more about this syntax by reading the Fontspring blog post about it. The code for it is as follows:

554 | 555 | 556 | 557 | @font-face{ 558 | font-family: 'MyWebFont'; 559 | src: url('WebFont.eot'); 560 | src: url('WebFont.eot?#iefix') format('embedded-opentype'), 561 | url('WebFont.woff') format('woff'), 562 | url('WebFont.ttf') format('truetype'), 563 | url('WebFont.svg#webfont') format('svg'); 564 | } 565 | 566 | 567 |

We've already gone ahead and generated the code for you. All you have to do is link to the stylesheet in your HTML, like this:

568 | <link rel="stylesheet" href="stylesheet.css" type="text/css" charset="utf-8" /> 569 | 570 |

3. Modify your own stylesheet

571 |

To take advantage of your new fonts, you must tell your stylesheet to use them. Look at the original @font-face declaration above and find the property called "font-family." The name linked there will be what you use to reference the font. Prepend that webfont name to the font stack in the "font-family" property, inside the selector you want to change. For example:

572 | p { font-family: 'WebFont', Arial, sans-serif; } 573 | 574 |

4. Test

575 |

Getting webfonts to work cross-browser can be tricky. Use the information in the sidebar to help you if you find that fonts aren't loading in a particular browser.

576 |
577 | 578 | 604 |
605 | 606 |
607 | 608 |
609 | 612 |
613 | 614 | 615 | --------------------------------------------------------------------------------