<!DOCTYPE html>
<html ng-app="formlyExample">

  <head>
    <!-- Twitter bootstrap -->
    <script data-require="lodash.js@*" data-semver="3.10.0" src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.10.0/lodash.js"></script>
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" />
    <!-- apiCheck is used by formly to validate its api -->
    <script src="//npmcdn.com/api-check@latest/dist/api-check.js"></script>
    <!-- This is the latest version of angular (at the time this template was created) -->
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.4.9/angular.js"></script>
    <!-- Angular-UI Bootstrap has tabs directive we want -->
    <script src="//npmcdn.com/angular-ui-bootstrap@latest/dist/ui-bootstrap-tpls.js"></script>
    <!-- This is the latest version of formly core. -->
    <script src="//npmcdn.com/angular-formly@latest/dist/formly.js"></script>
    <!-- This is the latest version of formly bootstrap templates -->
    <script src="//npmcdn.com/angular-formly-templates-bootstrap@latest/dist/angular-formly-templates-bootstrap.js"></script>
    <script src="app.js"></script>
    <title>Angular Formly Example</title>
  </head>

  <body class="container" ng-controller="mainCtrl as vm">
    <div>
      <h1>angular-formly example: {{vm.exampleTitle}}</h1>
      <div>
        This is a better example of how to use the
                <a href="https://angular-ui.github.io/bootstrap/#/typeahead">UI Boostrap typeahead</a>

        with angular-formly.
      </div>
      <hr />
      <form novalidate="" name="vm.form" ng-submit="vm.onSubmit()">
        <formly-form options="vm.options" fields="vm.fields" model="vm.model">
          <button ng-disabled="vm.form.$invalid" class="btn btn-primary submit-button" type="submit">Submit</button>
          <button ng-click="vm.options.resetModel()" class="btn btn-default" type="button">Reset</button>
        </formly-form>
      </form>
      <hr />
      <h2>Model Value</h2>
      <pre>{{vm.model | json}}</pre>
      <h2>Fields         <small>(note, functions are not shown)</small>
      </h2>
      <pre>{{vm.originalFields | json}}</pre>
      <h2>Form</h2>
      <pre>{{vm.form | json}}</pre>
    </div>
    <div style="margin-top:30px">
      <small>
        This is an example for the
                <a href="https://formly-js.github.io/angular-formly">angular-formly</a>

        project made with ♥ by
                <strong>
          <span ng-if="!vm.author.name || !vm.author.url">
            {{vm.author.name || 'anonymous'}}
          </span>
          <a ng-href="{{::vm.author.url}}" ng-if="vm.author.url">
            {{vm.author.name}}
          </a>
        </strong>
        <br />

        This example is running angular version "{{vm.env.angularVersion}}" and formly version "{{vm.env.formlyVersion}}"
      </small>
    </div>
    <!-- Put custom templates here -->
  </body>

