Coder Social home page Coder Social logo

vue-typeahead's People

Contributors

matt-west avatar nerijunior avatar pespantelis avatar simulatedgreg avatar viirre avatar weklund avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vue-typeahead's Issues

Is there a way to provide source as JSON file

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.

remove 'q' parameter

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?

Problem showing bound value in text input

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

Error on `require()`

I get the following error just by requiring the component. I'm using Browserify.

Uncaught TypeError: Cannot redefine property: $url

screen shot 2015-08-25 at 11 10 46 pm

Update method firing when input field blurs

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>

Make width of list responsive

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!

items not always populated with latest results

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.

Switch from vue-resource to Axios?

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.

Current selection should be reset inside reset()

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.

Including 2 instances on a page?

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?

Not supported for RESTful queries

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.

Display selected

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

A proper way to import it to a .vue file

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

still active?

Hi, I was wondering if this package is still actively maintain?

thanks

Parent Watching event

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.

Query parameter is not sended in request

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?

fetch method [vue-resource]

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

Using in Vue 2 pulls in copy of Vue 1

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?

Prevent auto submit form in the onHit method

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;
                }
            }
        }
    }

Laravel Mix --production issue

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.

Debounce event

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.

Example of datasource

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

Uncaught ReferenceError: _vue is not defined

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.

Different v-model?

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.

Add delay function

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)

Use local resource for lookup

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?

Optional Preference to disable the appending of the trailing / in http url requests.

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 += '/'
}

min-chars param

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!

onHit(item) ... item undefined

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"
  }
}

trap the delete event on typeahead component

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?

about the demo

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!

selectFirst

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

Replace ajax call altogether with a fetch function

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.

Multiple instances on same page

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

capture

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.