├── .bowerrc ├── .editorconfig ├── .ember-cli ├── .gitignore ├── .jshintrc ├── .npmignore ├── .travis.yml ├── .watchmanconfig ├── Brocfile.js ├── CHANGELOG.md ├── LICENSE ├── LICENSE.md ├── README.md ├── addon ├── .gitkeep ├── components │ └── input-tokenfield.js └── templates │ └── components │ └── input-tokenfield.hbs ├── app ├── .gitkeep └── components │ └── input-tokenfield.js ├── blueprints ├── .jshintrc └── ember-cli-bootstrap-tokenfield │ └── index.js ├── bower.json ├── config ├── ember-try.js └── environment.js ├── deploy-gh-pages.sh ├── index.js ├── package.json ├── prep-deploy.sh ├── testem.json ├── tests ├── .jshintrc ├── dummy │ ├── app │ │ ├── app.js │ │ ├── controllers │ │ │ ├── .gitkeep │ │ │ └── application.js │ │ ├── index.html │ │ ├── router.js │ │ ├── styles │ │ │ └── app.css │ │ └── templates │ │ │ ├── -autocomplete-promise.hbs │ │ │ ├── -autocomplete.hbs │ │ │ ├── -tokens-promise.hbs │ │ │ ├── -typeahead.hbs │ │ │ └── application.hbs │ ├── config │ │ └── environment.js │ └── public │ │ ├── crossdomain.xml │ │ └── robots.txt ├── helpers │ ├── resolver.js │ └── start-app.js ├── index.html ├── test-helper.js └── unit │ ├── .gitkeep │ └── components │ └── input-tokenfield-test.js └── vendor └── .gitkeep /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components", 3 | "analytics": false 4 | } 5 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.js] 17 | indent_style = space 18 | indent_size = 2 19 | 20 | [*.hbs] 21 | insert_final_newline = false 22 | indent_style = space 23 | indent_size = 2 24 | 25 | [*.css] 26 | indent_style = space 27 | indent_size = 2 28 | 29 | [*.html] 30 | indent_style = space 31 | indent_size = 2 32 | 33 | [*.{diff,md}] 34 | trim_trailing_whitespace = false 35 | -------------------------------------------------------------------------------- /.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | 7 | # dependencies 8 | /node_modules 9 | /bower_components 10 | 11 | # misc 12 | /.sass-cache 13 | /connect.lock 14 | /coverage/* 15 | /libpeerconnection.log 16 | npm-debug.log 17 | testem.log 18 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "-Promise" 6 | ], 7 | "browser": true, 8 | "boss": true, 9 | "curly": true, 10 | "debug": false, 11 | "devel": true, 12 | "eqeqeq": true, 13 | "evil": true, 14 | "forin": false, 15 | "immed": false, 16 | "laxbreak": false, 17 | "newcap": true, 18 | "noarg": true, 19 | "noempty": false, 20 | "nonew": false, 21 | "nomen": false, 22 | "onevar": false, 23 | "plusplus": false, 24 | "regexp": false, 25 | "undef": true, 26 | "sub": true, 27 | "strict": false, 28 | "white": false, 29 | "eqnull": true, 30 | "esnext": true, 31 | "unused": true 32 | } 33 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | bower_components/ 2 | tests/ 3 | tmp/ 4 | dist/ 5 | 6 | .bowerrc 7 | .editorconfig 8 | .ember-cli 9 | .travis.yml 10 | .npmignore 11 | **/.gitkeep 12 | bower.json 13 | Brocfile.js 14 | testem.json 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | node_js: 4 | - "0.12" 5 | 6 | sudo: false 7 | 8 | cache: 9 | directories: 10 | - node_modules 11 | 12 | env: 13 | - EMBER_TRY_SCENARIO=ember-1.12.0 14 | - EMBER_TRY_SCENARIO=ember-1.13.2 15 | 16 | matrix: 17 | fast_finish: true 18 | allow_failures: 19 | 20 | before_install: 21 | - export PATH=/usr/local/phantomjs-2.0.0/bin:$PATH 22 | - "npm config set spin false" 23 | - "npm install -g npm@^2" 24 | 25 | install: 26 | - npm install -g bower 27 | - npm install 28 | - bower install 29 | 30 | script: 31 | - ember try $EMBER_TRY_SCENARIO test 32 | -------------------------------------------------------------------------------- /.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp"] 3 | } 4 | -------------------------------------------------------------------------------- /Brocfile.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | /* global require, module */ 3 | 4 | var EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); 5 | 6 | var app = new EmberAddon(); 7 | 8 | // Use `app.import` to add additional libraries to the generated 9 | // output files. 10 | // 11 | // If you need to use different assets in different 12 | // environments, specify an object as the first parameter. That 13 | // object's keys should be the environment name and the values 14 | // should be the asset to use in that environment. 15 | // 16 | // If the library that you are including contains AMD or ES6 17 | // modules that you would like to import into your application 18 | // please specify an object with the list of modules as keys 19 | // along with the exports of each module as its value. 20 | 21 | // Use Typeahead 22 | app.import('bower_components/typeahead.js/dist/typeahead.jquery.js'); 23 | 24 | // Use Bloodhound 25 | app.import('bower_components/typeahead.js/dist/bloodhound.js'); 26 | app.import('bower_components/typeahead.js-es6-shim/typeahead-shim.js', { 27 | exports: { 'bloodhound': ['default'] } 28 | }); 29 | 30 | module.exports = app.toTree(); 31 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # ember-cli-bootstrap-tokenfield 2 | 3 | ### 0.0.4 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Æther 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 all 13 | 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 THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ember-cli-bootstrap-tokenfield 2 | 3 | [![Build Status](https://travis-ci.org/aethermx/ember-cli-bootstrap-tokenfield.svg?branch=master)](https://travis-ci.org/aethermx/ember-cli-bootstrap-tokenfield) 4 | [![Ember Observer Score](http://emberobserver.com/badges/ember-cli-bootstrap-tokenfield.svg)](http://emberobserver.com/addons/ember-cli-bootstrap-tokenfield) 5 | [![Code Climate](https://codeclimate.com/github/aethermx/ember-cli-bootstrap-tokenfield/badges/gpa.svg)](https://codeclimate.com/github/aethermx/ember-cli-bootstrap-tokenfield) 6 | [![npm](https://img.shields.io/npm/dm/ember-cli-bootstrap-tokenfield.svg)](https://www.npmjs.com/package/ember-cli-bootstrap-tokenfield) 7 | 8 | 9 | A convenient component that wraps around Bootstrap Tokenfield. 10 | 11 | Examples: http://aethermx.github.io/ember-cli-bootstrap-tokenfield/ 12 | 13 | Supported versions: 14 | 15 | * ember 1.12 16 | * ember 1.13.2 17 | 18 | ## Addon Install 19 | 20 | ember install ember-cli-bootstrap-tokenfield 21 | # if ember-cli <= 0.2.2 22 | ember install:addon ember-cli-bootstrap-tokenfield 23 | 24 | ## Addon dependencies 25 | 26 | The addon already downloads Bootstrap, but it imports only the CSS. Fonts and 27 | JS components will still be required to be imported by you, if you need them. 28 | 29 | ## Installation 30 | 31 | * `git clone` this repository 32 | * `npm install` 33 | * `bower install` 34 | 35 | ## Running 36 | 37 | * `ember server` 38 | * Visit your app at http://localhost:4200. 39 | 40 | ## Running Tests 41 | 42 | * `ember test` 43 | * `ember test --server` 44 | 45 | ## Building 46 | 47 | * `ember build` 48 | 49 | For more information on using ember-cli, visit [http://www.ember-cli.com/](http://www.ember-cli.com/). 50 | 51 | ## Legal 52 | 53 | [Æther](http://aether.mx/) 54 | 55 | hello@aether.mx 56 | 57 | [Licensed under the MIT license](http://opensource.org/licenses/mit-license.php) 58 | -------------------------------------------------------------------------------- /addon/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aethermx/ember-cli-bootstrap-tokenfield/1bc5d458a92067dd860f88049fbd0508c9d4c80c/addon/.gitkeep -------------------------------------------------------------------------------- /addon/components/input-tokenfield.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import layout from '../templates/components/input-tokenfield'; 3 | 4 | export default Ember.TextField.extend({ 5 | 6 | layout: layout, 7 | 8 | classNames: ['form-control'], 9 | 10 | tokens: null, 11 | 12 | /* 13 | Appends only truthy values that are not promises. 14 | */ 15 | _appendOption: function(options, attributeName) { 16 | let attrValue = this.get(attributeName); 17 | if (attrValue && typeof attrValue.then !== 'function') { 18 | options[attributeName] = attrValue; 19 | } 20 | return options; 21 | }, 22 | 23 | _buildTokenfieldOptions: function() { 24 | var options = {}; 25 | options = this._appendOption(options, 'limit'); 26 | options = this._appendOption(options, 'minLength'); 27 | options = this._appendOption(options, 'minWidth'); 28 | options = this._appendOption(options, 'showAutocompleteOnFocus'); 29 | options = this._appendOption(options, 'delimiter'); 30 | options = this._appendOption(options, 'beautify'); 31 | options = this._appendOption(options, 'inputType'); 32 | options = this._appendOption(options, 'createTokensOnBlur'); 33 | options = this._appendOption(options, 'typeahead'); 34 | options = this._appendOption(options, 'tokens'); 35 | options = this._appendOption(options, 'autocomplete'); 36 | return options; 37 | }, 38 | 39 | didInsertElement: function() { 40 | let element$ = Ember.$('#' + this.get('elementId')); 41 | this.set('element$', element$); 42 | 43 | var options = this._buildTokenfieldOptions(); 44 | 45 | element$.tokenfield(options); 46 | 47 | element$.on('tokenfield:createdtoken', (/*ev*/) => { 48 | let tokens = element$.tokenfield('getTokens'); 49 | this.set('tokens', tokens); 50 | }); 51 | 52 | this._consumeAutocompletePromise(); 53 | this._consumeTokensPromise(); 54 | }, 55 | 56 | _consumeAutocompletePromise: function() { 57 | var autocomplete = this.get('autocomplete'); 58 | 59 | if (!autocomplete || typeof autocomplete.then !== 'function') { 60 | return; // nothing to do, value already passed in with the options object 61 | } 62 | 63 | autocomplete.then(autocompleteValues => { 64 | let element$ = this.get('element$'); 65 | if (element$) { 66 | element$ 67 | .data('bs.tokenfield') 68 | .$input.autocomplete(autocompleteValues); 69 | } 70 | 71 | this.set('autocomplete', autocompleteValues); 72 | }); 73 | }, 74 | 75 | _observeAutocomplete: Ember.observer('autocomplete', function() { 76 | this._consumeAutocompletePromise(); 77 | }), 78 | 79 | _consumeTokensPromise: function() { 80 | var tokens = this.get('tokens'); 81 | 82 | if (!tokens || typeof tokens.then !== 'function') { 83 | return; // nothing to do, value already passed in with the options object 84 | } 85 | 86 | // test for Ember.ArrayProxy 87 | /* 88 | if ( tokens.get && typeof tokens.get('hasArrayObservers') === 'boolean') { 89 | let tokensList = tokens.toArray(); 90 | element$.tokenfield('setTokens', tokensList); 91 | } 92 | */ 93 | 94 | tokens.then(tokensList => { 95 | let element$ = this.get('element$'); 96 | if (element$) { 97 | element$.tokenfield('setTokens', tokensList); 98 | } 99 | this.set('tokens', tokensList); 100 | }); 101 | }, 102 | 103 | _observeTokens: Ember.observer('tokens', function() { 104 | this._consumeTokensPromise(); 105 | }) 106 | 107 | }); 108 | -------------------------------------------------------------------------------- /addon/templates/components/input-tokenfield.hbs: -------------------------------------------------------------------------------- 1 | {{yield}} 2 | -------------------------------------------------------------------------------- /app/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aethermx/ember-cli-bootstrap-tokenfield/1bc5d458a92067dd860f88049fbd0508c9d4c80c/app/.gitkeep -------------------------------------------------------------------------------- /app/components/input-tokenfield.js: -------------------------------------------------------------------------------- 1 | import inputTokenfield from 'ember-cli-bootstrap-tokenfield/components/input-tokenfield'; 2 | 3 | export default inputTokenfield; 4 | -------------------------------------------------------------------------------- /blueprints/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "console" 4 | ], 5 | "strict": false 6 | } 7 | -------------------------------------------------------------------------------- /blueprints/ember-cli-bootstrap-tokenfield/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | description: '', 3 | 4 | // locals: function(options) { 5 | // // Return custom template variables here. 6 | // return { 7 | // foo: options.entity.options.foo 8 | // }; 9 | // } 10 | 11 | normalizeEntityName: function() { 12 | // allows us to run ember -g ember-cli-bootswatch and not blow up 13 | // because ember cli normally expects the format 14 | // ember generate 15 | }, 16 | 17 | afterInstall: function(options) { 18 | var _this = this; 19 | 20 | console.log('Note: bootstrap-tokenfield depends on jquery 2.1.0'); 21 | console.log(' Use that version or higher.'); 22 | 23 | return _this.addBowerPackageToProject('jquery', '2.1.0').then(function() { 24 | return _this.addBowerPackageToProject('jquery-ui', '1.11.4').then(function() { 25 | return _this.addBowerPackageToProject('bootstrap-tokenfield'); 26 | }); 27 | }); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-cli-bootstrap-tokenfield", 3 | "dependencies": { 4 | "bootstrap-tokenfield": "~0.12.1", 5 | "ember": "1.13.2", 6 | "ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3", 7 | "ember-cli-test-loader": "ember-cli-test-loader#0.1.3", 8 | "ember-load-initializers": "ember-cli/ember-load-initializers#0.1.4", 9 | "ember-qunit": "0.3.3", 10 | "ember-qunit-notifications": "0.0.7", 11 | "ember-resolver": "~0.1.15", 12 | "jquery": "~2.1.4", 13 | "jquery-ui": "~1.11.4", 14 | "loader.js": "ember-cli/loader.js#3.2.0", 15 | "qunit": "~1.17.1", 16 | "typeahead.js": "0.10.5", 17 | "typeahead.js-es6-shim": "0.10.5" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /config/ember-try.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | scenarios: [ 3 | { 4 | name: 'ember-1.12.0', 5 | dependencies: { 6 | 'ember': '1.12.0' 7 | } 8 | }, 9 | { 10 | name: 'ember-1.13.2', 11 | dependencies: { 12 | 'ember': '1.13.2' 13 | } 14 | } 15 | ] 16 | }; 17 | -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /deploy-gh-pages.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ember build --environment='production' 4 | 5 | cd ../ember-cli-bootstrap-tokenfield-gh-pages/ 6 | 7 | rm -r assets 8 | 9 | cp -Rv ../ember-cli-bootstrap-tokenfield/dist/* . 10 | 11 | git add -A . 12 | 13 | git commit -m 'update' 14 | 15 | git push -u origin gh-pages 16 | 17 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | 'use strict'; 3 | 4 | module.exports = { 5 | included: function(app) { 6 | this._super.included(app); 7 | 8 | // Bootstrap 9 | app.import('bower_components/bootstrap/dist/css/bootstrap.css'); 10 | 11 | // JQuery UI 12 | app.import('bower_components/jquery-ui/jquery-ui.js'); 13 | app.import('bower_components/jquery-ui/themes/base/jquery-ui.css'); 14 | 15 | // Bootstrap Tokenfield 16 | app.import('bower_components/bootstrap-tokenfield/dist/css/tokenfield-typeahead.css'); 17 | app.import('bower_components/bootstrap-tokenfield/dist/css/bootstrap-tokenfield.css'); 18 | app.import('bower_components/bootstrap-tokenfield/dist/bootstrap-tokenfield.js'); 19 | }, 20 | 21 | name: 'ember-cli-bootstrap-tokenfield' 22 | }; 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-cli-bootstrap-tokenfield", 3 | "version": "0.0.9", 4 | "description": "Bootstrap Tokenfield for Ember CLI", 5 | "directories": { 6 | "doc": "doc", 7 | "test": "tests" 8 | }, 9 | "scripts": { 10 | "start": "ember server", 11 | "build": "ember build", 12 | "test": "ember try:testall" 13 | }, 14 | "repository": "git@github.com:aethermx/ember-cli-bootstrap-tokenfield.git", 15 | "engines": { 16 | "node": ">= 0.10.0" 17 | }, 18 | "author": "", 19 | "license": "MIT", 20 | "devDependencies": { 21 | "broccoli-asset-rev": "^2.0.2", 22 | "ember-cli": "0.2.7", 23 | "ember-cli-app-version": "0.3.3", 24 | "ember-cli-content-security-policy": "0.4.0", 25 | "ember-cli-dependency-checker": "^1.0.0", 26 | "ember-cli-htmlbars": "0.7.6", 27 | "ember-cli-ic-ajax": "0.1.1", 28 | "ember-cli-inject-live-reload": "^1.3.0", 29 | "ember-cli-qunit": "0.3.13", 30 | "ember-cli-uglify": "^1.0.1", 31 | "ember-disable-proxy-controllers": "^1.0.0", 32 | "ember-export-application-global": "^1.0.2", 33 | "ember-disable-prototype-extensions": "^1.0.0", 34 | "ember-try": "0.0.6" 35 | }, 36 | "keywords": [ 37 | "ember-addon", 38 | "tokenfield", 39 | "tags", 40 | "token", 41 | "typeahead", 42 | "autocomplete" 43 | ], 44 | "dependencies": { 45 | "ember-cli-babel": "^5.0.0", 46 | "ember-cli-htmlbars": "^0.7.9" 47 | }, 48 | "ember-addon": { 49 | "configPath": "tests/dummy/config", 50 | "demoURL": "http://aethermx.github.io/ember-cli-bootstrap-tokenfield" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /prep-deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | mkdir ../ember-cli-bootstrap-tokenfield-gh-pages/ 4 | cd ../ember-cli-bootstrap-tokenfield-gh-pages/ 5 | git init 6 | git remote add origin git@github.com:aethermx/ember-cli-bootstrap-tokenfield.git 7 | git checkout -b gh-pages 8 | git pull origin gh-pages 9 | -------------------------------------------------------------------------------- /testem.json: -------------------------------------------------------------------------------- 1 | { 2 | "framework": "qunit", 3 | "test_page": "tests/index.html?hidepassed", 4 | "disable_watching": true, 5 | "launch_in_ci": [ 6 | "PhantomJS" 7 | ], 8 | "launch_in_dev": [ 9 | "PhantomJS", 10 | "Chrome" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /tests/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "predef": [ 3 | "document", 4 | "window", 5 | "location", 6 | "setTimeout", 7 | "$", 8 | "-Promise", 9 | "define", 10 | "console", 11 | "visit", 12 | "exists", 13 | "fillIn", 14 | "click", 15 | "keyEvent", 16 | "triggerEvent", 17 | "find", 18 | "findWithAssert", 19 | "wait", 20 | "DS", 21 | "andThen", 22 | "currentURL", 23 | "currentPath", 24 | "currentRouteName" 25 | ], 26 | "node": false, 27 | "browser": false, 28 | "boss": true, 29 | "curly": false, 30 | "debug": false, 31 | "devel": false, 32 | "eqeqeq": true, 33 | "evil": true, 34 | "forin": false, 35 | "immed": false, 36 | "laxbreak": false, 37 | "newcap": true, 38 | "noarg": true, 39 | "noempty": false, 40 | "nonew": false, 41 | "nomen": false, 42 | "onevar": false, 43 | "plusplus": false, 44 | "regexp": false, 45 | "undef": true, 46 | "sub": true, 47 | "strict": false, 48 | "white": false, 49 | "eqnull": true, 50 | "esnext": true 51 | } 52 | -------------------------------------------------------------------------------- /tests/dummy/app/app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Resolver from 'ember/resolver'; 3 | import loadInitializers from 'ember/load-initializers'; 4 | import config from './config/environment'; 5 | 6 | var App; 7 | 8 | Ember.MODEL_FACTORY_INJECTIONS = true; 9 | 10 | App = Ember.Application.extend({ 11 | modulePrefix: config.modulePrefix, 12 | podModulePrefix: config.podModulePrefix, 13 | Resolver: Resolver 14 | }); 15 | 16 | loadInitializers(App, config.modulePrefix); 17 | 18 | export default App; 19 | -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aethermx/ember-cli-bootstrap-tokenfield/1bc5d458a92067dd860f88049fbd0508c9d4c80c/tests/dummy/app/controllers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/application.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Bloodhound from 'bloodhound'; 3 | 4 | export default Ember.Controller.extend({ 5 | 6 | autocomplete: { 7 | source: ['red', 'blue', 'green', 'yellow', 'violet', 8 | 'brown', 'purple', 'black', 'white'], 9 | delay: 100 // ms 10 | }, 11 | 12 | autocompletePromise: Ember.computed(function() { 13 | var autocomplete = { 14 | source: ['banana', 'apple', 'watermelon', 'pear', 15 | 'grape', 'peach', 'mango'], 16 | delay: 100 // ms 17 | }; 18 | 19 | return new Ember.RSVP.Promise(function(resolve) { 20 | Ember.run.later(function() { 21 | resolve( autocomplete ); 22 | }, 3000); // simulate a 3 seconds delay 23 | }); 24 | }), 25 | 26 | tokensPromise: Ember.computed(function() { 27 | var tokens = [ 28 | {value: 1, label: 'one'}, 29 | {value: 2, label: 'two'}, 30 | {value: 3, label: 'three'} 31 | ]; 32 | 33 | return new Ember.RSVP.Promise(function(resolve) { 34 | Ember.run.later(function() { 35 | resolve( tokens ); 36 | }, 3000); // simulate a 3 seconds delay 37 | }); 38 | }), 39 | 40 | typeahead: (function() { 41 | var engine = new Bloodhound({ 42 | local: [{value: 'red'}, {value: 'blue'}, {value: 'green'} , 43 | {value: 'yellow'}, {value: 'violet'}, {value: 'brown'}, 44 | {value: 'purple'}, {value: 'black'}, {value: 'white'}], 45 | datumTokenizer: function(d) { 46 | return Bloodhound.tokenizers.whitespace(d.value); 47 | }, 48 | queryTokenizer: Bloodhound.tokenizers.whitespace 49 | }); 50 | engine.initialize(); 51 | 52 | return [null, { source: engine.ttAdapter() }]; 53 | })() 54 | 55 | }); 56 | -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ember-cli-bootstrap-tokenfield 7 | 8 | 9 | 10 | {{content-for 'head'}} 11 | 12 | 13 | 14 | 15 | {{content-for 'head-footer'}} 16 | 17 | 18 | {{content-for 'body'}} 19 | 20 | 21 | 22 | 23 | {{content-for 'body-footer'}} 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import config from './config/environment'; 3 | 4 | var Router = Ember.Router.extend({ 5 | location: config.locationType 6 | }); 7 | 8 | Router.map(function() { 9 | }); 10 | 11 | export default Router; 12 | -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 0; 3 | } 4 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/-autocomplete-promise.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 | Autocomplete with a promise 4 |
5 | 6 |
7 |

