UI Bootstrap

Bootstrap components written in pure AngularJS by the AngularUI Team

Code on Github Download (0.6.0) Create a Build

Dependencies

This repository contains a set of native AngularJS directives based on Twitter Bootstrap's markup and CSS. As a result no dependency on jQuery or Bootstrap's JavaScript is required. The only required dependencies are:

  • AngularJS (minimal version 1.0.4 or 1.1.2)
  • Bootstrap CSS

Files to download

Build files for all directives are distributed in several flavours: minified for production usage, un-minified for development, with or without templates. All the options are described and can be downloaded from here.

Alternativelly, if you are only interested in a subset of directives, you can create your own build.

Whichever method you choose the good news that the overall size of a download is very small: <20kB for all directives (~5kB with gzip compression!)

Installation

As soon as you've got all the files downloaded and included in your page you just need to declare a dependency on the ui.bootstrap module:
angular.module('myModule', ['ui.bootstrap']);

You can fork one of the plunkers from this page to see a working example of what is described here.

CSS

Original Bootstrap's CSS depends on empty href attributes to style cursors for several components (pagination, tabs etc.). But in AngularJS adding empty href attributes to link tags will cause unwanted route changes. This is why we need to remove empty href attributes from directive templates and as a result styling is not applied correctly. The remedy is simple, just add the following styling to your application: .nav, .pagination, .carousel a { cursor: pointer; }

This content is straight in the template. {{group.content}}

The body of the accordion group grows to fit the contents

{{item}}
I can have markup, too! This is just some content to illustrate fancy headings.

The accordion directive builds on top of the collapse directive to provide a list of items, with collapsible bodies that are collapsed or expanded by clicking on the item's header.

We can control whether expanding an item will cause the other items to close, using the close-others attribute on accordion.

The body of each accordion group is transcluded in to the body of the collapsible element.


<div ng-controller="AccordionDemoCtrl">
  <label class="checkbox">
    <input type="checkbox" ng-model="oneAtATime">
    Open only one at a time
  </label>

  <accordion close-others="oneAtATime">
    <accordion-group heading="Static Header">
      This content is straight in the template.
    </accordion-group>
    <accordion-group heading="{{group.title}}" ng-repeat="group in groups">
      {{group.content}}
    </accordion-group>
    <accordion-group heading="Dynamic Body Content">
      <p>The body of the accordion group grows to fit the contents</p>
        <button class="btn btn-small" ng-click="addItem()">Add Item</button>
        <div ng-repeat="item in items">{{item}}</div>
    </accordion-group>
    <accordion-group>
        <accordion-heading>
            I can have markup, too! <i class="icon-check"></i>
        </accordion-heading>
        This is just some content to illustrate fancy headings.
    </accordion-group>
  </accordion>
</div>
function AccordionDemoCtrl($scope) {
  $scope.oneAtATime = true;

  $scope.groups = [
    {
      title: "Dynamic Group Header - 1",
      content: "Dynamic Group Body - 1"
    },
    {
      title: "Dynamic Group Header - 2",
      content: "Dynamic Group Body - 2"
    }
  ];

  $scope.items = ['Item 1', 'Item 2', 'Item 3'];

  $scope.addItem = function() {
    var newItemNo = $scope.items.length + 1;
    $scope.items.push('Item ' + newItemNo);
  };
}
{{alert.msg}}

Alert is an AngularJS-version of bootstrap's alert.

This directive can be used to generate alerts from the dynamic model data (using the ng-repeat directive);

The presence of the "close" attribute determines if a close button is displayed


<div ng-controller="AlertDemoCtrl">
  <alert ng-repeat="alert in alerts" type="alert.type" close="closeAlert($index)">{{alert.msg}}</alert>
  <button class='btn' ng-click="addAlert()">Add Alert</button>
</div>
function AlertDemoCtrl($scope) {
  $scope.alerts = [
    { type: 'error', msg: 'Oh snap! Change a few things up and try submitting again.' }, 
    { type: 'success', msg: 'Well done! You successfully read this important alert message.' }
  ];

  $scope.addAlert = function() {
    $scope.alerts.push({msg: "Another alert!"});
  };

  $scope.closeAlert = function(index) {
    $scope.alerts.splice(index, 1);
  };

}

