A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from http://angular-ui.github.io/bootstrap/ below:

Angular directives for Bootstrap

Angular 2

For Angular 2 support, check out ng-bootstrap , created by the UI Bootstrap team.

Dependencies

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

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. It should be noted that the -tpls files contain the templates bundled in JavaScript, while the regular version does not contain the bundled templates. For more information, check out the FAQ here and the README 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 fairly small: 122K minified for all directives with templates and 98K without (~31kB with gzip compression, with templates, and 28K gzipped without)

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']);

If you are using UI Bootstrap in the CSP mode, e.g. in an extension, make sure you link to the ui-bootstrap-csp.css in your HTML manually.

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

Migration to prefixes

Since version 0.14.0 we started to prefix all our components. If you are upgrading from ui-bootstrap 0.13.4 or earlier, check our migration guide.

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, .panel-title a { cursor: pointer; }
FAQ

Please check our FAQ section for common problems / solutions.

Reading the documentation

Each of the components provided in ui-bootstrap have documentation and interactive Plunker examples.

For the directives, we list the different attributes with their default values. In addition to this, some settings have a badge on it:

For the services (you will recognize them with the $ prefix), we list all the possible parameters you can pass to them and their default values if any.

* Some directives have a config service that follows the next pattern: uibDirectiveConfig. The service's settings use camel case. The services can be configured in a .config function for example.

Open only one at a time

This content is straight in the template.

{{group.content}}

The body of the uib-accordion group grows to fit the contents

{{item}}

Hello

Custom template with custom header template World

Please, to delete your account, click the button below

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.

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

uib-accordion settings uib-accordion-group settings Accordion heading

Instead of the heading attribute on the uib-accordion-group, you can use an uib-accordion-heading element inside a group that will be used as the group's header.

If you're using a custom template for the uib-accordion-group, you'll need to have an element for the heading to be transcluded into using uib-accordion-header (e.g. <div uib-accordion-header></div>).

Known issues

To use clickable elements within the accordion, you have to override the accordion-group template to use div elements instead of anchor elements, and add cursor: pointer in your CSS. This is due to browsers interpreting anchor elements as the target of any click event, which triggers routing when certain elements such as buttons are nested inside the anchor element.

If custom classes on the accordion-group element are desired, one needs to either modify the template to remove the ng-class usage in the accordion-group template and use ng-class on the accordion-group element (not recommended), or use an interpolated expression in the class attribute, i.e. <uib-accordion-group class="{{customClass()}}"></uib-accordion-group>.

<div ng-controller="AccordionDemoCtrl">
  <script type="text/ng-template" id="group-template.html">
    <div class="panel-heading">
      <h4 class="panel-title" style="color:#fa39c3">
        <a href tabindex="0" class="accordion-toggle" ng-click="toggleOpen()" uib-accordion-transclude="heading">
          <span uib-accordion-header ng-class="{'text-muted': isDisabled}">
            {{heading}}
          </span>
        </a>
      </h4>
    </div>
    <div class="panel-collapse collapse" uib-collapse="!isOpen">
      <div class="panel-body" style="text-align: right" ng-transclude></div>
    </div>
  </script>

  <p>
    <button type="button" class="btn btn-default btn-sm" ng-click="status.open = !status.open">Toggle last panel</button>
    <button type="button" class="btn btn-default btn-sm" ng-click="status.isFirstDisabled = ! status.isFirstDisabled">Enable / Disable first panel</button>
  </p>

  <div class="checkbox">
    <label>
      <input type="checkbox" ng-model="oneAtATime">
      Open only one at a time
    </label>
  </div>
  <uib-accordion close-others="oneAtATime">
    <div uib-accordion-group class="panel-default" heading="Static Header, initially expanded" is-open="status.isFirstOpen" is-disabled="status.isFirstDisabled">
      This content is straight in the template.
    </div>
    <div uib-accordion-group class="panel-default" heading="{{group.title}}" ng-repeat="group in groups">
      {{group.content}}
    </div>
    <div uib-accordion-group class="panel-default" heading="Dynamic Body Content">
      <p>The body of the uib-accordion group grows to fit the contents</p>
      <button type="button" class="btn btn-default btn-sm" ng-click="addItem()">Add Item</button>
      <div ng-repeat="item in items">{{item}}</div>
    </div>
    <div uib-accordion-group class="panel-default" heading="Custom template" template-url="group-template.html">
      Hello
    </div>
    <div uib-accordion-group class="panel-default" is-open="status.isCustomHeaderOpen" template-url="group-template.html">
      <uib-accordion-heading>
        Custom template with custom header template <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.isCustomHeaderOpen, 'glyphicon-chevron-right': !status.isCustomHeaderOpen}"></i>
      </uib-accordion-heading>
      World
    </div>
    <div uib-accordion-group class="panel-danger" heading="Delete account">
      <p>Please, to delete your account, click the button below</p>
      <button class="btn btn-danger">Delete</button>
    </div>
    <div uib-accordion-group class="panel-default" is-open="status.open">
      <uib-accordion-heading>
        I can have markup, too! <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': status.open, 'glyphicon-chevron-right': !status.open}"></i>
      </uib-accordion-heading>
      This is just some content to illustrate fancy headings.
    </div>
  </uib-accordion>
</div>
angular.module('ui.bootstrap.demo').controller('AccordionDemoCtrl', function ($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);
  };

  $scope.status = {
    isCustomHeaderOpen: false,
    isFirstOpen: true,
    isFirstDisabled: false
  };
});

{{alert.msg}}

A happy alert!

This directive can be used both to generate alerts from static and dynamic model data (using the ng-repeat directive).

uib-alert settings
<div ng-controller="AlertDemoCtrl">
  <script type="text/ng-template" id="alert.html">
    <div ng-transclude></div>
  </script>

  <div uib-alert ng-repeat="alert in alerts" ng-class="'alert-' + (alert.type || 'warning')" close="closeAlert($index)">{{alert.msg}}</div>
  <div uib-alert template-url="alert.html" style="background-color:#fa39c3;color:white">A happy alert!</div>
  <button type="button" class='btn btn-default' ng-click="addAlert()">Add Alert</button>
