0

I have a list which shows a query of words from a db, from there i can click on one word and it gets pushed to another list which i can save than. With this i can create different wordlists. What i want to do is to give the words another color if i have already pushed them on my new list.

To do so i use a function in my controller to compare the two lists with and angular.foreach. If wordFromQuery._id === wordOnNewList._id i gave the words another background color with ng-style.

Here is my code:

View

ng-repeat="word in searchWords" ng-click="addWordToSet(word)" ng-class="isInside(word)" ng-style="{ background: choosenWords.value == 'exist' ? 'lightgreen' : 'white' }"

I iterate over the words query (searchWords) and with addWordtoSet(word) i push them to my other array (this works great). isInside(word) will do the angular.foreach to compare the two arrays and the ng-style should provide different styles, according to the if-statement from the isInside function.

Controller

    $scope.isInside = function (word) {
      angular.forEach($scope.currentWordlist, function (item) {
        if (item._id === word._id) {
          $scope.choosenWords = {value: 'exist'};
        } else {
          $scope.choosenWords = {value: 'notOnList'};
        }
       });
    };

The angular.forEach compares the words from both arrays. currentWordList is the array in which i push with addWordToSet

What happens is that one word on the searchword array gets the green color (and its set of by +1, so if the word in arraypos. 0 would be right the arraypos. 1 gets the green color).

I suspect that i did it all wrong with the ng-class element, but i didnt found another good opportunity to get the word._id another way. Did i do something obviously wrong here?

I would appreciate tips or hints. Thanks!

UPDATE

It works quite fine with the addWordToSet function:

      $scope.addWordToSet = function (word) {
        var exists = false;
        angular.forEach($scope.currentWordlist, function (item) {
          if (item._id === word._id) {
          exists = true;
        }
      });
        if (exists === false) {
          $scope.currentWordlist.push(word);
        }
      };

The only thing i need i think is not doing this on click but instantly without clicking anything. is my ng-class="isInside(word)" the right choice for that?

d8ta
  • 167
  • 2
  • 13

3 Answers3

1

You can assign a color to a variable inside the same function and use it in the view.

$scope.isInside = function (word) {
  angular.forEach($scope.currentWordlist, function (item) {
    if (item._id === word._id) {
      $scope.choosenWords = {value: 'exist'};
      $scope.color = 'lightgreen'
    } else {
      $scope.choosenWords = {value: 'notOnList'};
      $scope.color = 'white'
    }
   });
};

ng-style="{'background-color':color}"

View:

ng-repeat="word in searchWords" ng-click="addWordToSet(word)" ng-class="isInside(word)" ng-style="{'background-color':color}" }"
Sravan
  • 18,467
  • 3
  • 30
  • 54
  • That sounds really nice. A thought in this direction myself but it was not working out. Your solution makes absolute sense but somehow only one word is green, and its always the word i click + 1 so i think i need to check my query if there is anything wrong here. – d8ta Nov 28 '16 at 08:43
  • what is the issue you are getting now? – Sravan Nov 28 '16 at 09:29
  • It only showed the wrong word marked in the frontend, i will provide an answer how i manage to do this at the end – d8ta Nov 29 '16 at 09:57
  • yes, but i came up with another really good working version, i posted it at the end here as answer. But thank you for the Information. With your infos i could solved it by changing it a bit and testing things. So thanks a lot! – d8ta Nov 29 '16 at 10:09
0

Try

$scope.choosenWords.value = 'exist';

Also initialize choosenWords at the start of the controller.

If this doesn't work check the order of priority of execution of the ng modules.

Is the controller initialized through a partial?

Danh
  • 5,916
  • 7
  • 30
  • 45
user3086298
  • 290
  • 1
  • 4
  • 14
  • if i use choosenWords without the object i get TypeErrors that value is not set. What do you mean bei "initialized throught a partial", and how do i check the order of priority for the ng-modules? – d8ta Nov 26 '16 at 07:47
  • I believe there was a bug a while back when a controller was set as part of a partial, that's ions ago... priority is used to sort directives before they are compiled checkout the angular docs... – user3086298 Nov 26 '16 at 07:59
  • Nested templates referred to as partials – user3086298 Nov 26 '16 at 08:05
0

I sat together with a friend and we came up with a working version of this problem, so here is the solution in case someone has a similar problem and hand.

In the Controller we used the following function:

    $scope.isSelected = function (word) {
      var found = false;
      angular.forEach($scope.currentWordlist, function (item) {
        if (item._id === word._id) {
          found = true;
        }
      });
    return found;
    };

It uses the foreach to compare the arrays and if there are ids that are a match the found bool returns true.

In the View we used the following:

ng-class="isSelected(word) ? 'marked' : 'unmarked'"

which uses the marked or unmarked css class for, in my case, coloring the matched words in green (marked). All other words are getting the background color white.

here is the CSS:

.marked {
  background: $lightgreen;
}

.unmarked {
  background: $nicewhite;
}

In my case i use scss and colorvariables, but you can, of course use all other colors like red; or #fff. The result of this are two arrays that are views. The first one is a searchquery from a DB which shows all words. The second is a new array in which you can push words by clicking on one of the words. If you do so the word gets pushed AND it gets a green background. Thats it, i hope this is good information.

d8ta
  • 167
  • 2
  • 13