</html>
(function(angular) {

    "use strict";


    function initializer(formlyConfig) {
        formlyConfig.setType({
            name: "typeahead",
            template: function(elem) {
                var key;
                if (elem.data.isArrayOfObjects && !elem.data.labelProp) {
                    key = "item[0]";
                } else if (elem.data.isArrayOfObjects && elem.data.labelProp) {
                    key = "item[options.data.labelProp]";
                } else {
                    key = "item";
                }

                var template = [
                    '<input type="text" ng-model="model[options.key]" typeahead-wait-ms="options.data.debounce" typeahead-select-on-blur="options.data.selectOnBlur" typeahead-focus-first="options.data.focusFirst" typeahead-min-length="options.data.minLength" typeahead-on-select="selectItemCallback($item, $model, $label, $event)"',
                    'uib-typeahead="item as ' + key + ' for item in to.options',
                    '| filter: filterBy($viewValue) | limitTo: options.data.limit" class="form-control">'
                ].join(" ");
                return template;
            },
            wrapper: ["bootstrapLabel", "bootstrapHasError"],
            defaultOptions: function(options) {
                return {
                    data: {
                        limit: 10,
                        isArrayOfObjects: false,
                        labelProp: undefined,
                        filterOnlyByLabel: false,
                        selectOnBlur: false,
                        focusFirst: false,
                        debounce: 0,
                        minLength: 1,
                        onSelect: angular.noop
                    }
                };
            },
            //The $filter service is not required. I used it only for some tests...
            controller: ["$scope", "$filter", function($scope, $filter) {
                var vm = $scope;
                vm.filterBy = function(value) {
                    /*
                     * In order to filter based on a key we have to create an object type { key: $viewValue } 
                     * in our particular case it is { State: $viewValue } but to make it generic it's necessary
                     * to add some logic and generate the object filter inside the controller.
                     * If the filterOnlyByLabel variable is false then we use the standard filter which applies 
                     * the filter to the entire object.
                     */
                    if (!vm.options.data.filterOnlyByLabel) return value;

                    var obj = {};
                    obj[vm.options.data.labelProp] = value;
                    return obj;

                    //Some interesting Tests using angular $filter service and lodash _.pluck
                    // var results = $filter('filter')(vm.to.options, obj);
                    // console.log("results: ", results);

                    // var results2 = _.pluck(results, vm.options.data.filterByProp);
                    // console.log("results2: ", results2);
                };

                vm.selectItemCallback = vm.options.data.onSelect;
            }]
        });
    }

    function mainCtrl(formlyVersion, USStates, $timeout, $http) {
        var vm = this;

        vm.onSubmit = onSubmit;

        // variable assignment
        vm.author = { // optionally fill in your info below :-)
            name: "Marcelino Jorge Romero",
            url: "http://tinyurl.com/marcelinojorgeromero"
        };
        vm.exampleTitle = 'UI Bootstrap Typeahead'; // add this
        vm.env = {
            angularVersion: angular.version.full,
            formlyVersion: formlyVersion
        };

        vm.model = {};
        vm.options = {};

        vm.fields = [
            {
                key: "usstates",
                type: "typeahead",
                templateOptions: {
                    label: "State",
                    placeholder: "Start typing a US State...",
                    options: USStates
                },
                data: { //Override typeahead defaults (or add more data)
                    isArrayOfObjects: true,
                    filterOnlyByLabel: true,
                    labelProp: "State",
                    debounce: 500,
                    selectOnBlur: true,
                    focusFirst: true,
                    onSelect: function() {
                        console.log("onSelect overrided: ", arguments);
                    }
                }
            },
            {
                key: "asyncusstates",
                type: "typeahead",
                templateOptions: {
                    label: "State (Async load after 3 sec)",
                    placeholder: "This is Asynchronous load...",
                    options: []
                },
                expressionProperties: {
                    "templateOptions.options": function($viewValue, $modelValue, scope) {
                        return $timeout(function(){
                            console.log("states loaded asynchronously at " + new Date());
                            return USStates;
                        }, 3000);
                    }
                },
                data: { //Override typeahead defaults (or add more data)
                    isArrayOfObjects: true,
                    filterOnlyByLabel: true,
                    labelProp: "State",
                    debounce: 500,
                    selectOnBlur: true,
                    focusFirst: true,
                    onSelect: function() {
                        console.log("onSelect overrided: ", arguments);
                    }
                }
            },
			{
                key: "address",
                type: "typeahead",
                templateOptions: {
                    label: "Address",
                    placeholder: "This is Asynchronous load. Start typing a place...",
                    options: []
                },
                expressionProperties: {
                    "templateOptions.options": function($viewValue, $modelValue, scope) {
                        return $http.get("//maps.googleapis.com/maps/api/geocode/json", {
                            params: {
                                address: $viewValue,
                                sensor: false
                            }
                        }).then(function(response) {
                            return response.data.results.map(function(item) {
                                return item.formatted_address;
                            });
                        });
                    }
                },
                data: { //Override typeahead defaults (or add more data)
                    debounce: 500,
                    onSelect: function() {
                        console.log("onSelect overrided: ", arguments);
                    }
                }
            }
        ];

        vm.originalFields = angular.copy(vm.fields);

        // function definition
        function onSubmit() {
            vm.options.updateInitialValue();
            alert(JSON.stringify(vm.model), null, 2);
        }
    }

    mainCtrl.$inject = ["formlyVersion", "USStates", "$timeout", "$http"];
    
    angular
        .module("formlyExample", ["formly", "formlyBootstrap", "ui.bootstrap"])
        .constant("USStates", [{Id:1 , State: "Alabama"}, {Id:2 , State: "Alaska"}, {Id:3 , State: "Arizona"}, {Id:4 , State: "Arkansas"}, {Id:5 , State: "California"}, {Id:6 , State: "Colorado"}, {Id:7 , State: "Connecticut"}, {Id:8 , State: "Delaware"}, {Id:9 , State: "Florida"}, {Id:10, State: "Georgia"}, {Id:11, State: "Hawaii"}, {Id:12, State: "Idaho"}, {Id:13, State: "Illinois"}, {Id:14, State: "Indiana"}, {Id:15, State: "Iowa"}, {Id:16, State: "Kansas"}, {Id:17, State: "Kentucky"}, {Id:18, State: "Louisiana"}, {Id:19, State: "Maine"}, {Id:20, State: "Maryland"}, {Id:21, State: "Massachusetts"}, {Id:22, State: "Michigan"}, {Id:23, State: "Minnesota"}, {Id:24, State: "Mississippi"}, {Id:25, State: "Missouri"}, {Id:26, State: "Montana"}, {Id:27, State: "Nebraska"}, {Id:28, State: "Nevada"}, {Id:29, State: "New Hampshire"}, {Id:30, State: "New Jersey"}, {Id:31, State: "New Mexico"}, {Id:32, State: "New York"}, {Id:33, State: "North Dakota"}, {Id:34, State: "North Carolina"}, {Id:35, State: "Ohio"}, {Id:36, State: "Oklahoma"}, {Id:37, State: "Oregon"}, {Id:38, State: "Pennsylvania"}, {Id:39, State: "Rhode Island"}, {Id:40, State: "South Carolina"}, {Id:41, State: "South Dakota"}, {Id:42, State: "Tennessee"}, {Id:43, State: "Texas"}, {Id:44, State: "Utah"}, {Id:45, State: "Vermont"}, {Id:46, State: "Virginia"}, {Id:47, State: "Washington"}, {Id:48, State: "West Virginia"}, {Id:49, State: "Wisconsin"}, {Id:50, State: "Wyoming"}])
        .controller("mainCtrl", mainCtrl)
        .run(initializer);

})(angular);