</div>
angular.module('ui.bootstrap.demo').controller('AlertDemoCtrl', function ($scope) {
  $scope.alerts = [
    { type: 'danger', 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
Model: {{checkModel}}
Results: {{checkResults}}

Left Middle Right

Radio & Uncheckable Radio
{{radioModel || 'null'}}

Left Middle Right

Left Middle Right

With the buttons directive, we can make a group of buttons behave like a set of checkboxes (uib-btn-checkbox) or behave like a set of radio buttons (uib-btn-radio).

uib-btn-checkbox settings uib-btn-radio settings Additional settings uibButtonConfig Known issues

To use tooltips or popovers on elements within a btn-group, set the tooltip/popover appendToBody option to true. This is due to Bootstrap CSS styling. See here for more information.

<div ng-controller="ButtonsCtrl">
    <h4>Single toggle</h4>
    <pre>{{singleModel}}</pre>
    <button type="button" class="btn btn-primary" ng-model="singleModel" uib-btn-checkbox btn-checkbox-true="1" btn-checkbox-false="0">
        Single Toggle
    </button>
    <h4>Checkbox</h4>
    <pre>Model: {{checkModel}}</pre>
    <pre>Results: {{checkResults}}</pre>
    <div class="btn-group">
        <label class="btn btn-primary" ng-model="checkModel.left" uib-btn-checkbox>Left</label>
        <label class="btn btn-primary" ng-model="checkModel.middle" uib-btn-checkbox>Middle</label>
        <label class="btn btn-primary" ng-model="checkModel.right" uib-btn-checkbox>Right</label>
    </div>
    <h4>Radio &amp; Uncheckable Radio</h4>
    <pre>{{radioModel || 'null'}}</pre>
    <div class="btn-group">
        <label class="btn btn-primary" ng-model="radioModel" uib-btn-radio="'Left'">Left</label>
        <label class="btn btn-primary" ng-model="radioModel" uib-btn-radio="'Middle'">Middle</label>
        <label class="btn btn-primary" ng-model="radioModel" uib-btn-radio="'Right'">Right</label>
    </div>
    <div class="btn-group">
        <label class="btn btn-success" ng-model="radioModel" uib-btn-radio="'Left'" uncheckable>Left</label>
        <label class="btn btn-success" ng-model="radioModel" uib-btn-radio="'Middle'" uncheckable>Middle</label>
        <label class="btn btn-success" ng-model="radioModel" uib-btn-radio="'Right'" uib-uncheckable="uncheckable">Right</label>
    </div>
    <div>
        <button class="btn btn-default" ng-click="uncheckable = !uncheckable">
            Toggle uncheckable
        </button>
    </div>
</div>
angular.module('ui.bootstrap.demo').controller('ButtonsCtrl', function ($scope) {
  $scope.singleModel = 1;

  $scope.radioModel = 'Middle';

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

  $scope.checkResults = [];

  $scope.$watchCollection('checkModel', function () {
    $scope.checkResults = [];
    angular.forEach($scope.checkModel, function (value, key) {
      if (value) {
        $scope.checkResults.push(key);
      }
    });
  });
});
Slide {{slide.id}}

{{slide.text}}

Interval, in milliseconds:
Enter a negative number or 0 to stop the interval.

Carousel creates a carousel similar to bootstrap's image carousel.

The carousel also offers support for touchscreen devices in the form of swiping. To enable swiping, load the ngTouch module as a dependency.

Use a <uib-carousel> element with <uib-slide> elements inside it.

uib-carousel settings uib-slide settings
<div ng-controller="CarouselDemoCtrl">
  <div style="height: 305px">
    <div uib-carousel active="active" interval="myInterval" no-wrap="noWrapSlides">
      <div uib-slide ng-repeat="slide in slides track by slide.id" index="slide.id">
        <img ng-src="{{slide.image}}" style="margin:auto;">
        <div class="carousel-caption">
          <h4>Slide {{slide.id}}</h4>
          <p>{{slide.text}}</p>
        </div>
      </div>
    </div>
  </div>
  <div class="row">
    <div class="col-md-6">
      <button type="button" class="btn btn-info" ng-click="addSlide()">Add Slide</button>
      <button type="button" class="btn btn-info" ng-click="randomize()">Randomize slides</button>
      <div class="checkbox">
        <label>
          <input type="checkbox" ng-model="noWrapSlides">
          Disable Slide Looping
        </label>
      </div>
    </div>
    <div class="col-md-6">
      Interval, in milliseconds: <input type="number" class="form-control" ng-model="myInterval">
      <br />Enter a negative number or 0 to stop the interval.
    </div>
  </div>
</div>
angular.module('ui.bootstrap.demo').controller('CarouselDemoCtrl', function ($scope) {
  $scope.myInterval = 5000;
  $scope.noWrapSlides = false;
  $scope.active = 0;
  var slides = $scope.slides = [];
  var currIndex = 0;

  $scope.addSlide = function() {
    var newWidth = 600 + slides.length + 1;
    slides.push({
      image: '//unsplash.it/' + newWidth + '/300',
      text: ['Nice image','Awesome photograph','That is so cool','I love that'][slides.length % 4],
      id: currIndex++
    });
  };

  $scope.randomize = function() {
    var indexes = generateIndexesArray();
    assignNewIndexesToSlides(indexes);
  };

  for (var i = 0; i < 4; i++) {
    $scope.addSlide();
  }

  // Randomize logic below

  function assignNewIndexesToSlides(indexes) {
    for (var i = 0, l = slides.length; i < l; i++) {
      slides[i].id = indexes.pop();
    }
  }

  function generateIndexesArray() {
    var indexes = [];
    for (var i = 0; i < currIndex; ++i) {
      indexes[i] = i;
    }
    return shuffle(indexes);
  }

  // http://stackoverflow.com/questions/962802#962890
  function shuffle(array) {
    var tmp, current, top = array.length;

    if (top) {
      while (--top) {
        current = Math.floor(Math.random() * (top + 1));
        tmp = array[current];
        array[current] = array[top];
        array[top] = tmp;
      }
    }

    return array;
  }
});

Resize window to less than 768 pixels to display mobile menu toggle button.

uib-collapse provides a simple way to hide and show an element with a css transition

uib-collapse settings Known Issues

When using the horizontal attribute with this directive, CSS can reflow as the collapse element goes from 0px to its desired end width, which can result in height changes. This can cause animations to not appear to run. The best way around this is to set a fixed height via CSS on the horizontal collapse element so that this situation does not occur, and so the animation can run as expected.

<style>
  .horizontal-collapse {
    height: 70px;
  }
  .navbar-collapse.in {
    overflow-y: hidden;
  }
</style>
<div ng-controller="CollapseDemoCtrl">
	<p>Resize window to less than 768 pixels to display mobile menu toggle button.</p>
	<nav class="navbar navbar-default" role="navigation">
		<div class="navbar-header">
			<button type="button" class="navbar-toggle" ng-click="isNavCollapsed = !isNavCollapsed">
				<span class="sr-only">Toggle navigation</span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
				<span class="icon-bar"></span>
			</button>
			<a class="navbar-brand" href="#">A menu</a>
		</div>
		<div class="collapse navbar-collapse" uib-collapse="isNavCollapsed">
			<ul class="nav navbar-nav">
				<li><a href="#">Link 1</a></li>
				<li><a href="#">Link 2</a></li>
			</ul>
		</div>
	</nav>
	<hr>
	<button type="button" class="btn btn-default" ng-click="isCollapsed = !isCollapsed">Toggle collapse Vertically</button>
	<hr>
	<div uib-collapse="isCollapsed">
		<div class="well well-lg">Some content</div>
	</div>

	<button type="button" class="btn btn-default" ng-click="isCollapsedHorizontal = !isCollapsedHorizontal">Toggle collapse Horizontally</button>
	<hr>
	<div class="horizontal-collapse" uib-collapse="isCollapsedHorizontal" horizontal>
		<div class="well well-lg">Some content</div>
	</div>
</div>
angular.module('ui.bootstrap.demo').controller('CollapseDemoCtrl', function ($scope) {
  $scope.isNavCollapsed = true;
  $scope.isCollapsed = false;
  $scope.isCollapsedHorizontal = false;
});
Formatting codes playground

Define your format

Result

The uibDateParser is what the uib-datepicker uses internally to parse the dates. You can use it standalone by injecting the uibDateParser service where you need it.

The public API for the dateParser is a single method called parse.

Certain format codes support i18n. Check this guide for more information.

uibDateParser's parse function parameters return uibDateParser's format codes

* The ones marked with Leading 0, needs a leading 0 for values less than 10. Exception being milliseconds which needs it for values under 100.

** It also supports fullDate|longDate|medium|mediumDate|mediumTime|short|shortDate|shortTime as the format for parsing.

*** It supports template literals as a string between the single quote ' character, i.e. 'The Date is' MM/DD/YYYY. If one wants the literal single quote character, one must use ''''.

<div ng-controller="DateParserDemoCtrl">
  <h4>Formatting codes playground</h4>
  <p class="form-group">
    <label>Define your format</label>
    <input type="text" ng-model="format" class="form-control">
  </p>
  <p class="form-group">
    <label>Result</label>
    <input type="text" class="form-control" uib-datepicker-popup="{{format}}" ng-model="date" />
  </p>
</div>
angular.module('ui.bootstrap.demo').controller('DateParserDemoCtrl', function ($scope, uibDateParser) {
  $scope.format = 'yyyy/MM/dd';
  $scope.date = new Date();
});
Selected date is: {{dt | date:'fullDate' }}
Inline

Our datepicker is flexible and fully customizable.

You can navigate through days, months and years.

The datepicker has 3 modes:

uib-datepicker settings

Apart from the previous settings, to configure the uib-datepicker you need to create an object in Javascript with all the options and use it on the datepicker-options attribute:

Keyboard support

Depending on datepicker's current mode, the date may refer either to day, month or year. Accordingly, the term view refers either to a month, year or year range.

Notes

If the date a user enters falls outside of the min-/max-date range, a dateDisabled validation error will show on the form.

<style>
  .full button span {
    background-color: limegreen;
    border-radius: 32px;
    color: black;
  }
  .partially button span {
    background-color: orange;
    border-radius: 32px;
    color: black;
  }
</style>
<div ng-controller="DatepickerDemoCtrl">
    <pre>Selected date is: <em>{{dt | date:'fullDate' }}</em></pre>

    <h4>Inline</h4>
    <div style="display:inline-block; min-height:290px;">
      <div uib-datepicker ng-model="dt" class="well well-sm" datepicker-options="options"></div>
    </div>

    <hr />
    <button type="button" class="btn btn-sm btn-info" ng-click="today()">Today</button>
    <button type="button" class="btn btn-sm btn-default" ng-click="setDate(2009, 7, 24)">2009-08-24</button>
    <button type="button" class="btn btn-sm btn-danger" ng-click="clear()">Clear</button>
    <button type="button" class="btn btn-sm btn-default" ng-click="toggleMin()" uib-tooltip="After today restriction">Min date</button>
</div>
angular.module('ui.bootstrap.demo').controller('DatepickerDemoCtrl', function ($scope) {
  $scope.today = function() {
    $scope.dt = new Date();
  };
  $scope.today();

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

  $scope.options = {
    customClass: getDayClass,
    minDate: new Date(),
    showWeeks: true
  };

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

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

  $scope.toggleMin();

  $scope.setDate = function(year, month, day) {
    $scope.dt = new Date(year, month, day);
  };

  var tomorrow = new Date();
  tomorrow.setDate(tomorrow.getDate() + 1);
  var afterTomorrow = new Date(tomorrow);
  afterTomorrow.setDate(tomorrow.getDate() + 1);
  $scope.events = [
    {
      date: tomorrow,
      status: 'full'
    },
    {
      date: afterTomorrow,
      status: 'partially'
    }
  ];

  function getDayClass(data) {
    var date = data.date,
      mode = data.mode;
    if (mode === 'day') {
      var dayToCheck = new Date(date).setHours(0,0,0,0);

      for (var i = 0; i < $scope.events.length; i++) {
        var currentDay = new Date($scope.events[i].date).setHours(0,0,0,0);

        if (dayToCheck === currentDay) {
          return $scope.events[i].status;
        }
      }
    }

    return '';
  }
});

Dropdown is a simple directive which will toggle a dropdown menu on click or programmatically.

This directive is composed by three parts:

Each of these parts need to be used as attribute directives.

uib-dropdown settings Additional settings uibDropdownConfig Known issues

For usage with ngTouch, it is recommended to use the programmatic is-open trigger with ng-click - this is due to ngTouch decorating ng-click to prevent propagation of the event.


<div ng-controller="DropdownCtrl">
    <!-- Simple dropdown -->
    <span uib-dropdown on-toggle="toggled(open)">
      <a href id="simple-dropdown" uib-dropdown-toggle>
        Click me for a dropdown, yo!
      </a>
      <ul class="dropdown-menu" uib-dropdown-menu aria-labelledby="simple-dropdown">
        <li ng-repeat="choice in items">
          <a href>{{choice}}</a>
        </li>
      </ul>
    </span>

    <!-- Single button -->
    <div class="btn-group" uib-dropdown is-open="status.isopen">
      <button id="single-button" type="button" class="btn btn-primary" uib-dropdown-toggle ng-disabled="disabled">
        Button dropdown <span class="caret"></span>
      </button>
      <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="single-button">
        <li role="menuitem"><a href="#">Action</a></li>
        <li role="menuitem"><a href="#">Another action</a></li>
        <li role="menuitem"><a href="#">Something else here</a></li>
        <li class="divider"></li>
        <li role="menuitem"><a href="#">Separated link</a></li>
      </ul>
    </div>

    <!-- Split button -->
    <div class="btn-group" uib-dropdown>
      <button id="split-button" type="button" class="btn btn-danger">Action</button>
      <button type="button" class="btn btn-danger" uib-dropdown-toggle>
        <span class="caret"></span>
        <span class="sr-only">Split button!</span>
      </button>
      <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="split-button">
        <li role="menuitem"><a href="#">Action</a></li>
        <li role="menuitem"><a href="#">Another action</a></li>
        <li role="menuitem"><a href="#">Something else here</a></li>
        <li class="divider"></li>
        <li role="menuitem"><a href="#">Separated link</a></li>
      </ul>
    </div>

    <!-- Single button using append-to-body -->
    <div class="btn-group" uib-dropdown dropdown-append-to-body>
      <button id="btn-append-to-body" type="button" class="btn btn-primary" uib-dropdown-toggle>
        Dropdown on Body <span class="caret"></span>
      </button>
      <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="btn-append-to-body">
        <li role="menuitem"><a href="#">Action</a></li>
        <li role="menuitem"><a href="#">Another action</a></li>
        <li role="menuitem"><a href="#">Something else here</a></li>
        <li class="divider"></li>
        <li role="menuitem"><a href="#">Separated link</a></li>
      </ul>
    </div>

    <!-- Single button using template-url -->
    <div class="btn-group" uib-dropdown>
      <button id="button-template-url" type="button" class="btn btn-primary" uib-dropdown-toggle ng-disabled="disabled">
        Dropdown using template <span class="caret"></span>
      </button>
      <ul class="dropdown-menu" uib-dropdown-menu template-url="dropdown.html" aria-labelledby="button-template-url">
      </ul>
    </div>

    <hr />
    <p>
        <button type="button" class="btn btn-default btn-sm" ng-click="toggleDropdown($event)">Toggle button dropdown</button>
        <button type="button" class="btn btn-warning btn-sm" ng-click="disabled = !disabled">Enable/Disable</button>
    </p>

    <hr>
    <!-- Single button with keyboard nav -->
    <div class="btn-group" uib-dropdown keyboard-nav>
        <button id="simple-btn-keyboard-nav" type="button" class="btn btn-primary" uib-dropdown-toggle>
            Dropdown with keyboard navigation <span class="caret"></span>
        </button>
        <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="simple-btn-keyboard-nav">
            <li role="menuitem"><a href="#">Action</a></li>
            <li role="menuitem"><a href="#">Another action</a></li>
            <li role="menuitem"><a href="#">Something else here</a></li>
            <li class="divider"></li>
            <li role="menuitem"><a href="#">Separated link</a></li>
        </ul>
    </div>

    <hr>
    <!-- AppendTo use case -->
    <h4>append-to vs. append-to-body vs. inline example</h4>
    <div id="dropdown-scrollable-container" style="height: 15em; overflow: auto;">
      <div id="dropdown-long-content">
        <div id="dropdown-hidden-container">
          <div class="btn-group" uib-dropdown keyboard-nav dropdown-append-to="appendToEl">
            <button id="btn-append-to" type="button" class="btn btn-primary" uib-dropdown-toggle>
              Dropdown in Container <span class="caret"></span>
            </button>
            <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="btn-append-to">
              <li role="menuitem"><a href="#">Action</a></li>
              <li role="menuitem"><a href="#">Another action</a></li>
              <li role="menuitem"><a href="#">Something else here</a></li>
              <li class="divider"></li>
              <li role="menuitem"><a href="#">Separated link</a></li>
            </ul>
          </div>
          <div class="btn-group" uib-dropdown dropdown-append-to-body>
            <button id="btn-append-to-to-body" type="button" class="btn btn-primary" uib-dropdown-toggle>
              Dropdown on Body <span class="caret"></span>
            </button>
            <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="btn-append-to-to-body">
              <li role="menuitem"><a href="#">Action</a></li>
              <li role="menuitem"><a href="#">Another action</a></li>
              <li role="menuitem"><a href="#">Something else here</a></li>
              <li class="divider"></li>
              <li role="menuitem"><a href="#">Separated link</a></li>
            </ul>
          </div>
          <div class="btn-group" uib-dropdown>
            <button id="btn-append-to-single-button" type="button" class="btn btn-primary" uib-dropdown-toggle>
              Inline Dropdown <span class="caret"></span>
            </button>
            <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="btn-append-to-single-button">
              <li role="menuitem"><a href="#">Action</a></li>
              <li role="menuitem"><a href="#">Another action</a></li>
              <li role="menuitem"><a href="#">Something else here</a></li>
              <li class="divider"></li>
              <li role="menuitem"><a href="#">Separated link</a></li>
            </ul>
          </div>
        </div>
      </div>
    </div>

    <script type="text/ng-template" id="dropdown.html">
        <ul class="dropdown-menu" uib-dropdown-menu role="menu" aria-labelledby="button-template-url">
          <li role="menuitem"><a href="#">Action in Template</a></li>
          <li role="menuitem"><a href="#">Another action in Template</a></li>
          <li role="menuitem"><a href="#">Something else here</a></li>
          <li class="divider"></li>
          <li role="menuitem"><a href="#">Separated link in Template</a></li>
        </ul>
    </script>
</div>
angular.module('ui.bootstrap.demo').controller('DropdownCtrl', function ($scope, $log) {
  $scope.items = [
    'The first choice!',
    'And another choice for you.',
    'but wait! A third!'
  ];

  $scope.status = {
    isopen: false
  };

  $scope.toggled = function(open) {
    $log.log('Dropdown is now: ', open);
  };

  $scope.toggleDropdown = function($event) {
    $event.preventDefault();
    $event.stopPropagation();
    $scope.status.isopen = !$scope.status.isopen;
  };

  $scope.appendToEl = angular.element(document.querySelector('#dropdown-long-content'));
});

Selection from a modal: {{ $ctrl.selected }}

$uibModal is a service to create modal windows. Creating modals is straightforward: create a template and controller, and reference them when using $uibModal.

The $uibModal service has only one method: open(options).

$uibModal's open function options parameter

Global defaults may be set for $uibModal via $uibModalProvider.options.

return

The open method returns a modal instance, an object with the following properties:

The scope associated with modal's content is augmented with:

Those methods make it easy to close a modal window without a need to create a dedicated controller.

Also, when using bindToController, you can define an $onInit method in the controller that will fire upon initialization.

Events fired:

UI Router resolves

If one wants to have the modal resolve using UI Router's pre-1.0 resolve mechanism, one can call $uibResolve.setResolver('$resolve') in the configuration phase of the application. One can also provide a custom resolver as well, as long as the signature conforms to UI Router's $resolve.

When the modal is opened with a controller, a $resolve object is exposed on the template with the resolved values from the resolve object. If using the component option, see details on how to access this object in component section of the modal documentation.

<div ng-controller="ModalDemoCtrl as $ctrl" class="modal-demo">
    <script type="text/ng-template" id="myModalContent.html">
        <div class="modal-header">
            <h3 class="modal-title" id="modal-title">I'm a modal!</h3>
        </div>
        <div class="modal-body" id="modal-body">
            <ul>
                <li ng-repeat="item in $ctrl.items">
                    <a href="#" ng-click="$event.preventDefault(); $ctrl.selected.item = item">{{ item }}</a>
                </li>
            </ul>
            Selected: <b>{{ $ctrl.selected.item }}</b>
        </div>
        <div class="modal-footer">
            <button class="btn btn-primary" type="button" ng-click="$ctrl.ok()">OK</button>
            <button class="btn btn-warning" type="button" ng-click="$ctrl.cancel()">Cancel</button>
        </div>
    </script>
    <script type="text/ng-template" id="stackedModal.html">
        <div class="modal-header">
            <h3 class="modal-title" id="modal-title-{{name}}">The {{name}} modal!</h3>
        </div>
        <div class="modal-body" id="modal-body-{{name}}">
            Having multiple modals open at once is probably bad UX but it's technically possible.
        </div>
    </script>

    <button type="button" class="btn btn-default" ng-click="$ctrl.open()">Open me!</button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.open('lg')">Large modal</button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.open('sm')">Small modal</button>
    <button type="button" 
        class="btn btn-default" 
        ng-click="$ctrl.open('sm', '.modal-parent')">
            Modal appended to a custom parent
    </button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.toggleAnimation()">Toggle Animation ({{ $ctrl.animationsEnabled }})</button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.openComponentModal()">Open a component modal!</button>
    <button type="button" class="btn btn-default" ng-click="$ctrl.openMultipleModals()">
        Open multiple modals at once 
    </button>
    <div ng-show="$ctrl.selected">Selection from a modal: {{ $ctrl.selected }}</div>
    <div class="modal-parent">
    </div>
</div>
angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($uibModal, $log, $document) {
  var $ctrl = this;
  $ctrl.items = ['item1', 'item2', 'item3'];

  $ctrl.animationsEnabled = true;

  $ctrl.open = function (size, parentSelector) {
    var parentElem = parentSelector ? 
      angular.element($document[0].querySelector('.modal-demo ' + parentSelector)) : undefined;
    var modalInstance = $uibModal.open({
      animation: $ctrl.animationsEnabled,
      ariaLabelledBy: 'modal-title',
      ariaDescribedBy: 'modal-body',
      templateUrl: 'myModalContent.html',
      controller: 'ModalInstanceCtrl',
      controllerAs: '$ctrl',
      size: size,
      appendTo: parentElem,
      resolve: {
        items: function () {
          return $ctrl.items;
        }
      }
    });

    modalInstance.result.then(function (selectedItem) {
      $ctrl.selected = selectedItem;
    }, function () {
      $log.info('Modal dismissed at: ' + new Date());
    });
  };

  $ctrl.openComponentModal = function () {
    var modalInstance = $uibModal.open({
      animation: $ctrl.animationsEnabled,
      component: 'modalComponent',
      resolve: {
        items: function () {
          return $ctrl.items;
        }
      }
    });

    modalInstance.result.then(function (selectedItem) {
      $ctrl.selected = selectedItem;
    }, function () {
      $log.info('modal-component dismissed at: ' + new Date());
    });
  };

  $ctrl.openMultipleModals = function () {
    $uibModal.open({
      animation: $ctrl.animationsEnabled,
      ariaLabelledBy: 'modal-title-bottom',
      ariaDescribedBy: 'modal-body-bottom',
      templateUrl: 'stackedModal.html',
      size: 'sm',
      controller: function($scope) {
        $scope.name = 'bottom';  
      }
    });

    $uibModal.open({
      animation: $ctrl.animationsEnabled,
      ariaLabelledBy: 'modal-title-top',
      ariaDescribedBy: 'modal-body-top',
      templateUrl: 'stackedModal.html',
      size: 'sm',
      controller: function($scope) {
        $scope.name = 'top';  
      }
    });
  };

  $ctrl.toggleAnimation = function () {
    $ctrl.animationsEnabled = !$ctrl.animationsEnabled;
  };
});

// Please note that $uibModalInstance represents a modal window (instance) dependency.
// It is not the same as the $uibModal service used above.

angular.module('ui.bootstrap.demo').controller('ModalInstanceCtrl', function ($uibModalInstance, items) {
  var $ctrl = this;
  $ctrl.items = items;
  $ctrl.selected = {
    item: $ctrl.items[0]
  };

  $ctrl.ok = function () {
    $uibModalInstance.close($ctrl.selected.item);
  };

  $ctrl.cancel = function () {
    $uibModalInstance.dismiss('cancel');
  };
});

// Please note that the close and dismiss bindings are from $uibModalInstance.

angular.module('ui.bootstrap.demo').component('modalComponent', {
  templateUrl: 'myModalContent.html',
  bindings: {
    resolve: '<',
    close: '&',
    dismiss: '&'
  },
  controller: function () {
    var $ctrl = this;

    $ctrl.$onInit = function () {
      $ctrl.items = $ctrl.resolve.items;
      $ctrl.selected = {
        item: $ctrl.items[0]
      };
    };

    $ctrl.ok = function () {
      $ctrl.close({$value: $ctrl.selected.item});
    };

    $ctrl.cancel = function () {
      $ctrl.dismiss({$value: 'cancel'});
    };
  }
});
Dynamic

Popup Text:

Popup Title:

Popup Template:

Positional Triggers Other

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

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

Note to mobile developers: Please note that while popovers may work correctly on mobile devices (including tablets), we have made the decision to not officially support such a use-case because it does not make sense from a UX perspective.

There are three versions of the popover: uib-popover and uib-popover-template, and uib-popover-html:

uib-popover-* settings

All these settings are available for the three types of popovers.

Note: To configure the tooltips, you need to do it on $uibTooltipProvider (also see below).

Triggers

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

The outsideClick trigger will cause the popover to toggle on click, and hide when anything else is clicked.

For any non-supported value, the trigger will be used to both show and hide the popover. Using the 'none' trigger will disable the internal trigger(s), one can then use the popover-is-open attribute exclusively to show and hide the popover.

$uibTooltipProvider

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

Known issues

For Safari 7+ support, if you want to use focus popover-trigger, you need to use an anchor tag with a tab index. For example:

<a tabindex="0" uib-popover="Test" popover-trigger="focus" class="btn btn-default">
  Click Me
</a>
<div ng-controller="PopoverDemoCtrl">
    <h4>Dynamic</h4>
    <div class="form-group">
      <label>Popup Text:</label>
      <input type="text" ng-model="dynamicPopover.content" class="form-control">
    </div>
    <div class="form-group">
      <label>Popup Title:</label>
      <input type="text" ng-model="dynamicPopover.title" class="form-control">
    </div>
    <div class="form-group">
      <label>Popup Template:</label>
      <input type="text" ng-model="dynamicPopover.templateUrl" class="form-control">
    </div>
    <button uib-popover="{{dynamicPopover.content}}" popover-title="{{dynamicPopover.title}}" type="button" class="btn btn-default">Dynamic Popover</button>

    <button uib-popover-template="dynamicPopover.templateUrl" popover-title="{{dynamicPopover.title}}" type="button" class="btn btn-default">Popover With Template</button>

    <script type="text/ng-template" id="myPopoverTemplate.html">
        <div>{{dynamicPopover.content}}</div>
        <div class="form-group">
          <label>Popup Title:</label>
          <input type="text" ng-model="dynamicPopover.title" class="form-control">
        </div>
    </script>
    <hr />
    <h4>Positional</h4>
    <div class="form-group">
      <label>Popover placement</label>
      <select class="form-control" ng-model="placement.selected" ng-options="o as o for o in placement.options"></select>
    </div>
    <button popover-placement="{{placement.selected}}" uib-popover="On the {{placement.selected}}" type="button" class="btn btn-default">Popover {{placement.selected}}</button>

    <hr />
    <h4>Triggers</h4>
    <p>
      <button uib-popover="I appeared on mouse enter!" popover-trigger="'mouseenter'" type="button" class="btn btn-default">Mouseenter</button>
    </p>
    <input type="text" value="Click me!" uib-popover="I appeared on focus! Click away and I'll vanish..."  popover-trigger="'focus'" class="form-control">

    <hr />
    <h4>Other</h4>
    <button popover-animation="true" uib-popover="I fade in and out!" type="button" class="btn btn-default">fading</button>
    <button uib-popover="I have a title!" popover-title="The title." type="button" class="btn btn-default">title</button>
    <button uib-popover="I am activated manually" popover-is-open="popoverIsOpen" ng-click="popoverIsOpen = !popoverIsOpen" type="button" class="btn btn-default">Toggle popover</button>
    <button uib-popover-html="htmlPopover" class="btn btn-default">HTML Popover</button>
    <button uib-popover-html="'<b>HTML</b>, <i>inline</i>'" class="btn btn-default">HTML Popover (inline)</button>
</div>
angular.module('ui.bootstrap.demo').controller('PopoverDemoCtrl', function ($scope, $sce) {
  $scope.dynamicPopover = {
    content: 'Hello, World!',
    templateUrl: 'myPopoverTemplate.html',
    title: 'Title'
  };

  $scope.placement = {
    options: [
      'top',
      'top-left',
      'top-right',
      'bottom',
      'bottom-left',
      'bottom-right',
      'left',
      'left-top',
      'left-bottom',
      'right',
      'right-top',
      'right-bottom'
    ],
    selected: 'top'
  };
  
  $scope.htmlPopover = $sce.trustAsHtml('<b style="color: red">I can</b> have <div class="label label-success">HTML</div> content');
});
$uibPosition service

Parent scrollable

Parent relative

Demo element

offsetParent: {{elemVals.offsetParent}}

scrollParent: {{elemVals.scrollParent}}

scrollbarWidth: {{scrollbarWidth}}

position: {{elemVals.position}}

offset: {{elemVals.offset}}

viewportOffset: {{elemVals.viewportOffset}}

positionElements: {{elemVals.positionElements}}

The $uibPosition service provides a set of DOM utilities used internally to absolute-position an element in relation to another element (tooltips, popovers, typeaheads etc...).

getRawNode(element)

Takes a jQuery/jqLite element and converts it to a raw DOM element.

parameters returns parseStyle(element)

Parses a numeric style value to a number. Strips units and will return 0 for invalid (NaN) numbers.

parameters returns offsetParent(element)

Gets the closest positioned ancestor.

parameters returns scrollbarWidth(isBody)

Calculates the browser scrollbar width and caches the result for future calls. Concept from the TWBS measureScrollbar() function in modal.js.

parameters returns scrollbarPadding(element)

Calculates the padding required to replace the scrollbar on an element.

parameters returns

An object with the following properties:

isScrollable(element, includeHidden)

Determines if an element is scrollable.

parameters returns scrollParent(element, includeHidden, includeSelf)

Gets the closest scrollable ancestor. Concept from the jQueryUI scrollParent.js.

parameters returns position(element, includeMargins)

A read-only equivalent of jQuery's position function, distance to closest positioned ancestor. Does not account for margins by default like jQuery's position.

parameters returns

An object with the following properties:

offset(element)

A read-only equivalent of jQuery's offset function, distance to viewport.

parameters returns

An object with the following properties:

viewportOffset(element, useDocument, includePadding)

Gets the elements available space relative to the closest scrollable ancestor. Accounts for padding, border, and scrollbar width. Right and bottom dimensions represent the distance to the respective edge of the viewport element, not the top and left edge. If the element edge extends beyond the viewport, a negative value will be reported.

parameters returns

An object with the following properties:

parsePlacement(placement)

Gets an array of placement values parsed from a placement string. Along with the 'auto' indicator, supported placement strings are:

A placement string with an 'auto' indicator is expected to be space separated from the placement, i.e: 'auto bottom-left'. If the primary and secondary placement values do not match 'top, bottom, left, right' then 'top' will be the primary placement and 'center' will be the secondary placement. If 'auto' is passed, true will be returned as the 3rd value of the array.

parameters returns

An array with the following values:

positionElements(hostElement, targetElement, placement, appendToBody)

Gets gets coordinates for an element to be positioned relative to another element.

parameters returns

An object with the following properties:

positionArrow(element, placement)

Positions the tooltip and popover arrow elements when using placement options beyond the standard top, left, bottom, or right.

parameters
<div ng-controller="PositionDemoCtrl">
  <h4>$uibPosition service</h4>
  <div id="posdemoparent" ng-style="{'overflow': (parentScrollable && 'scroll'), 'position': (parentRelative && 'relative')}" style="border: 1px solid #ccc; padding: 15px;">
    <div class="checkbox">
      <label>
        <input type="checkbox" ng-model="parentScrollable"> Parent scrollable
      </label>
    </div>
    <div class="checkbox">
      <label>
        <input type="checkbox" ng-model="parentRelative"> Parent relative
      </label>
    </div>
    <button id="posdemobtn" class="btn btn-default" ng-click="getValues()">Get values</button>

    <div id="posdemodiv" style="width: 100px; height: 100px; margin: 15px 0; padding: 10px; background-color: #f8f8f8; border: 1px solid #ccc;">
      Demo element
    </div>
  </div>
  <br />
  offsetParent: {{elemVals.offsetParent}}
  <br />
  scrollParent: {{elemVals.scrollParent}}
  <br />
  scrollbarWidth: {{scrollbarWidth}}
  <br />
  position: {{elemVals.position}}
  <br />
  offset: {{elemVals.offset}}
  <br />
  viewportOffset: {{elemVals.viewportOffset}}
  <br />
  positionElements: {{elemVals.positionElements}}
</div>
angular.module('ui.bootstrap.demo').controller('PositionDemoCtrl', function ($scope, $window, $uibPosition) {

    $scope.elemVals = {};
    $scope.parentScrollable = true;
    $scope.parentRelative = true;

    $scope.getValues = function() {
      var divEl = $window.document.querySelector('#posdemodiv');
      var btnEl = $window.document.querySelector('#posdemobtn');

      var offsetParent = $uibPosition.offsetParent(divEl);
      $scope.elemVals.offsetParent = 'type: ' + offsetParent.tagName + ', id: ' + offsetParent.id;

      var scrollParent = $uibPosition.scrollParent(divEl);
      $scope.elemVals.scrollParent = 'type: ' + scrollParent.tagName + ', id: ' + scrollParent.id;

      $scope.scrollbarWidth = $uibPosition.scrollbarWidth();

      $scope.elemVals.position = $uibPosition.position(divEl);

      $scope.elemVals.offset = $uibPosition.offset(divEl);

      $scope.elemVals.viewportOffset = $uibPosition.viewportOffset(divEl);

      $scope.elemVals.positionElements = $uibPosition.positionElements(btnEl, divEl, 'auto bottom-left');
    };
});
Static Dynamic {{dynamic}} / {{max}} No animation {{dynamic}}% Object (changes type based on value) {{type}} !!! Watch out !!! Stacked {{bar.value}}%

A progress bar directive that is focused on providing feedback on the progress of a workflow or action.

It supports multiple (stacked) <uib-bar> into the same <uib-progress> element or a single <uib-progressbar> element with optional max attribute and transition animations.

uib-progressbar settings uib-progress settings uib-bar settings
<div ng-controller="ProgressDemoCtrl">

    <h3>Static</h3>
    <div class="row">
        <div class="col-sm-4"><uib-progressbar value="55"></uib-progressbar></div>
        <div class="col-sm-4"><uib-progressbar class="progress-striped" value="22" type="warning">22%</uib-progressbar></div>
        <div class="col-sm-4"><uib-progressbar class="progress-striped active" max="200" value="166" type="danger"><i>166 / 200</i></uib-progressbar></div>
    </div>

    <hr />
    <h3>Dynamic <button type="button" class="btn btn-sm btn-primary" ng-click="random()">Randomize</button></h3>
    <uib-progressbar max="max" value="dynamic"><span style="color:white; white-space:nowrap;">{{dynamic}} / {{max}}</span></uib-progressbar>
    
    <small><em>No animation</em></small>
    <uib-progressbar animate="false" value="dynamic" type="success"><b>{{dynamic}}%</b></uib-progressbar>

    <small><em>Object (changes type based on value)</em></small>
    <uib-progressbar class="progress-striped active" value="dynamic" type="{{type}}">{{type}} <i ng-show="showWarning">!!! Watch out !!!</i></uib-progressbar>
    
    <hr />
    <h3>Stacked <button type="button" class="btn btn-sm btn-primary" ng-click="randomStacked()">Randomize</button></h3>
    <uib-progress><uib-bar ng-repeat="bar in stacked track by $index" value="bar.value" type="{{bar.type}}"><span ng-hide="bar.value < 5">{{bar.value}}%</span></uib-bar></uib-progress>

</div>
angular.module('ui.bootstrap.demo').controller('ProgressDemoCtrl', function ($scope) {
  $scope.max = 200;

  $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.showWarning = type === 'danger' || type === 'warning';

    $scope.dynamic = value;
    $scope.type = type;
  };

  $scope.random();

  $scope.randomStacked = function() {
    $scope.stacked = [];
    var types = ['success', 'info', 'warning', 'danger'];

    for (var i = 0, n = Math.floor(Math.random() * 4 + 1); i < n; i++) {
        var index = Math.floor(Math.random() * 4);
        $scope.stacked.push({
          value: Math.floor(Math.random() * 30 + 1),
          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.

uib-rating settings
<div ng-controller="RatingDemoCtrl">
    <h4>Default</h4>
    <span uib-rating ng-model="rate" max="max" read-only="isReadonly" on-hover="hoveringOver(value)" on-leave="overStar = null" titles="['one','two','three']" aria-labelledby="default-rating"></span>
    <span class="label" ng-class="{'label-warning': percent<30, 'label-info': percent>=30 && percent<70, 'label-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 type="button" class="btn btn-sm btn-danger" ng-click="rate = 0" ng-disabled="isReadonly">Clear</button>
    <button type="button" class="btn btn-sm btn-default" ng-click="isReadonly = ! isReadonly">Toggle Readonly</button>
    <hr />

    <h4>Custom icons</h4>
    <div ng-init="x = 5"><span uib-rating ng-model="x" max="15" state-on="'glyphicon-ok-sign'" state-off="'glyphicon-ok-circle'" aria-labelledby="custom-icons-1"></span> <b>(<i>Rate:</i> {{x}})</b></div>
    <div ng-init="y = 2"><span uib-rating ng-model="y" rating-states="ratingStates" aria-labelledby="custom-icons-2"></span> <b>(<i>Rate:</i> {{y}})</b></div>
</div>
angular.module('ui.bootstrap.demo').controller('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: 'glyphicon-ok-sign', stateOff: 'glyphicon-ok-circle'},
    {stateOn: 'glyphicon-star', stateOff: 'glyphicon-star-empty'},
    {stateOn: 'glyphicon-heart', stateOff: 'glyphicon-ban-circle'},
    {stateOn: 'glyphicon-heart'},
    {stateOff: 'glyphicon-off'}
  ];
});

Select a tab by setting active binding to true:

Static content {{tab.content}} Alert! I've got an HTML heading, and a select callback. Pretty cool! Vertical content 1 Vertical content 2 Justified content Short Labeled Justified content Long Labeled Justified content

Tabbed pills with CSS classes

Tab 1 content Tab 2 content

Tabs using nested forms:

Model:

{{ model | json }}

Nested Form:

{{ outerForm.nestedForm | json }}

AngularJS version of the tabs directive.

uib-tabset settings uib-tab settings Tabset heading

Instead of the heading attribute on the uib-tabset, you can use an uib-tab-heading element inside a tabset that will be used as the tabset's header. There you can use HTML as well.

Known issues

To use clickable elements within the tab, you have override the tab template to use div elements instead of anchor elements, and replicate the desired styles from Bootstrap's CSS. This is due to browsers interpreting anchor elements as the target of any click event, which triggers routing when certain elements such as buttons are nested inside the anchor element.

<style type="text/css">
  form.tab-form-demo .tab-pane {
    margin: 20px 20px;
  }
</style>

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

  <uib-tabset active="active">
    <uib-tab index="0" heading="Static title">Static content</uib-tab>
    <uib-tab index="$index + 1" ng-repeat="tab in tabs" heading="{{tab.title}}" disable="tab.disabled">
      {{tab.content}}
    </uib-tab>
    <uib-tab index="3" select="alertMe()">
      <uib-tab-heading>
        <i class="glyphicon glyphicon-bell"></i> Alert!
      </uib-tab-heading>
      I've got an HTML heading, and a select callback. Pretty cool!
    </uib-tab>
  </uib-tabset>

  <hr />

  <uib-tabset active="activePill" vertical="true" type="pills">
    <uib-tab index="0" heading="Vertical 1">Vertical content 1</uib-tab>
    <uib-tab index="1" heading="Vertical 2">Vertical content 2</uib-tab>
  </uib-tabset>

  <hr />

  <uib-tabset active="activeJustified" justified="true">
    <uib-tab index="0" heading="Justified">Justified content</uib-tab>
    <uib-tab index="1" heading="SJ">Short Labeled Justified content</uib-tab>
    <uib-tab index="2" heading="Long Justified">Long Labeled Justified content</uib-tab>
  </uib-tabset>

  <hr />

  Tabbed pills with CSS classes
  <uib-tabset type="pills">
    <uib-tab heading="Default Size">Tab 1 content</uib-tab>
    <uib-tab heading="Small Button" classes="btn-sm">Tab 2 content</uib-tab>
  </uib-tabset>

  <hr />

  Tabs using nested forms:
  <form name="outerForm" class="tab-form-demo">
    <uib-tabset active="activeForm">
      <uib-tab index="0" heading="Form Tab">
        <ng-form name="nestedForm">
          <div class="form-group">
            <label>Name</label>
            <input type="text" class="form-control" required ng-model="model.name"/>
          </div>
        </ng-form>
      </uib-tab>
      <uib-tab index="1" heading="Tab One">
        Some Tab Content
      </uib-tab>
      <uib-tab index="2" heading="Tab Two">
        More Tab Content
      </uib-tab>
    </uib-tabset>
  </form>
  Model:
  <pre>{{ model | json }}</pre>
  Nested Form:
  <pre>{{ outerForm.nestedForm | json }}</pre>
</div>
angular.module('ui.bootstrap.demo').controller('TabsDemoCtrl', function ($scope, $window) {
  $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() {
      $window.alert('You\'ve selected the alert tab!');
    });
  };

  $scope.model = {
    name: 'Tabs'
  };
});
Time is: {{mytime | date:'shortTime' }}

A lightweight & configurable timepicker directive.

uib-timepicker settings

Notes

This component makes no claims of absolutely supporting the preservation of dates in all cases, and it is highly recommended that model tracking of dates is encapsulated in a different object. This component should not be used with the same model as the datepicker. This is due to edge cases with situations such as Daylight Savings timezone changes which require a modification of the date in order to prevent an impossible to increment or decrement situation. See #5485 for details.

If the model value is updated (i.e. via Date.prototype.setDate), you must update the model value by breaking the reference by modelValue = new Date(modelValue) in order to have the timepicker update.

<div ng-controller="TimepickerDemoCtrl">

  <div uib-timepicker ng-model="mytime" ng-change="changed()" hour-step="hstep" minute-step="mstep" show-meridian="ismeridian"></div>

  <pre class="alert alert-info">Time is: {{mytime | date:'shortTime' }}</pre>

  <div class="row"> 
    <div class="col-xs-6">
        Hours step is:
      <select class="form-control" ng-model="hstep" ng-options="opt for opt in options.hstep"></select>
    </div>
    <div class="col-xs-6">
        Minutes step is:
      <select class="form-control" ng-model="mstep" ng-options="opt for opt in options.mstep"></select>
    </div>
  </div>

  <hr>

  <button type="button" class="btn btn-info" ng-click="toggleMode()">12H / 24H</button>
  <button type="button" class="btn btn-default" ng-click="update()">Set to 14:00</button>
  <button type="button" class="btn btn-danger" ng-click="clear()">Clear</button>

</div>
angular.module('ui.bootstrap.demo').controller('TimepickerDemoCtrl', function ($scope, $log) {
  $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 () {
    $log.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 fading eget arcu dictum varius duis at consectetur lorem. Vitae elementum curabitur show delay nunc sed velit dignissim sodales ut eu sem integer vitae. Turpis egestas hide delay pharetra convallis posuere morbi leo urna, Custom template at elementum eu, facilisis sed odio morbi quis commodo odio.

I can even contain HTML as a scope variable or inline string

I can have a custom class. Check me out!

Or use custom triggers, like focus:

Disable tooltips conditionally:

Open tooltips conditionally.

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

Note to mobile developers: Please note that while tooltips may work correctly on mobile devices (including tablets), we have made the decision to not officially support such a use-case because it does not make sense from a UX perspective.

There are three versions of the tooltip: uib-tooltip, uib-tooltip-template, and uib-tooltip-html:

uib-tooltip-* settings

All these settings are available for the three types of tooltips.

Note: To configure the tooltips, you need to do it on $uibTooltipProvider (also see below).

Triggers

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

The outsideClick trigger will cause the tooltip to toggle on click, and hide when anything else is clicked.

For any non-supported value, the trigger will be used to both show and hide the tooltip. Using the 'none' trigger will disable the internal trigger(s), one can then use the tooltip-is-open attribute exclusively to show and hide the tooltip.

$uibTooltipProvider

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

Known issues

For Safari 7+ support, if you want to use the focus tooltip-trigger, you need to use an anchor tag with a tab index. For example:

<a tabindex="0" uib-tooltip="Test" tooltip-trigger="focus" class="btn btn-default">
  Click Me
</a>

For Safari (potentially all versions up to 9), there is an issue with the hover CSS selector when using multiple elements grouped close to each other that are using the tooltip - it is possible for multiple elements to gain the hover state when mousing between the elements quickly and exiting the container at the right time. See issue #5445 for more details.

<div ng-controller="TooltipDemoCtrl">
    <div class="form-group">
      <label>Tooltip placement</label>
      <select class="form-control" ng-model="placement.selected" ng-options="o as o for o in placement.options"></select>
    </div>
    <button tooltip-placement="{{placement.selected}}" uib-tooltip="On the {{placement.selected}}" type="button" class="btn btn-default">Tooltip {{placement.selected}}</button>

    <hr />
    <div class="form-group">
      <label>Dynamic Tooltip Text</label>
      <input type="text" ng-model="dynamicTooltipText" class="form-control">
    </div>
    <div class="form-group">
      <label>Dynamic Tooltip Popup Text</label>
      <input type="text" ng-model="dynamicTooltip" class="form-control">
    </div>
    <p>
      Pellentesque <a href="#" uib-tooltip="{{dynamicTooltip}}">{{dynamicTooltipText}}</a>,
      sit amet venenatis urna cursus eget nunc scelerisque viverra mauris, in
      aliquam. Tincidunt lobortis feugiat vivamus at
      <a href="#" tooltip-animation="false" uib-tooltip="I don't fade. :-(">fading</a>
      eget arcu dictum varius duis at consectetur lorem. Vitae elementum curabitur
      <a href="#" tooltip-popup-delay='1000' uib-tooltip='appears with delay'>show delay</a>
      nunc sed velit dignissim sodales ut eu sem integer vitae. Turpis egestas
      <a href="#" tooltip-popup-close-delay='1000' uib-tooltip='hides with delay'>hide delay</a>
      pharetra convallis posuere morbi leo urna,
      <a href="#" uib-tooltip-template="'myTooltipTemplate.html'">Custom template</a>
      at elementum eu, facilisis sed odio morbi quis commodo odio.
    </p>

    <p>
        I can even contain HTML as a
        <a href="#" uib-tooltip-html="htmlTooltip">scope variable</a> or
        <a href="#" uib-tooltip-html="'static. {{dynamicTooltipText}}. <b>bold.</b>'">inline string</a>
    </p>

    <p>
      <style>
        /* Specify styling for tooltip contents */
        .tooltip.customClass .tooltip-inner {
          color: #880000;
          background-color: #ffff66;
          box-shadow: 0 6px 12px rgba(0,0,0,.175);
        }
        /* Hide arrow */
        .tooltip.customClass .tooltip-arrow {
          display: none;
        }
      </style>
      I can have a custom class. <a href="#" uib-tooltip="I can have a custom class applied to me!" tooltip-class="customClass">Check me out!</a>
    </p>


    <div class="form-group">
      <label>Or use custom triggers, like focus: </label>
      <input type="text" value="Click me!" uib-tooltip="See? Now click away..." tooltip-trigger="'focus'" tooltip-placement="right" class="form-control" />
    </div>

    <div class="form-group" ng-class="{'has-error' : !inputModel}">
      <label>Disable tooltips conditionally:</label>
      <input type="text" ng-model="inputModel" class="form-control"
             placeholder="Hover over this for a tooltip until this is filled"
             uib-tooltip="Enter something in this input field to disable this tooltip"
             tooltip-placement="top"
             tooltip-trigger="'mouseenter'"
             tooltip-enable="!inputModel" />
    </div>
    <div class="form-group">
      <label>
        Open tooltips <span uib-tooltip="Hello!" tooltip-is-open="tooltipIsOpen" tooltip-placement="bottom">conditionally.</span>
      </label>
      <button ng-click="tooltipIsOpen = !tooltipIsOpen">Toggle tooltip</button>
    </div>
    <script type="text/ng-template" id="myTooltipTemplate.html">
      <span>Special Tooltip with <strong>markup</strong> and {{ dynamicTooltipText }}</span>
    </script>
</div>
angular.module('ui.bootstrap.demo').controller('TooltipDemoCtrl', function ($scope, $sce) {
  $scope.dynamicTooltip = 'Hello, World!';
  $scope.dynamicTooltipText = 'dynamic';
  $scope.htmlTooltip = $sce.trustAsHtml('I\'ve been made <b>bold</b>!');
  $scope.placement = {
    options: [
      'top',
      'top-left',
      'top-right',
      'bottom',
      'bottom-left',
      'bottom-right',
      'left',
      'left-top',
      'left-bottom',
      'right',
      'right-top',
      'right-bottom'
    ],
    selected: 'top'
  };
});
Static arrays
Model: {{selected | json}}
Asynchronous results
Model: {{asyncSelected | json}}

No Results Found

ngModelOptions support
Model: {{ngModelOptionsSelected | json}}
Custom templates for results
Model: {{customSelected | json}}
Custom popup templates for typeahead's dropdown
Model: {{customPopupSelected | json}}

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

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

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

This directive works with promises, meaning you can retrieve matches using the $http service with minimal effort.

uib-typeahead settings

Notes

If a custom template for the popup is used, the wrapper selector used for the match items is the uib-typeahead-match class.

<style>
  .typeahead-demo .custom-popup-wrapper {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 1000;
    display: none;
    background-color: #f9f9f9;
  }

  .typeahead-demo .custom-popup-wrapper > .message {
    padding: 10px 20px;
    border-bottom: 1px solid #ddd;
    color: #868686;
  }

  .typeahead-demo .custom-popup-wrapper > .dropdown-menu {
    position: static;
    float: none;
    display: block;
    min-width: 160px;
    background-color: transparent;
    border: none;
    border-radius: 0;
    box-shadow: none;
  }
</style>

<script type="text/ng-template" id="customTemplate.html">
  <a>
      <img ng-src="http://upload.wikimedia.org/wikipedia/commons/thumb/{{match.model.flag}}" width="16">
      <span ng-bind-html="match.label | uibTypeaheadHighlight:query"></span>
  </a>
</script>

<script type="text/ng-template" id="customPopupTemplate.html">
  <div class="custom-popup-wrapper"
     ng-style="{top: position().top+'px', left: position().left+'px'}"
     style="display: block;"
     ng-show="isOpen() && !moveInProgress"
     aria-hidden="{{!isOpen()}}">
    <p class="message">select location from drop down.</p>

    <ul class="dropdown-menu" role="listbox">
      <li class="uib-typeahead-match" ng-repeat="match in matches track by $index" ng-class="{active: isActive($index) }"
        ng-mouseenter="selectActive($index)" ng-click="selectMatch($index)" role="option" id="{{::match.id}}">
        <div uib-typeahead-match index="$index" match="match" query="query" template-url="templateUrl"></div>
      </li>
    </ul>
  </div>
</script>

<div class='container-fluid typeahead-demo' ng-controller="TypeaheadCtrl">

    <h4>Static arrays</h4>
    <pre>Model: {{selected | json}}</pre>
    <input type="text" ng-model="selected" uib-typeahead="state for state in states | filter:$viewValue | limitTo:8" class="form-control">

    <h4>Asynchronous results</h4>
    <pre>Model: {{asyncSelected | json}}</pre>
    <input type="text" ng-model="asyncSelected" placeholder="Locations loaded via $http" uib-typeahead="address for address in getLocation($viewValue)" typeahead-loading="loadingLocations" typeahead-no-results="noResults" class="form-control">
    <i ng-show="loadingLocations" class="glyphicon glyphicon-refresh"></i>
    <div ng-show="noResults">
      <i class="glyphicon glyphicon-remove"></i> No Results Found
    </div>

    <h4>ngModelOptions support</h4>
    <pre>Model: {{ngModelOptionsSelected | json}}</pre>
    <input type="text" ng-model="ngModelOptionsSelected" ng-model-options="modelOptions" uib-typeahead="state for state in states | filter:$viewValue | limitTo:8" class="form-control">

    <h4>Custom templates for results</h4>
    <pre>Model: {{customSelected | json}}</pre>
    <input type="text" ng-model="customSelected" placeholder="Custom template" uib-typeahead="state as state.name for state in statesWithFlags | filter:{name:$viewValue}" typeahead-template-url="customTemplate.html" class="form-control" typeahead-show-hint="true" typeahead-min-length="0">

    <h4>Custom popup templates for typeahead's dropdown</h4>
    <pre>Model: {{customPopupSelected | json}}</pre>
    <input type="text" ng-model="customPopupSelected" placeholder="Custom popup template" uib-typeahead="state as state.name for state in statesWithFlags | filter:{name:$viewValue}" typeahead-popup-template-url="customPopupTemplate.html" class="form-control">
</div>
angular.module('ui.bootstrap.demo').controller('TypeaheadCtrl', function($scope, $http) {

  var _selected;

  $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'];
  // Any function returning a promise object can be used to load values asynchronously
  $scope.getLocation = function(val) {
    return $http.get('//maps.googleapis.com/maps/api/geocode/json', {
      params: {
        address: val,
        sensor: false
      }
    }).then(function(response){
      return response.data.results.map(function(item){
        return item.formatted_address;
      });
    });
  };

  $scope.ngModelOptionsSelected = function(value) {
    if (arguments.length) {
      _selected = value;
    } else {
      return _selected;
    }
  };

  $scope.modelOptions = {
    debounce: {
      default: 500,
      blur: 250
    },
    getterSetter: true
  };

  $scope.statesWithFlags = [{'name':'Alabama','flag':'5/5c/Flag_of_Alabama.svg/45px-Flag_of_Alabama.svg.png'},{'name':'Alaska','flag':'e/e6/Flag_of_Alaska.svg/43px-Flag_of_Alaska.svg.png'},{'name':'Arizona','flag':'9/9d/Flag_of_Arizona.svg/45px-Flag_of_Arizona.svg.png'},{'name':'Arkansas','flag':'9/9d/Flag_of_Arkansas.svg/45px-Flag_of_Arkansas.svg.png'},{'name':'California','flag':'0/01/Flag_of_California.svg/45px-Flag_of_California.svg.png'},{'name':'Colorado','flag':'4/46/Flag_of_Colorado.svg/45px-Flag_of_Colorado.svg.png'},{'name':'Connecticut','flag':'9/96/Flag_of_Connecticut.svg/39px-Flag_of_Connecticut.svg.png'},{'name':'Delaware','flag':'c/c6/Flag_of_Delaware.svg/45px-Flag_of_Delaware.svg.png'},{'name':'Florida','flag':'f/f7/Flag_of_Florida.svg/45px-Flag_of_Florida.svg.png'},{'name':'Georgia','flag':'5/54/Flag_of_Georgia_%28U.S._state%29.svg/46px-Flag_of_Georgia_%28U.S._state%29.svg.png'},{'name':'Hawaii','flag':'e/ef/Flag_of_Hawaii.svg/46px-Flag_of_Hawaii.svg.png'},{'name':'Idaho','flag':'a/a4/Flag_of_Idaho.svg/38px-Flag_of_Idaho.svg.png'},{'name':'Illinois','flag':'0/01/Flag_of_Illinois.svg/46px-Flag_of_Illinois.svg.png'},{'name':'Indiana','flag':'a/ac/Flag_of_Indiana.svg/45px-Flag_of_Indiana.svg.png'},{'name':'Iowa','flag':'a/aa/Flag_of_Iowa.svg/44px-Flag_of_Iowa.svg.png'},{'name':'Kansas','flag':'d/da/Flag_of_Kansas.svg/46px-Flag_of_Kansas.svg.png'},{'name':'Kentucky','flag':'8/8d/Flag_of_Kentucky.svg/46px-Flag_of_Kentucky.svg.png'},{'name':'Louisiana','flag':'e/e0/Flag_of_Louisiana.svg/46px-Flag_of_Louisiana.svg.png'},{'name':'Maine','flag':'3/35/Flag_of_Maine.svg/45px-Flag_of_Maine.svg.png'},{'name':'Maryland','flag':'a/a0/Flag_of_Maryland.svg/45px-Flag_of_Maryland.svg.png'},{'name':'Massachusetts','flag':'f/f2/Flag_of_Massachusetts.svg/46px-Flag_of_Massachusetts.svg.png'},{'name':'Michigan','flag':'b/b5/Flag_of_Michigan.svg/45px-Flag_of_Michigan.svg.png'},{'name':'Minnesota','flag':'b/b9/Flag_of_Minnesota.svg/46px-Flag_of_Minnesota.svg.png'},{'name':'Mississippi','flag':'4/42/Flag_of_Mississippi.svg/45px-Flag_of_Mississippi.svg.png'},{'name':'Missouri','flag':'5/5a/Flag_of_Missouri.svg/46px-Flag_of_Missouri.svg.png'},{'name':'Montana','flag':'c/cb/Flag_of_Montana.svg/45px-Flag_of_Montana.svg.png'},{'name':'Nebraska','flag':'4/4d/Flag_of_Nebraska.svg/46px-Flag_of_Nebraska.svg.png'},{'name':'Nevada','flag':'f/f1/Flag_of_Nevada.svg/45px-Flag_of_Nevada.svg.png'},{'name':'New Hampshire','flag':'2/28/Flag_of_New_Hampshire.svg/45px-Flag_of_New_Hampshire.svg.png'},{'name':'New Jersey','flag':'9/92/Flag_of_New_Jersey.svg/45px-Flag_of_New_Jersey.svg.png'},{'name':'New Mexico','flag':'c/c3/Flag_of_New_Mexico.svg/45px-Flag_of_New_Mexico.svg.png'},{'name':'New York','flag':'1/1a/Flag_of_New_York.svg/46px-Flag_of_New_York.svg.png'},{'name':'North Carolina','flag':'b/bb/Flag_of_North_Carolina.svg/45px-Flag_of_North_Carolina.svg.png'},{'name':'North Dakota','flag':'e/ee/Flag_of_North_Dakota.svg/38px-Flag_of_North_Dakota.svg.png'},{'name':'Ohio','flag':'4/4c/Flag_of_Ohio.svg/46px-Flag_of_Ohio.svg.png'},{'name':'Oklahoma','flag':'6/6e/Flag_of_Oklahoma.svg/45px-Flag_of_Oklahoma.svg.png'},{'name':'Oregon','flag':'b/b9/Flag_of_Oregon.svg/46px-Flag_of_Oregon.svg.png'},{'name':'Pennsylvania','flag':'f/f7/Flag_of_Pennsylvania.svg/45px-Flag_of_Pennsylvania.svg.png'},{'name':'Rhode Island','flag':'f/f3/Flag_of_Rhode_Island.svg/32px-Flag_of_Rhode_Island.svg.png'},{'name':'South Carolina','flag':'6/69/Flag_of_South_Carolina.svg/45px-Flag_of_South_Carolina.svg.png'},{'name':'South Dakota','flag':'1/1a/Flag_of_South_Dakota.svg/46px-Flag_of_South_Dakota.svg.png'},{'name':'Tennessee','flag':'9/9e/Flag_of_Tennessee.svg/46px-Flag_of_Tennessee.svg.png'},{'name':'Texas','flag':'f/f7/Flag_of_Texas.svg/45px-Flag_of_Texas.svg.png'},{'name':'Utah','flag':'f/f6/Flag_of_Utah.svg/45px-Flag_of_Utah.svg.png'},{'name':'Vermont','flag':'4/49/Flag_of_Vermont.svg/46px-Flag_of_Vermont.svg.png'},{'name':'Virginia','flag':'4/47/Flag_of_Virginia.svg/44px-Flag_of_Virginia.svg.png'},{'name':'Washington','flag':'5/54/Flag_of_Washington.svg/46px-Flag_of_Washington.svg.png'},{'name':'West Virginia','flag':'2/22/Flag_of_West_Virginia.svg/46px-Flag_of_West_Virginia.svg.png'},{'name':'Wisconsin','flag':'2/22/Flag_of_Wisconsin.svg/45px-Flag_of_Wisconsin.svg.png'},{'name':'Wyoming','flag':'b/bc/Flag_of_Wyoming.svg/43px-Flag_of_Wyoming.svg.png'}];
});

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4