3

My purpose is to make a drop down select with options from 0 to 9 digits. I'm actually composing 4 such modules together and running calculations. Now I met problem on reset the 4 selects into a default state after user accidentally selected options that can not be posted to the backend.

<select ng-init="q8_1_selected" ng-model="q8_1_selected" ng-change="q8_select_digit_1(q8_1_selected)" ng-options="item1 for item1 in q8_digit_array">
                        {{item1}}
</select>

I have this simple select code using Angular, now I can get the q8_1_selected value with $scope.q8_1_selected no problem, however when I set the value like

$scope.q8_1_selected = 1; 

This is not updating the selected option on the web page. What's wrong?

q8_digit_array is [0..9], a digit array.

Just tried,

<option ng-selected="item1 == q8_1_selected">{{item1}}</option>

to replace {{item1}}, but after $scope.q8_1_selected = 1; it still not changing anything on the web page. After removing ng-init, still not working.

Update: It is just the web page not updating.

Maybe I should show the whole picture, I'm actually using Ionic, which uses AngularJS for all the bindings.

 <select class="q8_select" ng-model="q8_1_selected" ng-change="q8_select_digit_1(q8_1_selected)" ng-options="item1 for item1 in q8_digit_array">
                        {{item1}}
 </select>

js,

//change function, I have total 4 like this one.
$scope.q8_select_digit_1 = function(digit){
        $scope.q8_1_selected = parseInt(digit) ;
        q8_update_answer() ;
      }
//each time the answer must be calcluated
 var q8_update_answer = function(){
        var n1 = $scope.q8_1_selected * 10 + $scope.q8_2_selected ;
        var n2 = $scope.q8_3_selected * 10 + $scope.q8_4_selected ;

        //!!!!---- Problem happens here, the following changes on $scope.q8_1_selected etc. Sometimes working, but most of the time, not updating the web page ----!!!!
        //However the value of $scope.q8_1_selected and all others are correct. The data is binded, at the JS side. 

        if (n1 == 0){
          $scope.q8_1_selected = 0 ;
          $scope.q8_2_selected = 1 ;
        }
        else if (n2 == 0){
          $scope.q8_3_selected = $scope.q8_1_selected ;
          $scope.q8_4_selected = $scope.q8_2_selected ;
        }
        else if (n2 < n1){
          $scope.q8_3_selected = $scope.q8_1_selected ;
          $scope.q8_4_selected = $scope.q8_2_selected ;
        }

        n1 = $scope.q8_1_selected * 10 + $scope.q8_2_selected ;
        n2 = $scope.q8_3_selected * 10 + $scope.q8_4_selected ;

        $rootScope.answerData[$scope.whichQuestion-1] = [n1,n2] ;


      }
tomriddle_1234
  • 3,145
  • 6
  • 41
  • 71

3 Answers3

1

I write answer in order to avoid flood in comment.

This should works :

<select ng-init="q8_1_selected" ng-model="q8_1_selected" ng-change="q8_select_digit_1(q8_1_selected)" ng-options="item1 for item1 in q8_digit_array" ng-true-value="'YES'" ng-false-value="'NO'">
                        {{item1}}
</select>

Then :

$scope.q8_1_selected = 'YES'; // checked

$scope.q8_1_selected = 'NO'; // unchecked

You can put whatever you want in ng-true-value="'YES'" and ng-false-value="'NO'".

According your need, as I understand, you can put digit instead.

EDIT :

Try this :

html

 <select class="q8_select" ng-model="q8_1_selected" ng-change="q8_select_digit_1()" ng-options="item1 for item1 in q8_digit_array">
                        {{item1}}
 </select>

js

//change function
    $scope.q8_select_digit_1 = function(){
      $scope.q8_1_selected = parseInt($scope.q8_1_selected) ;
      q8_update_answer() ;
    }
    //each time the answer must be calcluated
    var q8_update_answer = function(){
      var n1 = $scope.q8_1_selected * 10 + $scope.q8_2_selected ;
      var n2 = $scope.q8_3_selected * 10 + $scope.q8_4_selected ;

      //!!!!---- Problem happens here, the following changes on $scope.q8_1_selected etc. Sometimes working, but most of the time, not updating the web page ----!!!!
      if (n1 == 0){
        $scope.q8_1_selected = 0 ;
        $scope.q8_2_selected = 1 ;
      }
      else if (n2 == 0){
        $scope.q8_3_selected = $scope.q8_1_selected ;
        $scope.q8_4_selected = $scope.q8_2_selected ;
      }
      else if (n2 < n1){
        $scope.q8_3_selected = $scope.q8_1_selected ;
        $scope.q8_4_selected = $scope.q8_2_selected ;
      }

      n1 = $scope.q8_1_selected * 10 + $scope.q8_2_selected ;
      n2 = $scope.q8_3_selected * 10 + $scope.q8_4_selected ;

      $rootScope.answerData[$scope.whichQuestion-1] = [n1,n2] ;
      $scope.$apply()

    }

Not sure but if it's still not working, it might be due to some async troubles...

Hope it helps. :)

