I am implementing a dropdown for which I am writing my own directive. I am not using any kind of input element hence not using ngModel. Is two way binding possible with custom attributes?
var mainApp = angular.module('mainApp', []);
mainApp.directive('tableDropdown', ['$timeout',
function($timeout) {
return {
restrict: 'C',
scope: {
selectedFilter: '=?'
},
link: function(scope, elem, attrs) {
$timeout(function() {
angular.element(elem).find('li:first-child').addClass(angular.element(elem).find('li').hasClass('selected') ? '' : 'selected');
scope.selectedFilter.cycleStatus = null;
angular.element(elem).find('li').click(function(e) {
if (angular.element(this).closest('ul').hasClass('active')) {
angular.element(this).closest('ul').removeClass('active');
scope.selectedFilter.selected = angular.element(this).attr('value');
} else {
angular.element(this).closest('ul').addClass('active');
scope.selectedFilter.selected = null;
}
angular.element(this).addClass('selected').siblings().removeClass('selected');
})
}, 0);
}
}
}
])
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<th ng-app="mainApp" ng-init="datefilter.selected=null">
--{{datefilter.selected}}
<ul class="tableDropdown" selected-filter="datefilter.selected">
<li value="null" class="default"><span>Cycle Status</span>
</li>
<li value="completed"><span>Completed</span>
</li>
<li value="cancelled"><span>Cancelled</span>
</li>
</ul>
</th>
Please note I did not add the CSS which makes it look like a dropdown. I didn't think it was necessary.
I want to get the selected value in datefilter.selected
and then use it to do something else. Is that even possible? If not are there any workaround?
For the time being, disregarding your code to setup the classes, you can use the below code to change datefilter.selected.cycleStatus
from inside the directive
and it would reflect in the UI.
UI:
--{{datefilter.selected.cycleStatus}}
<ul class="tableDropdown" selected-filter="datefilter.selected">
<li value="null" class="default"><span>Cycle Status</span>
</li>
<li value="completed"><span>Completed</span>
</li>
<li value="cancelled"><span>Cancelled</span>
</li>
</ul>
Code:
scope: {
selectedFilter: '='
},
link: function(scope, elem, attrs) {
$timeout(function() {
scope.selectedFilter.cycleStatus = null;
elem.find('li').click(
function(e) {
scope.selectedFilter.cycleStatus =angular.element(this).attr('value');
scope.$apply();
});
}, 0);
}
Note the scope.$apply()
, which is responsible for changing the value in the UI automatically (otherwise it might reflect late after some other element forces the digest cycle)
Here is an example fiddle: http://jsfiddle.net/Lvc0u55v/5503/