Single toggle

{{singleModel}}

Checkbox

{{checkModel}}

Radio

{{radioModel}}

There are 2 directives that can make a group of buttons to behave like a set of checkboxes or radio buttons.


<div ng-controller="ButtonsCtrl">
    <h4>Single toggle</h4>
    <pre>{{singleModel}}</pre>
    <button type="button" class="btn btn-primary" ng-model="singleModel" btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
        Single Toggle
    </button>
    <h4>Checkbox</h4>
    <pre>{{checkModel}}</pre>
    <div class="btn-group">
        <button type="button" class="btn btn-primary" ng-model="checkModel.left" btn-checkbox>Left</button>
        <button type="button" class="btn btn-primary" ng-model="checkModel.middle" btn-checkbox>Middle</button>
        <button type="button" class="btn btn-primary" ng-model="checkModel.right" btn-checkbox>Right</button>
    </div>
    <h4>Radio</h4>
    <pre>{{radioModel}}</pre>
    <div class="btn-group">
        <button type="button" class="btn btn-primary" ng-model="radioModel" btn-radio="'Left'">Left</button>
        <button type="button" class="btn btn-primary" ng-model="radioModel" btn-radio="'Middle'">Middle</button>
        <button type="button" class="btn btn-primary" ng-model="radioModel" btn-radio="'Right'">Right</button>
    </div>
</div>
var ButtonsCtrl = function ($scope) {

  $scope.singleModel = 1;

  $scope.radioModel = 'Middle';

  $scope.checkModel = {
    left: false,
    middle: true,
    right: false
  };
};

Some content

AngularJS version of twitter's collapse plugin. Provides a simple way to hide and show an element with a css transition


<div ng-controller="CollapseDemoCtrl">
	<button class="btn" ng-click="isCollapsed = !isCollapsed">Toggle collapse</button>
	<hr>
	<div collapse="isCollapsed">
		<div class="well well-large">Some content</div> 
	</div>
</div>
function CollapseDemoCtrl($scope) {
  $scope.isCollapsed = false;
}
Selected date is: {{dt | date:'fullDate' }}

A clean, flexible, and fully customizable date picker.

User can navigate through months and years. The datepicker shows dates that come from other than the main month being displayed. These other dates are also selectable.

Everything is formatted using the date filter and thus is also localized.

Settings

All settings can be provided as attributes in the <datepicker> or globally configured through the datepickerConfig.

  • ng-model : The date object.

  • show-weeks (Defaults: true) : Whether to display week numbers.

  • starting-day (Defaults: 0) : Starting day of the week from 0-6 (0=Sunday, ..., 6=Saturday).

  • min (Default: null) : Defines the minimum available date.

  • max (Default: null) : Defines the maximum available date.

  • date-disabled (date, mode) (Default: null) : An optional expression to disable visible options based on passing date and current mode (day|month|year).

  • day-format (Default: 'dd') : Format of day in month.

  • month-format (Default: 'MMMM') : Format of month in year.

  • year-format (Default: 'yyyy') : Format of year in year range.

  • year-range (Default: 20) : Number of years displayed in year selection.

  • day-header-format (Default: 'EEE') : Format of day in week header.

  • day-title-format (Default: 'MMMM yyyy') : Format of title when selecting day.

  • month-title-format (Default: 'yyyy') : Format of title when selecting month.


