├── .gitignore
├── LICENSE
├── README.md
├── build.js
├── demo.gif
├── example.html
├── gulpfile.js
├── index.html
├── package.json
├── vue-autocomplete.css
├── vue-autocomplete.js
├── vue-autocomplete.min.js
├── vue-autocomplete.vue
└── vueku.js
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Naufal Rabbani
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-autocomplete
2 | Autocomplete Component for [Vue.Js](http://vuejs.org)
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | ## Intro
11 | Vue Autocomplete is a Vue.Js component to make some suggestions for user input. come with .vue and .js file make it easier to be installed for your next project.
12 |
13 | Vue Autocomplete is inspired by [aFarkas remote-list Jquery Plugin](https://github.com/aFarkas/remote-list). crafted with simple javascript (Also ES6 support), and doesn't require Jquery.
14 |
15 | ## Features
16 | - full customizable
17 | - Already, Complete callback event
18 | - Included `.vue` file
19 | - well commented code
20 | - writen in ES6 (Still in Learning now)
21 | - doesn't require any javascript libs, except [Vue.Js](http://vuejs.org)
22 | - Support multiple autocomplete components
23 |
24 | ## Install
25 | Simply include the [vue-autocomplete.js](./vue-autocomplete.js) to your HTML or web page file, next to [Vue.Js](http://vuejs.org). You can take a peek an example at [example.html](./example.html). And don't forget to include [vue-autocomplete.css](./vue-autocomplete.css) file when you choose this way.
26 |
27 | Or
28 |
29 | You can import [vue-autocomplete.vue](./vue-autocomplete.vue) to your vue component file like [this](./vueku.js) and process it with your preprocessor.
30 |
31 |
32 | ```javascript
33 | import autocomplete from ./vue-autocomplete.vue
34 | // Or
35 | var autocomplete = require('./vue-autocomplete.vue');
36 | ```
37 |
38 | ## Usage
39 | minimal:
40 | ```html
41 |
47 |
48 | ```
49 | Full Example:
50 | ```html
51 |
62 |
63 | ```
64 |
65 | ## Additional parameters
66 |
67 | If you need to pass more parameters in url, use Computed Properties (https://vuejs.org/guide/computed.html) :
68 |
69 | Example:
70 |
71 | ``` computed: {
72 | param: function () {
73 | return 'foo=' + this.bar + '&q';
74 | }
75 | }```
76 |
77 | in component change ```param ="q" for :param="param" ```
78 |
79 | ## Props
80 |
81 | ##### `name` (*) : Component Identity
82 | will use for Identify the autocomplete component. for multiple use purpose.
83 |
84 |
85 |
86 | ##### `url` (*) : Ajax URL to fetch
87 | the URL must be active (not from file). the component will fetch JSON from this URL with (default : `q`) query. like:
88 | `http://some-url.com/API/list?q=`.
89 | There are no filter and limit action inside the component. So, do it in your API logic.
90 |
91 |
92 |
93 | ##### `param` : name of the search query in Ajax call. default ( q )
94 |
95 |
96 | ##### `min` : Minimum input typed chars before performing the search query. default ( 3 )
97 |
98 |
99 | ##### `limit` : amount of query limit in ajax call.
100 | example, `limit=5` the AJAX URL will be `http://some-url.com/API/list?q=blabla&limit=5`
101 |
102 |
103 |
104 | ##### `anchor`(*) : Anchor for Suggestion list
105 | Anchor for listing suggestions. Example `anchor="name"` will get the name object of your JSON data for suggestion listing like ("Bambang", "Sukijan", "Bejo") in the demo above.
106 |
107 |
108 |
109 | ##### `label` : Description for Suggestion list
110 | For description to your suggestion. the uses is like `anchor` props but for the description of each suggestion. like ("Alamat", "alamat sesuai ktp", "alamat") in the demo above. not required but if it's null the component will look bad.
111 |
112 |
113 |
114 | ##### `model` : v-model like for your component
115 | v-model like of component to make two data binding working like usual.
116 |
117 |
118 |
119 | ##### `placeholder` : input placeholder (optional)
120 |
121 |
122 | ##### `class` : Component Class (optional)
123 | will generate an class for input element. this only for the input element in autocomplete.
124 |
125 |
126 |
127 | ##### `id` : Component Id (optional)
128 | will generate an Id for input element.
129 |
130 |
131 |
132 | ## Callback Events
133 | Make an events in component's parent than the [vue-autocomplete](https://github.com/BosNaufal/vue-autocomplete) component will dispatch some events to it.
134 | ```javascript
135 | ...
136 | events: {
137 |
138 | /**
139 | * Global Autocomplete Callback Event
140 | *
141 | * @event-name autocomplete:{event-name}
142 | * @param {String} name name of auto
143 | * @param {Object} data
144 | * @param {Object} json - ajax-loaded only
145 | */
146 |
147 | // Autocomplete on before ajax progress
148 | 'autocomplete:before-ajax': function (name,data){
149 | console.log('before-ajax',name,data);
150 | },
151 |
152 | // Autocomplete on ajax progress
153 | 'autocomplete:ajax-progress': function(name,data){
154 | console.log('ajax-progress',data);
155 | },
156 |
157 | // Autocomplete on ajax loaded
158 | 'autocomplete:ajax-loaded': function(name,data,json){
159 | console.log('ajax-loaded',data,json);
160 | },
161 |
162 | // Autocomplete on focus
163 | 'autocomplete:focus': function(name,evt){
164 | console.log('focus',name,evt);
165 | },
166 |
167 | // Autocomplete on input
168 | 'autocomplete:input': function(name,data){
169 | console.log('input',data);
170 | },
171 |
172 | // Autocomplete on blur
173 | 'autocomplete:blur': function(name,evt){
174 | console.log('blur',evt);
175 | },
176 |
177 | // Autocomplete on show
178 | 'autocomplete:show': function(name){
179 | console.log('show',name);
180 | },
181 |
182 | // Autocomplete on selected
183 | 'autocomplete:selected': function(name,data){
184 | console.log('selected',data);
185 | this.data = data;
186 | },
187 |
188 | // Autocomplete on hide
189 | 'autocomplete:hide': function(name){
190 | console.log('hide',name);
191 | },
192 |
193 |
194 | /**
195 | * Spesific Autocomplete Callback Event By Name
196 | *
197 | * @event-name autocomplete-{component-name}:{event-name}
198 | * @param {String} name name of auto
199 | * @param {Object} data
200 | * @param {Object} json - ajax-loaded only
201 | */
202 |
203 | // Autocomplete on before ajax progress
204 | 'autocomplete-people:before-ajax': function(data){
205 | console.log('before-ajax-people',data);
206 | },
207 |
208 | // Autocomplete on ajax progress
209 | 'autocomplete-people:ajax-progress': function(data){
210 | console.log('ajax-progress-people',data);
211 | },
212 |
213 | // Autocomplete on ajax loaded
214 | 'autocomplete-people:ajax-loaded': function(data,json){
215 | console.log('ajax-loaded-people',data,json);
216 | },
217 |
218 | // Autocomplete-people on focus
219 | 'autocomplete-people:focus': function(evt){
220 | console.log('focus-people',evt);
221 | },
222 |
223 | // Autocomplete-people on input
224 | 'autocomplete-people:input': function(data){
225 | console.log('input-people',data);
226 | },
227 |
228 | // Autocomplete-people on blur
229 | 'autocomplete-people:blur': function(evt){
230 | console.log('blur-people',evt);
231 | },
232 |
233 | // Autocomplete-people on show
234 | 'autocomplete-people:show': function(){
235 | console.log('show-people');
236 | },
237 |
238 | // Autocomplete-people on selected
239 | 'autocomplete-people:selected': function(data){
240 | console.log('selected-people',data);
241 | },
242 |
243 | // Autocomplete-people on hide
244 | 'autocomplete-people:hide': function(){
245 | console.log('hide-people');
246 | },
247 |
248 | }
249 | ```
250 |
251 |
252 | ## Clear Method
253 |
254 | If you need to Clear or Netralize your autocomplete, You can simply make some refs then call a method named ```clearInput()```. You can take a look at the [Example](./index.html) :
255 |
256 | ```html
257 | Clear
258 |
270 |
271 | ```
272 |
273 | ```javascript
274 | // ... another vue scope
275 |
276 | methods: {
277 | clearAutocomplete() {
278 | this.$refs.myAutocomplete.clearInput()
279 | }
280 | },
281 |
282 | // ...
283 | ```
284 |
285 | ## Thank You for Making this helpful for your projects~
286 | Hopefully this can be usefull for the others.
287 |
288 | ## Let's talk about some projects with me
289 | Just Contact Me At:
290 | - Email: [bosnaufalemail@gmail.com](mailto:bosnaufalemail@gmail.com)
291 | - Skype Id: bosnaufal254
292 | - twitter: [@BosNaufal](https://twitter.com/BosNaufal)
293 |
294 | ## License
295 | [MIT](http://opensource.org/licenses/MIT)
296 | Copyright (c) 2016 - forever Naufal Rabbani
297 |
--------------------------------------------------------------------------------
/demo.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/BosNaufal/vue-autocomplete/dbce88f4ea787d1afa400d27801842ee22358edf/demo.gif
--------------------------------------------------------------------------------
/example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Vue Autocomplete Component
6 |
7 |
25 |
26 |
27 |
28 |
29 |
Vue Autocomplete {{ vModelLike }}
30 |
41 |
42 |
43 |
44 |
Data Selected
45 |
{{ data | json 2 }}
46 |
47 |
48 |
49 |
50 |
51 |
176 |
177 |
178 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp');
2 | var browserify = require('browserify');
3 | var vueify = require('vueify');
4 | var source = require('vinyl-source-stream');
5 | var livereload = require('gulp-livereload');
6 |
7 |
8 | gulp.task('build-js',function () {
9 | return browserify({
10 | entries: './vueku.js',
11 | debug: true
12 | })
13 | .transform(vueify)
14 | .bundle()
15 | .pipe(source('build.js'))
16 | .pipe(gulp.dest('./'))
17 | .pipe(livereload());
18 | });
19 |
20 | gulp.task('dev', function () {
21 | livereload.listen();
22 | gulp.watch(['./*.vue','./vueku.js','./*.html'],['build-js']);
23 | });
24 |
25 | gulp.task('default', ['dev']);
26 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Vue Autocomplete Component
6 |
24 |
25 |
26 |
27 |
28 |
Vue Autocomplete {{ vModelLike }}
29 |
Clear
30 |
42 |
43 |
44 |
45 |
Data Selected
46 |
{{ data | json 2 }}
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-autocomplete",
3 | "version": "0.0.2",
4 | "description": "Autocomplete Components for Vue.js",
5 | "main": "./vue-autocomplete.vue",
6 | "scripts": {
7 | "dev": "gulp"
8 | },
9 | "keywords": [
10 | "vue-js",
11 | "autocomplete",
12 | "remote-list",
13 | "form",
14 | "component"
15 | ],
16 | "author": "Bos Naufal",
17 | "license": "MIT",
18 | "devDependencies": {
19 | "babel-core": "^6.4.0",
20 | "babel-plugin-transform-runtime": "^6.4.3",
21 | "babel-preset-es2015": "^6.3.13",
22 | "browserify": "^13.0.0",
23 | "gulp": "^3.9.0",
24 | "gulp-livereload": "^3.8.1",
25 | "vinyl-source-stream": "^1.1.0",
26 | "vue-hot-reload-api": "^1.2.2",
27 | "vueify": "^8.3.2",
28 | "dev": "^0.1.3",
29 | "vueify-insert-css": "^1.0.0"
30 | },
31 | "dependencies": {
32 | "vue": "^1.0.7"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/vue-autocomplete.css:
--------------------------------------------------------------------------------
1 | .transition, .autocomplete, .showAll-transition, .autocomplete ul, .autocomplete ul li a{
2 | transition:all 0.3s ease-out;
3 | -moz-transition:all 0.3s ease-out;
4 | -webkit-transition:all 0.3s ease-out;
5 | -o-transition:all 0.3s ease-out;
6 | }
7 |
8 | .autocomplete ul{
9 | font-family: sans-serif;
10 | position: absolute;
11 | list-style: none;
12 | background: #f8f8f8;
13 | padding: 10px 0;
14 | margin: 0;
15 | display: inline-block;
16 | min-width: 15%;
17 | margin-top: 10px;
18 | }
19 |
20 | .autocomplete ul:before{
21 | content: "";
22 | display: block;
23 | position: absolute;
24 | height: 0;
25 | width: 0;
26 | border: 10px solid transparent;
27 | border-bottom: 10px solid #f8f8f8;
28 | left: 46%;
29 | top: -20px
30 | }
31 |
32 | .autocomplete ul li a{
33 | text-decoration: none;
34 | display: block;
35 | background: #f8f8f8;
36 | color: #2b2b2b;
37 | padding: 5px;
38 | padding-left: 10px;
39 | }
40 |
41 | .autocomplete ul li a:hover, .autocomplete ul li.focus-list a{
42 | color: white;
43 | background: #2F9AF7;
44 | }
45 |
46 | .autocomplete ul li a span{
47 | display: block;
48 | margin-top: 3px;
49 | color: grey;
50 | font-size: 13px;
51 | }
52 |
53 | .autocomplete ul li a:hover span, .autocomplete ul li.focus-list a span{
54 | color: white;
55 | }
56 |
57 | .showAll-transition{
58 | opacity: 1;
59 | height: 50px;
60 | overflow: hidden;
61 | }
62 |
63 | .showAll-enter{
64 | opacity: 0.3;
65 | height: 0;
66 | }
67 |
68 | .showAll-leave{
69 | display: none;
70 | }
71 |
--------------------------------------------------------------------------------
/vue-autocomplete.js:
--------------------------------------------------------------------------------
1 | /*! Copyright (c) 2016 Naufal Rabbani (http://github.com/BosNaufal)
2 | * Licensed Under MIT (http://opensource.org/licenses/MIT)
3 | *
4 | * Version 0.0.1
5 | *
6 | */
7 |
8 | // Transition (Optional)
9 | Vue.transition('showAll',{});
10 |
11 | var VueAutocomplete = Vue.extend ({
12 | template: ' ',
13 |
14 | props: {
15 | id: String,
16 | class: String,
17 | name: String,
18 | placeholder: String,
19 |
20 | model: String, // v-model like
21 |
22 | // Anchor of AJAX list
23 | anchor: {
24 | type: String,
25 | required: true
26 | },
27 |
28 | // Label of AJAX list
29 | label: String,
30 |
31 | // ajax URL will be get
32 | url: {
33 | type: String,
34 | required: true
35 | },
36 |
37 | // query param
38 | param: {
39 | type: String,
40 | default: 'q'
41 | },
42 |
43 | // minimum length
44 | min: {
45 | type: Number,
46 | default: 0
47 | },
48 |
49 | // add 'limit' query to AJAX URL will be fetched
50 | limit: {
51 | type: String,
52 | default: ''
53 | }
54 |
55 | },
56 |
57 | data: function () {
58 | return {
59 | showList: false,
60 | type: "",
61 | json: [],
62 | focusList: ""
63 | };
64 | },
65 |
66 | watch:{
67 | type: function (val,old){
68 | // Sync parent model with $data.type
69 | return this.$parent.$data[this.model] = val;
70 | }
71 | },
72 |
73 | methods: {
74 |
75 | // Netralize Autocomplete
76 | clearInput: function () {
77 | this.showList = false;
78 | this.type = "";
79 | this.json = [];
80 | this.focusList = "";
81 | },
82 |
83 | // Get the original data
84 | cleanUp: function (data) {
85 | return JSON.parse(JSON.stringify(data));
86 | },
87 |
88 | input: function (val){
89 | this.showList = true;
90 |
91 | // Callback Event
92 | this.$dispatch('autocomplete:input',this.$get('name'),val);
93 | this.$dispatch('autocomplete-'+this.$get('name')+':input',val);
94 |
95 | this.$emit('getData',val);
96 | return this.$parent.$data[this.model] = val;
97 | },
98 |
99 | showAll: function () {
100 | this.json = [];
101 | this.$emit('getData',"");
102 |
103 | // Callback Event
104 | this.$dispatch('autocomplete:show',this.$get('name'));
105 | this.$dispatch('autocomplete-'+this.$get('name')+':show');
106 |
107 | this.showList = true;
108 | },
109 |
110 | hideAll: function (e) {
111 | var self = this;
112 |
113 | // Callback Event
114 | this.$dispatch('autocomplete:blur',this.$get('name'),e);
115 | this.$dispatch('autocomplete-'+this.$get('name')+':blur',e);
116 |
117 | setTimeout(function () {
118 | self.showList = false;
119 |
120 | // Callback Event
121 | self.$dispatch('autocomplete:hide',self.$get('name'));
122 | self.$dispatch('autocomplete-'+self.$get('name')+':hide');
123 |
124 | },250);
125 | },
126 |
127 | focus: function (e) {
128 | this.focusList = 0;
129 |
130 | // Callback Event
131 | this.$dispatch('autocomplete:focus',this.$get('name'),e);
132 | this.$dispatch('autocomplete-'+this.$get('name')+':focus',e);
133 |
134 | },
135 |
136 | mousemove: function (i) {
137 | this.focusList = i;
138 | },
139 |
140 | keydown: function (e) {
141 | var key = e.keyCode;
142 |
143 | // Disable when list isn't showing up
144 | if(!this.showList) return;
145 |
146 | switch (key) {
147 | case 40: //down
148 | this.focusList++;
149 | break;
150 | case 38: //up
151 | this.focusList--;
152 | break;
153 | case 13: //enter
154 | this.$emit('selectList', this.json[this.focusList]);
155 | this.showList = false;
156 | break;
157 | case 27: //esc
158 | this.showList = false;
159 | break;
160 | }
161 |
162 | // When cursor out of range
163 | var listLength = this.json.length - 1;
164 | this.focusList = this.focusList > listLength ? 0 : this.focusList < 0 ? listLength : this.focusList;
165 |
166 | },
167 |
168 | activeClass: function (i) {
169 | return {
170 | 'focus-list' : i == this.focusList
171 | };
172 | }
173 |
174 | },
175 |
176 | events: {
177 |
178 | selectList: function (data) {
179 | var clean = this.cleanUp(data);
180 |
181 | // Put the selected data to type (model)
182 | this.type = clean[this.anchor];
183 |
184 | this.showList = false;
185 |
186 | /**
187 | * Callback Event
188 | * Deep clone of the original object
189 | */
190 | this.$dispatch('autocomplete:selected',this.$get('name'),clean);
191 | this.$dispatch('autocomplete-'+this.$get('name')+':selected',clean);
192 | },
193 |
194 | getData: function (val) {
195 | var self = this;
196 |
197 | if (val.length < this.min) return;
198 |
199 | if(this.url != null){
200 |
201 | // Callback Event
202 | this.$dispatch('autocomplete:before-ajax',self.$get('name'),val);
203 | this.$dispatch('autocomplete-'+self.$get('name')+':before-ajax',val);
204 |
205 | var ajax = new XMLHttpRequest();
206 |
207 | var limit;
208 | if(this.$get('limit') != ''){
209 | this.limit = parseFloat(this.limit);
210 | limit = this.limit != "" ? '&limit=' + this.limit : '';
211 | }else{
212 | limit = '';
213 | }
214 |
215 | ajax.open('GET', this.url+'?'+this.param+'='+val+limit, true);
216 | ajax.send();
217 |
218 | ajax.addEventListener('progress', function (data) {
219 | if(data.lengthComputable){
220 |
221 | // Callback Event
222 | self.$dispatch('autocomplete:ajax-progress',self.$get('name'),data);
223 | self.$dispatch('autocomplete-'+self.$get('name')+':ajax-progress',data);
224 | }
225 | });
226 |
227 | ajax.addEventListener('loadend', function (data) {
228 | var json = JSON.parse(this.responseText);
229 |
230 | // Callback Event
231 | self.$dispatch('autocomplete:ajax-loaded',self.$get('name'),this,json);
232 | self.$dispatch('autocomplete-'+self.$get('name')+':ajax-loaded',this,json);
233 |
234 | self.json = json;
235 | });
236 |
237 | }
238 | }
239 |
240 | },
241 |
242 | created: function () {
243 | // Sync parent model with $data.type
244 | this.type = this.$parent.$data[this.model];
245 | }
246 |
247 | });
248 |
249 | // Register
250 | Vue.component('autocomplete',VueAutocomplete);
251 |
--------------------------------------------------------------------------------
/vue-autocomplete.min.js:
--------------------------------------------------------------------------------
1 | /*! Copyright (c) 2016 Naufal Rabbani (http://github.com/BosNaufal)
2 | * Licensed Under MIT (http://opensource.org/licenses/MIT)
3 | *
4 | * Version 0.0.1
5 | *
6 | */
7 | Vue.transition("showAll",{});
8 | var VueAutocomplete=Vue.extend({template:' ',props:{id:String,
9 | "class":String,name:String,placeholder:String,model:String,anchor:{type:String,required:!0},label:String,url:{type:String,required:!0},param:{type:String,"default":"q"},min:{type:Number,"default":0},limit:{type:String,"default":""}},data:function(){return{showList:!1,type:"",json:[],focusList:""}},watch:{type:function(a,b){return this.$parent.$data[this.model]=a}},methods:{clearInput:function(){this.showList=!1;this.type="";this.json=[];this.focusList=""},cleanUp:function(a){return JSON.parse(JSON.stringify(a))},
10 | input:function(a){this.showList=!0;this.$dispatch("autocomplete:input",this.$get("name"),a);this.$dispatch("autocomplete-"+this.$get("name")+":input",a);this.$emit("getData",a);return this.$parent.$data[this.model]=a},showAll:function(){this.json=[];this.$emit("getData","");this.$dispatch("autocomplete:show",this.$get("name"));this.$dispatch("autocomplete-"+this.$get("name")+":show");this.showList=!0},hideAll:function(a){var b=this;this.$dispatch("autocomplete:blur",this.$get("name"),a);this.$dispatch("autocomplete-"+
11 | this.$get("name")+":blur",a);setTimeout(function(){b.showList=!1;b.$dispatch("autocomplete:hide",b.$get("name"));b.$dispatch("autocomplete-"+b.$get("name")+":hide")},250)},focus:function(a){this.focusList=0;this.$dispatch("autocomplete:focus",this.$get("name"),a);this.$dispatch("autocomplete-"+this.$get("name")+":focus",a)},mousemove:function(a){this.focusList=a},keydown:function(a){a=a.keyCode;if(this.showList){switch(a){case 40:this.focusList++;break;case 38:this.focusList--;break;case 13:this.$emit("selectList",
12 | this.json[this.focusList]);this.showList=!1;break;case 27:this.showList=!1}a=this.json.length-1;this.focusList=this.focusList>a?0:0>this.focusList?a:this.focusList}},activeClass:function(a){return{"focus-list":a==this.focusList}}},events:{selectList:function(a){a=this.cleanUp(a);this.type=a[this.anchor];this.showList=!1;this.$dispatch("autocomplete:selected",this.$get("name"),a);this.$dispatch("autocomplete-"+this.$get("name")+":selected",a)},getData:function(a){var b=this;if(!(a.length
2 | .transition, .autocomplete, .showAll-transition, .autocomplete ul, .autocomplete ul li a{
3 | transition:all 0.3s ease-out;
4 | -moz-transition:all 0.3s ease-out;
5 | -webkit-transition:all 0.3s ease-out;
6 | -o-transition:all 0.3s ease-out;
7 | }
8 |
9 | .autocomplete ul{
10 | font-family: sans-serif;
11 | position: absolute;
12 | list-style: none;
13 | background: #f8f8f8;
14 | padding: 10px 0;
15 | margin: 0;
16 | display: inline-block;
17 | min-width: 15%;
18 | margin-top: 10px;
19 | }
20 |
21 | .autocomplete ul:before{
22 | content: "";
23 | display: block;
24 | position: absolute;
25 | height: 0;
26 | width: 0;
27 | border: 10px solid transparent;
28 | border-bottom: 10px solid #f8f8f8;
29 | left: 46%;
30 | top: -20px
31 | }
32 |
33 | .autocomplete ul li a{
34 | text-decoration: none;
35 | display: block;
36 | background: #f8f8f8;
37 | color: #2b2b2b;
38 | padding: 5px;
39 | padding-left: 10px;
40 | }
41 |
42 | .autocomplete ul li a:hover, .autocomplete ul li.focus-list a{
43 | color: white;
44 | background: #2F9AF7;
45 | }
46 |
47 | .autocomplete ul li a span{
48 | display: block;
49 | margin-top: 3px;
50 | color: grey;
51 | font-size: 13px;
52 | }
53 |
54 | .autocomplete ul li a:hover span, .autocomplete ul li.focus-list a span{
55 | color: white;
56 | }
57 |
58 | .showAll-transition{
59 | opacity: 1;
60 | height: 50px;
61 | overflow: hidden;
62 | }
63 |
64 | .showAll-enter{
65 | opacity: 0.3;
66 | height: 0;
67 | }
68 |
69 | .showAll-leave{
70 | display: none;
71 | }
72 |
73 |
74 |
75 |
76 |
88 |
89 |
105 |
106 |
107 |
354 |
--------------------------------------------------------------------------------
/vueku.js:
--------------------------------------------------------------------------------
1 | global.Vue = require('vue');
2 |
3 | new Vue({
4 | el: 'body',
5 |
6 | data(){
7 | return {
8 | vModelLike: "",
9 | data: {}
10 | };
11 | },
12 |
13 | components: {
14 | autocomplete: require('./vue-autocomplete.vue')
15 | },
16 |
17 | methods: {
18 | clearAutocomplete() {
19 | this.$refs.myAutocomplete.clearInput()
20 | }
21 | },
22 |
23 | events: {
24 |
25 | /**
26 | * Global Autocomplete Callback Event
27 | *
28 | * @event-name autocomplete:{event-name}
29 | * @param {String} name name of auto
30 | * @param {Object} data
31 | * @param {Object} json - ajax-loaded only
32 | */
33 |
34 | // Autocomplete on before ajax progress
35 | 'autocomplete:before-ajax': function (name,data){
36 | console.log('before-ajax',name,data);
37 | },
38 |
39 | // Autocomplete on ajax progress
40 | 'autocomplete:ajax-progress': function(name,data){
41 | console.log('ajax-progress',data);
42 | },
43 |
44 | // Autocomplete on ajax loaded
45 | 'autocomplete:ajax-loaded': function(name,data,json){
46 | console.log('ajax-loaded',data,json);
47 | },
48 |
49 | // Autocomplete on focus
50 | 'autocomplete:focus': function(name,evt){
51 | console.log('focus',name,evt);
52 | },
53 |
54 | // Autocomplete on input
55 | 'autocomplete:input': function(name,data){
56 | console.log('input',data);
57 | },
58 |
59 | // Autocomplete on blur
60 | 'autocomplete:blur': function(name,evt){
61 | console.log('blur',evt);
62 | },
63 |
64 | // Autocomplete on show
65 | 'autocomplete:show': function(name){
66 | console.log('show',name);
67 | },
68 |
69 | // Autocomplete on selected
70 | 'autocomplete:selected': function(name,data){
71 | console.log('selected',data);
72 | this.data = data;
73 | },
74 |
75 | // Autocomplete on hide
76 | 'autocomplete:hide': function(name){
77 | console.log('hide',name);
78 | },
79 |
80 |
81 | /**
82 | * Spesific Autocomplete Callback Event By Name
83 | *
84 | * @event-name autocomplete-{component-name}:{event-name}
85 | * @param {String} name name of auto
86 | * @param {Object} data
87 | * @param {Object} json - ajax-loaded only
88 | */
89 |
90 | // Autocomplete on before ajax progress
91 | 'autocomplete-people:before-ajax': function(data){
92 | console.log('before-ajax-people',data);
93 | },
94 |
95 | // Autocomplete on ajax progress
96 | 'autocomplete-people:ajax-progress': function(data){
97 | console.log('ajax-progress-people',data);
98 | },
99 |
100 | // Autocomplete on ajax loaded
101 | 'autocomplete-people:ajax-loaded': function(data,json){
102 | console.log('ajax-loaded-people',data,json);
103 | },
104 |
105 | // Autocomplete-people on focus
106 | 'autocomplete-people:focus': function(evt){
107 | console.log('focus-people',evt);
108 | },
109 |
110 | // Autocomplete-people on input
111 | 'autocomplete-people:input': function(data){
112 | console.log('input-people',data);
113 | },
114 |
115 | // Autocomplete-people on blur
116 | 'autocomplete-people:blur': function(evt){
117 | console.log('blur-people',evt);
118 | },
119 |
120 | // Autocomplete-people on show
121 | 'autocomplete-people:show': function(){
122 | console.log('show-people');
123 | },
124 |
125 | // Autocomplete-people on selected
126 | 'autocomplete-people:selected': function(data){
127 | console.log('selected-people',data);
128 | },
129 |
130 | // Autocomplete-people on hide
131 | 'autocomplete-people:hide': function(){
132 | console.log('hide-people');
133 | },
134 |
135 | }
136 | });
137 |
--------------------------------------------------------------------------------