Bitmask checkbox group in angular - angularjs

Quite straightforward, but I am fairly new to angular, and I think I have bitwise-sick, so I am kinda stuck :
// Checkboxes control existence of value in an array
var app = angular.module('myApp', []);
app.controller('MainController', function($scope) {
$scope.bitMaskFromDB = 5;
$scope.fruits = [{value:1, label: 'apple'}, {value:2, label:'orange'}, {value:4, label:'pear'}, {value:8, label:'naartjie'}];
});
app.directive('bitMask', function() {
return {
scope: {
bitMask: '=',
value: '#'
},
link: function(scope, elem, attrs ) {
var handler = function(setup) {
if (setup){
var checked = scope.bitMask&scope.value;
elem.prop('checked', checked);
}else{
var checked = elem.prop('checked');
if (!scope.bitMask&scope.value)
scope.bitMask |= scope.value
// elem.prop('checked', !checked);
scope.bitMask ^= scope.value
}
console.log ('bit = '+ scope.bitMask)
// console.log ('value = '+ scope.value)
// console.log ('checked ='+ checked)
};
var setupHandler = handler.bind(null, true);
var changeHandler = handler.bind(null, false);
elem.on('change', function() {
scope.$apply(changeHandler);
});
scope.$watch('bitMask', setupHandler, true);
}
};
});
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script src="app.js"></script>
</head>
<body ng-app="myApp" ng-controller='MainController'>
Bitmask checkboxes <br>
<span ng-repeat="fruit in fruits">
<input type='checkbox' value="{{fruit.value}}" bit-mask='bitMaskFromDB' > {{fruit.label}}<br />
</span>
<div>Current value of bitmask: {{bitMaskFromDB }}</div>
</body>
</html>
I failed to
1/ change the bit mask value correctly to checkbox values and
2/ show/bind value back to controller
http://plnkr.co/edit/3M8KNyOxMBgPwj9jf01q

You are very close my friend.
Here is the fix for you. Well, I don't really remember what they said about that. But there are weird behavior binding primitive to scope
updated your plkr
// Checkboxes control existence of value in an array
var app = angular.module('myApp', []);
app.controller('MainController', function($scope) {
$scope.IforgetHowTheyExplainThis = {bitMaskFromDB:5};
$scope.fruits = [{value:1, label: 'apple'}, {value:2, label:'orange'}, {value:4, label:'pear'}, {value:8, label:'naartjie'}];
});
app.directive('bitMask', function() {
return {
scope: {
bitMask: '=',
value: '#'
},
link: function(scope, elem, attrs ) {
var handler = function(setup) {
if (setup){
console.log ('value1 = '+ scope.value)
var checked = scope.bitMask&scope.value;
elem.prop('checked', checked);
}else{
console.log ('value2 = '+ scope.value)
var checked = elem.prop('checked');
if (!scope.bitMask&scope.value)
scope.bitMask |= scope.value
else
scope.bitMask ^= scope.value
}
console.log ('bit = '+ scope.bitMask)
// console.log ('value = '+ scope.value)
// console.log ('checked ='+ checked)
};
var setupHandler = handler.bind(null, true);
var changeHandler = handler.bind(null, false);
elem.on('change', function() {
scope.$apply(changeHandler);
});
scope.$watch('bitMask', setupHandler, true);
}
};
});
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script src="app.js"></script>
</head>
<body ng-app="myApp" ng-controller='MainController'>
Bitmask checkboxes <br>
<span ng-repeat="fruit in fruits">
<input type='checkbox' value="{{fruit.value}}" bit-mask='IforgetHowTheyExplainThis.bitMaskFromDB' > {{fruit.label}}<br />
</span>
<div>Current value of bitmask: {{IforgetHowTheyExplainThis.bitMaskFromDB }}</div>
</body>
</html>

Related

isolate scope won't update model - angular 1.6