Promises can be used to update the autocomplete object used by jQuery UI.

8 | {{input-tokenfield value="banana,apple,watermelon" 9 | placeholder="Type something and hit enter" 10 | autocomplete=autocompletePromise 11 | showAutocompleteOnFocus=true}} 12 |
13 | 14 | Controller 15 |
// contribed example, this data is likely to come from ember-data
16 | autocompletePromise: Ember.computed({
17 |   var autocomplete = {
18 |     source: ['banana','apple','watermelon','pear','grape','peach','mango'],
19 |     delay: 100
20 |   };
21 | 
22 |   return new Ember.RSVP.Promise(function(resolve) {
23 |     Ember.run.later(function() {
24 |       resolve( autocomplete );
25 |     }, 3000); // simulate a 3 seconds delay 
26 |   });
27 | })
28 | Template 29 |
\{{input-tokenfield value="banana,apple,watermelon" 
30 |                    placeholder="Type something and hit enter"
31 |                    autocomplete=autocompletePromise
32 |                    showAutocompleteOnFocus=true}}
33 |
34 |
35 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/-autocomplete.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 | Using jQuery UI Autocomplete 4 |
5 | 6 |
7 |

Create elegant taggable fields with copy/paste and keyboard support.

8 | 9 | {{input-tokenfield value="red,green,blue" 10 | placeholder="Type something and hit enter" 11 | autocomplete=autocomplete 12 | showAutocompleteOnFocus=true}} 13 |
14 | 15 | Controller 16 |
autocomplete: {
17 |   source: ['red','blue','green','yellow','violet','brown','purple','black','white'],
18 |   delay: 100
19 | }
20 | Template 21 |
\{{input-tokenfield value="red,green,blue" 
22 |                    placeholder="Type something and hit enter"
23 |                    autocomplete=autocomplete
24 |                    showAutocompleteOnFocus=true}}
25 |
26 |
27 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/-tokens-promise.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 | Set tokens with a promise 4 |
5 | 6 |
7 |

