Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS typeahead + multi select tags

What I'm looking for is a input that resembles Gmails typeahead for email addresses

enter image description here

Challenges:

1) It should display both the Name EmailAddress and Image (Basically a customizable template)

2) It should display the Name of the contact added to the list

3) It should work with backspace to remove the previous entry

4) It should work with select and , to add the new etnry

like image 878
sj7 Avatar asked Mar 27 '14 16:03

sj7


1 Answers

.directive('typeahead', function () {
    return {
        restrict: 'AEC',
        scope: {
            model: '=ngModel'
        },
        link: function link($scope, $element, $attrs) {
            $scope.$watch('inputValue', function (value) {
                $scope.changed();
            });

            $scope.Emails = ['[email protected]', '[email protected]', '[email protected]'];

            $element.bind("keydown keypress", function (event) {
                switch (event.keyCode) {
                    case 40:
                        $scope.$apply(function () {
                            if ($scope.selected < $scope.List.length) {
                                $scope.selected++;
                            }
                        });
                        event.preventDefault();
                        break;
                    case 38:
                        $scope.$apply(function () {
                            if ($scope.selected > 0) {
                                $scope.selected--;
                            }
                        });
                        event.preventDefault();
                        break;
                    case 13:
                        $scope.$apply(function () {
                            $scope.selectAndClose($scope.List[$scope.selected]);
                        });
                        event.preventDefault();
                        break;
                    case 32:
                    case 188:
                        $scope.$apply(function () {
                            inputValues = $scope.inputValue.split(',');
                            for (var i = 0; i < inputValues.length; i++) {
                                if (inputValues[i].length > 0) {
                                    $scope.GetOrCreateEmailAndSelect(inputValues[i]);
                                }
                            }
                            $scope.clear();
                            $scope.close();
                        });
                        event.preventDefault();
                        break;
                    case 27:
                        $scope.$apply(function () {
                            $scope.close();
                        });
                        event.preventDefault();
                        break;
                    case 8:
                        $scope.$apply(function () {
                            if ($scope.inputValue == null || $scope.inputValue.length == 0) {
                                $scope.model.pop();
                            }
                        });
                        break;
                }
            });

            $scope.remove = function (emailid) {
                $scope.model.splice($scope.model.indexOf(emailid), 1);
            }

            $scope.changed = function () {
                fetchEmail({
                    'EmailAddress__icontains': $scope.inputValue
                }).then(function (data) {
                    $scope.List = data;
                    if (typeof ($scope.model) === typeof ([]) && $scope.model !== null) {
                        for (var i = 0; i < $scope.model.length; i++) {
                            for (var j = 0; j < $scope.List.length; j++) {
                                if ($scope.List[j].id == $scope.model[i].id) {
                                    $scope.List.splice(j, 1);
                                }
                            }
                        }
                    }
                    $scope.selected = 0;
                    dropdownShow = false;
                    if ($scope.List.length > 0) {
                        if (typeof ($scope.inputValue) !== 'undefined' && $scope.inputValue !== null) {
                            if ($scope.inputValue.length > 1) {
                                dropdownShow = true;
                            }
                        }
                    }
                    $scope.dropdownShow = dropdownShow;
                });
            };

            $scope.selectAndClose = function (value) {
                $scope.select(value);
                $scope.clear();
                $scope.close();
            };

            $scope.select = function (value) {
                $scope.model.push(value);
            };
            $scope.clear = function () {
                $scope.inputValue = null;
            };
            $scope.close = function () {
                $scope.dropdownShow = false;
            };
            $scope.GetOrCreateEmailAndSelect = function (EmailAddress) {
                EmailAddress = EmailAddress.toString();
                data = $scope.fetchEmail(EmailAddress); //you can add an ajax call here
                if (data.length == 0) {
                    $scope.CreateEmail(EmailAddress);
                } else {
                    $scope.select(data[0]);
                }
            });

        $scope.fetchEmail =function(EmailAddress) {
            result = [];
            for (var i = 0; i < $scope.Emails.length; i++) {
                if ($scope.Emails[i].indexOf(EmailAddress) > -1) {
                    result.push($scope.Emails[i]);
                }
            }
        }

        $scope.CreateEmail =function(EmailAddress) {
            $scope.Emails.push(EmailAddress);
        };
    }
    $scope.mouseoverChoice = function (emailidobject) {
        $scope.selected = $scope.List.indexOf(emailidobject);
    };
    $scope.editEmailId = function (emailidobject) {
        $scope.inputValue = emailidobject.EmailAddress;
        $scope.remove(emailidobject);
    }
    $scope.CheckSelected = function (element) {
        if (typeof ($scope.List) !== 'undefined' && typeof ($scope.selected) !== 'undefined' && typeof ($scope.List[$scope.selected]) !== 'undefined') {
            return $scope.List[$scope.selected].id == element.id;
        } else {
            return false;
        }
    }
},
    templateUrl: 'typeaheadtemplate.html',
}
});
like image 165
sj7 Avatar answered Oct 07 '22 15:10

sj7