<div ng-controller="DatepickerDemoCtrl">
    <pre>Selected date is: <em>{{dt | date:'fullDate' }}</em></pre>

    <div class="well well-small pull-left" ng-model="dt">
        <datepicker min="minDate" show-weeks="showWeeks"></datepicker>
    </div>

    <div class="form-horizontal">
        <input type="text" datepicker-popup="dd-MMMM-yyyy" ng-model="dt" is-open="opened" min="minDate" max="'2015-06-22'" datepicker-options="dateOptions" date-disabled="disabled(date, mode)" ng-required="true" />
        <button class="btn" ng-click="open()"><i class="icon-calendar"></i></button>
    </div>

    <hr />
    <button class="btn btn-small btn-inverse" ng-click="today()">Today</button>
    <button class="btn btn-small btn-inverse" ng-click="dt = '2009-08-24'">2009-08-24</button>
    <button class="btn btn-small btn-success" ng-click="toggleWeeks()" tooltip="For inline datepicker">Toggle Weeks</button>
    <button class="btn btn-small btn-danger" ng-click="clear()">Clear</button>
    <button class="btn btn-small" ng-click="toggleMin()" tooltip="After today restriction">Min date</button>
</div>
var DatepickerDemoCtrl = function ($scope, $timeout) {
  $scope.today = function() {
    $scope.dt = new Date();
  };
  $scope.today();

  $scope.showWeeks = true;
  $scope.toggleWeeks = function () {
    $scope.showWeeks = ! $scope.showWeeks;
  };

  $scope.clear = function () {
    $scope.dt = null;
  };

  // Disable weekend selection
  $scope.disabled = function(date, mode) {
    return ( mode === 'day' && ( date.getDay() === 0 || date.getDay() === 6 ) );
  };

  $scope.toggleMin = function() {
    $scope.minDate = ( $scope.minDate ) ? null : new Date();
  };
  $scope.toggleMin();

  $scope.open = function() {
    $timeout(function() {
      $scope.opened = true;
    });
  };

  $scope.dateOptions = {
    'year-format': "'yy'",
    'starting-day': 1
  };
};

Default

The selected page no: {{currentPage}}

Pager


Limit the maximimum visible buttons

Page: {{bigCurrentPage}} / {{numPages}}

A lightweight pagination directive that is focused on ... providing pagination & will take care of visualising a pagination bar and enable / disable buttons correctly!

Pagination Settings

Settings can be provided as attributes in the <pagination> or globally configured through the paginationConfig.

  • page : Current page number. First page is 1.

  • total-items : Total number of items in all pages.

  • items-per-page (Defaults: 10) : Maximum number of items per page. A value less than one indicates all items on one page.

  • max-size (Defaults: null) : Limit number for pagination size.

  • num-pages readonly : Total number of pages to display.

  • rotate (Defaults: true) : Whether to keep current page in the middle of the visible ones.

  • on-select-page (page) (Default: null) : An optional expression called when a page is selected having the page number as argument.

  • direction-links (Default: true) : Whether to display Previous / Next buttons.

  • previous-text (Default: 'Previous') : Text for Previous button.

  • next-text (Default: 'Next') : Text for Next button.

  • boundary-links (Default: false) : Whether to display First / Last buttons.

  • first-text (Default: 'First') : Text for First button.

  • last-text (Default: 'Last') : Text for Last button.

Pager Settings

Settings can be provided as attributes in the <pager> or globally configured through the pagerConfig.
For page, total-items, items-per-page, num-pages and on-select-page (page) see pagination settings. Other settings are:

  • align (Default: true) : Whether to align each link to the sides.

  • previous-text (Default: '« Previous') : Text for Previous button.

  • next-text (Default: 'Next »') : Text for Next button.


<div ng-controller="PaginationDemoCtrl" class="well well-small">
    <h4>Default</h4>

    <pagination total-items="totalItems" page="currentPage"></pagination>
    <pagination boundary-links="true" total-items="totalItems" page="currentPage" class="pagination-small" previous-text="&lsaquo;" next-text="&rsaquo;" first-text="&laquo;" last-text="&raquo;"></pagination>
    <pagination direction-links="false" boundary-links="true" total-items="totalItems" page="currentPage"></pagination>
    <pagination direction-links="false" total-items="totalItems" page="currentPage" num-pages="smallnumPages"></pagination>

    <button class="btn" ng-click="setPage(3)">Set current page to: 3</button>
    The selected page no: {{currentPage}}

    <hr />
    <h4>Pager</h4>
    <pager total-items="totalItems" page="currentPage"></pager>

    <hr />
    <h4>Limit the maximimum visible buttons</h4>
    <pagination total-items="bigTotalItems" page="bigCurrentPage" max-size="maxSize" class="pagination-small" boundary-links="true"></pagination>
    <pagination total-items="bigTotalItems" page="bigCurrentPage" max-size="maxSize" class="pagination-small" boundary-links="true" rotate="false" num-pages="numPages"></pagination>

    <pre>Page: {{bigCurrentPage}} / {{numPages}}</pre>