We are trying to use a jquery time entry component in angularjs. We have a directive for the time entry component. When I try to change the ngModel from directive based on DOM value the model is not reflected. Please see the controller, index.html, app.js below.
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css" />
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script src="jquery.plugin.js"></script>
<script src="jquery.timeentry.js"></script>
<script data-require="angular.js#1.0.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js" data-semver="1.0.8"></script>
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Time {{orderPermitViews[0].permitDetails[0].effectiveTimeForDispaly}}!</p>
<div ng-repeat="permitDetail in orderPermitViews[0].permitDetails">
<input type="text" name="spinner" class="time-spinner"
time-spinner ng-model="permitDetail.effectiveTimeForDispaly" >
</div>
</body>
</html>
angular.module('plunker', [])
.directive('timeSpinner', function() {
return {
restrict: 'A',
scope: {timeModel: "=ngModel"},
link: function( scope, elem, attrs) {
$(elem).timeEntry({
spinnerImage: 'assets/img/spinnerUpDown.png',
spinnerSize: [15, 16, 0],
spinnerBigSize: [30, 32, 0],
spinnerIncDecOnly: true,
show24Hours: true
}).change(function () {
scope.timeModel = $(elem).timeEntry('getTime');
console.log("Time model:" + scope.timeModel);
});
scope.$watch('timeModel', function(newValue, oldValue) {
$(elem).timeEntry('setTime', newValue);
console.log("Set time:" + newValue);
});
}
}
})
.controller('MainCtrl', function($scope) {
var permitDetails = new Array();
$scope.orderPermitViews = new Array();
$scope.orderPermitViews[0] = {};
$scope.orderPermitViews[0].permitDetails = new Array();
$scope.orderPermitViews[0].permitDetails[0] = {};
$scope.orderPermitViews[0].permitDetails[0].effectiveTimeForDispaly = new Date();
});
When I change the text, I see the change function getting executed and update the model. However it is not reflected in the HTML {{orderPermitViews[0].permitDetails[0].effectiveTimeForDispaly}}. I need some help in figuring out what is going wrong here.

Angular JS multiple select unable to get the value selected

