Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJs: How make ui-select working properly?

THE SITUATION:

I am making an angular app where I have to use ui-select: in the user info page, in the select have to be possible to choose one or many tag. It is almost working, except from the fact that i have problems to get and display the pre-existent tags.

THE CODE:

View:

<ui-select multiple ng-model="info_data.tags" theme="bootstrap" ng-disabled="disabled">

  <ui-select-match placeholder="Select tag...">{{$item.name}} </ui-select-match>

  <ui-select-choices repeat="tag in all_tags | propsFilter: {name: $select.search}">

    {{tag.name}}

  </ui-select-choices>

</ui-select>

<p>Selected: {{info_data.tags}}</p>

Controller:

$http({

    url: base_url + 'main/db_get_all_tags',
    method: "POST",

 }).success(function (data) {

    $scope.all_tags = data;

});

$scope.show_info = function() {

    var result_info = DbService.get_info( $stateParams.db_data_id );

    result_info.then( function( data )
    {
        $scope.info_data = data;

    });

};

ATTEMPT 1:

It happens a very strange behavior. I don't see the tags in the info page of the user, and not even in the ui-select. Except if refresh 5/6 times, then suddenly it will magically work, displaying the tags in the user info page and in the ui-select. In both cases, working and not, i get several error message of the same kind:

Cannot read property 'length' of undefined.

ATTEMPT 2:

In order to resolve this problem, I have added this code in the controller:

$scope.info_data = { tags: [] };
$scope. all_tags = [];

And i don't get anymore any error message. The app is stable and i can see the proper tags in the user info page. The only problem is that the tags are not loaded anymore in the ui-select.

If i select a new tag then it works fine, but i loose the pre-existing tags.

QUESTION(s):

How can i make ui-select properly working? (currently v0.8.3) There is a problem of conflict?

How can i properly call pre-existent data from the server?

Thank you very much!

like image 476
FrancescoMussi Avatar asked Oct 22 '14 11:10

FrancescoMussi


2 Answers

You haven't been particularly descriptive with the errors you're seeing so I don't know if the following will help..

I had a problem originally when using the ui-select demo code as an example because they're using the propsFilter filter which is a custom filter they have written for the demo:

<ui-select-choices repeat="tag in all_tags | propsFilter: {name: $select.search}">

I am assuming you're not including this filter in your code which may be a reason you're experiencing a problem. You can resolve it by using angular's normal filter:

<ui-select-choices repeat="tag in all_tags | filter: {name: $select.search}">

Alternatively, if you have multiple properties to filter you can write the propsFilter filter to filter on OR rather than AND. If you use 'filter' to filter multiple properties it will try to match the search value across all of the properties.

app.filter('propsFilter', function() {
  return function(items, props) {
            var out = [];
                if (angular.isArray(items)) {
                  items.forEach(function(item) {
                        var itemMatches = false;

                        var keys = Object.keys(props);
                        for (var i = 0; i < keys.length; i++) {
                              var prop = keys[i];
                              var text = props[prop].toLowerCase();
                              if (item[prop].toString().toLowerCase().indexOf(text) !== -1) {
                                    itemMatches = true;
                                    break;
                                  }
                            }

                            if (itemMatches) {
                              out.push(item);
                            }
                      });
                } else {
                  // Let the output be the input untouched
                      out = items;
                }

                return out;
          };
    });

you can see the commit with the filter in it here: https://github.com/angular-ui/ui-select/commit/3fac88cfad0ad2369c567142eadba52bdb7998b1

Although if you have some specific filtering requirements I would recommend you to write your own filter to ensure optimum performance.

like image 96
Nick Martin Avatar answered Nov 01 '22 19:11

Nick Martin


I don't know what the situation was like before Select2#4.0, but it's really not all that hard to use it without angular-ui-select (and it's one less dependency)

Just include select2 in your bower dependencies and use it in your link function within the directive:

.directive('someDirective', function() {
    return {
        restrict: 'E',
        link: function(scope, element, attrs) {
            element.find('.your-select2').select2({
                theme: 'classic',
                placeholder: 'Select a placeholder...',
                allowClear: true,
                data: [{ id: 'New', text: 'New'}]...
            });
        },
    };
})

and your HTML:

<select class="your-select2" ng-model="a.model.field"></select>

You can also load the data from the controller via a service if you want, then just use the scope to set it!

I say this as I tried using angular-ui-select because I thought "hey it's Angular, you must use a plugin for it!", but that's not always the case :). Plus I found the docs not so helpful (call me lazy but hey)

like image 40
a7omiton Avatar answered Nov 01 '22 19:11

a7omiton