pespantelis / vue-typeahead Goto Github PK
View Code? Open in Web Editor NEW:mag: Typeahead component for Vue.js
Home Page: http://pespantelis.github.io/vue-typeahead
License: MIT License
:mag: Typeahead component for Vue.js
Home Page: http://pespantelis.github.io/vue-typeahead
License: MIT License
I have added the cancel method in my Vue file but the logic to cancel the request is not clear.
I have read all the code of yours but unable to find how you are processing it.
Hi,
I have been trying since last 2 days and looking to find a way to provide source as a local JSON file or array rather providing a URL.
Is there any documentation around this, or this functionality is currently not available.
Please suggest.
Hi there,
I need to replace the 'q' parameter with 'search' for the api I'm consuming.
In the context of the api I'm consuming, 'q' has a different meaning and it needs to not be present at all in the URL.
Is there any way for me to remove the 'q' parameter on the search requests? I've tried setting it to null in the component definition:
data: {
'search': function() {
return vc.query;
},
'q' : null
},
But the requests generated still include it, eg /my-endpoint?q=&search=enteredtext
Is this possible?
Just tried the live demo in firefox and found this, looks like css problem. It does not happen in chrome.
Hey guys,
Im trying to use this package as a normal text field, updating the input value on hit.
I have the value updating, however the rendered field doesnt reflect the value, it just goes back to placeholder.
If i pass a value on construction it is working as expected, so im guessing its something to do with focus/reset?
Any ideas on how I can get around this?
Cheers
Hi there
First off, thanks for making a great package! 👍
I'm doing a Vue 1 -> Vue 2 upgrade and I'm coming across an issue where by when I search for a resource, I can select it from the dropdown that appears, it populates the input field but when I exit the field it makes another request and the dropdown appears again.
It seems that it the update method is being fired when I leave the input field. Any ideas what I could be doing wrong?
<template>
<div>
<input :name="fieldName + '_id'" type="hidden" v-bind:value="fieldNameId">
<input :id="fieldName"
:name="fieldName"
type="text"
class="form-control"
placeholder="Search..."
autocomplete="off"
v-model="query"
@keydown.down="down"
@keydown.up="up"
@keydown.enter.prevent
@keydown.enter="hit"
@keydown.esc="reset"
@input="update"/>
<div id="autocomplete-results" v-if="hasItems">
<ul class="list-group results">
<li class="list-group-item results-item" v-for="(item, index) in items" :class="activeClass(index)" @mousedown="hit" @mousemove="setActive(index)">
{{ item.display }}
</li>
</ul>
</div>
</div>
</template>
<script>
import VueTypeahead from 'vue-typeahead'
export default {
extends: VueTypeahead,
props: ['fieldName', 'value', 'endpoint', 'attributes', 'relationships'],
data () {
return {
query: '',
src: this.endpoint,
limit: 5,
minChars: 3,
queryParamName: 'q',
fieldNameId: ''
}
},
mounted () {
this.query = this.value
},
methods: {
prepareResponseData (items) {
for (let i = 0; i < items.length; i++) {
var fields = this.transformAttributes(items[i])
var relationships = this.transformRelationships(items[i])
items[i].display = fields + ' - ' + relationships
}
return items
},
transformAttributes (item) {
let q = []
for (let i = 0; i < this.attributes.length; i++) {
q.push(item[this.attributes[i]])
}
return q.join(' ')
},
transformRelationships (item) {
let r = []
for (let [key, value] of Object.entries(this.relationships)) {
if (this.relationships.hasOwnProperty(key)) {
for (let data of item[key]) {
r.push(data[value])
}
}
}
return r.join(', ')
},
onHit (item) {
console.log(item)
this.query = this.transformAttributes(item)
this.fieldNameId = item.id
this.value = this.query
this.items = []
},
isValid () {
if (this.value != this.query) {
this.fieldNameId = ''
}
}
}
}
</script>
Hello,
first, thanks a lot for taking the time to develop this awesome stuff!
I'm trying to make the width of the list always match width of the input textbox. When I resize the screen the width of the list doesn't change. Right now I'm listening to an onResize event and binding the width to the ul tag of the list, but it doesn't work (the width of the list doesn't change).
Is there a way to do this? Any ideas?
Thank you!
Hi,
first of all thanks for your component. It's easy to use and works well.
Howeve, I sometimes come across an issue where the latest query completes before previous ones.
For instance, if I type "something" it will trigger the following queries:
"som"
"some"
"somet"
"someth"
"somethi"
"somethin"
"something"
Sometimes query for "some" will complete after "something" so final items are not the ones that match "something" but those of "some". Bummer.
I've implemented a solution and will submit for review.
Thanks.
Since the VueJS project has officially retired vue-resource, I suggest this package should be migrated to Axios? Agreed?
This would be easy, more-or-less a swap-out maneuver. I'd be willing to take this on and submit a PR if it will be considered.
I'm working on a Vue component that hooks Bloodhound and Twitter Typeahead
https://github.com/twitter/typeahead.js
Is that something you plan on doing later on?
I'm currently using this component in a pseudo-form that allows the user to submit the form if the input field receives an enter (not the autocomplete popup). I'm doing this by implementing a processEnter method based off of the onHit method:
processEnter() {
if (this.current !== -1) {
this.onHit(this.items[this.current]);
} else {
this.$emit('pressed:enter');
}
}
Currently, onHit will be called instead of emitting the enter press event after a reset(), which breaks that behavior.
Is it possible with this plugin or a slight modification to include 2 instances of it on a page?
For example, if I wanted two typeahead input boxes for different categories of content?
Currently you only have the fetch method configured for query strings. I have an API where it's "resource/method/{uri}"
I'll go ahead and make a config defined for it and do a pull request and see what you think.
hello man,
how set data preloaded in a array as data source, not through a url?
When there is only one result and you hover it, making it active the top-border-radius disappear
Hi .. is there any way to display selected item after i select from list?
also the only way i found to sync with my data (user_id) is to add this this.$emit('input', item.id)
on onHit method.
Also one small issue on handling @keydown.enter event. when i click enter it submits the form.i tried add @keydown.enter.prevent or @keydown.enter.stop but no luck
Hello!
Could you pleas tell me how is the proper way to include the package where you are working with .vue files?
I just create a project with vue-cli
$ npm install -g vue-cli
$ vue init webpack my-project
$ cd my-project
$ npm install
$ npm run dev
And this is my component
<template>
<div class="autocomplete">
</div>
</template>
<script>
VueTypeaheadMixin = require('vue-typeahead');
export default {
mixins: [VueTypeaheadMixin],
ready () {
console.log('Autocomplete');
},
}
</script>
<style type="text/css">
</style>
But I'm receiving
vue-typeahead.js?51da:1 Uncaught SyntaxError: Unexpected token import
This error when the webpack tries to transpile the code
How can avoid this?
If you need more information just let me know, thanks in advance
Hi, I was wondering if this package is still actively maintain?
thanks
Is there any way to watch this component from my main vm and bind other events on isDirty
etc? I'd like to hide some of my UI when results are showing.
Hey, when I tried out your component I recognized that the query parameter does not got send along with my request. I double checked in the ChromeDev tools but there is no GET parameter in the rquest send by vue-resource. But if I change the line
return this.$http.get(this.src, Object.assign(queryParam, this.data))
to
return this.$http.get(this.src, {params: Object.assign(queryParam, this.data)})
everything works as expected.
So maybe the params
option needs to be statet explicitly?
I couldn't set GET params data for request via component props.
I managed to override the component fetch()
method and set params data like:
methods: {
onHit(item) {
console.log("onhit", item);
},
prepareResponseData(data) {
console.log("prepareResponseData", data);
return data;
},
//@override
fetch() {
var opts = {
params : {
"foo" : "bar"
}
}
return this.$http.get(this.url, opts);
}
}
It's possible that vue-resource was taking params as config input.
vue-resource api
Hi,
I'm using this under Vue @ ^2.0.1
, and noticed that in my compiled source when I include vue-typeahead
there's also a full copy of Vue @ 1.0.28
included, adding ~90k of unneeded code after compression. If I remove node_modules/vue-typeahead/node_modules/vue
this goes away, and it just uses Vue 2 as expected.
I believe all your dependencies
should maybe just be devDependencies
, so a package local copy of an old Vue doesn't get installed?
Do you plan to release support for vue 1.0?
Hi, great component.
In my Laravel project, the selection via "enter" key auto submits the enclosing form. Do you know a good way to prevent this in the onHit method?
Kind regards
import VueTypeahead from 'vue-typeahead';
import Axios from 'axios';
Vue.prototype.$http = Axios;
var elem;
export default {
extends: VueTypeahead,
props: ['targetInput', 'keywordCategory', 'append'],
data () {
return {
src: '/api/autocomplete',
data: {
query: this.query,
category: this.keywordCategory,
append: this.append
},
limit: 10,
minChars: 3,
selectFirst: true,
queryParamName: 'search'
}
},
methods: {
onHit (item) {
elem = document.getElementById(this.targetInput);
if(this.append !== undefined && elem.value !== '') {
elem.value += this.append + item.name;
} else {
elem.value = item.name;
}
}
}
}
I know this may possibly be a laravel mix issue, however all of my other vue components are working, so will post here first.
Compiling with npm run dev
or npm run watch
everything is fine. However when running npm run production
I am getting issues.
Everything compiles fine, however the component is just not available and does not render.
This is my component
<template>
<div class="input-wrapper">
<span class="label">
<i class="fa fa-spinner fa-spin" v-if="loading"></i>
<i class="fa fa-download" aria-hidden="true" v-else></i>
</span>
<input type="text"
placeholder="Enter your route number..."
autocomplete="off"
v-model="query"
@keydown.down="down"
@keydown.up="up"
@keydown.enter="hit"
@keydown.esc="reset"
@blur="reset"
@input="update"
/>
<ul v-show="hasItems">
<li v-for="(item, $item) in items" :class="activeClass($item)" @mousedown="hit" @mousemove="setActive($item)">
<span class="body" v-text="item.title"></span>
</li>
</ul>
</div>
</template>
<script>
import VueTypeahead from 'vue-typeahead'
export default {
extends: VueTypeahead,
props: [],
data () {
return {
src: '/axios/timetables',
limit: 5,
minChars: 2,
selectFirst: false,
queryParamName: 'search',
data: {}
}
},
methods: {
onHit (item) {
window.open('../uploads/'+item.file, '_blank');
},
prepareResponseData (data) {
console.log(data)
return data
}
}
}
</script>
<style>
</style>
This is how I am using it
window.Vue = require('vue');
require('vue-resource');
window.axios = require('axios');
// Setup axios headers
window.axios.defaults.headers.common = {
'X-Requested-With': 'XMLHttpRequest'
};
import Timetables from './components/Timetables.vue';
Vue.component('timetables', Timetables);
const el = document.getElementById('timetable-wrapper');
if (el) {
const timetables = new Vue({
el: '#timetable-wrapper',
});
}
As I am getting no errors there isnt much more to give, hoping someone has solved a similar case though.
The XHR request is started as soon as the user starts typing, which means that for every character a request new request is spawned immediately. It would be nice to have debounce event parameter in order to delay the request until the user stops typing.
is it possible to have the source from a static array of strings or objects instead of making an http call?
I can't figure out why the queryParamName adds a '/' before my search term. It ends up looking like this.. 'http://myapi?searchTerm=/sdf'. Any ideas? Here is my code:
Has anyone got an example of the data source I'm struggling to understand how the json data is mapped to the items list.
Many Thanks
Hi I'm getting the error: Uncaught ReferenceError: _vue is not defined when using the component...
This is where it fails:
fetch: function() {
var e = this;
if (!this.$http) {
return _vue.util.warn('You need to provide a HTTP client', this) <---
}
if (!this.src) {
return _vue.util.warn('You need to set the src
property', this)
}
var t = this.queryParamName ? this.src : this.src + this.query
, n = this.queryParamName ? (0,
_assign2.default)((0,
Any help to solve this would be great.
Thanks.
I tried adding debounce
to the input template but it didn't help. Unless I type at the rate of 1 key per second, the ajax requests are basically ignored completely and nothing happens.
Is it possible to bind the v-model to something other than query? It would be nice to have the typeahead work with an existing form where the type ahead was only one portion of the form.
change some attribute that:
data:{
delayTime:500, // 延迟输入
lastTime:0
}
methods:{
update (event) {
this.lastTime = event.timeStamp
if (!this.query) {
return this.reset()
}
if (this.minChars && this.query.length < this.minChars) {
return
}
// 添加的延时
setTimeout(() => {
if (this.lastTime - event.timeStamp == 0){
this.loading = true
this.fetch().then((response) => {
if (this.query) {
let data = response.body.data['docs']?response.body.data['docs']:[]
this.counter = response.body.data.numFound?response.body.data.numFound:{}
// data = this.prepareResponseData ? this.prepareResponseData(data) : data
this.items = this.render(this.limit ? data.slice(0, this.limit) : data)
this.current = -1
this.loading = false
if (this.selectFirst) {
this.down()
}
}
})
}
},this.delayTime)
},
}
and make update to update($event)
Hi!
Thanks for the great component! It helped me a few time already, but I came across a new request and I'm unsure how to solve this one.
The problem is that I'm trying to implement this as a part of a tag/token selector, and all the possible tags/tokens are already available locally and there's no actual need for an ajax request, but the component only supports remote requests.
Could this component be extended to optionally support local resources?
The plugin works wonderfully however, in our environment, our api endpoints don't have trailing '/' in our urls. ATM I have to comment out the snippet that appends a trailing slash. You probably don't need those lines if you let the users decide whether or not to at a trailing forward slash.
if (this.src.substr(-1) !== '/') {
this.src += '/'
}
Hi,
great work mate, I love it.
Do you think it is possible to add condition let's say "min-chars" that has to be fulfilled to spawn the XHR request? Somethink like "you have to enter at least 3 chars".
Thanks in advance!
Hello. I'm using Vue 2 and I get undefined for item in onHit(item)
.
Also pulling in your demo Typeahead.vue returns undefined.
My package.json:
{
"private": true,
"scripts": {
"prod": "gulp --production",
"dev": "gulp watch"
},
"devDependencies": {
"bootstrap-sass": "^3.3.7",
"gulp": "^3.9.1",
"jquery": "^3.1.0",
"laravel-elixir": "^6.0.0-9",
"laravel-elixir-vue-2": "^0.2.0",
"laravel-elixir-webpack-official": "^1.0.2",
"lodash": "^4.16.2",
"vue": "^2.0.1",
"vue-resource": "^1.0.3"
},
"dependencies": {
"typeahead.js": "^0.11.1",
"vue-typeahead": "^2.3.0"
}
}
I have added the cancel method in my Vue file but the logic to cancel the request is not clear.
I have read all the code of yours but unable to find how you are processing it.
could you add in the readme the installation guide in nuxt.js? ty
I'm seeing an issue with Internet Explorer 11 with this line:
Line 69 in 69d58b9
Should browserify/babel be polyfilling Object?
I have used typeahead as component in my project and so far it's been useful, now I need to trap the delete
and backspace
buttons when clicked, but I have no idea how to trap these events in typeahead component
could you please help me through this issue?
Would you mind upload the source code of the demo? I have a little difficulty in using the component, maybe a little more example would help me. Thanks a lot!
When you search for the first time, the first item cannot be selected because the list has not been rendered yet.
if (this.selectFirst) {
this.down();
Any idea how this can be solved?
PS: the attribute selectFirst is already set to true
.
PPS: great work :D
It is not guaranteed that the suggestions may come from a remote location and only from one source. It would be great if the code for making ajax call could be moved to fetch(query)
function that is required to return a promise with "raw" data that will be passed to prepareResponseData(data)
. The default implementation of fetch
could be the same code as ajax call. However, developer will be able to overwrite it with their own implementation (such as making calls to multiple remote locations or reading a local file if nw or electron are used).
So update()
would transform from this:
update () {
if (! this.query) {
this.reset()
return
}
this.loading = true
this.$http.get(this.src, Object.assign({q:this.query}, this.data))
.then(function (response) {
if (this.query) {
var data = response.data
data = this.prepareResponseData ? this.prepareResponseData(data) : data
this.items = !!this.limit ? data.slice(0, this.limit) : data
this.current = -1
this.loading = false
}
}.bind(this))
},
To this:
update () {
if (! this.query) {
this.reset()
return
}
this.loading = true
this.fetch(this.query)
.then(function (response) {
if (this.query) {
var data = response.data
data = this.prepareResponseData ? this.prepareResponseData(data) : data
this.items = !!this.limit ? data.slice(0, this.limit) : data
this.current = -1
this.loading = false
}
}.bind(this))
},
fetch (query) {
return this.$http.get(this.src, Object.assign({q:this.query}, this.data))
}
In fact, src
and data
can be removed, assuming that the dev will always implement fetch()
Finally, I see that fetching (ajax) happens when query is empty but the results aren't used. I think it should either not make the extra fetch or expect the developer to manually handle that condition inside the new fetch()
and return an empty array, indicating no data.
Hi there,
jsut a quick fix
When you get data from server, do not set first item (delete this line https://github.com/pespantelis/vue-typeahead/blob/master/vue-typeahead.js#L60) as current. First item is current when you hit arrrow down.
Hello All,
I am using this control to create an invoice page that allows user to add multiple items on the invoice. User enters an "item name"' in this control, that in turn searches for an item, if found populates other field such as price, available quantity etc. automatically.
Here is the screenshot of my page:
http://www.awesomescreenshot.com/image/2107586/bf9cbac09ca323724493c4079780fe9f
Each item name column is unique to each specific row. In short - if I select "iphone 5" from the first row then it should populate price, quantity for iPhone 5 in the other fields. I can do this using VUEJS events. However, issue is - using event I can't determine which row this "item name" corresponds to. Due to this my code updates incorrect values.
I have added a screenshot of invoice page. At the moment - only item name is typeahead while other fields are part of a different component to which typeahead component has been imported.
http://www.awesomescreenshot.com/image/2107586/bf9cbac09ca323724493c4079780fe9f
any suggestions how to tackle this? Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.