glossary term

by angularjsdc

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/angular.js/1.1.1/angular.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css">
<div ng-app="app">
    <!-- http://www.deloreanipsum.com/ -->
    <p>Hey. Let's put him in there. You know, Doc, you left your
        <glossary-term>equipment</glossary-term> on all week. That's a great idea. I'd love to
        park. You extol me with a lot of confidence, Doc.</p>
    <p>Are you sure about this storm? That's good advice, Marty. Nothing's coming
        to my mind. Oh. But I can't go to the dance, I'll miss my favorite
        <glossary-term>television</glossary-term> program, Science Fiction Theater.</p>
    <p>You wanna a Pepsi, pall, you're gonna pay for it. Right, George. Well,
        good luck you guys. Oh, one other thing, if you guys ever have kids and
        one of them when he's eight years old,
        <glossary-term>accidentally</glossary-term> sets fire to the living room rug, be easy
        on him. You don't understand. Yeah. You
        <glossary-term>extol</glossary-term> me with a lot of confidence, Doc.</p>
</div>

CSS

.modal {
    padding: 1em;
}
p{
    font-size:1.3em;
    line-height:1.4em;
    margin-bottom:1em
}

JavaScript

var app = angular.module('app', ['app.services']);

// services

angular.module('app.services', []).factory('glossary', function ($http) {
    return {
        getDefinition: function (term) {
            // Pull definition from Google's unofficial dictionary API
            var definition = $http.jsonp("http://www.google.com/dictionary/json?q=" + term + "&sl=en&tl=en&restrict=pr%2Cde&client=te&callback=JSON_CALLBACK").success(function (response) {
                return response;
            });
            return definition;
        }
    }
});

// directives

app.directive('glossaryTerm', function () {
    return {
        controller: 'Glossary',
        restrict: 'E',
        scope: { /* empty */
        },
        template: '<span><a class="glossary-term" href="#{{$id}}" data-toggle="modal" ng-transclude></a><div id="{{$id}}" class="modal hide fade"><h1>{{glossary[term].name}}</h1><p ng-repeat="term in glossary[term].terms" ng-bind-html-unsafe="term.text"></p></div></span>',
        replace: true,
        transclude: true,
        compile: function (tElement, tAttrs, transclude) {
            return {
                pre: function (scope) {
                    transclude(scope, function (clone) {
                        scope.term = clone[0].textContent.toLowerCase();
                    });
                },
                post: function (scope) {
                    // load the definition into scope
                    scope.getDefinition(scope.term);
                }
            }
        }
    }
});

// controllers

function Glossary($scope, $http, glossary) {
    $scope.glossary = {};
    $scope.getDefinition = function (term) {
        $scope.glossary[term] = glossary.getDefinition(term).then(function (definition) {
            var name = term;
            // just pull the first definition
            var terms = definition.data.webDefinitions[0].entries[0].terms;
            return {
                name: term,
                terms: terms
        ...