1.2.0 • Published 6 years ago

meteor-typeahead v1.2.0

Weekly downloads
4
License
MIT
Repository
github
Last release
6 years ago

meteor-typeahead Build Status LICENSE meteor package version

Deps Status DevDeps Status

Twitter's typeahead.js autocomplete package, wrapped for Meteor 1.0+. Issue command meteor add sergeyt:typeahead to install the package.

Initializing typeahead

When the DOM is loaded through Meteor.startup on each template

Meteor.startup(function() {
  Meteor.typeahead.inject();
});

with iron:router

Using iron:router the Meteor.startup is already triggered because it loads the template or the loading template and then inject the data. It must be delayed to when iron:router knows it is rendered completely.

Template.demo.rendered = function() {
  Meteor.typeahead.inject();
};

Examples

See demo application in this repository to find more examples.

data-source attribute

<input class="form-control typeahead" name="team" type="text"
       placeholder="NBA teams"
       autocomplete="off" spellcheck="off"
       data-source="nba"/>
Nba = new Meteor.Collection("nba");

if (Meteor.isServer){
	Nba.insert({name:'Boston Celtics'});
	// fill Nba collection
}

Template.demo.helpers({
  nba: function() {
    return Nba.find().fetch().map(function(it){ return it.name; });
  }
});

Multiple datasets

<template name="demo">
  <div class="form-group">
    <input class="form-control typeahead" name="team" type="text"
           placeholder="NBA and NHL teams"
           autocomplete="off" spellcheck="off"
           data-sets="teams"/>
  </div>
</template>

<template name="team">
	<h4><i>{{name}}</i></h4>
</template>
Template.demo.helpers({
  teams: function() {
    return [
      {
        name: 'nba-teams',
        valueKey: 'name',
        local: function() { return Nba.find().fetch(); },
        header: '<h3 class="league-name">NBA Teams</h3>',
        template: 'team'
      },
      {
        name: 'nhl-teams',
        valueKey: 'name',
        local: function() { return Nhl.find().fetch(); },
        header: '<h3 class="league-name">NHL Teams</h3>',
        template: 'team'
      }
    ];
  }
});

Custom template to render suggestion

<input class="form-control typeahead" name="repo" type="text"
       placeholder="open source projects by Twitter"
       autocomplete="off" spellcheck="off"
       data-source="repos" data-template="repo"/>

<template name="repo">
       <p class="repo-language">{{language}}</p>
       <p class="repo-name">{{name}}</p>
       <p class="repo-description">{{description}}</p>
</template>
Repos = new Meteor.Collection("repos");

if (Meteor.isServer){
	Meteor.startup(function(){
		Repos.remove({});
		// fill repos from private repos.json asset
		JSON.parse(Assets.getText('repos.json')).forEach(function(it){
			Repos.insert(it);
		});
	});
}

if (Meteor.isClient){
  Template.demo.helpers({
    repos: function() {
      // this only works if returned objects have
      // an attribute named "value" containing the text
      // See docs for "data-value-key" attribute
      return Repos.find().fetch();
    }
  });
}

Server side search

<input class="form-control typeahead" name="search" type="text" placeholder="Type to query"
       autocomplete="off" spellcheck="off"
       data-source="search"/>
BigCollection = new Meteor.Collection('bigcollection');

if (Meteor.isServer) {
	Meteor.startup(function() {
		if (!BigCollection.find().count()) {
			// fill BigCollection
		}
	});

	Meteor.methods({
		search: function(query, options) {
			options = options || {};

			// guard against client-side DOS: hard limit to 50
			if (options.limit) {
				options.limit = Math.min(50, Math.abs(options.limit));
			} else {
				options.limit = 50;
			}

			// TODO fix regexp to support multiple tokens
			var regex = new RegExp("^" + query);
			return BigCollection.find({name: {$regex:  regex}}, options).fetch();
		}
	});
} else {

  Template.demo.helpers({
    search = function(query, sync, callback) {
      Meteor.call('search', query, {}, function(err, res) {
        if (err) {
          console.log(err);
          return;
        }
        callback(res.map(function(v){ return {value: v.name}; }));
      });
    }
  });
}

Catching selected event with id

Template.example.rendered = function() {
  Meteor.typeahead.inject();
}

Template.example.helpers({
  items: function() {
    // data source function
    // TODO fetch items from meteor collection
    return someCollections.find().fetch().map(function(object){ return {id: object._id, value: object.value}; });
  },
  selected: function(event, suggestion, datasetName) {
    // event - the jQuery event object
    // suggestion - the suggestion object
    // datasetName - the name of the dataset the suggestion belongs to
    // TODO your event handler here
    console.log(suggestion.id);
  }
});

Template:

<template name="example">
  <input placeholder="Kies een plaats" autocomplete="off" spellcheck="off"
      data-source="items" data-select="selected"/>
</template>

Styling

By default, there is no style applied with this package. If you want the same styling as in the demo app, please do the following:

  • add bootstrap: meteor add twbs:bootstrap
  • add the style.css file to your application
1.2.0

6 years ago

0.10.5

10 years ago

0.1.2

10 years ago

0.1.1

10 years ago

0.0.12

10 years ago

0.0.11

10 years ago

0.0.10

10 years ago

0.0.9

10 years ago

0.0.8

10 years ago

0.0.7

10 years ago

0.0.6

10 years ago

0.0.5

10 years ago

0.0.4

10 years ago

0.0.3

10 years ago

0.0.2

10 years ago

0.0.1

10 years ago