</div>
var PaginationDemoCtrl = function ($scope) {
  $scope.totalItems = 64;
  $scope.currentPage = 4;
  $scope.maxSize = 5;
  
  $scope.setPage = function (pageNo) {
    $scope.currentPage = pageNo;
  };

  $scope.bigTotalItems = 175;
  $scope.bigCurrentPage = 1;
};

Dynamic

Dynamic Popover :
Dynamic Popover Popup Text:
Dynamic Popover Popup Title:

Positional

Triggers

Other

A lightweight, extensible directive for fancy popover creation. The popover directive supports multiple placements, optional transition animation, and more.

Like the Twitter Bootstrap jQuery plugin, the popover requires the tooltip module.

The popover directives provides several optional attributes to control how it will display:

  • popover-title: A string to display as a fancy title.
  • popover-placement: Where to place it? Defaults to "top", but also accepts "bottom", "left", "right".
  • popover-animation: Should it fade in and out? Defaults to "true".
  • popover-popup-delay: For how long should the user have to have the mouse over the element before the popover shows (in milliseconds)? Defaults to 0.
  • popover-trigger: What should trigger the show of the popover? See the tooltip directive for supported values.
  • popover-append-to-body: Should the tooltip be appended to $body instead of the parent element?

The popover directives require the $position service.

The popover directive also supports various default configurations through the $tooltipProvider. See the tooltip section for more information.


<div ng-controller="PopoverDemoCtrl">
  <div class="well">
    <div>
      <h4>Dynamic</h4>
      <div>Dynamic Popover : <input type="text" ng-model="dynamicPopoverText"></div>
      <div>Dynamic Popover Popup Text: <input type="text" ng-model="dynamicPopover"></div>
      <div>Dynamic Popover Popup Title: <input type="text" ng-model="dynamicPopoverTitle"></div>
      <div><button popover="{{dynamicPopover}}" popover-title="{{dynamicPopoverTitle}}" class="btn">{{dynamicPopoverText}}</button></div>
    </div>
    <div>
      <h4>Positional</h4>
      <button popover-placement="top" popover="On the Top!" class="btn">Top</button>
      <button popover-placement="left" popover="On the Left!" class="btn">Left</button>
      <button popover-placement="right" popover="On the Right!" class="btn">Right</button>
      <button popover-placement="bottom" popover="On the Bottom!" class="btn">Bottom</button>
    </div>
    <div>
      <h4>Triggers</h4>
      <button popover="I appeared on mouse enter!" popover-trigger="mouseenter" class="btn">Mouseenter</button>
      <input type="text" value="Click me!" 
        popover="I appeared on focus! Click away and I'll vanish..." 
        popover-trigger="focus" />
    </div>
    <div>
      <h4>Other</h4>
      <button Popover-animation="true" popover="I fade in and out!" class="btn">fading</button>
      <button popover="I have a title!" popover-title="The title." class="btn">title</button>
    </div>
  </div>
</div>
var PopoverDemoCtrl = function ($scope) {
  $scope.dynamicPopover = "Hello, World!";
  $scope.dynamicPopoverText = "dynamic";
  $scope.dynamicPopoverTitle = "Title";
};

Static

Dynamic

Value: {{dynamic}}
No animation Object (changes type based on value)

Stacked

Array values with automatic types
Value: {{stackedArray}}
Objects
Value: {{stacked}}

A lightweight progress bar directive that is focused on providing progress visualization!

