1

I have 3 dropdowns.Dropdown first will control, out of Dropdown 2 & Dropdown 3 which dropdown to populate.

I am doing this using ng-if, I am able to use ng-if with the second dropdown, but when I unable to use ng-if with the third dropdown.

Reason I figured out is, dropdown 2 is not binding any value with it.

I don't know why this is happening.

code

<select ng-model="selcetedValue">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
  <option value="D">D</option>
</select>
<select ng-model="selcetedValueSecond" ng-if="selcetedValue === 'B'">
  <option value="E">E</option>
  <option value="F">F</option>
  <option value="G">G</option>
  <option value="H">H</option>
</select>
<select ng-model="selcetedValueThird" ng-if="selcetedValueSecond === 'H'">
  <option value="I">I</option>
  <option value="J">J</option>
  <option value="K">K</option>
  <option value="L">L</option>
</select>

<p>Selected value from first dropdown:: <i>{{selcetedValue}}</i></p>
<p>Selected value from second dropdown:: <i>{{selcetedValueSecond}}</i></p>


Please help.

Vivz
  • 6,625
  • 2
  • 17
  • 33
mayank bisht
  • 784
  • 9
  • 19
  • `ng-show` will only hide the control from the page, but `ng-if`will remove the component from the DOM. I want to remove component if it is not required. – mayank bisht Sep 07 '17 at 06:19
  • 1
    Here is the working one: https://jsfiddle.net/8wtvd46q/3/ – Rakib Sep 07 '17 at 06:34

5 Answers5

5

ng-if will create its own child scope. So your ng-model values are not directly binded to the controllers scope. You can use controller as syntax to avoid it. Other solution is to bind your ng-model to an object. controller as syntax is more preferred as it will implicitly take care of the Dot Rule.

var app = angular.module("app", []);
 app.controller("myCtrl", function() {
   var vm =this;
 });
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
</head>
<body ng-controller="myCtrl as vm">
<select ng-model="vm.selcetedValue">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
  <option value="D">D</option>
</select>
<select ng-model="vm.selcetedValueSecond" ng-if="vm.selcetedValue === 'B'">
  <option value="E">E</option>
  <option value="F">F</option>
  <option value="G">G</option>
  <option value="H">H</option>
</select>
<select ng-model="vm.selcetedValueThird" ng-if="vm.selcetedValueSecond === 'H'">
  <option value="I">I</option>
  <option value="J">J</option>
  <option value="K">K</option>
  <option value="L">L</option>
</select>

<p>Selected value from first dropdown:: <i>{{vm.selcetedValue}}</i></p>
<p>Selected value from second dropdown:: <i>{{vm.selcetedValueSecond}}</i></p>
<p>Selected value from third dropdown:: <i>{{vm.selcetedValueThird}}</i></p>
</body>
</html>

For more Info: What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

Vivz
  • 6,625
  • 2
  • 17
  • 33
4

You should use controller as syntax:

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>

<div ng-app="myApp">
<div ng-controller="myctrl as $ctrl">
<select ng-model="$ctrl.selcetedValue">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
  <option value="D">D</option>
</select>
<select ng-model="$ctrl.selcetedValueSecond" ng-if="$ctrl.selcetedValue === 'B'">
  <option value="E">E</option>
  <option value="F">F</option>
  <option value="G">G</option>
  <option value="H">H</option>
</select>
<select ng-model="$ctrl.selcetedValueThird" ng-if="$ctrl.selcetedValueSecond === 'H'">
  <option value="I">I</option>
  <option value="J">J</option>
  <option value="K">K</option>
  <option value="L">L</option>
</select>

<p>Selected value from first dropdown:: <i>{{$ctrl.selcetedValue}}</i></p>
<p>Selected value from second dropdown:: <i>{{$ctrl.selcetedValueSecond}}</i></p>

</div>
</div>
<script>
angular.module('myApp',[])
.controller('myctrl',function(){
})
</script>
</body>
</html>
Nitesh Rana
  • 512
  • 1
  • 7
  • 20
  • You should always bind your model with dot. – Nitesh Rana Sep 07 '17 at 06:22
  • https://thinkster.io/egghead/the-dot Check this link. Upvote if helpful.. – Nitesh Rana Sep 07 '17 at 06:28
  • 1
    http://jimhoskins.com/2012/12/14/nested-scopes-in-angularjs.html or you can see this link. Much helpful.. – Nitesh Rana Sep 07 '17 at 06:29
  • So, my problem was, I was not using `Dot`, that's why I couldn't get the selected value of `Dropdown 2`, because it is referring to new space, instead of pointing to parent. – mayank bisht Sep 07 '17 at 06:39
  • I didnot understand this line `
    `
    – mayank bisht Sep 07 '17 at 06:40
  • advantage is that it allows you to define your controllers as a simple javascript constructor function with properties and functions exposed directly from the instantiated object rather than the $scope. Please mark correct if it solved your problem. Thanks.. – Nitesh Rana Sep 07 '17 at 06:40
