npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

meteor-typeahead

v1.2.0

Published

Autocomplete package for meteor powered by twitter typeahead.js

Downloads

26

Readme

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