The progress bar directive supports multiple (stacked) bars into the same element, optional transition animation, event handler for full & empty state and many more.


<div ng-controller="ProgressDemoCtrl" class="well">
    <h2>Static</h2>
    <div class="row-fluid">
        <div class="span4"><progress percent="55"></progress></div>
        <div class="span4"><progress percent="22" class="progress-warning progress-striped"></progress></div>
        <div class="span4"><progress percent="88" class="progress-danger progress-striped active"></div>
    </div>
    
    <h2>Dynamic <button class="btn btn-primary" type="button" ng-click="random()">Randomize</button></h2>
    <pre>Value: {{dynamic}}</pre>
    <progress percent="dynamic"></progress>
    
    <small><em>No animation</em></small>
    <progress percent="dynamic" class="progress-success" animate="false"></progress>

    <small><em>Object (changes type based on value)</em></small>
    <progress percent="dynamicObject" class="progress-striped active"></progress>
    
    <h2>Stacked <button class="btn btn-primary" type="button" ng-click="randomStacked()">Randomize</button></h2>
    <small><em>Array values with automatic types</em></small>
    <pre>Value: {{stackedArray}}</pre>
    <progress percent="stackedArray" auto-type="true"></progress>
    
    <small><em>Objects</em></small>
    <pre>Value: {{stacked}}</pre>
    <progress percent="stacked"></progress>
</div>
var ProgressDemoCtrl = function ($scope) {
   
  $scope.random = function() {
    var value = Math.floor((Math.random()*100)+1);
    var type;

    if (value < 25) {
      type = 'success';
    } else if (value < 50) {
      type = 'info';
    } else if (value < 75) {
      type = 'warning';
    } else {
      type = 'danger';
    }

    $scope.dynamic = value;
    $scope.dynamicObject = {
      value: value,
      type: type
    };
  };
  $scope.random();
  
  var types = ['success', 'info', 'warning', 'danger'];
  $scope.randomStacked = function() {
    $scope.stackedArray = [];
    $scope.stacked = [];
    
    var n = Math.floor((Math.random()*4)+1);

    for (var i=0; i < n; i++) {
        var value = Math.floor((Math.random()*30)+1);
        $scope.stackedArray.push(value);
        
        var index = Math.floor((Math.random()*4));
        $scope.stacked.push({
          value: value,
          type: types[index]
        });
    }
  };
  $scope.randomStacked();
};

Default

{{percent}}%
Rate: {{rate}} - Readonly is: {{isReadonly}} - Hovering over: {{overStar || "none"}}

Custom icons

(Rate: {{x}})
(Rate: {{y}})

Rating directive that will take care of visualising a star rating bar.

Settings

<rating>

  • value : The current rate.

  • max (Defaults: 5) : Changes the number of icons.

  • readonly (Defaults: false) : Prevent user's interaction.

  • on-hover(value) : An optional expression called when user's mouse is over a particular icon.

  • on-leave() : An optional expression called when user's mouse leaves the control altogether.

  • state-on (Defaults: null) : A variable used in template to specify the state (class, src, etc) for selected icons.

  • state-off (Defaults: null) : A variable used in template to specify the state for unselected icons.

  • rating-states (Defaults: null) : An array of objects defining properties for all icons. In default template, stateOn & stateOff property is used to specify the icon's class.


<div ng-controller="RatingDemoCtrl" class="well well-small">
    <h4>Default</h4>
    <rating value="rate" max="max" readonly="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null"></rating>
    <span class="badge" ng-class="{'badge-warning': percent<30, 'badge-info': percent>=30 && percent<70, 'badge-success': percent>=70}" ng-show="overStar && !isReadonly">{{percent}}%</span>

    <pre style="margin:15px 0;">Rate: <b>{{rate}}</b> - Readonly is: <i>{{isReadonly}}</i> - Hovering over: <b>{{overStar || "none"}}</b></pre>

    <button class="btn btn-small btn-danger" ng-click="rate = 0" ng-disabled="isReadonly">Clear</button>
    <button class="btn btn-small" ng-click="isReadonly = ! isReadonly">Toggle Readonly</button>
    <hr />

    <h4>Custom icons</h4>
    <div ng-init="x = 5"><rating value="x" max="15" state-on="'icon-ok-sign'" state-off="'icon-ok-circle'"></rating> <b>(<i>Rate:</i> {{x}})</b></div>
    <div ng-init="y = 2"><rating value="y" rating-states="ratingStates"></rating> <b>(<i>Rate:</i> {{y}})</b></div>
