shankys
shankys

Reputation: 67

ui boostrap typeahead directive doesn't work when wrapped in a directive and loaded dynamically

I've a directive that creates an input text element and uses ui bootstrap directive to attach typeahead functionality to the input field.

This input field is dynamically appended to one of the field on the form on dom ready event. I've to do this since, I don't have access to edit/modify html page generated by server. i.e - Dynamically add a typeahead field using angularjs and bootstrap angularjs as well.

I'm using ui boostrap - v0.12.0, angularjs version - v1.2.26 and jquery - v1.8.3

Problem: the directive is not working (or may be not correctly compiled or access scope) in IE 11, whereas works perfectly in chrome browser without any problem. I can see the appended elements on form load with no errors or exceptions on the console, however no typeahead magic.

here's the what i've -

// added required js references
// initialize angular app
        var typeAheadApp = angular.module("typeAheadApp", ['smart-table', 'ui.bootstrap']);

controller:

typeAheadApp.controller('TypeaheadCtrl', ['$scope', '$http', '$compile', function ($scope, $http, $compile) {
    $scope.getCategoriesSize = 1;
    $scope.categorylkp = getCategoryField().val();

    $scope.getCategories = function (val) {
        return $http({
            url: "/some/data/source/url",
            method: 'GET',
            headers: {
                "Accept": "application/json;odata=verbose"
            }
        }).then(function (response) {
            $scope.getCategoriesSize = response.data.d.results.length;
            return response.data.d.results.map(function (item) {
                return item.categoryName;
            });
        }, function (ex) {
            alert("ERROR!!");
        });
    };
    $scope.selectedCategory = function (item, model, label) {
        getCategoryField().val(label);
    };
    $scope.updateCategory = function (setVal) {        
        getCategoryField().val(setVal);
    };

}]);

directive:

typeAheadApp.directive('categoryLookup', ['$compile', function ($compile) { 
        return {
            restrict: 'A',                  
            link: function (scope, element, attrs) {                            
                    var typeAheadTemplate = angular.element('<div class="form-inline">' +            
                                              '<input id="categorylkpTxt" type="text" ng-model="categorylkp" ng-change="updateCategory(categorylkp)" typeahead="category for category in getCategories($viewValue)" typeahead-on-select="selectedCategory($item, $model, $label)" typeahead-min-length="3" typeahead-loading="loadingCategories" style="width: 345px;" autocomplete="off">'  +
                                            '</div>' +
                                            '<div ng-show="loadingCategories">' + 
                                              '<i class="icon-refresh"></i> Loading...' + 
                                            '</div>' +
                                            '<div ng-show="!getCategoriesSize">' + 
                                              '<i class="icon-remove"></i> No Results Found ' + 
                                            '</div>');
                    var compiled = $compile(angular.element('<div>').append(typeAheadTemplate).html())(scope);
                    element.append(compiled);                       
            }
        }
    }]); 

init function:

function initTypeAhead(){   
    var typeAheadField = getCategoryField(); // some field on the form

    typeAheadField.parent().append('<div id="typeAheadEl"><div ng-controller="TypeaheadCtrl"><div id="category-lookup" class="custom-typeahead" category-lookup></div></div></div>');       

    // manual bootstrapping the angular
    angular.bootstrap($('#typeAheadEl'), ['typeAheadApp']);
}

 angular.element(document).ready(function() {               
    initTypeAhead();    
});

Any advise or comments ?

Thanks in advance!

Upvotes: 0

Views: 898

Answers (1)

maurycy
maurycy

Reputation: 8465

I'd start fixing it from category lookup directive as it looks rather messy, you are compiling in link method what should be in template

typeAheadApp.directive('categoryLookup', function () {
  return {
    restrict: 'A',
    template: '<div class="form-inline">' +
      '<input id="categorylkpTxt" type="text" ng-model="categorylkp" ng-change="updateCategory(categorylkp)" typeahead="category for category in getCategories($viewValue)" typeahead-on-select="selectedCategory($item, $model, $label)" typeahead-min-length="3" typeahead-loading="loadingCategories" style="width: 345px;" autocomplete="off">' +
      '</div>' +
      '<div ng-show="loadingCategories">' +
      '<i class="icon-refresh"></i> Loading...' +
      '</div>' +
      '<div ng-show="!getCategoriesSize">' +
      '<i class="icon-remove"></i> No Results Found ' +
      '</div>',
    controller: 'TypeaheadCtrl'
  }
}); 

and then init function

function initTypeAhead(){   
    var typeAheadField = getCategoryField(); // some field on the form

    typeAheadField.parent().append('<div id="typeAheadEl"><div id="category-lookup" class="custom-typeahead" category-lookup></div></div>');       

    // manual bootstrapping the angular
    angular.bootstrap($('#typeAheadEl'), ['typeAheadApp']);
}

 angular.element(document).ready(function() {               
    initTypeAhead();    
});

Upvotes: 1

Related Questions