I am trying to populate a multiple select option using Angular JS . This is my List
var depositoryList =[
{
"depos":"Any",
"deposName":"Any"
},
{
"depos":"DUB",
"deposName":"DUBAI"
},
{
"depos":"MUM",
"deposName":"MUMBAI"
},
{
"depos":"SNG",
"deposName":"SINGAPORE"
}],
// didnt Work
$scope.depositoryId = {value:{depos:'Any'}}
This is how i populate it in HTML
<select multiple
ng-model="depositoryId.value"
data-ng-options="obj.depos + ' - ' + obj.deposName for obj in depositoryList track by obj.depos">
</select>
1)I tried to set default value to Any and i am not able set them .
2) I tried to get the selected value and did alert($scope.depositoryId.value.depos) . Its giving me an undefined alert message
where am i going wrong
Final Edit:
Show Any- Any without any break and get selected values in ng-model
var app = angular.module('myApp', []);
app.controller('MainCtrl', function ($scope) {
$scope.depositoryId = ['Any'];
$scope.depositoryList =[
{
"depos":"Any",
"deposName":"Any"
},
{
"depos":"DUB",
"deposName":"DUBAI"
},
{
"depos":"MUM",
"deposName":"MUMBAI"
},
{
"depos":"SNG",
"deposName":"SINGAPORE"
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app="myApp">
<head></head>
<body ng-controller="MainCtrl">
<select multiple="true" ng-model="depositoryId" ng-options="obj.depos as (obj.depos + ' - ' +obj.deposName) for obj in depositoryList">
</select>
<div>{{depositoryId}}</div>
</body>
</html>
For a more elegant solution without hardcoding the initial value, since you have the string needed in your array, you could do:
<select multiple='true' ng-init="depositoryInitialValue = depositoryList[0].deposName"
ng-model="depositoryInitialValue"
ng-options="obj.depos as (obj.depos + ' - ' + obj.deposName) for obj in depositoryList">
</select>
See plunkr here
hope it helps.
var app = angular.module('ngApp', []);
app.controller('MainCtrl', ['$scope', function($scope) {
'use strict';
$scope.depositoryList = [{
"depos": "Any",
"deposName": "Any"
}, {
"depos": "DUB",
"deposName": "DUBAI"
}, {
"depos": "MUM",
"deposName": "MUMBAI"
}, {
"depos": "SNG",
"deposName": "SINGAPORE"
}]
}]);
<!DOCTYPE html>
<html ng-app="ngApp">
<head lang="en">
<meta charset="utf-8">
<title>maxisam's ngApp</title>
<link href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.2.0/css/bootstrap-combined.min.css" rel="stylesheet">
<link rel="stylesheet" href="style.css">
<script>
document.write('<base href="' + document.location + '" />');
</script>
</head>
<body ng-controller="MainCtrl" class="container">
<br/>
<select multiple='true' ng-init="depositoryInitialValue = depositoryList[0].deposName" ng-model="depositoryInitialValue" ng-options="obj.depos as (obj.depos + ' - ' + obj.deposName) for obj in depositoryList">
</select>
<br /> {{depositoryInitialValue}}
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>
<script src="app.js"></script>
</body>
</html>

Insert directives from custom filters

Is it possible to insert directives from within custom filters?
For example given the following HTML:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.6/css/bootstrap.min.css" />
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.3.x" src="https://code.angularjs.org/1.3.20/angular.js" data-semver="1.3.20"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/1.0.3/ui-bootstrap-tpls.min.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello <span ng-bind-html="name | test"></span>!</p>
</body>
</html>
And javascript:
var app = angular.module('plunker', ['ui.bootstrap']);
app.filter('test', ['$sce', function($sce){
return function(val) {
var out = '<b>' + val + '</b>';
out += '<uib-progressbar value="55">55</uib-progressbar>';
return $sce.trustAsHtml(out);
}
}]);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});
How do I get the "uib-progressbar" to display properly as a progress bar?
From what I've read I'll need to manually $compile the directive and then append the resulting element to the page but to do that the rest of the html (generated in the filter) will need to be rendered first, so it's kind of impossible from what I can see?
I've set up a plunker here: https://plnkr.co/edit/V5SmmQXPdrfKeVEbNwaV?p=preview
Filetrs are not for this, write directive instead, like:
app.directive('test', function() {
return {
restrict : 'E',
template : function(elem, attrs) {
var out = '<b>' + attrs.val + '</b>';
out += '<uib-progressbar value="55">55</uib-progressbar>';
return out;
}
}
});
https://plnkr.co/edit/oQ0AekzCBjd9eiNqhL6c?p=preview

AngularJS - controllers communication

On my site I have the following structure
Header_controller:
myApp.controller('Header_controller',function($scope,$rootScope,$location,Genral_model){
$scope.logout = function(){
var data = {};
$rootScope.$emit('logout_clicked', data); // NOT WORKING
$rootScope.$broadcast('logout_clicked', data); // NOT WORKING
}
});
Users_controller:
myApp.controller('Users_controller', function ($scope,$rootScope,Users_model,$location,$state) {
$rootScope.$on('logout_clicked', function(event, resp) {
Users_model.unRegisterCookies();
});
})
Users_model:
myApp.factory('Users_model', function($rootScope,$http,$cookies) {
var factory={};
factory.unRegisterCookies = function(){
alert('log out');
}
return factory;
});
I'm trying to invoke unRegisterCookies function by sending broadcast from Header_controller to Users_controller, but it's doesn't work with emit and not with broadcast.
How to make it work?
This is the same basic code you're trying and it's working for me. Maybe there's an error somewhere else in your code?
http://plnkr.co/edit/SADWwkZWztoVJVjv0tKt
html:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.0.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="HeaderCtrl">
<p>Button has been hit {{counter}} times.</p>
</div>
<div ng-controller="UsersCtrl">
<button ng-click="pushme()">Count Me In</button>
</div>
</body>
</html>
script:
var app = angular.module('plunker', []);
app.controller('HeaderCtrl', function($scope, $rootScope) {
$scope.counter = 0;
$rootScope.$on('countMeIn', function (event, data) {
$scope.counter = $scope.counter + 1;
});
});
app.controller('UsersCtrl', function($scope, $rootScope) {
$scope.pushme = function() {
$rootScope.$emit("countMeIn", {});
};
});
See this plnkr for working version of your code:
http://plnkr.co/edit/JN5yWBUjmjBh5m7FiQww
This is pretty identical to the code you posted and it's working. You might have some other error in your page. If you are in Chrome or FireFox, pull up the console and see what errors are being shown for your page.
html:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.0.x" src="https://code.angularjs.org/1.2.28/angular.js" data-semver="1.2.28"></script>
<script data-require="angular.js#1.0.x" src="https://code.angularjs.org/1.2.28/angular-cookies.js" data-semver="1.2.28"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="HeaderCtrl">
<h1>Headers Controller</h1>
<button ng-click="logout()">Log out</button>
</div>
<div ng-controller="UsersCtrl">
<h1>Users Controller</h1>
</div>
</body>
</html>
script:
var myApp = angular.module('myApp', ['ngCookies']);
myApp.controller('HeaderCtrl', function($scope, $rootScope) {
$scope.logout = function(){
var data = {};
$rootScope.$emit('logout_clicked', data); // NOT WORKING
$rootScope.$broadcast('logout_clicked', data); // NOT WORKING
}
});
myApp.controller('UsersCtrl', function($scope, $rootScope, Users_model) {
$rootScope.$on('logout_clicked', function(event, resp) {
Users_model.unRegisterCookies();
});
});
myApp.factory('Users_model', function($rootScope,$http,$cookies) {
var factory={};
factory.unRegisterCookies = function(){
alert('log out');
}
return factory;
});

How do I insert text into active textarea using angularjs

I am pretty new to AngularJS and I am stuck on a project for a client. I need to have multiple textareas on a page and have the last active one populate with text when I press a button. I found a plunker that does what I need with an input and a single textarea but when I add an extra textarea, I either end up populating both textareas or just one.
Plunker that I'm trying to edit:
var app = angular.module('plunker', []);
app.controller('MyCtrl', function($scope, $rootScope) {
$scope.items = [];
$scope.add = function() {
$scope.items.push($scope.someInput);
$rootScope.$broadcast('add', $scope.someInput);
}
});
app.directive('myText', ['$rootScope',
function($rootScope) {
return {
link: function(scope, element, attrs) {
$rootScope.$on('add', function(e, val) {
var domElement = element[0];
if (document.selection) {
domElement.focus();
var sel = document.selection.createRange();
sel.text = val;
domElement.focus();
} else if (domElement.selectionStart || domElement.selectionStart === 0) {
var startPos = domElement.selectionStart;
var endPos = domElement.selectionEnd;
var scrollTop = domElement.scrollTop;
domElement.value = domElement.value.substring(0, startPos) + val + domElement.value.substring(endPos, domElement.value.length);
domElement.focus();
domElement.selectionStart = startPos + val.length;
domElement.selectionEnd = startPos + val.length;
domElement.scrollTop = scrollTop;
} else {
domElement.value += val;
domElement.focus();
}
});
}
}
}
])
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link href="style.css" rel="stylesheet" />
<script data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular.js" data-require="angular.js#1.2.x"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="MyCtrl">
<input ng-model="someInput">
<button ng-click="add()">Add</button>
<p ng-repeat="item in items">Created {{ item }}</p>
</div>
<textarea my-text="">
</textarea>
</body>
</html>
I'm not sure if I need to keep the $on that's in the fiddle or use $watch instead. Also, I think I should be using document.activeElement somewhere in there or not. Any help or snippets explaining what to be done would be much appreciated
A quick prototype, if this match what you are looking for, please note that it is only a draft and should be refactored properly. I would refrain from using DOM element attribute too much in Angular and injecting rootScope just for one simple boardcasting is somewhat overkill.
<html>
<head>
</head>
<body ng-app="App" ng-controller="MyCtrl">
<input type="text" ng-model="input">
<span ng-bind="input"></span>
<button ng-click="populate()">Populate</button>
<textarea my-text></textarea>
<textarea my-text></textarea>
<textarea my-text></textarea>
<textarea my-text></textarea>
<script src="angular.js"></script>
<script>
(function(){
angular.module("App",[])
.value('TextManager', {
lastActive: -1,
texts: []
})
.controller('MyCtrl', function($scope, TextManager){
$scope.input = '';
$scope.populate = function(){
console.log(TextManager.texts[TextManager.lastActive]);
if (TextManager.texts[TextManager.lastActive])
TextManager.texts[TextManager.lastActive][0].value += $scope.input;
};
})
.directive("myText", function(TextManager){
return {
restrict: "A",
scope: [],
link: function(scope, element, attr){
TextManager.texts.push(element);
scope.index = TextManager.texts.length-1;
element.index = scope.index;
element.on('click', function(event){
TextManager.lastActive = scope.index;
});
}
};
});
})();
</script>
</body>
</html>

Resources