</div>
var RatingDemoCtrl = function ($scope) {
  $scope.rate = 7;
  $scope.max = 10;
  $scope.isReadonly = false;

  $scope.hoveringOver = function(value) {
    $scope.overStar = value;
    $scope.percent = 100 * (value / $scope.max);
  };

  $scope.ratingStates = [
    {stateOn: 'icon-ok-sign', stateOff: 'icon-ok-circle'},
    {stateOn: 'icon-star', stateOff: 'icon-star-empty'},
    {stateOn: 'icon-heart', stateOff: 'icon-ban-circle'},
    {stateOn: 'icon-heart'},
    {stateOff: 'icon-off'}
  ];
};
Select a tab by setting active binding to true:

Static content {{tab.content}} Select me for alert! I've got an HTML heading, and a select callback. Pretty cool!
Vertical content 1 Vertical content 2

AngularJS version of the tabs directive.

Settings

<tabset>

  • vertical (Defaults: false) : Whether tabs appear vertically stacked.

  • type (Defaults: 'tabs') : Navigation type. Possible values are 'tabs' and 'pills'.

  • direction (Defaults: null) : What direction the tabs should be rendered. Available: 'right', 'left', 'below'.

<tab>

  • heading or <tab-heading> : Heading text or HTML markup.

  • active (Defaults: false) : Whether tab is currently selected.

  • disabled (Defaults: false) : Whether tab is clickable and can be activated.

  • select() (Defaults: null) : An optional expression called when tab is activated.


<div ng-controller="TabsDemoCtrl">
  Select a tab by setting active binding to true:
  <br />
  <button class="btn btn-small" ng-click="tabs[0].active = true">Select second tab</button>
  <button class="btn btn-small" ng-click="tabs[1].active = true">Select third tab</button>
  <button class="btn btn-small" ng-click="tabs[1].disabled = ! tabs[1].disabled">Enable / Disable third tab</button>
  <hr />

  <tabset>
    <tab heading="Static title">Static content</tab>
    <tab ng-repeat="tab in tabs" heading="{{tab.title}}" active="tab.active" disabled="tab.disabled">
      {{tab.content}}
    </tab>
    <tab select="alertMe()">
      <tab-heading>
        <i class="icon-bell"></i> Select me for alert!
      </tab-heading>
      I've got an HTML heading, and a select callback. Pretty cool!
    </tab>
  </tabset>

  <hr />

  <tabset vertical="true" type="navType">
    <tab heading="Vertical 1">Vertical content 1</tab>
    <tab heading="Vertical 2">Vertical content 2</tab>
  </tabset>
</div>
var TabsDemoCtrl = function ($scope) {
  $scope.tabs = [
    { title:"Dynamic Title 1", content:"Dynamic content 1" },
    { title:"Dynamic Title 2", content:"Dynamic content 2", disabled: true }
  ];

  $scope.alertMe = function() {
    setTimeout(function() {
      alert("You've selected the alert tab!");
    });
  };

  $scope.navType = 'pills';
};
Time is: {{mytime | date:'shortTime' }}
Hours step is:
Minutes step is:

A lightweight & configurable timepicker directive.

Settings

All settings can be provided as attributes in the <timepicker> or globally configured through the timepickerConfig.

  • ng-model : The Date object that provides the time state.

  • hour-step (Defaults: 1) : Number of hours to increase or decrease when using a button.

  • minute-step (Defaults: 1) : Number of minutes to increase or decrease when using a button.

  • show-meridian (Defaults: true) : Whether to display 12H or 24H mode.

  • meridians (Defaults: ['AM', 'PM']) : Meridian labels

  • readonly-input (Defaults: false) : Whether user can type inside the hours & minutes input.

  • mousewheel (Defaults: true) : Whether user can scroll inside the hours & minutes input to increase or decrease it's values.