3

ngIf creates its own scope, You should define an object in $scope then use that to bind ngModel with select elements.

$scope.selectValues ={};

Then use it in view

<select ng-model="selectValues.selcetedValue">
</select>
<select ng-model="selectValues.selcetedValueSecond" ng-if="selectValues.selcetedValue === 'B'">
</select>
<select ng-model="selectValues.selcetedValueThird" ng-if="selectValues.selcetedValueSecond === 'H'">
</select>

var app = angular.module("app", []);
app.controller("myCtrl", function($scope, $filter, $sce) {
  $scope.selectValues = {};
});
<!DOCTYPE html>
<html ng-app="app">

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
</head>

<body ng-controller="myCtrl">
  <select ng-model="selectValues.selcetedValue">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
  <option value="D">D</option>
</select>
  <select ng-model="selectValues.selcetedValueSecond" ng-if="selectValues.selcetedValue === 'B'">
  <option value="E">E</option>
  <option value="F">F</option>
  <option value="G">G</option>
  <option value="H">H</option>
</select>
  <select ng-model="selectValues.selcetedValueThird" ng-if="selectValues.selcetedValueSecond === 'H'">
  <option value="I">I</option>
  <option value="J">J</option>
  <option value="K">K</option>
  <option value="L">L</option>
</select>

  <p>Selected values <i>{{selectValues}}</i></p>
</body>

</html>
Satpal
  • 132,252
  • 13
  • 159
  • 168
2

You should use ng-show/hide instead of ng-if, because of your second dropdown DOM is not in the current scope if you using ng-if. So the third dropdown ng-if does not knows which scope value is assigned in there expression.

ngIf

The ngIf directive removes or recreates a portion of the DOM tree based on an expression. If the expression assigned to ngIf evaluates to a false value then the element is removed from the DOM, otherwise a clone of the element is reinserted into the DOM. Read this discussion for more details; what is the difference between ng-if and ng-show/ng-hide

angular.module("aaa",[]).controller("ccc",function($scope)
{
$scope.selcetedValue="";
$scope.selcetedValueSecond="";
$scope.selcetedValueThird="";
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="aaa" ng-controller="ccc">

<select ng-model="selcetedValue">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
  <option value="D">D</option>
</select>
<select ng-model="selcetedValueSecond" ng-show="selcetedValue === 'B'">
  <option value="E">E</option>
  <option value="F">F</option>
  <option value="G">G</option>
  <option value="H">H</option>
</select>
<select ng-model="selcetedValueThird" ng-show="selcetedValueSecond === 'H'">
  <option value="I">I</option>
  <option value="J">J</option>
  <option value="K">K</option>
  <option value="L">L</option>
</select>

<p>Selected value from first dropdown:: <i>{{selcetedValue}}</i></p>
<p>Selected value from second dropdown:: <i>{{selcetedValueSecond}}</i></p>

</div>
Ramesh Rajendran
  • 37,412
  • 45
  • 153
  • 234
1

Use ng-show/ng-hide instead

<select ng-model="selcetedValue">
  <option value="A">A</option>
  <option value="B">B</option>
  <option value="C">C</option>
  <option value="D">D</option>
</select>
<select ng-model="selcetedValueSecond" ng-show="selcetedValue === 'B'">
  <option value="E">E</option>
  <option value="F">F</option>
  <option value="G">G</option>
  <option value="H">H</option>
</select>
<select ng-model="selcetedValueThird" ng-show="selcetedValueSecond === 'H'">
  <option value="I">I</option>
  <option value="J">J</option>
  <option value="K">K</option>
  <option value="L">L</option>
</select>

<p>Selected value from first dropdown:: <i>{{selcetedValue}}</i></p>
<p>Selected value from second dropdown:: <i>{{selcetedValueSecond}}</i></p>

See this JsFiddle

Rakesh Chand
  • 3,105
  • 1
  • 20
  • 41