Promises can be used to set the current tokens.

8 | {{input-tokenfield tokens=tokensPromise 9 | autocomplete=autocomplete 10 | placeholder="Type something and hit enter"}} 11 |
12 | 13 | Controller 14 |
// contribed example, this data is likely to come from ember-data
15 | tokensPromise: Ember.computed(function() {
16 |   var tokens = [
17 |     {value: 1, label: 'one'},
18 |     {value: 2, label: 'two'},
19 |     {value: 3, label: 'three'}
20 |   ];
21 | 
22 |   return new Ember.RSVP.Promise(function(resolve) {
23 |     Ember.run.later(function() {
24 |       resolve( tokens );
25 |     }, 3000); // simulate a 3 seconds delay 
26 |   });
27 | })
28 | 29 | Template 30 |
\{{input-tokenfield tokens=tokensPromise 
31 |                    autocomplete=autocomplete
32 |                    placeholder="Type something and hit enter"}}
33 |
34 |
35 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/-typeahead.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 | Using Twitter Typeahead 4 |
5 | 6 |
7 | {{input-tokenfield value="red,green,blue" 8 | placeholder="Type something and hit enter" 9 | typeahead=typeahead}} 10 |
11 | 12 | Controller 13 |
typeahead: (function() {
14 |   var engine = new Bloodhound({
15 |     local: [{value: 'red'}, {value: 'blue'}, {value: 'green'} , 
16 |             {value: 'yellow'}, {value: 'violet'}, {value: 'brown'}, 
17 |             {value: 'purple'}, {value: 'black'}, {value: 'white'}],
18 |     datumTokenizer: function(d) {
19 |       return Bloodhound.tokenizers.whitespace(d.value);
20 |     },
21 |     queryTokenizer: Bloodhound.tokenizers.whitespace
22 |   });
23 |   engine.initialize();
24 | 
25 |   return [null, { source: engine.ttAdapter() }];
26 | })()
27 | Template 28 |
\{{input-tokenfield value="red,green,blue"
29 |                    placeholder="Type something and hit enter"
30 |                    typeahead=typeahead}}
31 |
32 |
33 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 | 2 | Fork me on GitHub 3 | 4 |
5 |
6 |
7 | 8 | 11 | 12 |

