0

I'm using AngularJs to change visibility of certain DOM elements. The visibility depends on what value was selected in a dropdownlist. More specifically, on a data-attribute of the selected option tag. I cannot populate the dropdown via AngularJs, because it's an existing ASP.NET control.

I thought about using ng-change and call a method on my controller but I'd have to pass an argument. This argument is in the DOM and not in my controller. Obviously, I'd like to keep it this way, and not access the DOM in my controller.

I've made a jsFiddle, but this is my code:

HTML

<body ng-app>
    <div ng-controller="VehicleDetailsCtrl">
         <select ng-model="selectedValue" ng-change="update()">
             <option value="1" data-carType="Car">Car 1</option>
             <option value="2" data-carType="Car">Car 2</option>
             <option value="3" data-carType="Truck">Truck</option>
        </select>
        <div ng-hide="isTruck">
            Hide if a truck was selected.
        </div>
    </div>
</body>

Javascript

function VehicleDetailsCtrl($scope) {
    $scope.isTruck = false;
    $scope.selectedValue = null;
    $scope.update = function() {
        $scope.isTruck = !$scope.isTruck;
        // hide div here?
        // but then I'd need to know the selected option, 
        // but I don't want to reference the DOM here.
    };
}

Am I approaching this in the wrong way?

Keep in mind that I cannot let AngularJs populate the select because ASP.NET already does that for me (and I can't change that at the moment).

Also, I need both the selectedValue (for post-back and saving it to the database) and the data-carType (for changing the DOM). I don't know at runtime what the id (or value) of the Truck option is.

2 Answers 2

3

Use a directive to create an object of vehicle types and watch the model value of the select to update your isTruck variable:

HTML:

 <select ng-model="selectedValue" check-is-truck>

JS:

var app = angular.module('myApp', []);

app.directive('checkIsTruck', function(){
    return function(scope, element, attrs){
        scope.vehicleTypes = {};
        scope.selectedType = false;
        angular.forEach(element.find('option'), function(item, idx) {
            scope.vehicleTypes[item.value] = item.dataset.cartype; 
        });  
        scope.$watch('selectedValue', function() {
            scope.selectedType=scope.vehicleTypes[scope.selectedValue];
            scope.isTruck = scope.selectedType == 'Truck'
        })
    };
})

function VehicleDetailsCtrl($scope) {
    $scope.isTruck = false;
    $scope.selectedValue = null;
}

DEMO: http://jsfiddle.net/7ttr6/2/

Sign up to request clarification or add additional context in comments.

1 Comment

In the end, I went with KnockoutJs, but you're solution works fine.
0

You don't need ng-change to update the value because ng-model takes care of that. And in ng-hide you need to simply compare the selectedValue with the value of 'Truck' option (int 3):

<select ng-model="selectedValue">
     <option value="1" data-carType="Car">Car 1</option>
     <option value="2" data-carType="Car">Car 2</option>
     <option value="3" data-carType="Truck">Truck</option>
</select>
<div ng-hide="selectedValue==3">
    Hide if a truck was selected.
</div>

Fiddle

1 Comment

No can do. I edited my question to clarify, but at runtime, I don't know that Truck's value is 3.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.