<div ng-controller="TimepickerDemoCtrl">
  <div ng-model="mytime" ng-change="changed()" class="well well-small" style="display:inline-block;">
    <timepicker hour-step="hstep" minute-step="mstep" show-meridian="ismeridian"></timepicker>
  </div>

  <pre>Time is: {{mytime | date:'shortTime' }}</pre>

  <div>Hours step is: <select ng-model="hstep" ng-options="opt for opt in options.hstep"></select></div>
  <div>Minutes step is: <select ng-model="mstep" ng-options="opt for opt in options.mstep"></select></div>

  <button class="btn" ng-click="toggleMode()">12H / 24H</button>
  <button class="btn" ng-click="update()">Set to 14:00</button>
  <button class="btn btn-danger" ng-click="clear()">Clear</button>
</div>
var TimepickerDemoCtrl = function ($scope) {
  $scope.mytime = new Date();

  $scope.hstep = 1;
  $scope.mstep = 15;

  $scope.options = {
    hstep: [1, 2, 3],
    mstep: [1, 5, 10, 15, 25, 30]
  };

  $scope.ismeridian = true;
  $scope.toggleMode = function() {
    $scope.ismeridian = ! $scope.ismeridian;
  };

  $scope.update = function() {
    var d = new Date();
    d.setHours( 14 );
    d.setMinutes( 0 );
    $scope.mytime = d;
  };

  $scope.changed = function () {
    console.log('Time changed to: ' + $scope.mytime);
  };

  $scope.clear = function() {
    $scope.mytime = null;
  };
};
Dynamic Tooltip Text:
Dynamic Tooltip Popup Text:

Pellentesque {{dynamicTooltipText}}, sit amet venenatis urna cursus eget nunc scelerisque viverra mauris, in aliquam. Tincidunt lobortis feugiat vivamus at left eget arcu dictum varius duis at consectetur lorem. Vitae elementum curabitur right nunc sed velit dignissim sodales ut eu sem integer vitae. Turpis egestas bottom pharetra convallis posuere morbi leo urna, fading at elementum eu, facilisis sed odio morbi quis commodo odio. In cursus delayed turpis massa tincidunt dui ut.

I can even contain HTML. Check me out!

Or use custom triggers, like focus:

A lightweight, extensible directive for fancy tooltip creation. The tooltip directive supports multiple placements, optional transition animation, and more.

There are two versions of the tooltip: tooltip and tooltip-html-unsafe. The former takes text only and will escape any HTML provided. The latter takes whatever HTML is provided and displays it in a tooltip; it called "unsafe" because the HTML is not sanitized. The user is responsible for ensuring the content is safe to put into the DOM!

The tooltip directives provide several optional attributes to control how they will display:

  • tooltip-placement: Where to place it? Defaults to "top", but also accepts "bottom", "left", "right".
  • tooltip-animation: Should it fade in and out? Defaults to "true".
  • tooltip-popup-delay: For how long should the user have to have the mouse over the element before the tooltip shows (in milliseconds)? Defaults to 0.
  • tooltip-trigger: What should trigger a show of the tooltip?
  • tooltip-append-to-body: Should the tooltip be appended to $body instead of the parent element?

The tooltip directives require the $position service.

Triggers

The following show triggers are supported out of the box, along with their provided hide triggers:

  • mouseenter: mouseleave
  • click: click
  • focus: blur

For any non-supported value, the trigger will be used to both show and hide the tooltip.

$tooltipProvider

Through the $tooltipProvider, you can change the way tooltips and popovers behave by default; the attributes above always take precedence. The following methods are available:

  • setTriggers( obj ): Extends the default trigger mappings mentioned above with mappings of your own. E.g. { 'openTrigger': 'closeTrigger' }.
  • options( obj ): Provide a set of defaults for certain tooltip and popover attributes. Currently supports 'placement', 'animation', 'popupDelay', and appendToBody. Here are the defaults:

    placement: 'top',
    animation: true,
    popupDelay: 0,
    appendToBody: false
    