Emidomenge
  • 1,172
  • 17
  • 26
  • I have 10 digital values in the options, I 'm confused 'yes' or 'no' will work in my case ? – tomriddle_1234 Aug 26 '16 at 07:24
  • @tomriddle_1234 Yes, it should. In your function `q8_select_digit_1(q8_1_selected)` which is in your ng-change, you set somewhere 'yes' or 'no' value to select or not the option. Maybe you can also try to put `$scope.$apply()` to update changes on the view, but it's not suppose to be a requirement according my knowledge.. – Emidomenge Aug 26 '16 at 07:29
  • I updated my code, thank you so much, but I'm still confused. – tomriddle_1234 Aug 26 '16 at 08:33
  • I have an idea, http://stackoverflow.com/questions/35506864/ionic-select-does-not-update-function-dependent-on-scope-variable. – tomriddle_1234 Aug 26 '16 at 08:46
  • @tomriddle_1234 I edited my post, take a look and tell me if behaviour improved or not. :) Edit : Which error ? – Emidomenge Aug 26 '16 at 08:46
  • 1
    Sovled, check my own answer. Thank you! – tomriddle_1234 Aug 26 '16 at 10:04
1

Try this out:

<select ng-model="q8_1_selected" ng-change="q8_select_digit_1(q8_1_selected)" ng-options="item1 for item1 in q8_digit_array"></select>

and in controller

$scope.q8_1_selected = $scope.q8_digit_array[1];

UPDATE

I guess you don't need to make a function which trigger on onChange of select. Each time value change, it automatically assigns in q8_1_selected model. If you're going to manipulate, then you could direct user $scope.q8_1_selected and it will contain the selected option. I hope it may help with the code. :)

Vineet
  • 4,525
  • 3
  • 23
  • 42
  • I think you might not be right, if I remove the ng-change, the q8_1_selected is not updated in my case – tomriddle_1234 Aug 26 '16 at 09:04
  • Because you're using `ng-init` for the same model too. – Vineet Aug 26 '16 at 09:15
  • In the code above, I already removed ng-init. My problem is actually the ng-model value is correct, but it is not bind to the web page. – tomriddle_1234 Aug 26 '16 at 09:22
  • There are many ways to show the changes on views. You can go through `ndDirective`. In such cases you can tell angular forcefully to apply the changes to show on the view. Actually in your case angular doesn't know whether the variable is changed. You can use `$scope.$apply()` in such cases. It throws error, if it will be used in between the ongoing process. Let me know what error are you getting ? – Vineet Aug 26 '16 at 09:47
  • Sovled, check my own answer. Thank you! – tomriddle_1234 Aug 26 '16 at 10:04
0

I'm quite excited that I just met one of the most important gotcha in AngularJS. Please have a look here 'the always dot practice'. And this official document. And a video presentation. What I had to do is to add the dot in all the ng-model directives.

So the data model must be changed to,

 var q8_result = [0,1,0,1] ;

      $scope.q8_s_obj = {
        q8_1_selected: q8_result[0],
        q8_2_selected: q8_result[1],
        q8_3_selected: q8_result[2],
        q8_4_selected: q8_result[3]
      } ;

And the html,

<select class="q8_select" ng-model="q8_s_obj.q8_3_selected" ng-change="q8_select_digit_3(q8_s_obj.q8_3_selected)" ng-options="item3 for item3 in q8_digit_array">        
     {{item3}}            
 </select>

The ng-change,

$scope.q8_select_digit_3 = function(digit){   
  $scope.q8_s_obj.q8_3_selected = parseInt(digit) ;
  q8_update_answer() ;
}

And finally the update function,

var q8_update_answer = function(){
        var n1 = $scope.q8_s_obj.q8_1_selected * 10 + $scope.q8_s_obj.q8_2_selected ;
        var n2 = $scope.q8_s_obj.q8_3_selected * 10 + $scope.q8_s_obj.q8_4_selected ;

        if (n1 == 0){
          $scope.q8_s_obj.q8_1_selected = 0 ;
          $scope.q8_s_obj.q8_2_selected = 1 ;
        }
        else if (n2 == 0){
          $scope.q8_s_obj.q8_3_selected = $scope.q8_s_obj.q8_1_selected ;
          $scope.q8_s_obj.q8_4_selected = $scope.q8_s_obj.q8_2_selected ;
        }

        else if (n2 < n1){
          $scope.q8_s_obj.q8_3_selected = $scope.q8_s_obj.q8_1_selected ;
          $scope.q8_s_obj.q8_4_selected = $scope.q8_s_obj.q8_2_selected ;
        }

        n1 = $scope.q8_s_obj.q8_1_selected * 10 + $scope.q8_s_obj.q8_2_selected ;
        n2 = $scope.q8_s_obj.q8_3_selected * 10 + $scope.q8_s_obj.q8_4_selected ;

        $rootScope.answerData[$scope.whichQuestion-1] = [n1,n2] ;

        //$apply() will not work here, if it must be there, it can be the new evalAsync(), but it hasn't to be there, this is not need to be explicit.
        //$scope.$evalAsync() ;

   }
Community
  • 1
  • 1
tomriddle_1234
  • 3,145
  • 6
  • 41
  • 71