Repository: miguelcobain/ember-cli-selectize
Branch: master
Commit: 0f7206e9f82e
Files: 53
Total size: 100.5 KB
Directory structure:
gitextract_85rycd2w/
├── .editorconfig
├── .ember-cli
├── .eslintrc.js
├── .gitignore
├── .npmignore
├── .travis.yml
├── .watchmanconfig
├── CHANGELOG.md
├── HISTORY.md
├── LICENSE.md
├── README.md
├── addon/
│ ├── .gitkeep
│ └── components/
│ └── ember-selectize.js
├── app/
│ ├── .gitkeep
│ └── components/
│ └── ember-selectize.js
├── config/
│ ├── ember-try.js
│ └── environment.js
├── ember-cli-build.js
├── index.js
├── package.json
├── testem.js
├── tests/
│ ├── .eslintrc.js
│ ├── dummy/
│ │ ├── app/
│ │ │ ├── app.js
│ │ │ ├── components/
│ │ │ │ ├── .gitkeep
│ │ │ │ └── test-component.js
│ │ │ ├── controllers/
│ │ │ │ ├── .gitkeep
│ │ │ │ └── application.js
│ │ │ ├── helpers/
│ │ │ │ └── .gitkeep
│ │ │ ├── index.html
│ │ │ ├── models/
│ │ │ │ └── .gitkeep
│ │ │ ├── resolver.js
│ │ │ ├── router.js
│ │ │ ├── routes/
│ │ │ │ └── .gitkeep
│ │ │ ├── styles/
│ │ │ │ └── app.css
│ │ │ ├── templates/
│ │ │ │ ├── application.hbs
│ │ │ │ ├── components/
│ │ │ │ │ ├── .gitkeep
│ │ │ │ │ └── test-component.hbs
│ │ │ │ └── test.hbs
│ │ │ └── views/
│ │ │ └── .gitkeep
│ │ ├── config/
│ │ │ ├── environment.js
│ │ │ └── targets.js
│ │ └── public/
│ │ ├── .gitkeep
│ │ ├── crossdomain.xml
│ │ └── robots.txt
│ ├── helpers/
│ │ ├── destroy-app.js
│ │ ├── module-for-acceptance.js
│ │ ├── resolver.js
│ │ └── start-app.js
│ ├── index.html
│ ├── test-helper.js
│ └── unit/
│ ├── .gitkeep
│ └── components/
│ └── ember-selectize-test.js
└── vendor/
└── .gitkeep
================================================
FILE CONTENTS
================================================
================================================
FILE: .editorconfig
================================================
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2
[*.hbs]
insert_final_newline = false
[*.{diff,md}]
trim_trailing_whitespace = false
================================================
FILE: .ember-cli
================================================
{
/**
Ember CLI sends analytics information by default. The data is completely
anonymous, but there are times when you might want to disable this behavior.
Setting `disableAnalytics` to true will prevent any data from being sent.
*/
"disableAnalytics": false
}
================================================
FILE: .eslintrc.js
================================================
module.exports = {
root: true,
parserOptions: {
ecmaVersion: 2017,
sourceType: 'module'
},
extends: 'eslint:recommended',
env: {
browser: true
},
rules: {
}
};
================================================
FILE: .gitignore
================================================
# See https://help.github.com/ignore-files/ for more about ignoring files.
# compiled output
/dist
/tmp
# dependencies
/node_modules
/bower_components
# misc
/.sass-cache
/connect.lock
/coverage/*
/libpeerconnection.log
npm-debug.log*
yarn-error.log
testem.log
# ember-try
.node_modules.ember-try/
bower.json.ember-try
package.json.ember-try
================================================
FILE: .npmignore
================================================
/bower_components
/config/ember-try.js
/dist
/tests
/tmp
**/.gitkeep
.bowerrc
.editorconfig
.ember-cli
.gitignore
.eslintrc.js
.watchmanconfig
.travis.yml
bower.json
ember-cli-build.js
testem.js
================================================
FILE: .travis.yml
================================================
---
language: node_js
node_js:
# we recommend testing addons with the same minimum supported node version as Ember CLI
# so that your addon works for all apps
- "4"
sudo: false
dist: trusty
addons:
chrome: stable
cache:
directories:
- $HOME/.npm
env:
global:
# See https://git.io/vdao3 for details.
- JOBS=1
matrix:
# we recommend new addons test the current and previous LTS
# as well as latest stable release (bonus points to beta/canary)
- EMBER_TRY_SCENARIO=ember-1.13
- EMBER_TRY_SCENARIO=ember-lts-2.8
- EMBER_TRY_SCENARIO=ember-lts-2.12
- EMBER_TRY_SCENARIO=ember-release
- EMBER_TRY_SCENARIO=ember-beta
- EMBER_TRY_SCENARIO=ember-canary
- EMBER_TRY_SCENARIO=ember-default
matrix:
fast_finish: true
allow_failures:
- env: EMBER_TRY_SCENARIO=ember-canary
before_install:
- npm config set spin false
- npm install -g npm@4
- npm --version
script:
# Usually, it's ok to finish the test scenario without reverting
# to the addon's original dependency state, skipping "cleanup".
- node_modules/.bin/ember try:one $EMBER_TRY_SCENARIO --skip-cleanup
================================================
FILE: .watchmanconfig
================================================
{
"ignore_dirs": ["tmp", "dist"]
}
================================================
FILE: CHANGELOG.md
================================================
# Changelog
## [Unreleased](https://github.com/miguelcobain/ember-cli-selectize/tree/HEAD)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.12...HEAD)
**Closed issues:**
- Label truncates when second word contains letters in the first in multiple mode [\#190](https://github.com/miguelcobain/ember-cli-selectize/issues/190)
- Using multiple=true with ember-changeset-validations [\#187](https://github.com/miguelcobain/ember-cli-selectize/issues/187)
- Having trouble clearing the input when the model is replaced [\#167](https://github.com/miguelcobain/ember-cli-selectize/issues/167)
- Can I use selectize load method with ember-cli-selective ? [\#137](https://github.com/miguelcobain/ember-cli-selectize/issues/137)
- Know from which select you come [\#101](https://github.com/miguelcobain/ember-cli-selectize/issues/101)
**Merged pull requests:**
- Update ember [\#199](https://github.com/miguelcobain/ember-cli-selectize/pull/199) ([rwwagner90](https://github.com/rwwagner90))
- Use ember-cli-node-assets to import selectize [\#198](https://github.com/miguelcobain/ember-cli-selectize/pull/198) ([rwwagner90](https://github.com/rwwagner90))
- Update selectize website link [\#196](https://github.com/miguelcobain/ember-cli-selectize/pull/196) ([tchan](https://github.com/tchan))
## [v0.5.12](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.12) (2017-01-12)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.11...v0.5.12)
**Merged pull requests:**
- Remove deprecated Ember.K [\#180](https://github.com/miguelcobain/ember-cli-selectize/pull/180) ([cibernox](https://github.com/cibernox))
- Upgrade ember-getowner-polyfill [\#178](https://github.com/miguelcobain/ember-cli-selectize/pull/178) ([dfreeman](https://github.com/dfreeman))
## [v0.5.11](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.11) (2016-11-10)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.10...v0.5.11)
## [v0.5.10](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.10) (2016-11-03)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.9...v0.5.10)
**Closed issues:**
- Updating to ember 2.7 causes problems with item/optionComponent usage [\#159](https://github.com/miguelcobain/ember-cli-selectize/issues/159)
## [v0.5.9](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.9) (2016-10-18)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.8...v0.5.9)
**Fixed bugs:**
- v0.5.8 broke the selectize styles [\#174](https://github.com/miguelcobain/ember-cli-selectize/issues/174)
## [v0.5.8](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.8) (2016-10-13)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.7...v0.5.8)
**Closed issues:**
- hideSelected and multiple don't work together [\#173](https://github.com/miguelcobain/ember-cli-selectize/issues/173)
**Merged pull requests:**
- Modified index.js to get correct parent when the addon is used a second level addon [\#172](https://github.com/miguelcobain/ember-cli-selectize/pull/172) ([showy](https://github.com/showy))
## [v0.5.7](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.7) (2016-10-10)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.6...v0.5.7)
## [v0.5.6](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.6) (2016-10-07)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.5...v0.5.6)
**Implemented enhancements:**
- support for the score option [\#154](https://github.com/miguelcobain/ember-cli-selectize/pull/154) ([4xposed](https://github.com/4xposed))
**Closed issues:**
- Allow addon to be used as a nested addon [\#162](https://github.com/miguelcobain/ember-cli-selectize/issues/162)
- How to set initial selections? [\#157](https://github.com/miguelcobain/ember-cli-selectize/issues/157)
- DEPRECATION: Using the injected `container` is deprecated. [\#153](https://github.com/miguelcobain/ember-cli-selectize/issues/153)
- Trouble with Async-Search [\#149](https://github.com/miguelcobain/ember-cli-selectize/issues/149)
- Allowing use of empty templates [\#147](https://github.com/miguelcobain/ember-cli-selectize/issues/147)
- ember-getowner-polyfill [\#142](https://github.com/miguelcobain/ember-cli-selectize/issues/142)
- Clearing multiple selection selectize generates model error [\#123](https://github.com/miguelcobain/ember-cli-selectize/issues/123)
- Set searchField option [\#64](https://github.com/miguelcobain/ember-cli-selectize/issues/64)
**Merged pull requests:**
- use resolveRegistration instead of lookupFactory [\#164](https://github.com/miguelcobain/ember-cli-selectize/pull/164) ([safeforge](https://github.com/safeforge))
- Add possibility to use this addon inside another \#162 [\#163](https://github.com/miguelcobain/ember-cli-selectize/pull/163) ([Sinled](https://github.com/Sinled))
- Add name as binding attribute [\#161](https://github.com/miguelcobain/ember-cli-selectize/pull/161) ([GreatWizard](https://github.com/GreatWizard))
- Update included hook for nested addons [\#158](https://github.com/miguelcobain/ember-cli-selectize/pull/158) ([GreatWizard](https://github.com/GreatWizard))
- Allow the ability to set searchField [\#146](https://github.com/miguelcobain/ember-cli-selectize/pull/146) ([SirZach](https://github.com/SirZach))
## [v0.5.5](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.5) (2016-05-16)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.4...v0.5.5)
**Merged pull requests:**
- Couldn't find module `ember-getowner-polyfill` [\#145](https://github.com/miguelcobain/ember-cli-selectize/pull/145) ([juanesarango](https://github.com/juanesarango))
## [v0.5.4](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.4) (2016-05-12)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.3...v0.5.4)
## [v0.5.3](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.3) (2016-05-03)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.2...v0.5.3)
**Closed issues:**
- Is it possible to set the tabindex for this component? [\#132](https://github.com/miguelcobain/ember-cli-selectize/issues/132)
**Merged pull requests:**
- Ember Fastboot compatibility [\#141](https://github.com/miguelcobain/ember-cli-selectize/pull/141) ([mike-north](https://github.com/mike-north))
- Tabindex support [\#139](https://github.com/miguelcobain/ember-cli-selectize/pull/139) ([MartinMalinda](https://github.com/MartinMalinda))
## [v0.5.2](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.2) (2016-01-19)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.1...v0.5.2)
**Closed issues:**
- Does itemComponent work for you? [\#135](https://github.com/miguelcobain/ember-cli-selectize/issues/135)
- Deprecation warnings with itemTemplate/optionTemplate params [\#122](https://github.com/miguelcobain/ember-cli-selectize/issues/122)
- Passing value to template [\#116](https://github.com/miguelcobain/ember-cli-selectize/issues/116)
## [v0.5.1](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.1) (2016-01-13)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.5.0...v0.5.1)
**Closed issues:**
- optionTemplate and optionView not working anymore [\#29](https://github.com/miguelcobain/ember-cli-selectize/issues/29)
## [v0.5.0](https://github.com/miguelcobain/ember-cli-selectize/tree/v0.5.0) (2016-01-13)
[Full Changelog](https://github.com/miguelcobain/ember-cli-selectize/compare/v0.4.4...v0.5.0)
**Closed issues:**
- unable to require.unsee, please upgrade loader.js to \>= v3.3.0 [\#127](https://github.com/miguelcobain/ember-cli-selectize/issues/127)
**Merged pull requests:**
- Upgrading loading to 3.3.0 to fix warning [\#128](https://github.com/miguelcobain/ember-cli-selectize/pull/128) ([juliankmazo](https://github.com/juliankmazo))
- Accept white-spaces in `plugins` parameter [\#121](https://github.com/miguelcobain/ember-cli-selectize/pull/121) ([Romanior](https://github.com/Romanior))
# Ember Selectize Changelog
### 0.4.4 (Dec 15, 2015)
- [#113](https://github.com/miguelcobain/ember-cli-selectize/pull/130) Disable remove_button plugin when multiple option is not set
### 0.4.3 (Sep 21, 2015)
- [#113](https://github.com/miguelcobain/ember-cli-selectize/pull/113) Ensure resolved is not null
### 0.4.2 (Sep 07, 2015)
- [3941b7e](https://github.com/miguelcobain/ember-cli-selectize/commit/3941b7e7d8b080b29ac1d5ccf819a4b6121f09db) Accept content from promise
### 0.4.1 (Sep 04, 2015)
- [#154](https://github.com/miguelcobain/ember-cli-selectize/pull/107) use ember-new-computed only when needed (fixes `computed.default.alias is not a function` [#98](https://github.com/miguelcobain/ember-cli-selectize/issues/98))
- [#99](https://github.com/miguelcobain/ember-cli-selectize/issues/99) Add changelog
\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/skywinder/Github-Changelog-Generator)*
================================================
FILE: HISTORY.md
================================================
# Ember Selectize Changelog
### 0.4.4 (Dec 15, 2015)
- [#113](https://github.com/miguelcobain/ember-cli-selectize/pull/130) Disable remove_button plugin when multiple option is not set
### 0.4.3 (Sep 21, 2015)
- [#113](https://github.com/miguelcobain/ember-cli-selectize/pull/113) Ensure resolved is not null
### 0.4.2 (Sep 07, 2015)
- [3941b7e](https://github.com/miguelcobain/ember-cli-selectize/commit/3941b7e7d8b080b29ac1d5ccf819a4b6121f09db) Accept content from promise
### 0.4.1 (Sep 04, 2015)
- [#154](https://github.com/miguelcobain/ember-cli-selectize/pull/107) use ember-new-computed only when needed (fixes `computed.default.alias is not a function` [#98](https://github.com/miguelcobain/ember-cli-selectize/issues/98))
- [#99](https://github.com/miguelcobain/ember-cli-selectize/issues/99) Add changelog
================================================
FILE: LICENSE.md
================================================
The MIT License (MIT)
Copyright (c) 2017
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:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
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.
================================================
FILE: README.md
================================================
# Ember-cli-selectize [](https://travis-ci.org/miguelcobain/ember-cli-selectize) [](http://emberobserver.com/addons/ember-cli-selectize)
# NOTE: consider using [ember-power-select](http://www.ember-power-select.com/)
An Ember and Selectize integration, packaged as an Ember-cli addon. Check [Selectize](https://selectize.github.io/selectize.js/) and [Ember-cli](http://www.ember-cli.com/)!
## Demo
Check (old demo): http://miguelcobain.github.io/ember-selectize
## Installation
```shell
ember install ember-cli-selectize
```
## Usage
This addon provides an `ember-selectize` component.
Its usage should be very similar to `Ember.Select`, but with additional features.
```handlebars
{{ember-selectize
content=controller.items
optionValuePath="content.id"
optionLabelPath="content.name"
selection=model.item
placeholder="Select an item" }}
```
### Properties
<table width="100%">
<tr>
<th valign="top" width="120px" align="left">Property</th>
<th valign="top" align="left">Description</th>
</tr>
<tr>
<td valign="top"><code>content</code></td>
<td valign="top">Array containing all the options to select from</td>
</tr>
<tr>
<td valign="top"><code>selection</code></td>
<td valign="top">Ember-selectize will set this property to the selection that was made. Usually some property on a model, for example. If <code>multiple</code> is <code>true</code>, then it should be an array.</td>
</tr>
<tr>
<td valign="top"><code>value</code></td>
<td valign="top">Ember-selectize will set this property to the *value of the selection* that was made. It is not currently supported in multiple selection mode.</td>
</tr>
<tr>
<td valign="top"><code>optionValuePath</code></td>
<td valign="top">Selectize requires a unique hash for each option available. Set this to a path to such a property on your options. Prefix with <code>content.</code>. Example: <code>content.id</code></td>
</tr>
<tr>
<td valign="top"><code>optionLabelPath</code></td>
<td valign="top">Set this to a path where selectize can get a label for display. Computed properties are many times useful for this. If Ember-selectize detects a "falsy" value, it will use an empty string. Example: <code>content.name</code></td>
</tr>
<tr>
<td valign="top"><code>plugins</code></td>
<td valign="top">Set this to a comma delimited list of selectize plugins to override the default plugin selection (currently remove_button). Note, not all plugins have been tested to work with ember-cli-selectize, YMMV. Example: <code>restore_on_backspace,drag_drop</code></td>
</tr>
<tr>
<td valign="top"><code>placeholder</code> or <code>prompt</code></td>
<td valign="top">Set any of these to display a text when there is no choice made. Example <code>"Please select an option"</code></td>
</tr>
<tr>
<td valign="top"><code>disabled</code></td>
<td valign="top">If <code>true</code> disables changes in selectize</td>
</tr>
<tr>
<td valign="top"><code>multiple</code></td>
<td valign="top">If <code>true</code> ember-selectize will enter multiple mode. <code>selection</code> is an array of options.</td>
</tr>
<tr>
<td valign="top"><code>sortField</code></td>
<td valign="top">Pass a string of a property to sort by. You can also pass an array of objects <code>[{ field: 'someProperty', direction: 'asc' }, {/*...*/}]</code>. See <a href="https://github.com/brianreavis/selectize.js/blob/master/docs/usage.md">selectize usage</a> for details. Example: <code>"name"</code></td>
</tr>
<tr>
<td valign="top"><code>sortDirection</code></td>
<td valign="top">If <code>sortField</code> is a string, specify the direction. Example: <code>"asc"</code> or <code>"desc"</code>. This is ignored if <code>sortField</code> is an array (you can specify direction inside that array).</td>
</tr>
<tr>
<td valign="top"><code>searchField</code></td>
<td valign="top">If <code>searchField</code> is a string, it specifies what field should be searched on. It also accepts an array to search on multiple fields, e.g., <code>['label', 'value']</code>. Defaults to <code>'label'</code>.</td>
<tr>
<td valign="top"><code>filter</code></td>
<td valign="top">This property will have the text that the user entered to filter options. Useful for searching options in server from a large set.</td>
</tr>
<tr>
<td valign="top"><code>loading</code></td>
<td valign="top">When <code>true</code> ember-selectize adds a loading class to selectize wrapper. Just like selectize does. Then you can customize. Useful with async relationships or "finds" in Ember-Data: <code>loading=types.isPending</code>.</td>
</tr>
<tr>
<td valign="top">
<code>optionFunction</code>, <code>itemFunction</code>, <code>optionCreateFunction</code>, <code>optgroupHeaderFunction</code>, <code>optgroupFunction</code>
</td>
<td valign="top">Will be called on the component with two parameters <code>data</code> and <code>escape</code>. <code>escape</code> is a function to escape text. These functions are expected to build the desired html and return it as a string or DOM elements. These functions take precedence over their <code>Component</code> counterparts.</td>
</tr>
<tr>
<td valign="top">
<code>optionComponent</code>, <code>itemComponent</code>,
<code>optionCreateComponent</code>, <code>optgroupHeaderComponent</code>
and <code>optgroupComponent</code>
</td>
<td valign="top">Render using components! Functions (see above) take precedence over components, so if you do strange things like setting <code>optionFunction</code> and <code>optionComponent</code>, the latter will be ignored. Inside your component and template <code>data</code> will contain the data for the current item being rendered. An example component could be <code>Hi, {{data.firstname}}!</code></td>
</tr>
<tr>
<td valign="top"><code>required</code></td>
<td valign="top">If <code>true</code> adds <code>required</code> attribute</td>
</tr>
</table>
ember-selectize also supports [selectize's general options](https://github.com/brianreavis/selectize.js/blob/master/docs/usage.md#general), excluding `options` and `items` (equivalent to `content` and `selection` respectively).
### Actions
Ember is moving towards a paradigm that encourages the use of actions. With this in mind, ember selectize provides a set of actions. The goal is to not use two way data bindings, that is, you pass the data to your components, but the components send actions up to let you (and only you) change the data. Here are the actions the ember selectize supports:
<table width="100%">
<tr>
<th valign="top" width="160px" align="left">Action</th>
<th valign="top" align="left">Description</th>
</tr>
<tr>
<td valign="top"><code>create-item</code></td>
<td valign="top">Sent when the user creates a tag. The text is sent as a parameter.</td>
</tr>
<tr>
<td valign="top"><code>update-filter</code></td>
<td valign="top">Sent when the user types in the input element (functional equivalent of observing <code>filter</code> property)</td>
</tr>
<tr>
<td valign="top"><code>select-item</code> / <code>select-value</code></td>
<td valign="top">Sent when the user selects an item (functional equivalent of observing <code>selection</code> property). The selected object is sent as a parameter. When the user deselects the option, parameter is <code>null</code>. `select-value` is identical, but gets the selected value passed in.</td>
</tr>
<tr>
<td valign="top"><code>add-item</code> / <code>add-value</code></td>
<td valign="top">sent when the user selects an item in multiple mode. The added object is sent as a parameter. `add-value` is identical, but gets the added value passed in.</td>
</tr>
<tr>
<td valign="top"><code>remove-item</code> / <code>remove-value</code></td>
<td valign="top">Sent when the user deselects an item in multiple mode. The removed object is sent as a parameter. `remove-value` is identical, but gets the removed value passed in.</td>
</tr>
<tr>
<td valign="top"><code>on-focus</code></td>
<td valign="top">Sent when the control gains focus.</td>
</tr>
<tr>
<td valign="top"><code>on-blur</code></td>
<td valign="top">Sent when the control loses focus.</td>
</tr>
<tr>
<td valign="top"><code>on-init</code></td>
<td valign="top">Sent once the control is completely initialized.</td>
</tr>
<tr>
<td valign="top"><code>score</code></td>
<td valign="top">Overrides the default score() method if a cutom one is passed as an option to
the component.</td>
</tr>
</table>
Ember selectize supports both APIs.
More info:
- ember-selectize registers observers on object labels. This is great because if you change the label property anywhere in your application, selectize labels will also update.
We will folow Ember Select's approach, which is really flexible:
### Option Groups ###
Ember-selectize supports two flavors of option grouping.
#### `#1` optionGroupPath ####
Set `optionGroupPath` to a path for a property to group for.
Example:
```javascript
[
{
id: 1,
category: 'Nature',
title: 'This title will appear on select'
},
{
id: 2,
category: 'Nature',
title: 'This title will appear on select'
},
{
id: 3,
category: 'Another category',
title: 'This title will appear on select'
},
//...
]
```
`optionGroupPath` would be `"content.category"`, which would group items according to that property automatically.
like
```handlebars
{{ember-selectize optionGroupPath="content.category"}}
```
### `#2` groupedContent ###
If you prefer you can group your items yourself and pass them to ember selectize.
Just set the property `groupedContent` to an array with the following format:
```javascript
[
{
label: 'Nature',
content: [
{
id: 1,
title: 'This title will appear on select'
},
{
id: 2,
title: 'This title will appear on select'
}
]
},
{
label: 'Another category',
content: [
//...
]
},
//...
]
```
and in your template
```handlebars
{{ember-selectize groupedContent=someArray}}
```
### Theme customization
You can customize which theme to use in your Brocfile.
```javascript
//your-app/Brocfile.js
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
var app = new EmberApp({
'ember-cli-selectize': {
//valid values are `default`, `bootstrap2`, `bootstrap3` or false
'theme': 'bootstrap3'
}
});
module.exports = app.toTree();
```
If you want to use the default theme, you don't need to specify any option.
If you don't want to include any css at all for some reason, simply assign `false` or any "falsy" value to the `theme` option.
## Running
* `ember server`
* Visit your app at http://localhost:4200.
## Running Tests
* `npm test` (Runs `ember try:testall` to test your addon against multiple Ember versions)
* `ember test`
* `ember test --server`
## Building
* `ember build`
For more information on using ember-cli, visit [https://ember-cli.com/](https://ember-cli.com/).
================================================
FILE: addon/.gitkeep
================================================
================================================
FILE: addon/components/ember-selectize.js
================================================
import Ember from 'ember';
const {
Component,
computed,
observer,
run,
get,
isArray,
isEmpty,
isNone,
typeOf,
String: { camelize },
assert,
assign,
getOwner
} = Ember;
/**
* Ember.Selectize is an Ember View that encapsulates a Selectize component.
* The goal is to use this as a near dropin replacement for Ember.Select.
*/
export default Component.extend({
attributeBindings: ['name', 'multiple', 'autocomplete', 'required', 'tabindex'],
classNames: ['ember-selectize'],
autocomplete: 'off',
multiple: false,
tabindex: 0,
maxItems: computed('multiple', function() {
return this.get('multiple') ? null : 1;
}),
// Allows to use prompt (like in Ember.Select) or placeholder property
placeholder: computed.alias('prompt'),
sortField: null,
sortDirection: 'asc',
tagName: 'select',
/**
* overrideable object paths for value and label paths
*/
optionValuePath: 'content',
optionLabelPath: 'content',
optionGroupPath: 'content.group',
selection: null,
value: computed('selection', {
get() {
var valuePath = this.get('_valuePath');
var selection = this.get('selection');
return valuePath && selection ? get(selection, valuePath) : selection;
},
set(key, value) {
return value;
}
}),
/*
* Contains optgroups.
*/
optgroups: computed('content.[]', 'groupedContent.[]', function() {
var groupedContent = this.get('groupedContent');
if (groupedContent) {
return groupedContent.mapBy('label');
} else {
//compute option groups from content
var content = this.get('content');
if (!isArray(content)) { return; }
return content.reduce((previousValue, item) => {
return previousValue.addObject(get(item, this.get('_groupPath')));
}, Ember.A());
}
}),
/**
* Computes content from grouped content.
* If `content` is set, this computed property is overriden and never executed.
*/
content: computed('groupedContent.[]', function() {
var groupedContent = this.get('groupedContent');
if (!groupedContent) { return; }
//concatenate all content properties in each group
return groupedContent.reduce((previousValue, group) => {
var content = get(group, 'content') || Ember.A();
var groupLabel = get(group, 'label');
//create proxies for each object. Selectize requires the group value to be
//set in the object. Use ObjectProxy to keep original object intact.
var proxiedContent = content.map(item => {
var proxy = { content: item };
proxy[this.get('_groupPath')] = groupLabel;
return Ember.ObjectProxy.create(proxy);
});
return previousValue.pushObjects(proxiedContent);
}, Ember.A());
}),
_optgroupsDidChange: observer('optgroups.[]', function() {
if (!this._selectize) {
return;
}
//TODO right now we reset option groups.
//Ideally we would set up an array observer and use selectize's [add|remove]OptionGroup
this._selectize.clearOptionGroups();
var optgroups = this.get('optgroups');
if (!optgroups) { return; }
optgroups.forEach(group => {
this._selectize.addOptionGroup(group, { label: group, value: group});
});
}),
/**
* The array of the default plugins to load into selectize
*/
plugins: ['remove_button'],
/**
* Computed properties that hold the processed paths ('content.' replacement),
* as it is done on Ember.Select
*/
_valuePath: computed('optionValuePath', function() {
return this.get('optionValuePath').replace(/^content\.?/, '');
}),
_labelPath: computed('optionLabelPath', function() {
return this.get('optionLabelPath').replace(/^content\.?/, '');
}),
_groupPath: computed('optionGroupPath', function() {
return this.get('optionGroupPath').replace(/^content\.?/, '');
}),
getValueFor(item) {
let valuePath = this.get('_valuePath');
return isEmpty(valuePath) || isEmpty(item) ? item : get(item, valuePath);
},
getLabelFor(item) {
let labelPath = this.get('_labelPath');
return isEmpty(labelPath) || isEmpty(item) ? item : get(item, labelPath);
},
/**
* Loading feature default values.
* If you want to override the css class that is applied, change the `loadingClass` property.
*/
loading: false,
loadingClass: 'loading',
/**
* The render function names selectize expects.
* We will use these to automatically infer the properties with the template and view names.
*/
functionNames: ['option', 'item', 'option_create', 'optgroup_header', 'optgroup'],
templateSuffix: 'Template',
componentSuffix: 'Component',
functionSuffix: 'Function',
renderOptions: computed(function() {
var functionNames = this.get('functionNames');
//this hash will contain the render functions
var renderFunctions = {};
functionNames.forEach(item => {
// infer the function name by camelizing selectize's function and appending the function suffix (overridable)
var functionSuffix = this.get('functionSuffix');
var functionPropertyName = camelize(item) + functionSuffix;
var renderFunction = this.get(functionPropertyName);
// functions take precedence
if (renderFunction) {
renderFunctions[item] = (data, escape) => {
return renderFunction.call(this.get('targetObject') || this, data.data || data, escape);
};
} else {
// infer the view name by camelizing selectize's function and appending a view suffix (overridable)
var componentSuffix = this.get('componentSuffix');
var componentPropertyName = camelize(item) + componentSuffix;
var componentToRender = this.get(componentPropertyName);
if (componentToRender) {
// we have a view to render. set the function.
renderFunctions[item] = data => {
return this._componentToDOM(componentToRender, data.data || data);
};
}
}
});
return renderFunctions;
}),
selectizeOptions: computed(function() {
var allowCreate = this.get('create-item');
var multiple = this.get('multiple');
//Split the passed in plugin config into an array.
if (typeof this.plugins === 'string') {
this.plugins = this.plugins.trim().split(/[\s,]+/);
}
var plugins = this.plugins.slice(0);
if (!multiple) {
var index = plugins.indexOf('remove_button');
if (index !== -1) {
plugins.splice(index, 1);
}
}
var options = {
plugins: plugins,
labelField: 'label',
valueField: 'value',
searchField: 'label',
optgroupField: 'optgroup',
create: allowCreate ? run.bind(this, '_create') : false,
onItemAdd: run.bind(this, '_onItemAdd'),
onItemRemove: run.bind(this, '_onItemRemove'),
onType: run.bind(this, '_onType'),
render: this.get('renderOptions'),
placeholder: this.get('placeholder'),
score: this.get('score'),
onBlur: this._registerAction('on-blur'),
onFocus: this._registerAction('on-focus'),
onInitialize: this._registerAction('on-init'),
onClear: this._registerAction('on-clear')
};
var generalOptions = ['delimiter', 'diacritics', 'createOnBlur',
'createFilter', 'highlight', 'persist', 'openOnFocus',
'maxOptions', 'maxItems', 'hideSelected',
'closeAfterSelect', 'allowEmptyOption',
'scrollDuration', 'loadThrottle', 'preload',
'dropdownParent', 'addPrecedence', 'selectOnTab',
'searchField'];
generalOptions.forEach((option) => {
options[option] = this.getWithDefault(option, options[option]);
});
options = this._mergeSortField(options);
return options;
}),
didInsertElement() {
// ensure selectize is loaded
assert('selectize has to be loaded', typeof this.$().selectize === 'function');
//Create Selectize's instance
this.$().selectize(this.get('selectizeOptions'));
//Save the created selectize instance
this._selectize = this.$()[0].selectize;
//Some changes to content, selection and disabled could have happened before the Component was inserted into the DOM.
//We trigger all the observers manually to account for those changes.
this._disabledDidChange();
this._optgroupsDidChange();
if(this.get('groupedContent')) {
this._groupedContentDidChange();
}
this._contentDidChange();
var selection = this.get('selection');
var value = this.get('value');
if (!isNone(selection)) { this._selectionDidChange(); }
if (!isNone(value)) { this._valueDidChange(); }
this._loadingDidChange();
},
willDestroyElement() {
//Unbind observers
this._contentWillChange(this.get('content'));
this._selectionWillChange(this.get('selection'));
this._groupedContentWillChange(this.get('groupedContent'));
//Invoke Selectize's destroy
this._selectize.destroy();
//We are no longer in DOM
this._selectize = null;
},
/**
* Event callback that is triggered when user creates a tag
*/
_create(input, callback) {
// Delete user entered text
this._selectize.setTextboxValue('');
// Send create action
// allow the observers and computed properties to run first
run.schedule('actions', this, function() {
this.sendAction('create-item', input);
});
// We cancel the creation here, so it's up to you to include the created element
// in the content and selection property
callback(null);
},
/**
* Event callback for DOM events
*/
_registerAction(action){
return run.bind(this, function() {
var args = Array.prototype.slice.call(arguments);
args.unshift(action);
this.sendAction.apply(this, args);
});
},
/**
* Event callback that is triggered when user types in the input element
*/
_onType(str) {
this.set('filter', str);
run.schedule('actions', this, function() {
this.sendAction('update-filter', str);
});
},
/**
* Event callback triggered when an item is added (when something is selected)
* Here we need to update our selection property (if single selection) or array (if multiple selection)
* We also send an action
*/
_onItemAdd(value) {
var content = this.get('content');
var selection = this.get('selection');
var multiple = this.get('multiple');
if (content) {
var obj = content.find(function(item) {
return (this.getValueFor(item) + '') === value;
}, this);
if (multiple && isArray(selection) && obj) {
let selected = selection.find((item) => {
return isEmpty(this.get('_valuePath')) ? item === obj : this.getValueFor(obj) === this.getValueFor(item);
});
if (!selected) {
this._addSelection(obj);
}
} else if (obj) {
if (!selection || (this.getValueFor(obj) !== this.getValueFor(selection))) {
this._updateSelection(obj);
}
}
}
},
/**
* Event callback triggered when an item is removed (when something is deselected)
* Here we need to update our selection property (if single selection, here set to null) or remove item from array (if multiple selection)
*/
_onItemRemove(value) {
//in order to know if this event was triggered by observers or if it came from user interaction
if (this._removing) { return; }
var content = this.get('content');
var selection = this.get('selection');
var multiple = this.get('multiple');
if (content) {
var obj = content.find(function(item) {
return this.getValueFor(item) + '' === value;
}, this);
if (multiple && isArray(selection) && obj) {
this._removeSelection(obj);
} else if (!multiple) {
this._updateSelection(null);
}
}
},
/**
* Update the selection value and send main actions
* In addition to emitting the selection object, a selection value is sent via `select-value` based on `optionValuePath`
*/
_updateSelection(selection) {
this.set('selection', selection);
// allow the observers and computed properties to run first
run.schedule('actions', this, function() {
var value = this.get('value');
this.sendAction('select-item', selection, value);
this.sendAction('select-value', value);
});
},
_addSelection(obj) {
let val = this.getValueFor(obj);
this.get('selection').addObject(obj);
run.schedule('actions', this, function() {
this.sendAction('add-item', obj);
this.sendAction('add-value', val);
});
},
_removeSelection(obj) {
let val = this.getValueFor(obj);
this.get('selection').removeObject(obj);
run.schedule('actions', this, function() {
this.sendAction('remove-item', obj);
this.sendAction('remove-value', val);
});
},
/**
* Ember observer triggered before the selection property is changed
* We need to unbind any array observers if we're in multiple selection
*/
_selectionWillChange(selection) {
var multiple = this.get('multiple');
if (selection && isArray(selection) && multiple) {
selection.removeArrayObserver(this, {
willChange: 'selectionArrayWillChange',
didChange: 'selectionArrayDidChange'
});
var len = selection ? get(selection, 'length') : 0;
this.selectionArrayWillChange(selection, 0, len);
}
},
/**
* Ember observer triggered when the selection property is changed
* We need to bind an array observer when selection is multiple
*/
_selectionDidChange: observer('selection', function() {
var selection = this.get('selection');
if (this._oldSelection !== selection) {
this._selectionWillChange(this._oldSelection);
this._oldSelection = selection;
}
if (!this._selectize) { return; }
var multiple = this.get('multiple');
if (selection) {
if (multiple) {
assert('When ember-selectize is in multiple mode, the provided selection must be an array.', isArray(selection));
//bind array observers to listen for selection changes
selection.addArrayObserver(this, {
willChange: 'selectionArrayWillChange',
didChange: 'selectionArrayDidChange'
});
//Trigger a selection change that will update selectize with the new selection
var len = selection ? get(selection, 'length') : 0;
this.selectionArrayDidChange(selection, 0, null, len);
} else {
if (selection.then) {
selection.then(resolved => {
if (resolved) {
// Ensure that we don't overwrite new value
if (get(this, 'selection') === selection) {
this._selectize.addItem(this.getValueFor(resolved));
}
} else {
//selection was changed to a falsy value. Clear selectize.
this._selectize.clear();
this._selectize.showInput();
}
});
} else {
this._selectize.addItem(this.getValueFor(selection));
}
}
} else {
//selection was changed to a falsy value. Clear selectize.
this._selectize.clear();
this._selectize.showInput();
}
}),
/**
* It is possible to control the selected item through its value.
*/
_valueDidChange: observer('value', function() {
if (this.get('multiple')) { return; }
var content = this.get('content');
var value = this.get('value');
var selectedValue = this.getValueFor(this.get('selection'));
var selection;
if (value !== selectedValue) {
selection = content ? content.find((obj) => {
return value === this.getValueFor(obj);
}) : null;
this.set('selection', selection);
}
}),
/*
* Triggered before the selection array changes
* Here we process the removed elements
*/
selectionArrayWillChange(array, idx, removedCount) {
this._removing = true;
for (var i = idx; i < idx + removedCount; i++) {
this.selectionObjectWasRemoved(array.objectAt(i));
}
this._removing = false;
},
/*
* Triggered after the selection array changes
* Here we process the inserted elements
*/
selectionArrayDidChange(array, idx, removedCount, addedCount) {
for (var i = idx; i < idx + addedCount; i++) {
this.selectionObjectWasAdded(array.objectAt(i), i);
}
},
/*
* Function that is responsible for Selectize's item inserting logic
*/
selectionObjectWasAdded(obj) {
if (this._selectize) {
this._selectize.addItem(this.getValueFor(obj));
}
},
/*
* Function that is responsible for Selectize's item removing logic
*/
selectionObjectWasRemoved(obj) {
if (this._selectize) {
this._selectize.removeItem(this.getValueFor(obj));
}
},
/**
* Ember observer triggered before the content property is changed
* We need to unbind any array observers
*/
_contentWillChange(content) {
if (!this._selectize) { return; }
if (isArray(content)) {
content.removeArrayObserver(this, {
willChange: 'contentArrayWillChange',
didChange: 'contentArrayDidChange'
});
}
//Trigger remove logic
var len = content ? get(content, 'length') : 0;
this._removing = true;
this.contentArrayWillChange(content, 0, len);
this._removing = false;
},
/**
* Ember observer triggered when the content property is changed
* We need to bind an array observer to become notified of its changes
*/
_contentDidChange: observer('content', function() {
var content = this.get('content');
if (this._oldContent !== content) {
this._contentWillChange(this._oldContent);
this._oldContent = content;
}
if (!this._selectize) { return; }
if (isArray(content)) {
content.addArrayObserver(this, {
willChange: 'contentArrayWillChange',
didChange: 'contentArrayDidChange'
});
} else if(content && content.then) {
content.then(resolved => {
// Ensure that we don't overwrite new value
if (get(this, 'content') === content) {
this.set('content', resolved);
}
});
}
var len = content ? get(content, 'length') : 0;
this.contentArrayDidChange(content, 0, null, len);
}),
/*
* Triggered before the content array changes
* Here we process the removed elements
*/
contentArrayWillChange(array, idx, removedCount) {
for (var i = idx; i < idx + removedCount; i++) {
this.objectWasRemoved(array.objectAt(i));
}
if (this._selectize) {
this._selectize.refreshOptions(this._selectize.isFocused && !this._selectize.isInputHidden);
}
},
/*
* Triggered after the content array changes
* Here we process the inserted elements
*/
contentArrayDidChange(array, idx, removedCount, addedCount) {
for (var i = idx; i < idx + addedCount; i++) {
this.objectWasAdded(array.objectAt(i));
this.addLabelObserver(array.objectAt(i));
}
if (this._selectize) {
this._selectize.refreshOptions(this._selectize.isFocused && !this._selectize.isInputHidden);
}
this._selectionDidChange();
},
_groupedContentWillChange(groupedContent) {
if (!this._selectize) { return; }
if (isEmpty(groupedContent)) { return; }
groupedContent.forEach(group => {
group.get('content').removeArrayObserver(this, {
willChange: '_groupedContentArrayWillChange',
didChange: '_groupedContentArrayDidChange',
});
});
},
/**
* Ember observer triggered when the groupedContent property is changed
* We need to bind an array observer to become notified of each group's array changes,
* then notify that the parent array has changed. This is because computed properties
* have trouble with nested array changes.
*/
_groupedContentDidChange: observer('groupedContent', function() {
var groupedContent = this.get('groupedContent');
if (this._oldGroupedContent !== groupedContent) {
this._groupedContentWillChange(this._oldGroupedContent);
this._oldGroupedContent = groupedContent;
}
if (!this._selectize) {
return;
}
if (isEmpty(groupedContent)) { return; }
//var willChangeWrapper = run.bind(this, function() { this.groupedContentArrayWillChange.apply(this, arguments); });
//var didChangeWrapper = run.bind(this, function() { this.groupedContentArrayDidChange.apply(this, arguments); });
groupedContent.forEach(group => {
group.get('content').addArrayObserver(this, {
willChange: '_groupedContentArrayWillChange',
didChange: '_groupedContentArrayDidChange',
});
});
var len = groupedContent ? get(groupedContent, 'length') : 0;
this._groupedContentArrayDidChange(groupedContent, 0, null, len);
}),
/*
* Triggered before the grouped content array changes
* Here we process the removed elements
*/
_groupedContentArrayWillChange() {},
/*
* Triggered after the grouped content array changes
* Here we process the inserted elements
*/
_groupedContentArrayDidChange() {
this.notifyPropertyChange('groupedContent.[]');
},
/*
* Function that is responsible for Selectize's option inserting logic
* If the option is an object or Ember instance, we set an observer on the label value of it.
* This way, we can later update the label of it.
* Useful for dealing with objects that 'lazy load' some properties/relationships.
*/
objectWasAdded(obj) {
var data = {};
var sortField = this.get('sortField');
if (typeOf(obj) === 'object' || typeOf(obj) === 'instance') {
data = {
label: this.getLabelFor(obj),
value: this.getValueFor(obj),
data: obj
};
if (sortField) {
if (isArray(sortField)) {
sortField.forEach(function(field) {
data[field.field] = get(obj, field.field);
});
} else {
data[sortField] = get(obj, sortField);
}
}
if (get(obj, this.get('_groupPath'))) {
data.optgroup = get(obj, this.get('_groupPath'));
}
} else {
data = {
label: obj,
value: obj,
data: obj
};
if (sortField && !isArray(sortField)) {
data[sortField] = obj;
}
}
if (this._selectize && data.label) {
this._selectize.addOption(data);
}
},
addLabelObserver(obj) {
//Only attach observer if the label is a property of an object
if (typeOf(obj) === 'object' || typeOf(obj) === 'instance') {
Ember.addObserver(obj, this.get('_labelPath'), this, '_labelDidChange');
}
},
/*
* Function that is responsible for Selectize's option removing logic
*/
objectWasRemoved(obj) {
if (typeOf(obj) === 'object' || typeOf(obj) === 'instance') {
Ember.removeObserver(obj, this.get('_labelPath'), this, '_labelDidChange');
}
if (this._selectize) {
this._selectize.removeOption(this.getValueFor(obj));
}
},
/*
* Ember Observer that triggers when an option's label changes.
* Here we need to update its corresponding option with the new data
*/
_labelDidChange(sender) {
if (!this._selectize) { return; }
var data = {
label: this.getLabelFor(sender),
value: this.getValueFor(sender),
data: sender
};
if(this._selectize.getOption(data.value).length !== 0) {
this._selectize.updateOption(data.value, data);
} else {
this.objectWasAdded(sender);
}
},
/*
* Observer on the disabled property that enables or disables selectize.
*/
_disabledDidChange: observer('disabled', function() {
if (!this._selectize) { return; }
var disable = this.get('disabled');
if (disable) {
this._selectize.disable();
} else {
this._selectize.enable();
}
}),
/*
* Observer on the placeholder property that updates selectize's placeholder.
*/
_placeholderDidChange: observer('placeholder', function() {
if (!this._selectize) { return; }
var placeholder = this.get('placeholder');
this._selectize.settings.placeholder = placeholder;
this._selectize.updatePlaceholder();
}),
/*
* Observer on the loading property.
* Here we add/remove a css class, similarly to how selectize does.
*/
_loadingDidChange: observer('loading', function() {
var loading = this.get('loading');
var loadingClass = this.get('loadingClass');
if (loading) {
this._selectize.$wrapper.addClass(loadingClass);
} else {
this._selectize.$wrapper.removeClass(loadingClass);
}
}),
_lookupComponent(name) {
let owner = getOwner(this);
let componentLookupKey = `component:${name}`;
let layoutLookupKey = `template:components/${name}`;
let layout = owner.lookup(layoutLookupKey);
let component = owner.factoryFor(componentLookupKey);
if (layout && !component) {
owner.register(componentLookupKey, Component);
component = owner.factoryFor(componentLookupKey);
}
return { component, layout };
},
_componentToDOM(componentName, data) {
let { component, layout } = this._lookupComponent(componentName);
assert(`ember-selectize could not find a component named "${componentName}" in your Ember application.`, component);
let attrs = { data };
if (layout) {
attrs.layout = layout;
}
let componentInstance = component.create(attrs);
let container = document.createElement('div');
componentInstance.appendTo(container);
return container;
},
_mergeSortField(options) {
var sortField = this.get('sortField');
if (sortField) {
var sortArray = this._getSortArray(sortField);
assign(options, { sortField: sortArray });
}
return options;
},
_getSortArray(sortField) {
if (isArray(sortField)) {
return sortField;
} else {
return [{
field: sortField,
direction: this.get('sortDirection')
}];
}
}
});
================================================
FILE: app/.gitkeep
================================================
================================================
FILE: app/components/ember-selectize.js
================================================
import EmberSelectizeComponent from 'ember-cli-selectize/components/ember-selectize';
export default EmberSelectizeComponent;
================================================
FILE: config/ember-try.js
================================================
/* eslint-env node */
module.exports = {
useYarn: true,
scenarios: [
{
name: 'ember-1.13',
bower: {
dependencies: {
'ember': '~1.13.0'
},
resolutions: {
'ember': '~1.13.0'
}
}
},
{
name: 'ember-lts-2.8',
bower: {
dependencies: {
'ember': 'components/ember#lts-2-8'
},
resolutions: {
'ember': 'lts-2-8'
}
},
npm: {
devDependencies: {
'ember-source': null
}
}
},
{
name: 'ember-lts-2.12',
npm: {
devDependencies: {
'ember-source': '~2.12.0'
}
}
},
{
name: 'ember-release',
bower: {
dependencies: {
'ember': 'components/ember#release'
},
resolutions: {
'ember': 'release'
}
},
npm: {
devDependencies: {
'ember-source': null
}
}
},
{
name: 'ember-beta',
bower: {
dependencies: {
'ember': 'components/ember#beta'
},
resolutions: {
'ember': 'beta'
}
},
npm: {
devDependencies: {
'ember-source': null
}
}
},
{
name: 'ember-canary',
bower: {
dependencies: {
'ember': 'components/ember#canary'
},
resolutions: {
'ember': 'canary'
}
},
npm: {
devDependencies: {
'ember-source': null
}
}
},
{
name: 'ember-default',
npm: {
devDependencies: {}
}
}
]
};
================================================
FILE: config/environment.js
================================================
/* eslint-env node */
'use strict';
module.exports = function(/* environment, appConfig */) {
return { };
};
================================================
FILE: ember-cli-build.js
================================================
/* eslint-env node */
'use strict';
const EmberAddon = require('ember-cli/lib/broccoli/ember-addon');
module.exports = function(defaults) {
let app = new EmberAddon(defaults, {
// Add options here
});
/*
This build file specifies the options for the dummy test app of this
addon, located in `/tests/dummy`
This build file does *not* influence how the addon or the app using it
behave. You most likely want to be modifying `./index.js` or app's build file
*/
return app.toTree();
};
================================================
FILE: index.js
================================================
/* eslint-env node */
'use strict';
const fastbootTransform = require('fastboot-transform');
module.exports = {
name: 'ember-cli-selectize',
options: {
nodeAssets: {
selectize() {
return {
srcDir: 'dist',
import: {
include: [
'js/standalone/selectize.js',
`css/selectize.${this.theme}.css`
],
processTree(tree) {
return fastbootTransform(tree);
}
}
};
}
}
},
included(app) {
// If the addon has the _findHost() method (in ember-cli >= 2.7.0), we'll just
// use that.
if (typeof this._findHost === 'function') {
app = this._findHost();
}
// Otherwise, we'll use this implementation borrowed from the _findHost()
// method in ember-cli.
// Keep iterating upward until we don't have a grandparent.
// Has to do this grandparent check because at some point we hit the project.
var current = this;
do {
app = current.app || app;
} while (current.parent.parent && (current = current.parent));
// default theme name is 'default'
this.theme = 'default';
if (app.options && app.options['ember-cli-selectize'] && app.options['ember-cli-selectize'].theme) {
this.theme = app.options['ember-cli-selectize'].theme;
}
this._super.included.apply(this, arguments);
}
};
================================================
FILE: package.json
================================================
{
"name": "ember-cli-selectize",
"version": "0.6.0",
"description": "An Ember and Selectize integration, packaged as an Ember-cli addon.",
"keywords": [
"ember-addon",
"ember",
"selectize",
"combobox"
],
"license": "MIT",
"author": "Miguel Andrade <jmandrade0@gmail.com>",
"directories": {
"doc": "doc",
"test": "tests"
},
"repository": {
"type": "git",
"url": "git://github.com/miguelcobain/ember-cli-selectize.git"
},
"scripts": {
"build": "ember build",
"start": "ember server",
"test": "ember try:each"
},
"dependencies": {
"ember-cli-babel": "^6.6.0",
"ember-cli-node-assets": "0.2.2",
"ember-getowner-polyfill": "^2.2.0",
"fastboot-transform": "^0.1.3",
"selectize": "miguelcobain/selectize.js#master"
},
"devDependencies": {
"broccoli-asset-rev": "^2.4.5",
"ember-ajax": "^3.0.0",
"ember-assign-polyfill": "^2.4.0",
"ember-cli": "~2.16.2",
"ember-cli-dependency-checker": "^2.0.0",
"ember-cli-eslint": "^4.0.0",
"ember-cli-htmlbars": "^2.0.1",
"ember-cli-htmlbars-inline-precompile": "^1.0.0",
"ember-cli-inject-live-reload": "^1.4.1",
"ember-cli-qunit": "^4.0.0",
"ember-cli-shims": "^1.1.0",
"ember-cli-sri": "^2.1.0",
"ember-cli-uglify": "^2.0.0",
"ember-disable-prototype-extensions": "^1.1.2",
"ember-export-application-global": "^2.0.0",
"ember-load-initializers": "^1.0.0",
"ember-resolver": "^4.0.0",
"ember-source": "~2.16.0",
"loader.js": "^4.2.3"
},
"engines": {
"node": "^4.5 || 6.* || >= 7.*"
},
"ember-addon": {
"configPath": "tests/dummy/config",
"demoURL": "http://miguelcobain.github.io/ember-selectize"
}
}
================================================
FILE: testem.js
================================================
module.exports = {
test_page: 'tests/index.html?hidepassed',
disable_watching: true,
launch_in_ci: [
'Chrome'
],
launch_in_dev: [
'Chrome'
],
browser_args: {
Chrome: {
mode: 'ci',
args: [
// --no-sandbox is needed when running Chrome inside a container
process.env.TRAVIS ? '--no-sandbox' : null,
'--disable-gpu',
'--headless',
'--remote-debugging-port=0',
'--window-size=1440,900'
].filter(Boolean)
}
}
};
================================================
FILE: tests/.eslintrc.js
================================================
module.exports = {
env: {
embertest: true
}
};
================================================
FILE: tests/dummy/app/app.js
================================================
import Application from '@ember/application';
import Resolver from './resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
const App = Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver
});
loadInitializers(App, config.modulePrefix);
export default App;
================================================
FILE: tests/dummy/app/components/.gitkeep
================================================
================================================
FILE: tests/dummy/app/components/test-component.js
================================================
import Ember from 'ember';
export default Ember.Component.extend({
// body
});
================================================
FILE: tests/dummy/app/controllers/.gitkeep
================================================
================================================
FILE: tests/dummy/app/controllers/application.js
================================================
/* global alert */
import Ember from 'ember';
export default Ember.Controller.extend({
names: Ember.A(['Tom', 'Yehuda', 'Mike']),
items: Ember.A([
Ember.Object.create({
id: 1,
label: 'Item 1'
}),
Ember.Object.create({
id: 2,
label: 'Item 2'
}),
Ember.Object.create({
id: 3,
label: 'Item 3'
}),
Ember.Object.create({
id: 4,
label: 'Item 4'
})
]),
getOption: function(item, escape) {
return '<div class="hello"><i>' + escape(item.value) + '</i>) ' + escape(item.label) +'</div>';
},
taggedContent: Ember.A(),
taggedValues: Ember.A(),
itemValue: 3,
taggedValuesString: Ember.computed('taggedValues.[]', function () {
return this.get('taggedValues').join(', ');
}),
groupedContent: Ember.A([
Ember.Object.create({
label: 'Nature',
content: Ember.A([
{
id: 1,
title: 'This title will appear on select'
},
{
id: 2,
title: 'This title will appear on select'
}
])
}),
Ember.Object.create({
label: 'Another',
content: Ember.A([
{
id: 3,
title: 'This title will appear on select'
}
])
})
]),
posts: Ember.A([
{
id: 1,
category: 'Nature',
title: '#1 This title will appear on select'
},
{
id: 2,
category: 'Nature',
title: '#2 This title will appear on select'
},
{
id: 3,
category: 'Another',
title: '#3 This title will appear on select'
}
]),
lastPostId: 3,
lastPostGroupedId: 3,
actions:{
createAction:function(str){
alert(str);
},
selectItem:function(v){
this.set('itemValue', v);
},
createTag: function (input) {
this.get('taggedContent').addObject(input);
this.get('taggedValues').addObject(input);
},
addPost: function() {
this.incrementProperty('lastPostId');
this.get('posts').addObject({
id: this.get('lastPostId'),
category: 'Another 2',
title: '#' + this.get('lastPostId') + ' This title will appear on select'
});
},
addPostGrouped: function() {
this.incrementProperty('lastPostGroupedId');
this.get('groupedContent').findBy('label', 'Another').get('content').addObject({
id: this.get('lastPostGroupedId'),
title: '#' + this.get('lastPostGroupedId') + ' This title will appear on select'
});
}
}
});
================================================
FILE: tests/dummy/app/helpers/.gitkeep
================================================
================================================
FILE: tests/dummy/app/index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Dummy</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{content-for "head"}}
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/dummy.css">
{{content-for "head-footer"}}
</head>
<body>
{{content-for "body"}}
<script src="{{rootURL}}assets/vendor.js"></script>
<script src="{{rootURL}}assets/dummy.js"></script>
{{content-for "body-footer"}}
</body>
</html>
================================================
FILE: tests/dummy/app/models/.gitkeep
================================================
================================================
FILE: tests/dummy/app/resolver.js
================================================
import Resolver from 'ember-resolver';
export default Resolver;
================================================
FILE: tests/dummy/app/router.js
================================================
import EmberRouter from '@ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
});
export default Router;
================================================
FILE: tests/dummy/app/routes/.gitkeep
================================================
================================================
FILE: tests/dummy/app/styles/app.css
================================================
html, body {
margin: 20px;
}
================================================
FILE: tests/dummy/app/templates/application.hbs
================================================
<h2 id='title'>Selectize test</h2>
<h3>Normal usage with strings</h3>
<p>
{{ember-selectize
content=names
tabindex=6
selection=name
placeholder="Select a name" }}
</p>
<p>Selected: {{name}}</p>
<h3>Normal usage with objects + <code>selection</code></h3>
<p>
{{ember-selectize
content=items
optionValuePath="content.id"
optionLabelPath="content.label"
selection=item
create-item="createAction"
placeholder="Select an item" }}
</p>
<p>Selected: {{item.label}}</p>
<h3>Normal usage with objects + <code>value</code></h3>
<p>
{{ember-selectize
content=items
optionValuePath="content.id"
optionLabelPath="content.label"
value=itemValue
create-item="createAction"
placeholder="Select an item" }}
</p>
<p>Selected: {{itemValue}}</p>
<button {{action "selectItem" 1}}>Select 1</button>
<button {{action "selectItem" 3}}>Select 3</button>
<h3>Multiple usage with objects + <code>selection</code></h3>
<p>
{{ember-selectize
multiple=true
content=items
optionValuePath="content.id"
optionLabelPath="content.label"
selection=itemValues
create="createAction"
placeholder="Select an item" }}
</p>
<p>Selected: <ul>{{#each itemValues as |v|}}<li>{{v.label}}</li>{{/each}}</ul></p>
<h3>Multiple usage with objects + <code>optionFunction</code> rendering</h3>
<p>
{{ember-selectize
multiple=true
content=items
optionValuePath="content.id"
optionLabelPath="content.label"
selection=itemValues
create="createAction"
optionFunction=getOption
placeholder="Select an item" }}
</p>
<p>Selected: <ul>{{#each itemValues as |v|}}<li>{{v.label}}</li>{{/each}}</ul></p>
<h3><code>optionComponent</code> usage example</h3>
<p>
{{ember-selectize
content=items
optionValuePath="content.id"
optionLabelPath="content.label"
selection=item
optionComponent="test-component"
placeholder="Select an item"}}
</p>
<h3>Delimiter example</h3>
<p>
{{ember-selectize
persist=false
multiple=true
content=taggedContent
selection=taggedValues
delimiter=","
create-item="createTag"}}
</p>
<p>Selected: {{taggedValuesString}}</p>
<h3>Optgroup example with <code>groupedContent</code></h3>
<p>
{{ember-selectize
optionValuePath="content.id"
optionLabelPath="content.title"
groupedContent=groupedContent
selection=selectedPostGrouped}}
</p>
<p>Selected: {{selectedPostGrouped.title}}</p>
<button {{action "addPostGrouped"}}>Add post on "Another" category (groupedContent)</button>
<h3>Optgroup example with <code>optionGroupPath</code></h3>
<p>
{{ember-selectize
optionValuePath="content.id"
optionLabelPath="content.title"
content=posts
optionGroupPath="content.category"
selection=selectedPost}}
</p>
<p>Selected: {{selectedPost.title}}</p>
<button {{action "addPost"}}>Add post on "Another 2" category</button>
================================================
FILE: tests/dummy/app/templates/components/.gitkeep
================================================
================================================
FILE: tests/dummy/app/templates/components/test-component.hbs
================================================
Blah
================================================
FILE: tests/dummy/app/templates/test.hbs
================================================
Hi
================================================
FILE: tests/dummy/app/views/.gitkeep
================================================
================================================
FILE: tests/dummy/config/environment.js
================================================
/* eslint-env node */
'use strict';
module.exports = function(environment) {
let ENV = {
modulePrefix: 'dummy',
environment,
rootURL: '/',
locationType: 'auto',
EmberENV: {
FEATURES: {
// Here you can enable experimental features on an ember canary build
// e.g. 'with-controller': true
},
EXTEND_PROTOTYPES: {
// Prevent Ember Data from overriding Date.parse.
Date: false
}
},
APP: {
// Here you can pass flags/options to your application instance
// when it is created
},
contentSecurityPolicy: {
'default-src': "'none'",
'script-src': "'self'",
'font-src': "'self'",
'connect-src': "'self'",
'img-src': "'self'",
'style-src': "'self' 'unsafe-inline'",
'media-src': "'self'"
}
};
if (environment === 'development') {
// ENV.APP.LOG_RESOLVER = true;
// ENV.APP.LOG_ACTIVE_GENERATION = true;
// ENV.APP.LOG_TRANSITIONS = true;
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
// ENV.APP.LOG_VIEW_LOOKUPS = true;
}
if (environment === 'test') {
// Testem prefers this...
ENV.locationType = 'none';
// keep test console output quieter
ENV.APP.LOG_ACTIVE_GENERATION = false;
ENV.APP.LOG_VIEW_LOOKUPS = false;
ENV.APP.rootElement = '#ember-testing';
}
if (environment === 'production') {
// here you can enable a production-specific feature
}
return ENV;
};
================================================
FILE: tests/dummy/config/targets.js
================================================
/* eslint-env node */
module.exports = {
browsers: [
'ie 9',
'last 1 Chrome versions',
'last 1 Firefox versions',
'last 1 Safari versions'
]
};
================================================
FILE: tests/dummy/public/.gitkeep
================================================
================================================
FILE: tests/dummy/public/crossdomain.xml
================================================
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
<!-- Most restrictive policy: -->
<site-control permitted-cross-domain-policies="none"/>
<!-- Least restrictive policy: -->
<!--
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" to-ports="*" secure="false"/>
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
-->
</cross-domain-policy>
================================================
FILE: tests/dummy/public/robots.txt
================================================
# http://www.robotstxt.org
User-agent: *
Disallow:
================================================
FILE: tests/helpers/destroy-app.js
================================================
import { run } from '@ember/runloop';
export default function destroyApp(application) {
run(application, 'destroy');
}
================================================
FILE: tests/helpers/module-for-acceptance.js
================================================
import { module } from 'qunit';
import { resolve } from 'rsvp';
import startApp from '../helpers/start-app';
import destroyApp from '../helpers/destroy-app';
export default function(name, options = {}) {
module(name, {
beforeEach() {
this.application = startApp();
if (options.beforeEach) {
return options.beforeEach.apply(this, arguments);
}
},
afterEach() {
let afterEach = options.afterEach && options.afterEach.apply(this, arguments);
return resolve(afterEach).then(() => destroyApp(this.application));
}
});
}
================================================
FILE: tests/helpers/resolver.js
================================================
import Resolver from '../../resolver';
import config from '../../config/environment';
const resolver = Resolver.create();
resolver.namespace = {
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix
};
export default resolver;
================================================
FILE: tests/helpers/start-app.js
================================================
import Application from '../../app';
import config from '../../config/environment';
import { merge } from '@ember/polyfills';
import { run } from '@ember/runloop';
export default function startApp(attrs) {
let attributes = merge({}, config.APP);
attributes = merge(attributes, attrs); // use defaults, but you can override;
return run(() => {
let application = Application.create(attributes);
application.setupForTesting();
application.injectTestHelpers();
return application;
});
}
================================================
FILE: tests/index.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Dummy Tests</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{content-for "head"}}
{{content-for "test-head"}}
<link rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link rel="stylesheet" href="{{rootURL}}assets/dummy.css">
<link rel="stylesheet" href="{{rootURL}}assets/test-support.css">
{{content-for "head-footer"}}
{{content-for "test-head-footer"}}
</head>
<body>
{{content-for "body"}}
{{content-for "test-body"}}
<script src="/testem.js" integrity=""></script>
<script src="{{rootURL}}assets/vendor.js"></script>
<script src="{{rootURL}}assets/test-support.js"></script>
<script src="{{rootURL}}assets/dummy.js"></script>
<script src="{{rootURL}}assets/tests.js"></script>
{{content-for "body-footer"}}
{{content-for "test-body-footer"}}
</body>
</html>
================================================
FILE: tests/test-helper.js
================================================
import resolver from './helpers/resolver';
import {
setResolver
} from 'ember-qunit';
import { start } from 'ember-cli-qunit';
setResolver(resolver);
start();
================================================
FILE: tests/unit/.gitkeep
================================================
================================================
FILE: tests/unit/components/ember-selectize-test.js
================================================
import Ember from 'ember';
import {
moduleForComponent,
test
} from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
moduleForComponent('ember-selectize', 'Unit | Component | ember-selectize', {
// Specify the other units that are required for this test
// needs: ['component:foo', 'helper:bar']
unit: true
});
test('it renders', function(assert) {
assert.expect(2);
// creates the component instance
var component = this.subject();
assert.equal(component._state, 'preRender');
// appends the component to the page
this.render();
assert.equal(component._state, 'inDOM');
//test select tagname and ember-selectize class
});
test('name attribute is bound', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('name', 'pouet');
});
assert.equal(this.$().attr('name'), 'pouet');
});
test('multiple attribute is bound', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('multiple', true);
});
assert.equal(this.$().attr('multiple'), 'multiple');
});
test('autocomplete attribute is bound and off', function(assert) {
assert.equal(this.$().attr('autocomplete'), 'off');
});
test('required attribute is bound', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('required', true);
});
assert.equal(this.$().attr('required'), 'required');
});
test('tabindex attribute is properly set to input', function(assert){
var component = this.subject();
var tabindex = 6;
Ember.run(function() {
component.set('tabindex', tabindex);
});
assert.equal(this.$().parent().find('input').attr('tabindex'), tabindex);
});
test('maxItems is passed to selectize', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('maxItems', 10);
});
this.render();
assert.equal(component._selectize.settings.maxItems, 10);
});
test('placeholder is passed to selectize', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('placeholder', 'some placeholder here');
});
this.render();
assert.equal(component._selectize.settings.placeholder, 'some placeholder here');
});
var exampleObjectContent = function() {
return Ember.A([
Ember.Object.create({
id: 1,
label: 'item 1'
}), Ember.Object.create({
id: 2,
label: 'item 2'
}), Ember.Object.create({
id: 3,
label: 'item 3'
})
]);
};
var exampleGroupedContent = function() {
return Ember.A([
Ember.Object.create({
label: 'Nature',
content: Ember.A([
{
id: 1,
title: 'This title will appear on select'
},
{
id: 2,
title: 'This title will appear on select'
}
])
}),
Ember.Object.create({
label: 'Another',
content: Ember.A([
{
id: 3,
title: 'This title will appear on select'
}
])
})
]);
};
var exampleGroupPathContent = function() {
return Ember.A([
{
id: 1,
category: 'Nature',
title: '#1 This title will appear on select'
},
{
id: 2,
category: 'Nature',
title: '#2 This title will appear on select'
},
{
id: 3,
category: 'Another',
title: '#3 This title will appear on select'
}
]);
};
var objectSize = function(obj) {
var size = 0; var key;
for (key in obj) {
if (obj.hasOwnProperty(key)) {
size++;
}
}
return size;
};
var asArray = function(obj, path) {
var key; var values = [];
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (path) {
values.push(obj[key][path]);
} else {
values.push(obj[key]);
}
}
}
return values;
};
var keysToArray = function(obj) {
var key; var keys = [];
for (key in obj) {
if (obj.hasOwnProperty(key)) {
keys.push(key);
}
}
return keys;
};
test('selectize has correct number of options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3']));
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
});
test('if no optionValuePath pass selectize the value itself', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3']));
});
this.render();
assert.deepEqual(keysToArray(component._selectize.options), ['item 1', 'item 2', 'item 3']);
assert.deepEqual(asArray(component._selectize.options, 'value'), ['item 1', 'item 2', 'item 3']);
});
test('if no optionLabelPath pass selectize the value itself', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3']));
});
this.render();
assert.deepEqual(asArray(component._selectize.options, 'label'), ['item 1', 'item 2', 'item 3']);
});
test('optionValuePath passes selectize the desired value', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', exampleObjectContent());
component.set('optionValuePath', 'id');
});
this.render();
assert.deepEqual(exampleObjectContent().mapBy('id'), asArray(component._selectize.options, 'value'));
});
test('optionLabelPath passes selectize the desired label', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', exampleObjectContent());
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'label');
});
this.render();
assert.deepEqual(asArray(component._selectize.options, 'label'), exampleObjectContent().mapBy('label'));
});
test('selectize labels are updated', function(assert) {
var component = this.subject();
var content = exampleObjectContent();
Ember.run(function() {
component.set('content', content);
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'label');
});
this.render();
assert.deepEqual(asArray(component._selectize.options, 'label'), exampleObjectContent().mapBy('label'));
Ember.run(function() {
content.objectAt(0).set('label', 'another label');
});
assert.equal(asArray(component._selectize.options, 'label')[0], 'another label');
});
test('adding to content updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3']));
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
Ember.run(function() {
component.get('content').pushObject('extra item');
});
assert.equal(objectSize(component._selectize.options), 4);
});
test('removing from content updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3']));
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
Ember.run(function() {
component.get('content').removeObject('item 1');
});
assert.equal(objectSize(component._selectize.options), 2);
});
test('replacing content updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3']));
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
Ember.run(function() {
component.set('content', Ember.A(['item 1']));
});
assert.equal(objectSize(component._selectize.options), 1);
assert.deepEqual(asArray(component._selectize.options, 'label'), ['item 1']);
});
test('setting initial groupedContent shows correct number of options and optgroups', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('groupedContent', exampleGroupedContent());
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(objectSize(component._selectize.optgroups), 2);
});
test('adding to groupedContent parent array updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('groupedContent', exampleGroupedContent());
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(objectSize(component._selectize.optgroups), 2);
Ember.run(function() {
component.get('groupedContent').addObject(Ember.Object.create({
label: 'Third Group',
content: Ember.A([
{
id: 3,
title: 'This title will appear on select'
}
])
}));
});
assert.equal(objectSize(component._selectize.options), 4);
assert.equal(objectSize(component._selectize.optgroups), 3);
});
test('removing from groupedContent parent array updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('groupedContent', exampleGroupedContent());
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(objectSize(component._selectize.optgroups), 2);
Ember.run(function() {
component.get('groupedContent').popObject();
});
assert.equal(objectSize(component._selectize.options), 2);
assert.equal(objectSize(component._selectize.optgroups), 1);
});
test('replacing groupedContent parent array updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('groupedContent', exampleGroupedContent());
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(objectSize(component._selectize.optgroups), 2);
Ember.run(function() {
var _newGroupedContent = exampleGroupedContent();
_newGroupedContent.addObject(Ember.Object.create({
label: 'Third Group',
content: Ember.A([
{
id: 3,
title: 'This title will appear on select'
}
])
}));
component.set('groupedContent', _newGroupedContent);
});
assert.equal(objectSize(component._selectize.options), 4);
assert.equal(objectSize(component._selectize.optgroups), 3);
});
test('adding to groupedContent child array updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('groupedContent', exampleGroupedContent());
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(objectSize(component._selectize.optgroups), 2);
Ember.run(function() {
component.get('groupedContent').findBy('label', 'Another').get('content').addObject({
id: 3,
title: 'new item'
});
});
assert.equal(objectSize(component._selectize.options), 4);
assert.equal(objectSize(component._selectize.optgroups), 2);
});
test('removing from groupedContent child array updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('groupedContent', exampleGroupedContent());
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(objectSize(component._selectize.optgroups), 2);
Ember.run(function() {
component.get('groupedContent').findBy('label', 'Nature').get('content').popObject();
});
assert.equal(objectSize(component._selectize.options), 2);
assert.equal(objectSize(component._selectize.optgroups), 2);
});
test('replacing groupedContent child array updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('groupedContent', exampleGroupedContent());
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(objectSize(component._selectize.optgroups), 2);
Ember.run(function() {
var _newGroupedContent = exampleGroupedContent();
_newGroupedContent.findBy('label', 'Nature').get('content').popObject();
component.set('content', _newGroupedContent);
});
assert.equal(objectSize(component._selectize.options), 2);
assert.equal(objectSize(component._selectize.optgroups), 2);
});
test('setting initial content with optionGroupPath shows correct number of options and optgroups', function(assert) {
var component = this.subject();
Ember.run(function() {
component.setProperties({
optionValuePath: 'content.id',
optionLabelPath: 'content.title',
optionGroupPath: 'content.category',
content: exampleGroupPathContent()
});
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(objectSize(component._selectize.optgroups), 2);
});
test('adding to content with optionGroupPath updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.setProperties({
optionValuePath: 'content.id',
optionLabelPath: 'content.title',
optionGroupPath: 'content.category',
content: exampleGroupPathContent()
});
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(objectSize(component._selectize.optgroups), 2);
Ember.run(function() {
component.get('content').addObject({
id: 4,
category: 'Third Group',
title: 'this title will appear on select'
});
});
assert.equal(objectSize(component._selectize.options), 4);
assert.equal(objectSize(component._selectize.optgroups), 3);
});
test('removing from content with optionGroupPath updates selectize options', function(assert) {
var component = this.subject();
Ember.run(function() {
component.setProperties({
optionValuePath: 'content.id',
optionLabelPath: 'content.title',
optionGroupPath: 'content.category',
content: exampleGroupPathContent()
});
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(objectSize(component._selectize.optgroups), 2);
Ember.run(function() {
component.get('content').popObject();
});
assert.equal(objectSize(component._selectize.options), 2);
assert.equal(objectSize(component._selectize.optgroups), 1);
});
test('having a selection creates selectize with a selection', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3']));
component.set('selection', 'item 2');
});
this.render();
assert.equal(component._selectize.items.length, 1);
assert.deepEqual(component._selectize.items, ['item 2']);
});
test('having a multiple selection adds remove_button plugin by default', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('multiple', true);
});
this.render();
assert.notEqual(component._selectize.settings.plugins.indexOf('remove_button'), -1);
});
test('not having a multiple selection does not add remove_button plugin by default', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('multiple', false);
});
this.render();
assert.equal(component._selectize.settings.plugins.indexOf('remove_button'), -1);
});
test('having a multiple selection creates selectize with a selection', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3']));
component.set('selection', Ember.A(['item 2', 'item 3']));
component.set('multiple', true);
});
this.render();
assert.equal(component._selectize.items.length, 2);
assert.deepEqual(component._selectize.items, ['item 2', 'item 3']);
});
test('updating a selection updates selectize selection', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3']));
component.set('selection', 'item 2');
});
this.render();
assert.equal(component._selectize.items.length, 1);
assert.deepEqual(component._selectize.items, ['item 2']);
Ember.run(function() {
component.set('selection', 'item 3');
});
assert.equal(component._selectize.items.length, 1);
assert.deepEqual(component._selectize.items, ['item 3']);
});
test('updating a selection updates selectize value', function(assert) {
var component = this.subject();
var content = exampleObjectContent();
Ember.run(function() {
component.set('content', content);
component.set('optionValuePath', 'content.id');
component.set('optionLabelPath', 'content.label');
component.set('value', 1);
});
this.render();
assert.equal(component._selectize.getValue(), 1);
assert.equal(component.get('selection'), content.objectAt(0));
Ember.run(function() {
component._selectize.setValue(2);
});
assert.equal(component.get('value'), 2);
assert.equal(component.get('selection'), content.objectAt(1));
});
test('replacing a multiple selection updates selectize selection', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3', 'item 4']));
component.set('selection', Ember.A(['item 2', 'item 3']));
component.set('multiple', true);
});
this.render();
assert.equal(component._selectize.items.length, 2);
assert.deepEqual(component._selectize.items, ['item 2', 'item 3']);
Ember.run(function() {
component.set('selection', Ember.A(['item 1', 'item 2', 'item 4']));
});
assert.equal(component._selectize.items.length, 3);
assert.deepEqual(component._selectize.items, ['item 1', 'item 2', 'item 4']);
});
test('adding a multiple selection updates selectize selection', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3', 'item 4']));
component.set('selection', Ember.A(['item 2', 'item 3']));
component.set('multiple', true);
});
this.render();
assert.equal(component._selectize.items.length, 2);
assert.deepEqual(component._selectize.items, ['item 2', 'item 3']);
Ember.run(function() {
component.get('selection').pushObject('item 4');
});
assert.equal(component._selectize.items.length, 3);
assert.deepEqual(component._selectize.items, ['item 2', 'item 3', 'item 4']);
});
test('it sends update-filter action when changing filter', function(assert) {
assert.expect(1);
var testText = 'dummy text';
var component = this.subject();
var targetObject = {
externalAction: function(query) {
assert.equal(query, testText, 'externalAction was called with proper argument');
}
};
component.set('update-filter', 'externalAction');
component.set('targetObject', targetObject);
Ember.run(function() {
component._onType(testText);
});
});
test('it sends create-item action when an item is created in selectize', function(assert) {
assert.expect(1);
var testText = 'dummy text';
var component = this.subject();
var targetObject = {
externalAction: function(query) {
assert.equal(query, testText, 'externalAction was called with proper argument');
}
};
this.render();
Ember.run(function() {
component.set('create-item', 'externalAction');
component.set('targetObject', targetObject);
component._create(testText, function() {});
});
});
test('it sends select-item action when an item is selected', function(assert) {
assert.expect(1);
var component = this.subject();
var targetObject = {
externalAction: function(obj) {
assert.equal(obj, 'item 3', 'externalAction was called with proper argument');
}
};
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3', 'item 4']));
component.set('select-item', 'externalAction');
component.set('targetObject', targetObject);
});
this.render();
Ember.run(function() {
component._onItemAdd('item 3');
});
});
test('it sends select-value action when an item is selected', function(assert) {
assert.expect(1);
var component = this.subject();
var contentArray = exampleObjectContent();
var targetObject = {
externalAction: function(value) {
assert.equal(value, 1);
}
};
Ember.run(function() {
component.set('content', contentArray);
component.set('select-value', 'externalAction');
component.set('targetObject', targetObject);
component.set('optionValuePath', 'id');
});
this.render();
Ember.run(function() {
component._onItemAdd('1');
});
});
test('it sends select-item action when an item is deselected', function(assert) {
assert.expect(1);
var component = this.subject();
var targetObject = {
externalAction: function(obj) {
assert.equal(obj, null, 'externalAction was called with proper argument');
}
};
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3', 'item 4']));
component.set('selection', 'item 1');
component.set('select-item', 'externalAction');
component.set('targetObject', targetObject);
});
this.render();
Ember.run(function() {
component._onItemRemove('item 1');
});
});
test('it sends select-value action when an item is deselected', function(assert) {
assert.expect(1);
var component = this.subject();
var contentArray = exampleObjectContent();
var targetObject = {
externalAction: function(value) {
assert.equal(value, null, 'externalAction was called with proper argument');
}
};
Ember.run(function() {
component.set('content', contentArray);
component.set('selection', contentArray.objectAt(0));
component.set('select-value', 'externalAction');
component.set('targetObject', targetObject);
component.set('optionValuePath', 'id');
});
this.render();
Ember.run(function() {
component._onItemRemove('1');
});
});
test('it sends add-item action when an item is selected in multiple mode', function(assert) {
assert.expect(1);
var component = this.subject();
var targetObject = {
externalAction: function(obj) {
assert.equal(obj, 'item 3', 'externalAction was called with proper argument');
}
};
Ember.run(function() {
component.set('multiple', true);
component.set('content', Ember.A(['item 1', 'item 2', 'item 3', 'item 4']));
component.set('selection', Ember.A(['item 2']));
component.set('add-item', 'externalAction');
component.set('targetObject', targetObject);
});
this.render();
Ember.run(function() {
component._onItemAdd('item 3');
});
});
test('it sends add-value action when an item is selected in multiple mode', function(assert) {
assert.expect(1);
var component = this.subject();
var contentArray = exampleObjectContent();
var targetObject = {
externalAction: function(obj) {
assert.equal(obj, 3, 'externalAction was called with proper argument');
}
};
Ember.run(function() {
component.set('multiple', true);
component.set('content', contentArray);
component.set('selection', Ember.A([contentArray.objectAt(1)]));
component.set('add-value', 'externalAction');
component.set('targetObject', targetObject);
component.set('optionValuePath', 'id');
});
this.render();
Ember.run(function() {
component._onItemAdd('3');
});
});
test('it sends remove-item action when an item is deselected in multiple mode', function(assert) {
assert.expect(1);
var component = this.subject();
var contentArray = exampleObjectContent();
var targetObject = {
externalAction: function(value) {
assert.equal(value, 2, 'externalAction was called with proper argument');
}
};
Ember.run(function() {
component.set('multiple', true);
component.set('content', contentArray);
component.set('selection', Ember.A([contentArray.objectAt(1)]));
component.set('remove-value', 'externalAction');
component.set('targetObject', targetObject);
component.set('optionValuePath', 'id');
});
this.render();
Ember.run(function() {
component._onItemRemove('2');
});
});
test('it sends remove-value action when an item is deselected in multiple mode', function(assert) {
assert.expect(1);
var component = this.subject();
var targetObject = {
externalAction: function(obj) {
assert.equal(obj, 'item 2', 'externalAction was called with proper argument');
}
};
Ember.run(function() {
component.set('multiple', true);
component.set('content', Ember.A(['item 1', 'item 2', 'item 3', 'item 4']));
component.set('selection', Ember.A(['item 2']));
component.set('remove-item', 'externalAction');
component.set('targetObject', targetObject);
});
this.render();
Ember.run(function() {
component._onItemRemove('item 2');
});
});
test('if label is falsy, don\'t add item', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', exampleObjectContent());
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'unknownLabel');
});
this.render();
assert.deepEqual(asArray(component._selectize.options, 'label'), []);
});
test('if label is falsy, don\'t add item, but add it once label updates', function(assert) {
var component = this.subject();
var content = exampleObjectContent();
Ember.run(function() {
component.set('content', content);
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'unknownLabel');
});
this.render();
assert.deepEqual(asArray(component._selectize.options, 'label'), []);
Ember.run(function() {
content.forEach(function(item, index) {
item.set('unknownLabel', 'item '+(index+1));
});
});
assert.deepEqual(asArray(component._selectize.options, 'label'), ['item 1', 'item 2', 'item 3']);
});
test('it sends on-init', function(assert) {
assert.expect(1);
var component = this.subject();
var targetObject = {
externalAction: function() {
assert.ok(true);
}
};
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3', 'item 4']));
component.set('on-init', 'externalAction');
component.set('targetObject', targetObject);
});
this.render();
});
test('having a selection creates selectize with a selection', function(assert) {
var component = this.subject();
Ember.run(function() {
component.set('content', Ember.A(['item 1', 'item 2', 'item 3']));
component.set('selection', 'item 2');
});
this.render();
assert.equal(component._selectize.items.length, 1);
assert.deepEqual(component._selectize.items, ['item 2']);
});
test('selection can be set from a Promise when multiple=false', function(assert) {
assert.expect(2);
var component = this.subject();
var yehuda = Ember.Object.create({ id: 1, firstName: 'Yehuda' });
var tom = Ember.Object.create({ id: 2, firstName: 'Tom' });
Ember.run(function() {
component.set('content', Ember.A([yehuda, tom]));
component.set('multiple', false);
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'firstName');
component.set('selection', Ember.RSVP.Promise.resolve(tom));
});
this.render();
assert.equal(component._selectize.items.length, 1);
assert.deepEqual(component._selectize.items, ["2"]);
});
test('changing selection to a promise that resolves to null clears selection', function(assert) {
assert.expect(4);
var component = this.subject();
var yehuda = Ember.Object.create({ id: 1, firstName: 'Yehuda' });
var tom = Ember.Object.create({ id: 2, firstName: 'Tom' });
Ember.run(function() {
component.set('content', Ember.A([yehuda, tom]));
component.set('multiple', false);
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'firstName');
component.set('selection', Ember.RSVP.Promise.resolve(tom));
});
this.render();
assert.equal(component._selectize.items.length, 1);
assert.deepEqual(component._selectize.items, ["2"]);
Ember.run(function() {
component.set('selection', Ember.RSVP.Promise.resolve(null));
});
assert.equal(component._selectize.items.length, 0);
assert.deepEqual(component._selectize.items, []);
});
test('selection from a Promise don\'t overwrite newer selection once resolved, when multiple=false', function(assert) {
assert.expect(1);
var component = this.subject();
var yehuda = Ember.Object.create({ id: 1, firstName: 'Yehuda' });
var tom = Ember.Object.create({ id: 2, firstName: 'Tom' });
var seb = Ember.Object.create({ id: 3, firstName: 'Seb' });
var done = assert.async();
Ember.run(function() {
component.set('content', Ember.A([yehuda, tom, seb]));
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'firstName');
component.set('multiple', false);
component.set('selection', new Ember.RSVP.Promise(function(resolve) {
Ember.run.later(function() {
Ember.run(function() {
resolve(tom);
});
assert.deepEqual(component._selectize.items, ["3"], 'Should not select from Promise if newer selection');
done();
}, 40);
}));
component.set('selection', new Ember.RSVP.Promise(function(resolve) {
Ember.run.later(function() {
Ember.run(function() {
resolve(seb);
});
}, 30);
}));
});
this.render();
});
test('content can be set from a Promise', function(assert) {
assert.expect(3);
var component = this.subject();
var yehuda = Ember.Object.create({ id: 1, firstName: 'Yehuda' });
var tom = Ember.Object.create({ id: 2, firstName: 'Tom' });
var seb = Ember.Object.create({ id: 3, firstName: 'Seb' });
Ember.run(function() {
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'firstName');
component.set('content', Ember.RSVP.Promise.resolve(Ember.A([yehuda, tom, seb])));
component.set('selection', tom);
});
this.render();
assert.equal(objectSize(component._selectize.options), 3);
assert.equal(component._selectize.items.length, 1);
assert.deepEqual(component._selectize.items, ["2"]);
});
test('content from a Promise don\'t overwrite newer content once resolved', function(assert) {
assert.expect(3);
var component = this.subject();
var yehuda = Ember.Object.create({ id: 1, firstName: 'Yehuda' });
var tom = Ember.Object.create({ id: 2, firstName: 'Tom' });
var seb = Ember.Object.create({ id: 3, firstName: 'Seb' });
var done = assert.async();
Ember.run(function() {
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'firstName');
component.set('content', new Ember.RSVP.Promise(function(resolve) {
Ember.run.later(function() {
Ember.run(function() {
resolve(Ember.A([yehuda, tom, seb]));
});
assert.equal(objectSize(component._selectize.options), 2, 'Should have 2 options and not 3');
assert.equal(component._selectize.items.length, 1);
assert.deepEqual(component._selectize.items, ["2"]);
done();
}, 40);
}));
component.set('content', new Ember.RSVP.Promise(function(resolve) {
Ember.run.later(function() {
Ember.run(function() {
resolve(Ember.A([yehuda, tom]));
});
}, 30);
}));
component.set('selection', tom);
});
this.render();
});
test('renders components', function(assert) {
this.register('component:foo-bar', Ember.Component.extend({}));
this.register('template:components/foo-bar', hbs`Hi, {{data.firstName}}!`);
var yehuda = Ember.Object.create({ id: 1, firstName: 'Yehuda' });
var tom = Ember.Object.create({ id: 2, firstName: 'Tom' });
var seb = Ember.Object.create({ id: 3, firstName: 'Seb' });
var component = this.subject();
Ember.run(function() {
component.set('optionComponent', 'foo-bar');
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'firstName');
component.set('content', Ember.A([yehuda, tom, seb]));
component.set('selection', tom);
});
this.render();
assert.deepEqual(component._selectize.items, ["2"]);
assert.equal(component._selectize.$dropdown_content.children().length, 3);
assert.equal(component._selectize.$dropdown_content.children().text(), 'Hi, Yehuda!Hi, Tom!Hi, Seb!');
Ember.run(() => {
component.set('content.firstObject.firstName', 'Miguel');
});
assert.equal(component._selectize.$dropdown_content.children().text(), 'Hi, Miguel!Hi, Tom!Hi, Seb!', 'It rerenders!');
});
test('renders function', function(assert) {
var yehuda = Ember.Object.create({ id: 1, firstName: 'Yehuda' });
var tom = Ember.Object.create({ id: 2, firstName: 'Tom' });
var seb = Ember.Object.create({ id: 3, firstName: 'Seb' });
var component = this.subject();
Ember.run(function() {
component.set('optionFunction', function(data) {
assert.equal(arguments.length, 2, 'arguments length');
return `<div>Hi, ${data.get('firstName')}!</div>`;
});
component.set('optionValuePath', 'id');
component.set('optionLabelPath', 'firstName');
component.set('content', Ember.A([yehuda, tom, seb]));
component.set('selection', tom);
});
this.render();
assert.deepEqual(component._selectize.items, ["2"]);
assert.equal(component._selectize.$dropdown_content.children().length, 3);
assert.equal(component._selectize.$dropdown_content.children().text(), 'Hi, Yehuda!Hi, Tom!Hi, Seb!');
});
================================================
FILE: vendor/.gitkeep
================================================
gitextract_85rycd2w/
├── .editorconfig
├── .ember-cli
├── .eslintrc.js
├── .gitignore
├── .npmignore
├── .travis.yml
├── .watchmanconfig
├── CHANGELOG.md
├── HISTORY.md
├── LICENSE.md
├── README.md
├── addon/
│ ├── .gitkeep
│ └── components/
│ └── ember-selectize.js
├── app/
│ ├── .gitkeep
│ └── components/
│ └── ember-selectize.js
├── config/
│ ├── ember-try.js
│ └── environment.js
├── ember-cli-build.js
├── index.js
├── package.json
├── testem.js
├── tests/
│ ├── .eslintrc.js
│ ├── dummy/
│ │ ├── app/
│ │ │ ├── app.js
│ │ │ ├── components/
│ │ │ │ ├── .gitkeep
│ │ │ │ └── test-component.js
│ │ │ ├── controllers/
│ │ │ │ ├── .gitkeep
│ │ │ │ └── application.js
│ │ │ ├── helpers/
│ │ │ │ └── .gitkeep
│ │ │ ├── index.html
│ │ │ ├── models/
│ │ │ │ └── .gitkeep
│ │ │ ├── resolver.js
│ │ │ ├── router.js
│ │ │ ├── routes/
│ │ │ │ └── .gitkeep
│ │ │ ├── styles/
│ │ │ │ └── app.css
│ │ │ ├── templates/
│ │ │ │ ├── application.hbs
│ │ │ │ ├── components/
│ │ │ │ │ ├── .gitkeep
│ │ │ │ │ └── test-component.hbs
│ │ │ │ └── test.hbs
│ │ │ └── views/
│ │ │ └── .gitkeep
│ │ ├── config/
│ │ │ ├── environment.js
│ │ │ └── targets.js
│ │ └── public/
│ │ ├── .gitkeep
│ │ ├── crossdomain.xml
│ │ └── robots.txt
│ ├── helpers/
│ │ ├── destroy-app.js
│ │ ├── module-for-acceptance.js
│ │ ├── resolver.js
│ │ └── start-app.js
│ ├── index.html
│ ├── test-helper.js
│ └── unit/
│ ├── .gitkeep
│ └── components/
│ └── ember-selectize-test.js
└── vendor/
└── .gitkeep
SYMBOL INDEX (39 symbols across 5 files)
FILE: addon/components/ember-selectize.js
method get (line 49) | get() {
method set (line 54) | set(key, value) {
method getValueFor (line 138) | getValueFor(item) {
method getLabelFor (line 143) | getLabelFor(item) {
method didInsertElement (line 250) | didInsertElement() {
method willDestroyElement (line 277) | willDestroyElement() {
method _create (line 293) | _create(input, callback) {
method _registerAction (line 310) | _registerAction(action){
method _onType (line 321) | _onType(str) {
method _onItemAdd (line 333) | _onItemAdd(value) {
method _onItemRemove (line 361) | _onItemRemove(value) {
method _updateSelection (line 384) | _updateSelection(selection) {
method _addSelection (line 395) | _addSelection(obj) {
method _removeSelection (line 406) | _removeSelection(obj) {
method _selectionWillChange (line 421) | _selectionWillChange(selection) {
method selectionArrayWillChange (line 509) | selectionArrayWillChange(array, idx, removedCount) {
method selectionArrayDidChange (line 521) | selectionArrayDidChange(array, idx, removedCount, addedCount) {
method selectionObjectWasAdded (line 530) | selectionObjectWasAdded(obj) {
method selectionObjectWasRemoved (line 539) | selectionObjectWasRemoved(obj) {
method _contentWillChange (line 549) | _contentWillChange(content) {
method contentArrayWillChange (line 598) | contentArrayWillChange(array, idx, removedCount) {
method contentArrayDidChange (line 612) | contentArrayDidChange(array, idx, removedCount, addedCount) {
method _groupedContentWillChange (line 625) | _groupedContentWillChange(groupedContent) {
method _groupedContentArrayWillChange (line 672) | _groupedContentArrayWillChange() {}
method _groupedContentArrayDidChange (line 678) | _groupedContentArrayDidChange() {
method objectWasAdded (line 688) | objectWasAdded(obj) {
method addLabelObserver (line 730) | addLabelObserver(obj) {
method objectWasRemoved (line 740) | objectWasRemoved(obj) {
method _labelDidChange (line 753) | _labelDidChange(sender) {
method _lookupComponent (line 805) | _lookupComponent(name) {
method _componentToDOM (line 820) | _componentToDOM(componentName, data) {
method _mergeSortField (line 839) | _mergeSortField(options) {
method _getSortArray (line 848) | _getSortArray(sortField) {
FILE: index.js
method selectize (line 10) | selectize() {
method included (line 27) | included(app) {
FILE: tests/helpers/destroy-app.js
function destroyApp (line 3) | function destroyApp(application) {
FILE: tests/helpers/module-for-acceptance.js
method beforeEach (line 8) | beforeEach() {
method afterEach (line 16) | afterEach() {
FILE: tests/helpers/start-app.js
function startApp (line 6) | function startApp(attrs) {
Condensed preview — 53 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (110K chars).
[
{
"path": ".editorconfig",
"chars": 368,
"preview": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# edit"
},
{
"path": ".ember-cli",
"chars": 280,
"preview": "{\n /**\n Ember CLI sends analytics information by default. The data is completely\n anonymous, but there are times "
},
{
"path": ".eslintrc.js",
"chars": 188,
"preview": "module.exports = {\n root: true,\n parserOptions: {\n ecmaVersion: 2017,\n sourceType: 'module'\n },\n extends: 'esl"
},
{
"path": ".gitignore",
"chars": 346,
"preview": "# See https://help.github.com/ignore-files/ for more about ignoring files.\n\n# compiled output\n/dist\n/tmp\n\n# dependencies"
},
{
"path": ".npmignore",
"chars": 195,
"preview": "/bower_components\n/config/ember-try.js\n/dist\n/tests\n/tmp\n**/.gitkeep\n.bowerrc\n.editorconfig\n.ember-cli\n.gitignore\n.eslin"
},
{
"path": ".travis.yml",
"chars": 1140,
"preview": "---\nlanguage: node_js\nnode_js:\n # we recommend testing addons with the same minimum supported node version as Ember CLI"
},
{
"path": ".watchmanconfig",
"chars": 37,
"preview": "{\n \"ignore_dirs\": [\"tmp\", \"dist\"]\n}\n"
},
{
"path": "CHANGELOG.md",
"chars": 9250,
"preview": "# Changelog\n\n## [Unreleased](https://github.com/miguelcobain/ember-cli-selectize/tree/HEAD)\n\n[Full Changelog](https://gi"
},
{
"path": "HISTORY.md",
"chars": 820,
"preview": "# Ember Selectize Changelog\n\n### 0.4.4 (Dec 15, 2015)\n- [#113](https://github.com/miguelcobain/ember-cli-selectize/pull/"
},
{
"path": "LICENSE.md",
"chars": 1066,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2017\n\nPermission is hereby granted, free of charge, to any person obtaining a copy "
},
{
"path": "README.md",
"chars": 11373,
"preview": "# Ember-cli-selectize [](https://travis-ci.or"
},
{
"path": "addon/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "addon/components/ember-selectize.js",
"chars": 26111,
"preview": "import Ember from 'ember';\n\nconst {\n Component,\n computed,\n observer,\n run,\n get,\n isArray,\n isEmpty,\n isNone,\n "
},
{
"path": "app/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "app/components/ember-selectize.js",
"chars": 127,
"preview": "import EmberSelectizeComponent from 'ember-cli-selectize/components/ember-selectize';\n\nexport default EmberSelectizeComp"
},
{
"path": "config/ember-try.js",
"chars": 1675,
"preview": "/* eslint-env node */\nmodule.exports = {\n useYarn: true,\n scenarios: [\n {\n name: 'ember-1.13',\n bower: {\n"
},
{
"path": "config/environment.js",
"chars": 112,
"preview": "/* eslint-env node */\n'use strict';\n\nmodule.exports = function(/* environment, appConfig */) {\n return { };\n};\n"
},
{
"path": "ember-cli-build.js",
"chars": 516,
"preview": "/* eslint-env node */\n'use strict';\n\nconst EmberAddon = require('ember-cli/lib/broccoli/ember-addon');\n\nmodule.exports ="
},
{
"path": "index.js",
"chars": 1408,
"preview": "/* eslint-env node */\n'use strict';\n\nconst fastbootTransform = require('fastboot-transform');\n\nmodule.exports = {\n name"
},
{
"path": "package.json",
"chars": 1726,
"preview": "{\n \"name\": \"ember-cli-selectize\",\n \"version\": \"0.6.0\",\n \"description\": \"An Ember and Selectize integration, packaged "
},
{
"path": "testem.js",
"chars": 506,
"preview": "module.exports = {\n test_page: 'tests/index.html?hidepassed',\n disable_watching: true,\n launch_in_ci: [\n 'Chrome'\n"
},
{
"path": "tests/.eslintrc.js",
"chars": 55,
"preview": "module.exports = {\n env: {\n embertest: true\n }\n};\n"
},
{
"path": "tests/dummy/app/app.js",
"chars": 375,
"preview": "import Application from '@ember/application';\nimport Resolver from './resolver';\nimport loadInitializers from 'ember-loa"
},
{
"path": "tests/dummy/app/components/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "tests/dummy/app/components/test-component.js",
"chars": 82,
"preview": "import Ember from 'ember';\n\nexport default Ember.Component.extend({\n // body\n});\n"
},
{
"path": "tests/dummy/app/controllers/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "tests/dummy/app/controllers/application.js",
"chars": 2512,
"preview": "/* global alert */\nimport Ember from 'ember';\n\nexport default Ember.Controller.extend({\n names: Ember.A(['Tom', 'Yehuda"
},
{
"path": "tests/dummy/app/helpers/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "tests/dummy/app/index.html",
"chars": 684,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n "
},
{
"path": "tests/dummy/app/models/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "tests/dummy/app/resolver.js",
"chars": 65,
"preview": "import Resolver from 'ember-resolver';\n\nexport default Resolver;\n"
},
{
"path": "tests/dummy/app/router.js",
"chars": 245,
"preview": "import EmberRouter from '@ember/routing/router';\nimport config from './config/environment';\n\nconst Router = EmberRouter."
},
{
"path": "tests/dummy/app/routes/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "tests/dummy/app/styles/app.css",
"chars": 31,
"preview": "html, body {\n margin: 20px;\n}\n"
},
{
"path": "tests/dummy/app/templates/application.hbs",
"chars": 2901,
"preview": "<h2 id='title'>Selectize test</h2>\n\n<h3>Normal usage with strings</h3>\n<p>\n {{ember-selectize\n content=names\n tab"
},
{
"path": "tests/dummy/app/templates/components/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "tests/dummy/app/templates/components/test-component.hbs",
"chars": 5,
"preview": "Blah\n"
},
{
"path": "tests/dummy/app/templates/test.hbs",
"chars": 3,
"preview": "Hi\n"
},
{
"path": "tests/dummy/app/views/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "tests/dummy/config/environment.js",
"chars": 1473,
"preview": "/* eslint-env node */\n'use strict';\n\nmodule.exports = function(environment) {\n let ENV = {\n modulePrefix: 'dummy',\n "
},
{
"path": "tests/dummy/config/targets.js",
"chars": 164,
"preview": "/* eslint-env node */\nmodule.exports = {\n browsers: [\n 'ie 9',\n 'last 1 Chrome versions',\n 'last 1 Firefox ver"
},
{
"path": "tests/dummy/public/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "tests/dummy/public/crossdomain.xml",
"chars": 585,
"preview": "<?xml version=\"1.0\"?>\n<!DOCTYPE cross-domain-policy SYSTEM \"http://www.adobe.com/xml/dtds/cross-domain-policy.dtd\">\n<cro"
},
{
"path": "tests/dummy/public/robots.txt",
"chars": 51,
"preview": "# http://www.robotstxt.org\nUser-agent: *\nDisallow:\n"
},
{
"path": "tests/helpers/destroy-app.js",
"chars": 122,
"preview": "import { run } from '@ember/runloop';\n\nexport default function destroyApp(application) {\n run(application, 'destroy');\n"
},
{
"path": "tests/helpers/module-for-acceptance.js",
"chars": 576,
"preview": "import { module } from 'qunit';\nimport { resolve } from 'rsvp';\nimport startApp from '../helpers/start-app';\nimport dest"
},
{
"path": "tests/helpers/resolver.js",
"chars": 255,
"preview": "import Resolver from '../../resolver';\nimport config from '../../config/environment';\n\nconst resolver = Resolver.create("
},
{
"path": "tests/helpers/start-app.js",
"chars": 509,
"preview": "import Application from '../../app';\nimport config from '../../config/environment';\nimport { merge } from '@ember/polyfi"
},
{
"path": "tests/index.html",
"chars": 1045,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"utf-8\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n "
},
{
"path": "tests/test-helper.js",
"chars": 162,
"preview": "import resolver from './helpers/resolver';\nimport {\n setResolver\n} from 'ember-qunit';\nimport { start } from 'ember-cli"
},
{
"path": "tests/unit/.gitkeep",
"chars": 0,
"preview": ""
},
{
"path": "tests/unit/components/ember-selectize-test.js",
"chars": 33729,
"preview": "import Ember from 'ember';\nimport {\n moduleForComponent,\n test\n} from 'ember-qunit';\nimport hbs from 'htmlbars-inline-"
},
{
"path": "vendor/.gitkeep",
"chars": 0,
"preview": ""
}
]
About this extraction
This page contains the full source code of the miguelcobain/ember-cli-selectize GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 53 files (100.5 KB), approximately 27.7k tokens, and a symbol index with 39 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.