<div ng-controller="TooltipDemoCtrl">
  <div class="well">
    <div>Dynamic Tooltip Text: <input type="text" ng-model="dynamicTooltipText"></div>
    <div>Dynamic Tooltip Popup Text: <input type="text" ng-model="dynamicTooltip"></div>
    <p>
      Pellentesque <a><span tooltip="{{dynamicTooltip}}">{{dynamicTooltipText}}</span></a>,
      sit amet venenatis urna cursus eget nunc scelerisque viverra mauris, in
      aliquam. Tincidunt lobortis feugiat vivamus at 
      <a><span tooltip-placement="left" tooltip="On the Left!">left</span></a> eget
      arcu dictum varius duis at consectetur lorem. Vitae elementum curabitur
      <a><span tooltip-placement="right" tooltip="On the Right!">right</span></a> 
      nunc sed velit dignissim sodales ut eu sem integer vitae. Turpis egestas 
      <a><span tooltip-placement="bottom" tooltip="On the Bottom!">bottom</span></a> 
      pharetra convallis posuere morbi leo urna, 
      <a><span tooltip-animation="false" tooltip="I don't fade. :-(">fading</span></a>
      at elementum eu, facilisis sed odio morbi quis commodo odio. In cursus
      <a><span tooltip-popup-delay='1000' tooltip='appears with delay'>delayed</span></a> turpis massa tincidunt dui ut.
    </p>

    <p>
      I can even contain HTML. <a><span tooltip-html-unsafe="{{htmlTooltip}}">Check me out!</span></a>
    </p>
    <p>
      Or use custom triggers, like focus: 
      <input type="text" value="Click me!"
        tooltip="See? Now click away..." 
        tooltip-trigger="focus"
        tooltip-placement="right" />
    </p>
  </div>
</div>
var TooltipDemoCtrl = function ($scope) {
  $scope.dynamicTooltip = "Hello, World!";
  $scope.dynamicTooltipText = "dynamic";
  $scope.htmlTooltip = "I've been made <b>bold</b>!";
};
Model: {{selected| json}}

Typeahead is a AngularJS version of Twitter Bootstrap typeahead plugin. This directive can be used to quickly create elegant typeheads with any form text input.

It is very well integrated into the AngularJS as it uses subset of the select directive syntax, which is very flexible. Supported expressions:

  • label for value in sourceArray
  • select as label for value in sourceArray

The sourceArray expression can use a special $viewValue variable that corresponds to a value entered inside input by a user.

Also this directive works with promises and it means that you can retrieve matches using the $http service with minimal effort.

The typeahead directives provide several attributes:

  • ng-model : Assignable angular expression to data-bind to

  • typeahead : Comprehension Angular expression (see select directive)

  • typeahead-editable (Defaults: true) : Should it restrict model values to the ones selected from the popup only ?

  • typeahead-input-formatter (Defaults: undefined) : Format the ng-model result after selection

  • typeahead-loading (Defaults: angular.noop) : Binding to a variable that indicates if matches are being retrieved asynchronously

  • typeahead-min-length (Defaults: 1) : Minimal no of characters that needs to be entered before typeahead kicks-in

  • typeahead-on-select (Defaults: null) : A callback executed when a match is selected

  • typeahead-template-url : Set custom item template

  • typeahead-wait-ms (Defaults: 0) : Minimal wait time after last character typed before typehead kicks-in


<div class='container-fluid' ng-controller="TypeaheadCtrl">
    <pre>Model: {{selected| json}}</pre>
    <input type="text" ng-model="selected" typeahead="state for state in states | filter:$viewValue | limitTo:8">
</div>
function TypeaheadCtrl($scope) {

  $scope.selected = undefined;
  $scope.states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Dakota', 'North Carolina', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'];
}