<!DOCTYPE html>
<html ng-app="plunker">
<head>
<title>Type-ahead with form validation</title>
<link rel="stylesheet" href="style.css">
<script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>
<script data-require="ui-bootstrap@*" data-semver="1.3.2" src="https://cdn.rawgit.com/angular-ui/bootstrap/gh-pages/ui-bootstrap-tpls-1.3.2.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular-messages/1.5.5/angular-messages.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.0/angular-resource.js'></script>
<script src="app.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<form name="wkProfileCompany">
<div class="col-xs-12 works">
<div class='form-group' ng-class="{'has-error': wkProfileCompany.location2.$touched && wkProfileCompany.location2.$invalid}">
<label class="control-label" for="location2">Location <span class='text-muted'>(type-ahead version 1 directive)</span></label>
<div>
<wk-location-suggest-old class="form-control" type="text" name="location2" ng-model="location2" form="wkProfileCompany" is-required="true"></wk-location-suggest-old>
<br/>
<div ng-messages="wkProfileCompany.location2.$touched && wkProfileCompany.location2.$error" class="text-danger">
<div ng-message="required">
Location 2 is required
</div>
</div>
<h4>location2's value:</h4>
<pre >{{ location2 }}</pre>
</div>
</div>
</form>
</body>
</html>
var app = angular.module('plunker', ['ngMessages','ui.bootstrap', 'ngResource']);
app.controller('MainCtrl', function($scope) {
$scope.location2 = 'Location 2';
})
.directive('wkLocationSuggestOld', [function () {
return {
restrict: 'E',
require: '?ngModel',
scope: {
name: '@',
form: '=',
isRequired: '='
},
template: '<input name="{{name}}" type="text" class="{{innerClass}}" ng-model="innerModel" ng-change="onChange()" uib-typeahead="location as row.location for row in typeAhead($viewValue)" typeahead-wait-ms="250" typeahead-on-select="onSelectInternal($item, $model, $label)" typeahead-min-length="2" typeahead-focus-first="true" ng-required="isRequired">',
controller: 'LocationSuggestController',
link: function (scope, element, attrs, ngModel) {
if (!ngModel) {
return;
}
scope.attrs = attrs;
// locationSuggest form-control
scope.innerClass = attrs.class;
attrs.$set('class', null);
// invoked when model changes from the outside
ngModel.$render = function () {
console.log('ngModel.$render');
scope.innerModel = ngModel.$modelValue;
};
// invoked when model changes from the inside
scope.onChange = function () {
console.log('scope.onChange: ' + scope.innerModel);
ngModel.$setViewValue(scope.innerModel);
};
scope.onSelectInternal = function ($item) {
console.log('scope.onSelectInternal');
ngModel.$setViewValue($item.location);
scope.innerModel = $item.location;
};
}
};
}])
// Locations API
.factory('locationsApi', ['$resource', function ($resource) {
return $resource('', { },
{
'suggest': { method: 'GET', url: 'https://www.workible.com.au/api/v4/locations/suggest', isArray: true },
}
);
}])
// Type Ahead Suggestion
.controller('LocationSuggestController', ['$scope', 'locationsApi', function ($scope, locationsApi) {
console.log('instantiate: LocationSuggestController');
$scope.typeAhead = function (val) {
console.log('typeahead: ' + val)
return locationsApi.suggest({ location: val }).$promise.then(function (data) {
return data;
});
};
}]);
/* Styles go here */