Install addon

13 | 14 |
15 | ember install ember-cli-bootstrap-tokenfield
16 | 
17 | # if ember-cli <= 0.2.2
18 | ember install:addon ember-cli-bootstrap-tokenfield
19 |       
20 | 21 |

Examples

22 | 23 | {{partial 'autocomplete'}} 24 | 25 | {{partial 'autocomplete-promise'}} 26 | 27 | {{partial 'tokens-promise'}} 28 | 29 | {{partial 'typeahead'}} 30 | 31 |
32 |
33 |
34 | 35 | {{outlet}} 36 | -------------------------------------------------------------------------------- /tests/dummy/config/environment.js: -------------------------------------------------------------------------------- 1 | /* jshint node: true */ 2 | 3 | module.exports = function(environment) { 4 | var ENV = { 5 | modulePrefix: 'dummy', 6 | environment: environment, 7 | baseURL: '/', 8 | locationType: 'auto', 9 | EmberENV: { 10 | FEATURES: { 11 | // Here you can enable experimental features on an ember canary build 12 | // e.g. 'with-controller': true 13 | } 14 | }, 15 | 16 | APP: { 17 | // Here you can pass flags/options to your application instance 18 | // when it is created 19 | } 20 | }; 21 | 22 | if (environment === 'development') { 23 | // ENV.APP.LOG_RESOLVER = true; 24 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 25 | // ENV.APP.LOG_TRANSITIONS = true; 26 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 27 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 28 | } 29 | 30 | if (environment === 'test') { 31 | // Testem prefers this... 32 | ENV.baseURL = '/'; 33 | ENV.locationType = 'none'; 34 | 35 | // keep test console output quieter 36 | ENV.APP.LOG_ACTIVE_GENERATION = false; 37 | ENV.APP.LOG_VIEW_LOOKUPS = false; 38 | 39 | ENV.APP.rootElement = '#ember-testing'; 40 | } 41 | 42 | if (environment === 'production') { 43 | ENV.baseURL = '/ember-cli-bootstrap-tokenfield/'; 44 | } 45 | 46 | return ENV; 47 | }; 48 | -------------------------------------------------------------------------------- /tests/dummy/public/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /tests/helpers/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember/resolver'; 2 | import config from '../../config/environment'; 3 | 4 | var resolver = Resolver.create(); 5 | 6 | resolver.namespace = { 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix 9 | }; 10 | 11 | export default resolver; 12 | -------------------------------------------------------------------------------- /tests/helpers/start-app.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import Application from '../../app'; 3 | import Router from '../../router'; 4 | import config from '../../config/environment'; 5 | 6 | export default function startApp(attrs) { 7 | var application; 8 | 9 | var attributes = Ember.merge({}, config.APP); 10 | attributes = Ember.merge(attributes, attrs); // use defaults, but you can override; 11 | 12 | Ember.run(function() { 13 | application = Application.create(attributes); 14 | application.setupForTesting(); 15 | application.injectTestHelpers(); 16 | }); 17 | 18 | return application; 19 | } 20 | -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy Tests 7 | 8 | 9 | 10 | {{content-for 'head'}} 11 | {{content-for 'test-head'}} 12 | 13 | 14 | 15 | 16 | 17 | {{content-for 'head-footer'}} 18 | {{content-for 'test-head-footer'}} 19 | 20 | 21 | 22 | {{content-for 'body'}} 23 | {{content-for 'test-body'}} 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{content-for 'body-footer'}} 31 | {{content-for 'test-body-footer'}} 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import resolver from './helpers/resolver'; 2 | import { 3 | setResolver 4 | } from 'ember-qunit'; 5 | 6 | setResolver(resolver); 7 | -------------------------------------------------------------------------------- /tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aethermx/ember-cli-bootstrap-tokenfield/1bc5d458a92067dd860f88049fbd0508c9d4c80c/tests/unit/.gitkeep -------------------------------------------------------------------------------- /tests/unit/components/input-tokenfield-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import { 3 | moduleForComponent, 4 | test 5 | } from 'ember-qunit'; 6 | 7 | moduleForComponent('input-tokenfield', 'Unit | Component | input-tokenfield', { 8 | // specify the other units that are required for this test 9 | // needs: ['component:foo', 'helper:bar'] 10 | unit: true 11 | }); 12 | 13 | test('it renders', function(assert) { 14 | assert.expect(2); 15 | 16 | // creates the component instance 17 | var component = this.subject(); 18 | assert.equal(component._state, 'preRender'); 19 | 20 | // renders the component to the page 21 | this.render(); 22 | assert.equal(component._state, 'inDOM'); 23 | }); 24 | 25 | test('tokenfield.getTokens', function(assert) { 26 | assert.expect(2); 27 | 28 | var component = this.subject({ 29 | value: 'red' 30 | }); 31 | this.render(); 32 | 33 | var active = false; 34 | var element$ = component.get('element$'); 35 | var tokens = element$.tokenfield('getTokens', active); 36 | var expected = [{'label': 'red', 'value': 'red'}]; 37 | assert.deepEqual(tokens, expected); 38 | 39 | active = true; 40 | tokens = element$.tokenfield('getTokens', active); 41 | expected = []; 42 | assert.deepEqual(tokens, expected); 43 | }); 44 | 45 | test('listen to tokenfield:createdToken', function(assert) { 46 | assert.expect(2); 47 | 48 | var component = this.subject(); 49 | this.render(); 50 | 51 | var active = false; 52 | var element$ = component.get('element$'); 53 | var tokens = element$.tokenfield('getTokens', active); 54 | var expected = []; 55 | assert.deepEqual(tokens, expected); 56 | 57 | // fake typing in a token 58 | element$.tokenfield('createToken', 'blue'); 59 | 60 | tokens = element$.tokenfield('getTokens', active); 61 | expected = [{'label': 'blue', 'value': 'blue'}]; 62 | assert.deepEqual(tokens, expected); 63 | }); 64 | 65 | test('_appendOption', function(assert) { 66 | assert.expect(3); 67 | 68 | let component = this.subject({ 69 | autocomplete: {source: ['1', '2']} 70 | }); 71 | 72 | let options = {}; 73 | options = component._appendOption(options, 'not-a-real-option'); 74 | assert.deepEqual(options, {}, 'only truthy values are added'); 75 | 76 | options = {}; 77 | options = component._appendOption(options, 'autocomplete'); 78 | assert.deepEqual(options, {autocomplete: {source: ['1', '2']}}); 79 | 80 | Ember.run(() => { 81 | this.render(); 82 | component.set('autocomplete', Ember.RSVP.resolve({source: ['a', 'b']})); 83 | options = {}; 84 | options = component._appendOption(options, 'autocomplete'); 85 | assert.deepEqual(options, {}, 'promises are ignored'); 86 | }); 87 | }); 88 | 89 | test('autocomplete is a promise', function(assert) { 90 | assert.expect(1); 91 | 92 | let autocompletePromise = new Ember.RSVP.Promise(function(resolve) { 93 | Ember.run.later(function() { 94 | let autocomplete = {source: ['a', 'b']}; 95 | resolve(autocomplete); 96 | }, 7); // 7 ms must be enough to not let the test pass synchronously 97 | }); 98 | let component = this.subject({ 99 | autocomplete: autocompletePromise 100 | }); 101 | this.render(); 102 | 103 | Ember.run(() => { 104 | component._consumeAutocompletePromise(); 105 | component.get('autocomplete').then(() => { 106 | assert.deepEqual(component.get('autocomplete'), {source: ['a', 'b']}); 107 | }); 108 | }); 109 | }); 110 | 111 | test('tokens is a promise', function(assert) { 112 | assert.expect(1); 113 | 114 | let tokensPromise = new Ember.RSVP.Promise(function(resolve) { 115 | Ember.run.later(function() { 116 | let tokens = [{value: '1', label: 'uno'}, {value: '2', label: 'dos'}]; 117 | resolve(tokens); 118 | }, 7); // 7 ms must be enough to not let the test pass synchronously 119 | }); 120 | let component = this.subject({ 121 | tokens: tokensPromise 122 | }); 123 | this.render(); 124 | 125 | Ember.run(() => { 126 | component._consumeTokensPromise(); 127 | component.get('tokens').then(() => { 128 | let expected = [{value: '1', label: 'uno'}, {value: '2', label: 'dos'}]; 129 | assert.deepEqual(component.get('tokens'), expected); 130 | }); 131 | }); 132 | }); 133 | -------------------------------------------------------------------------------- /vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aethermx/ember-cli-bootstrap-tokenfield/1bc5d458a92067dd860f88049fbd0508c9d4c80c/vendor/.gitkeep --------------------------------------------------------------------------------